diff options
6 files changed, 43 insertions, 1 deletions
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 5394e04f727..51b2c555502 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -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; */ diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index b53571ab4e7..de2452af26c 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -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){ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c index 128745a5759..04f234f11d8 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c @@ -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", } }; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h index e103ce56371..8b9fa07dde2 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h @@ -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; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c index c922d3d9a44..3cc28972934 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c @@ -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); + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h index 77d444476f2..e6e2cc20c5a 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h @@ -60,4 +60,6 @@ int radeonTransformDeriv( struct rc_instruction * inst, void*); +void radeonTransformKILP(struct radeon_compiler * c); + #endif /* __RADEON_PROGRAM_ALU_H_ */ |