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; */
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){
{
.Opcode = RC_OPCODE_BEGIN_TEX,
.Name = "BEGIN_TEX"
+ },
+ {
+ .Opcode = RC_OPCODE_KILP,
+ .Name = "KILP",
}
};
* can run simultaneously. */
RC_OPCODE_BEGIN_TEX,
+ /** Stop execution of the shader (GLSL discard) */
+ RC_OPCODE_KILP,
+
MAX_RC_OPCODE
} rc_opcode;
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);
+ }
+}
struct rc_instruction * inst,
void*);
+void radeonTransformKILP(struct radeon_compiler * c);
+
#endif /* __RADEON_PROGRAM_ALU_H_ */