r600g: take into account force_add_cf in pops
authorVadim Girlin <vadimgirlin@gmail.com>
Wed, 3 Aug 2011 11:35:02 +0000 (15:35 +0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Aug 2011 14:17:50 +0000 (10:17 -0400)
When we have two ENDIFs in a row, we shouldn't modify the pop_count
for the same alu clause twice.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=38163

Note: this is a candidate for the 7.11 branch.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r600/r600_shader.c

index fc56656..c55cdd7 100644 (file)
@@ -2932,25 +2932,34 @@ static int emit_logic_pred(struct r600_shader_ctx *ctx, int opcode)
 
 static int pops(struct r600_shader_ctx *ctx, int pops)
 {
-       int alu_pop = 3;
-       if (ctx->bc->cf_last) {
-               if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) << 3)
-                       alu_pop = 0;
-               else if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3)
-                       alu_pop = 1;
-       }
-       alu_pop += pops;
-       if (alu_pop == 1) {
-               ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3;
-               ctx->bc->force_add_cf = 1;
-       } else if (alu_pop == 2) {
-               ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER) << 3;
-               ctx->bc->force_add_cf = 1;
-       } else {
+       unsigned force_pop = ctx->bc->force_add_cf;
+
+       if (!force_pop) {
+               int alu_pop = 3;
+               if (ctx->bc->cf_last) {
+                       if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) << 3)
+                               alu_pop = 0;
+                       else if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3)
+                               alu_pop = 1;
+               }
+               alu_pop += pops;
+               if (alu_pop == 1) {
+                       ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3;
+                       ctx->bc->force_add_cf = 1;
+               } else if (alu_pop == 2) {
+                       ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER) << 3;
+                       ctx->bc->force_add_cf = 1;
+               } else {
+                       force_pop = 1;
+               }
+       }
+
+       if (force_pop) {
                r600_bc_add_cfinst(ctx->bc, CTX_INST(V_SQ_CF_WORD1_SQ_CF_INST_POP));
                ctx->bc->cf_last->pop_count = pops;
                ctx->bc->cf_last->cf_addr = ctx->bc->cf_last->id + 2;
        }
+
        return 0;
 }