Mesa (7.10): i965/fs: Refactor control flow stack handling.

Ian Romanick idr at kemper.freedesktop.org
Tue Mar 1 01:37:16 UTC 2011


Module: Mesa
Branch: 7.10
Commit: bb90087edae6628e89109f4af56e5fc4e56a6aa5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bb90087edae6628e89109f4af56e5fc4e56a6aa5

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Sat Feb 19 16:12:28 2011 -0800

i965/fs: Refactor control flow stack handling.

We can't safely use fixed size arrays since Gen6+ supports unlimited
nesting of control flow.

NOTE: This is a candidate for the 7.10 branch.

Reviewed-by: Eric Anholt <eric at anholt.net>
(cherry picked from commit df2aef0e197f9276f60a8e755260420c90841269)

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index e24c728..dcbdacf 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -3337,20 +3337,25 @@ void
 fs_visitor::generate_code()
 {
    int last_native_inst = 0;
-   struct brw_instruction *if_stack[16], *loop_stack[16];
-   int if_stack_depth = 0, loop_stack_depth = 0;
-   int if_depth_in_loop[16];
    const char *last_annotation_string = NULL;
    ir_instruction *last_annotation_ir = NULL;
 
+   int if_stack_array_size = 16;
+   int loop_stack_array_size = 16;
+   int if_stack_depth = 0, loop_stack_depth = 0;
+   brw_instruction **if_stack =
+      rzalloc_array(this->mem_ctx, brw_instruction *, if_stack_array_size);
+   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);
+
+
    if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
       printf("Native code for fragment shader %d:\n",
 	     ctx->Shader.CurrentFragmentProgram->Name);
    }
 
-   if_depth_in_loop[loop_stack_depth] = 0;
-
-   memset(&if_stack, 0, sizeof(if_stack));
    foreach_iter(exec_list_iterator, iter, this->instructions) {
       fs_inst *inst = (fs_inst *)iter.get();
       struct brw_reg src[3], dst;
@@ -3434,7 +3439,6 @@ fs_visitor::generate_code()
 	 break;
 
       case BRW_OPCODE_IF:
-	 assert(if_stack_depth < 16);
 	 if (inst->src[0].file != BAD_FILE) {
 	    assert(intel->gen >= 6);
 	    if_stack[if_stack_depth] = brw_IF_gen6(p, inst->conditional_mod, src[0], src[1]);
@@ -3443,6 +3447,11 @@ fs_visitor::generate_code()
 	 }
 	 if_depth_in_loop[loop_stack_depth]++;
 	 if_stack_depth++;
+	 if (if_stack_array_size <= if_stack_depth) {
+	    if_stack_array_size *= 2;
+	    if_stack = reralloc(this->mem_ctx, if_stack, brw_instruction *,
+			        if_stack_array_size);
+	 }
 	 break;
 
       case BRW_OPCODE_ELSE:
@@ -3457,6 +3466,13 @@ fs_visitor::generate_code()
 
       case BRW_OPCODE_DO:
 	 loop_stack[loop_stack_depth++] = brw_DO(p, BRW_EXECUTE_8);
+	 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);
+	 }
 	 if_depth_in_loop[loop_stack_depth] = 0;
 	 break;
 
@@ -3575,6 +3591,10 @@ fs_visitor::generate_code()
       last_native_inst = p->nr_insn;
    }
 
+   ralloc_free(if_stack);
+   ralloc_free(loop_stack);
+   ralloc_free(if_depth_in_loop);
+
    brw_set_uip_jip(p);
 
    /* OK, while the INTEL_DEBUG=wm above is very nice for debugging FS




More information about the mesa-commit mailing list