From: Brian Paul Date: Tue, 3 Jul 2012 21:51:22 +0000 (-0600) Subject: svga: fix register collision issue in emit_conditional() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0bd3a75de9002e73214cde883691da558db7bc70;p=mesa.git svga: fix register collision issue in emit_conditional() If the 'dst' register is the same as the 'pass' register we'll generate invalid code. Use a temporary register in that case. Reviewed-by: José Fonseca --- diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index 64dfa557539..42df4195fcc 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -1285,6 +1285,20 @@ static boolean emit_kilp(struct svga_shader_emitter *emit, return submit_op0( emit, inst, temp ); } + +/** + * Test if r1 and r2 are the same register. + */ +static boolean +same_register(struct src_register r1, struct src_register r2) +{ + return (r1.base.num == r2.base.num && + r1.base.type_upper == r2.base.type_upper && + r1.base.type_lower == r2.base.type_lower); +} + + + /* Implement conditionals by initializing destination reg to 'fail', * then set predicate reg with UFOP_SETP, then move 'pass' to dest * based on predicate reg. @@ -1335,6 +1349,16 @@ emit_conditional(struct svga_shader_emitter *emit, break; } + if (same_register(src(dst), pass)) { + /* We'll get bad results if the dst and pass registers are the same + * so use a temp register containing pass. + */ + SVGA3dShaderDestToken temp = get_temp(emit); + if (!submit_op1(emit, inst_token(SVGA3DOP_MOV), temp, pass)) + return FALSE; + pass = src(temp); + } + /* SETP src0, COMPOP, src1 */ if (!submit_op2( emit, setp_token, pred_reg, src0, src1 ))