[Mesa-dev] [PATCH 3/4] i965: Don't make consumers of brw_WHILE do pre-gen6 BREAK/CONT patching.

Eric Anholt eric at anholt.net
Tue Dec 6 13:19:33 PST 2011


The EU code itself can just do this work, since all the consumers were
duplicating it.
---
 src/mesa/drivers/dri/i965/brw_eu_emit.c     |   36 +++++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/brw_fs_emit.cpp   |   33 +++---------------------
 src/mesa/drivers/dri/i965/brw_vec4_emit.cpp |   33 +++---------------------
 src/mesa/drivers/dri/i965/brw_vs_emit.c     |   30 +++-------------------
 4 files changed, 46 insertions(+), 86 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index f18487e..6fbdcb3 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1317,7 +1317,36 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size)
    }
 }
 
-
+/**
+ * For pre-gen6, we patch BREAK/CONT instructions to point at the WHILE
+ * instruction here.
+ *
+ * For gen6+, see brw_set_uip_jip(), which doesn't care so much about the loop
+ * nesting, since it can always just point to the end of the block/current loop.
+ */
+static void
+brw_patch_break_cont(struct brw_compile *p)
+{
+   struct intel_context *intel = &p->brw->intel;
+   struct brw_instruction *while_inst = &p->store[p->nr_insn];
+   struct brw_instruction *do_inst = get_inner_do_insn(p);
+   struct brw_instruction *inst;
+   int br = (intel->gen == 5) ? 2 : 1;
+
+   for (inst = while_inst - 1; inst != do_inst; inst--) {
+      /* If the jump count is != 0, that means that this instruction has already
+       * been patched because it's part of a loop inside of the one we're
+       * patching.
+       */
+      if (inst->header.opcode == BRW_OPCODE_BREAK &&
+	  inst->bits3.if_else.jump_count == 0) {
+	 inst->bits3.if_else.jump_count = br * ((while_inst - inst) + 1);
+      } else if (inst->header.opcode == BRW_OPCODE_CONTINUE &&
+		 inst->bits3.if_else.jump_count == 0) {
+	 inst->bits3.if_else.jump_count = br * (while_inst - inst);
+      }
+   }
+}
 
 struct brw_instruction *brw_WHILE(struct brw_compile *p)
 {
@@ -1326,7 +1355,6 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p)
    GLuint br = 1;
 
    do_insn = get_inner_do_insn(p);
-   p->loop_stack_depth--;
 
    if (intel->gen >= 5)
       br = 2;
@@ -1370,11 +1398,15 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p)
 	 insn->bits3.if_else.jump_count = br * (do_insn - insn + 1);
 	 insn->bits3.if_else.pop_count = 0;
 	 insn->bits3.if_else.pad0 = 0;
+
+	 brw_patch_break_cont(p);
       }
    }
    insn->header.compression_control = BRW_COMPRESSION_NONE;
    p->current->header.predicate_control = BRW_PREDICATE_NONE;
 
+   p->loop_stack_depth--;
+
    return insn;
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 3a9dc2f..e772eaf 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -658,8 +658,6 @@ fs_visitor::generate_code()
 
    int loop_stack_array_size = 16;
    int loop_stack_depth = 0;
-   brw_instruction **loop_stack =
-      rzalloc_array(this->mem_ctx, brw_instruction *, loop_stack_array_size);
    int *if_depth_in_loop =
       rzalloc_array(this->mem_ctx, int, loop_stack_array_size);
 
@@ -795,11 +793,10 @@ fs_visitor::generate_code()
 	 break;
 
       case BRW_OPCODE_DO:
-	 loop_stack[loop_stack_depth++] = brw_DO(p, BRW_EXECUTE_8);
+	 brw_DO(p, BRW_EXECUTE_8);
+	 loop_stack_depth++;
 	 if (loop_stack_array_size <= loop_stack_depth) {
 	    loop_stack_array_size *= 2;
-	    loop_stack = reralloc(this->mem_ctx, loop_stack, brw_instruction *,
-				  loop_stack_array_size);
 	    if_depth_in_loop = reralloc(this->mem_ctx, if_depth_in_loop, int,
 				        loop_stack_array_size);
 	 }
@@ -819,31 +816,10 @@ fs_visitor::generate_code()
 	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 	 break;
 
-      case BRW_OPCODE_WHILE: {
-	 struct brw_instruction *inst0, *inst1;
-	 GLuint br = 1;
-
-	 if (intel->gen >= 5)
-	    br = 2;
-
+      case BRW_OPCODE_WHILE:
 	 assert(loop_stack_depth > 0);
 	 loop_stack_depth--;
-	 inst0 = inst1 = brw_WHILE(p);
-	 if (intel->gen < 6) {
-	    /* patch all the BREAK/CONT instructions from last BGNLOOP */
-	    while (inst0 > loop_stack[loop_stack_depth]) {
-	       inst0--;
-	       if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-		   inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-	    }
-	       else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-			inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-	       }
-	    }
-	 }
-      }
+	 brw_WHILE(p);
 	 break;
 
       case SHADER_OPCODE_RCP:
