r300/compiler: Implement KILP opcode.
authorTom Stellard <tstellar@gmail.com>
Mon, 5 Jul 2010 20:01:17 +0000 (13:01 -0700)
committerMarek Olšák <maraeo@gmail.com>
Tue, 6 Jul 2010 16:45:32 +0000 (18:45 +0200)
Signed-off-by: Marek Olšák <maraeo@gmail.com>
src/gallium/drivers/r300/r300_tgsi_to_rc.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h

index 5394e04f727c4d8610bf0d5583992ccc63bd5c72..51b2c5555024de54919a8860a9acd3fba1c2a695 100644 (file)
@@ -71,7 +71,7 @@ static unsigned translate_opcode(unsigned opcode)
         case TGSI_OPCODE_COS: return RC_OPCODE_COS;
         case TGSI_OPCODE_DDX: return RC_OPCODE_DDX;
         case TGSI_OPCODE_DDY: return RC_OPCODE_DDY;
-     /* case TGSI_OPCODE_KILP: return RC_OPCODE_KILP; */
+        case TGSI_OPCODE_KILP: return RC_OPCODE_KILP;
      /* case TGSI_OPCODE_PK2H: return RC_OPCODE_PK2H; */
      /* case TGSI_OPCODE_PK2US: return RC_OPCODE_PK2US; */
      /* case TGSI_OPCODE_PK4B: return RC_OPCODE_PK4B; */
index b53571ab4e7d298d3d20146a01367a170a5c6070..de2452af26c8f8c07e515b0997f35ddda901e245 100644 (file)
@@ -101,6 +101,10 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 
        rewrite_depth_out(c);
 
+       /* This transformation needs to be done before any of the IF
+        * instructions are modified. */
+       radeonTransformKILP(&c->Base);
+
        debug_program_log(c, "before compilation");
 
        if (c->Base.is_r500){
index 128745a575977afc2d8c55d6bad3bf9d3bdd439f..04f234f11d8cc4936a9a4f08bf0ca8a6d411dc9c 100644 (file)
@@ -399,6 +399,10 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
        {
                .Opcode = RC_OPCODE_BEGIN_TEX,
                .Name = "BEGIN_TEX"
+       },
+       {
+               .Opcode = RC_OPCODE_KILP,
+               .Name = "KILP",
        }
 };
 
index e103ce56371c881b14e91272b6ebd05b8bf92729..8b9fa07dde2c735f5247f739251eeb28791af6f8 100644 (file)
@@ -199,6 +199,9 @@ typedef enum {
         * can run simultaneously. */
        RC_OPCODE_BEGIN_TEX,
 
+       /** Stop execution of the shader (GLSL discard) */
+       RC_OPCODE_KILP,
+
        MAX_RC_OPCODE
 } rc_opcode;
 
index c922d3d9a448c367c6cfafde010429323ec1b0d0..3cc28972934d1d3143555ca01287384e08a957cc 100644 (file)
@@ -973,3 +973,32 @@ int radeonTransformDeriv(struct radeon_compiler* c,
 
        return 1;
 }
+
+/**
+ * IF Temp[0].x -\
+ * KILP         - > KIL -abs(Temp[0].x)
+ * ENDIF        -/
+ *
+ * This needs to be done in its own pass, because it modifies the instructions
+ * before and after KILP.
+ */
+void radeonTransformKILP(struct radeon_compiler * c)
+{
+       struct rc_instruction * inst;
+       for (inst = c->Program.Instructions.Next;
+                       inst != &c->Program.Instructions; inst = inst->Next) {
+
+               if (inst->U.I.Opcode != RC_OPCODE_KILP
+                       || inst->Prev->U.I.Opcode != RC_OPCODE_IF
+                       || inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) {
+                       continue;
+               }
+               inst->U.I.Opcode = RC_OPCODE_KIL;
+               inst->U.I.SrcReg[0] = negate(absolute(inst->Prev->U.I.SrcReg[0]));
+
+               /* Remove IF */
+               rc_remove_instruction(inst->Prev);
+               /* Remove ENDIF */
+               rc_remove_instruction(inst->Next);
+       }
+}
index 77d444476f2959d46dfc52f3f49b5732d79b6850..e6e2cc20c5ab42657931432d2067c8c1afc542b8 100644 (file)
@@ -60,4 +60,6 @@ int radeonTransformDeriv(
        struct rc_instruction * inst,
        void*);
 
+void radeonTransformKILP(struct radeon_compiler * c);
+
 #endif /* __RADEON_PROGRAM_ALU_H_ */