@@ -947,7 +923,6 @@ fs_visitor::generate_code()
       printf("\n");
    }
 
-   ralloc_free(loop_stack);
    ralloc_free(if_depth_in_loop);
 
    brw_set_uip_jip(p);
diff --git a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
index cd1d228..0199973 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4_emit.cpp
@@ -678,8 +678,6 @@ vec4_visitor::generate_code()
 
    int loop_stack_array_size = 16;
    int loop_stack_depth = 0;
-   brw_instruction **loop_stack =
-      rzalloc_array(this->mem_ctx, brw_instruction *, loop_stack_array_size);
    int *if_depth_in_loop =
       rzalloc_array(this->mem_ctx, int, loop_stack_array_size);
 
@@ -809,11 +807,10 @@ vec4_visitor::generate_code()
 	 break;
 
       case BRW_OPCODE_DO:
-	 loop_stack[loop_stack_depth++] = brw_DO(p, BRW_EXECUTE_8);
+	 brw_DO(p, BRW_EXECUTE_8);
+	 loop_stack_depth++;
 	 if (loop_stack_array_size <= loop_stack_depth) {
 	    loop_stack_array_size *= 2;
-	    loop_stack = reralloc(this->mem_ctx, loop_stack, brw_instruction *,
-				  loop_stack_array_size);
 	    if_depth_in_loop = reralloc(this->mem_ctx, if_depth_in_loop, int,
 				        loop_stack_array_size);
 	 }
@@ -833,31 +830,10 @@ vec4_visitor::generate_code()
 	 brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 	 break;
 
-      case BRW_OPCODE_WHILE: {
-	 struct brw_instruction *inst0, *inst1;
-	 GLuint br = 1;
-
-	 if (intel->gen >= 5)
-	    br = 2;
-
+      case BRW_OPCODE_WHILE:
 	 assert(loop_stack_depth > 0);
 	 loop_stack_depth--;
-	 inst0 = inst1 = brw_WHILE(p);
-	 if (intel->gen < 6) {
-	    /* patch all the BREAK/CONT instructions from last BGNLOOP */
-	    while (inst0 > loop_stack[loop_stack_depth]) {
-	       inst0--;
-	       if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-		   inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-	    }
-	       else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-			inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-	       }
-	    }
-	 }
-      }
+	 brw_WHILE(p);
 	 break;
 
       default:
@@ -885,7 +861,6 @@ vec4_visitor::generate_code()
       printf("\n");
    }
 
-   ralloc_free(loop_stack);
    ralloc_free(if_depth_in_loop);
 
    brw_set_uip_jip(p);
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 05f3ecb..62adc54 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1844,7 +1844,6 @@ void brw_old_vs_emit(struct brw_vs_compile *c )
    struct intel_context *intel = &brw->intel;
    const GLuint nr_insns = c->vp->program.Base.NumInstructions;
    GLuint insn, loop_depth = 0;
-   struct brw_instruction *loop_inst[MAX_LOOP_DEPTH] = { 0 };
    int if_depth_in_loop[MAX_LOOP_DEPTH];
    const struct brw_indirect stack_index = brw_indirect(0, 0);   
    GLuint index;
@@ -2095,7 +2094,8 @@ void brw_old_vs_emit(struct brw_vs_compile *c )
 	 break;			
       case OPCODE_BGNLOOP:
 	 clear_current_const(c);
-         loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
+	 brw_DO(p, BRW_EXECUTE_8);
+         loop_depth++;
 	 if_depth_in_loop[loop_depth] = 0;
          break;
       case OPCODE_BRK:
@@ -2113,32 +2113,10 @@ void brw_old_vs_emit(struct brw_vs_compile *c )
          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
          break;
 
-      case OPCODE_ENDLOOP: {
+      case OPCODE_ENDLOOP:
 	 clear_current_const(c);
-	 struct brw_instruction *inst0, *inst1;
-	 GLuint br = 1;
-
 	 loop_depth--;
-
-	 if (intel->gen == 5)
-	    br = 2;
-
-	 inst0 = inst1 = brw_WHILE(p);
-
-	 if (intel->gen < 6) {
-	    /* patch all the BREAK/CONT instructions from last BEGINLOOP */
-	    while (inst0 > loop_inst[loop_depth]) {
-	       inst0--;
-	       if (inst0->header.opcode == BRW_OPCODE_BREAK &&
-		   inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
-	       } else if (inst0->header.opcode == BRW_OPCODE_CONTINUE &&
-			  inst0->bits3.if_else.jump_count == 0) {
-		  inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
-	       }
-	    }
-	 }
-      }
+	 brw_WHILE(p);
          break;
 
       case OPCODE_BRA:
-- 
1.7.7.3



More information about the mesa-dev mailing list