[Mesa-dev] [PATCH 3/4] i965: Move IF stack handling into the EU abstraction layer/brw_compile.

Kenneth Graunke kenneth at whitecape.org
Mon May 16 15:09:45 PDT 2011


This hides the IF stack and back-patching of IF/ELSE instructions from
each of the code generators, greatly simplifying the interface.

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/mesa/drivers/dri/i965/brw_clip_line.c     |   26 ++++------
 src/mesa/drivers/dri/i965/brw_clip_tri.c      |   66 +++++++++++--------------
 src/mesa/drivers/dri/i965/brw_clip_unfilled.c |   45 +++++++----------
 src/mesa/drivers/dri/i965/brw_clip_util.c     |    5 +-
 src/mesa/drivers/dri/i965/brw_eu.c            |    8 +++
 src/mesa/drivers/dri/i965/brw_eu.h            |   16 ++++--
 src/mesa/drivers/dri/i965/brw_eu_emit.c       |   36 ++++++++++---
 src/mesa/drivers/dri/i965/brw_fs.cpp          |   22 ++------
 src/mesa/drivers/dri/i965/brw_sf_emit.c       |    5 +-
 src/mesa/drivers/dri/i965/brw_vs_emit.c       |   25 ++++------
 10 files changed, 122 insertions(+), 132 deletions(-)

Suggested by Eric.  The interface is /so much nicer/ now.

diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
index 4b9117b..d771853 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -133,10 +133,6 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
    struct brw_indirect newvtx1   = brw_indirect(3, 0);
    struct brw_indirect plane_ptr = brw_indirect(4, 0);
    struct brw_instruction *plane_loop;
-   struct brw_instruction *plane_active;
-   struct brw_instruction *is_negative;
-   struct brw_instruction *is_neg2 = NULL;
-   struct brw_instruction *not_culled;
    struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
 
    brw_MOV(p, get_addr_reg(vtx0),      brw_address(c->reg.vertex[0]));
@@ -169,7 +165,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1));
       
-      plane_active = brw_IF(p, BRW_EXECUTE_1);
+      brw_IF(p, BRW_EXECUTE_1);
       {
 	 if (c->key.nr_userclip)
 	    brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0));
@@ -184,7 +180,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
 	  */
 	 brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
 	 brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
-	 is_negative = brw_IF(p, BRW_EXECUTE_1);
+	 brw_IF(p, BRW_EXECUTE_1);
 	 {
              /*
               * Both can be negative on GM965/G965 due to RHW workaround
@@ -192,11 +188,11 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
               */
              if (brw->has_negative_rhw_bug) {
                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
-                 is_neg2 = brw_IF(p, BRW_EXECUTE_1);
+                 brw_IF(p, BRW_EXECUTE_1);
                  {
                      brw_clip_kill_thread(c);
                  }
-                 brw_ENDIF(p, is_neg2);
+                 brw_ENDIF(p);
              }
 
              brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
@@ -207,7 +203,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
              brw_MOV(p, c->reg.t1, c->reg.t);
              brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 	 } 
-	 is_negative = brw_ELSE(p, is_negative);
+	 brw_ELSE(p);
 	 {
              /* Coming back in.  We know that both cannot be negative
               * because the line would have been culled in that case.
@@ -217,7 +213,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
              /* Only on GM965/G965 */
              if (brw->has_negative_rhw_bug) {
                  brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
-                 is_neg2 = brw_IF(p, BRW_EXECUTE_1);
+                 brw_IF(p, BRW_EXECUTE_1);
              }
 
              {
@@ -231,12 +227,12 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
              }
 
              if (brw->has_negative_rhw_bug) {
-                 brw_ENDIF(p, is_neg2);
+                 brw_ENDIF(p);
              }
          }
-	 brw_ENDIF(p, is_negative);	 
+	 brw_ENDIF(p);
       }
-      brw_ENDIF(p, plane_active);
+      brw_ENDIF(p);
       
       /* plane_ptr++;
        */
@@ -251,7 +247,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
 
    brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
-   not_culled = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE);
       brw_clip_interp_vertex(c, newvtx1, vtx1, vtx0, c->reg.t1, GL_FALSE);
@@ -259,7 +255,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
       brw_clip_emit_vue(c, newvtx0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
       brw_clip_emit_vue(c, newvtx1, 0, 1, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END); 
    }
-   brw_ENDIF(p, not_culled);
+   brw_ENDIF(p);
    brw_clip_kill_thread(c);
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index cb58d1d..0dca05d 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -134,7 +134,6 @@ void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
-   struct brw_instruction *is_rev;
 
    /* Initial list of indices for incoming vertexes:
     */
@@ -148,21 +147,21 @@ void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
    /* XXX: Is there an easier way to do this?  Need to reverse every
     * second tristrip element:  Can ignore sometimes?
     */
-   is_rev = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {   
       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[1]) );
       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[0]) );
       if (c->need_direction)
 	 brw_MOV(p, c->reg.dir, brw_imm_f(-1));
    }
-   is_rev = brw_ELSE(p, is_rev);
+   brw_ELSE(p);
    {
       brw_MOV(p, get_element(c->reg.inlist, 0),  brw_address(c->reg.vertex[0]) );
       brw_MOV(p, get_element(c->reg.inlist, 1),  brw_address(c->reg.vertex[1]) );
       if (c->need_direction)
 	 brw_MOV(p, c->reg.dir, brw_imm_f(1));
    }
-   brw_ENDIF(p, is_rev);
+   brw_ENDIF(p);
 
    brw_MOV(p, get_element(c->reg.inlist, 2),  brw_address(c->reg.vertex[2]) );
    brw_MOV(p, brw_vec8_grf(c->reg.outlist.nr, 0), brw_imm_f(0));
@@ -174,7 +173,6 @@ void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *is_poly, *is_trifan;
    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
 
    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
@@ -184,12 +182,12 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
 	   tmp0,
 	   brw_imm_ud(_3DPRIM_POLYGON));
 
-   is_poly = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       brw_clip_copy_colors(c, 1, 0);
       brw_clip_copy_colors(c, 2, 0);
    }
-   is_poly = brw_ELSE(p, is_poly);
+   brw_ELSE(p);
    {
       if (c->key.pv_first) {
 	 brw_CMP(p,
@@ -197,24 +195,24 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
 		 BRW_CONDITIONAL_EQ,
 		 tmp0,
 		 brw_imm_ud(_3DPRIM_TRIFAN));
-	 is_trifan = brw_IF(p, BRW_EXECUTE_1);
+	 brw_IF(p, BRW_EXECUTE_1);
 	 {
 	    brw_clip_copy_colors(c, 0, 1);
 	    brw_clip_copy_colors(c, 2, 1);
 	 }
-	 is_trifan = brw_ELSE(p, is_trifan);
+	 brw_ELSE(p);
 	 {
 	    brw_clip_copy_colors(c, 1, 0);
 	    brw_clip_copy_colors(c, 2, 0);
 	 }
-	 brw_ENDIF(p, is_trifan);
+	 brw_ENDIF(p);
       }
       else {
          brw_clip_copy_colors(c, 0, 2);
          brw_clip_copy_colors(c, 1, 2);
       }
    }
-   brw_ENDIF(p, is_poly);
+   brw_ENDIF(p);
 }
 
 
@@ -232,10 +230,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
    struct brw_indirect outlist_ptr = brw_indirect(5, 0);
    struct brw_indirect freelist_ptr = brw_indirect(6, 0);
    struct brw_instruction *plane_loop;
-   struct brw_instruction *plane_active;
    struct brw_instruction *vertex_loop;
-   struct brw_instruction *next_test;
-   struct brw_instruction *prev_test;
    
    brw_MOV(p, get_addr_reg(vtxPrev),     brw_address(c->reg.vertex[2]) );
    brw_MOV(p, get_addr_reg(plane_ptr),   brw_clip_plane0_address(c));
@@ -251,7 +246,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_AND(p, vec1(brw_null_reg()), c->reg.planemask, brw_imm_ud(1));
       
-      plane_active = brw_IF(p, BRW_EXECUTE_1);
+      brw_IF(p, BRW_EXECUTE_1);
       {
 	 /* vtxOut = freelist_ptr++ 
 	  */
@@ -275,13 +270,13 @@ void brw_clip_tri( struct brw_clip_compile *c )
 	    /* IS_NEGATIVE(prev) */
 	    brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
 	    brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
-	    prev_test = brw_IF(p, BRW_EXECUTE_1);
+	    brw_IF(p, BRW_EXECUTE_1);
 	    {
 	       /* IS_POSITIVE(next)
 		*/
 	       brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
 	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
-	       next_test = brw_IF(p, BRW_EXECUTE_1);
+	       brw_IF(p, BRW_EXECUTE_1);
 	       {
 
 		  /* Coming back in.
@@ -307,10 +302,10 @@ void brw_clip_tri( struct brw_clip_compile *c )
 		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
 		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
 	       }
-	       brw_ENDIF(p, next_test);
+	       brw_ENDIF(p);
 	       
 	    }
-	    prev_test = brw_ELSE(p, prev_test);
+	    brw_ELSE(p);
 	    {
 	       /* *outlist_ptr++ = vtxPrev;
 		* nr_verts++;
@@ -323,7 +318,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
 		*/
 	       brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
 	       brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
-	       next_test = brw_IF(p, BRW_EXECUTE_1);
+	       brw_IF(p, BRW_EXECUTE_1);
 	       {
 		  /* Going out of bounds.  Avoid division by zero as we
 		   * know dp != dpPrev from DIFFERENT_SIGNS, above.
@@ -349,9 +344,9 @@ void brw_clip_tri( struct brw_clip_compile *c )
 		  brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1));
 		  brw_MOV(p, get_addr_reg(vtxOut), brw_imm_uw(0) );
 	       } 	       
-	       brw_ENDIF(p, next_test);
+	       brw_ENDIF(p);
 	    }
-	    brw_ENDIF(p, prev_test);
+	    brw_ENDIF(p);
 	    
 	    /* vtxPrev = vtx;
 	     * inlist_ptr++;
@@ -377,7 +372,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
 	 brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist));
 	 brw_MOV(p, get_addr_reg(outlist_ptr), brw_address(c->reg.outlist));
       }
-      brw_ENDIF(p, plane_active);
+      brw_ENDIF(p);
       
       /* plane_ptr++;
        */
@@ -404,7 +399,7 @@ void brw_clip_tri( struct brw_clip_compile *c )
 void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *loop, *if_insn;
+   struct brw_instruction *loop;
 
    /* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
     */
@@ -414,7 +409,7 @@ void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
 	   c->reg.nr_verts,
 	   brw_imm_d(-2));
 
-   if_insn = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       struct brw_indirect v0 = brw_indirect(0, 0);
       struct brw_indirect vptr = brw_indirect(1, 0);
@@ -441,7 +436,7 @@ void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
 
       brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
    }
-   brw_ENDIF(p, if_insn);
+   brw_ENDIF(p);
 }
 
 static void do_clip_tri( struct brw_clip_compile *c )
@@ -455,14 +450,13 @@ static void do_clip_tri( struct brw_clip_compile *c )
 static void maybe_do_clip_tri( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *do_clip;
 
    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
-   do_clip = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       do_clip_tri(c);
    }
-   brw_ENDIF(p, do_clip);
+   brw_ENDIF(p);
 }
 
 static void brw_clip_test( struct brw_clip_compile *c )
@@ -481,7 +475,6 @@ static void brw_clip_test( struct brw_clip_compile *c )
     struct brw_indirect vt2 = brw_indirect(2, 0);
 
     struct brw_compile *p = &c->func;
-    struct brw_instruction *is_outside;
     struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
 
     brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
@@ -508,11 +501,11 @@ static void brw_clip_test( struct brw_clip_compile *c )
     brw_OR(p, tmp0, tmp0, get_element(t, 2));
     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
-    is_outside = brw_IF(p, BRW_EXECUTE_1);
+    brw_IF(p, BRW_EXECUTE_1);
     {
         brw_clip_kill_thread(c);
     }
-    brw_ENDIF(p, is_outside);
+    brw_ENDIF(p);
     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 
     /* some vertices are inside a plane, some are outside,need to clip */
@@ -549,11 +542,11 @@ static void brw_clip_test( struct brw_clip_compile *c )
     brw_OR(p, tmp0, tmp0, get_element(t, 2));
     brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
     brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
-    is_outside = brw_IF(p, BRW_EXECUTE_1);
+    brw_IF(p, BRW_EXECUTE_1);
     {
         brw_clip_kill_thread(c);
     }
-    brw_ENDIF(p, is_outside);
+    brw_ENDIF(p);
     brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 
     /* some vertices are inside a plane, some are outside,need to clip */
@@ -580,7 +573,6 @@ static void brw_clip_test( struct brw_clip_compile *c )
 
 void brw_emit_tri_clip( struct brw_clip_compile *c )
 {
-   struct brw_instruction *neg_rhw;
    struct brw_compile *p = &c->func;
    struct brw_context *brw = p->brw;
    brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
@@ -594,11 +586,11 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), 
               brw_imm_ud(1<<20));
-      neg_rhw = brw_IF(p, BRW_EXECUTE_1); 
+      brw_IF(p, BRW_EXECUTE_1);
       {
          brw_clip_test(c);
       }
-      brw_ENDIF(p, neg_rhw);
+      brw_ENDIF(p);
    }
    /* Can't push into do_clip_tri because with polygon (or quad)
     * flatshading, need to apply the flatshade here because we don't
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
index afd93f8..e761980 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
@@ -96,7 +96,6 @@ static void compute_tri_direction( struct brw_clip_compile *c )
 static void cull_direction( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *ccw;
    GLuint conditional;
 
    assert (!(c->key.fill_ccw == CLIP_CULL &&
@@ -113,11 +112,11 @@ static void cull_direction( struct brw_clip_compile *c )
 	   get_element(c->reg.dir, 2),
 	   brw_imm_f(0));
    
-   ccw = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       brw_clip_kill_thread(c);
    }
-   brw_ENDIF(p, ccw);
+   brw_ENDIF(p);
 }
 
 
@@ -125,7 +124,6 @@ static void cull_direction( struct brw_clip_compile *c )
 static void copy_bfc( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *ccw;
    GLuint conditional;
 
    /* Do we have any colors to copy? 
@@ -149,7 +147,7 @@ static void copy_bfc( struct brw_clip_compile *c )
 	   get_element(c->reg.dir, 2),
 	   brw_imm_f(0));
    
-   ccw = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       GLuint i;
 
@@ -165,7 +163,7 @@ static void copy_bfc( struct brw_clip_compile *c )
 		    byte_offset(c->reg.vertex[i], c->offset[VERT_RESULT_BFC1]));
       }
    }
-   brw_ENDIF(p, ccw);
+   brw_ENDIF(p);
 }
 
 
@@ -205,7 +203,6 @@ static void compute_offset( struct brw_clip_compile *c )
 static void merge_edgeflags( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *is_poly;
    struct brw_reg tmp0 = get_element_ud(c->reg.tmp0, 0);
 
    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
@@ -218,7 +215,7 @@ static void merge_edgeflags( struct brw_clip_compile *c )
    /* Get away with using reg.vertex because we know that this is not
     * a _3DPRIM_TRISTRIP_REVERSE:
     */
-   is_poly = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {   
       brw_set_conditionalmod(p, BRW_CONDITIONAL_EQ);
       brw_AND(p, vec1(brw_null_reg()), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<8));
@@ -230,7 +227,7 @@ static void merge_edgeflags( struct brw_clip_compile *c )
       brw_MOV(p, byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_EDGE]), brw_imm_f(0));
       brw_set_predicate_control(p, BRW_PREDICATE_NONE);
    }
-   brw_ENDIF(p, is_poly);
+   brw_ENDIF(p);
 }
 
 
@@ -255,7 +252,6 @@ static void emit_lines(struct brw_clip_compile *c,
 {
    struct brw_compile *p = &c->func;
    struct brw_instruction *loop;
-   struct brw_instruction *draw_edge;
    struct brw_indirect v0 = brw_indirect(0, 0);
    struct brw_indirect v1 = brw_indirect(1, 0);
    struct brw_indirect v0ptr = brw_indirect(2, 0);
@@ -300,12 +296,12 @@ static void emit_lines(struct brw_clip_compile *c,
 	      vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, 
 	      deref_1f(v0, c->offset[VERT_RESULT_EDGE]),
 	      brw_imm_f(0));
-      draw_edge = brw_IF(p, BRW_EXECUTE_1);
+      brw_IF(p, BRW_EXECUTE_1);
       {
 	 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_START);
 	 brw_clip_emit_vue(c, v1, 1, 0, (_3DPRIM_LINESTRIP << 2) | R02_PRIM_END);
       }
-      brw_ENDIF(p, draw_edge);
+      brw_ENDIF(p);
 
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
@@ -320,7 +316,6 @@ static void emit_points(struct brw_clip_compile *c,
 {
    struct brw_compile *p = &c->func;
    struct brw_instruction *loop;
-   struct brw_instruction *draw_point;
 
    struct brw_indirect v0 = brw_indirect(0, 0);
    struct brw_indirect v0ptr = brw_indirect(2, 0);
@@ -339,14 +334,14 @@ static void emit_points(struct brw_clip_compile *c,
 	      vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, 
 	      deref_1f(v0, c->offset[VERT_RESULT_EDGE]),
 	      brw_imm_f(0));
-      draw_point = brw_IF(p, BRW_EXECUTE_1);
+      brw_IF(p, BRW_EXECUTE_1);
       {
 	 if (do_offset)
 	    apply_one_offset(c, v0);
 
 	 brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END);
       }
-      brw_ENDIF(p, draw_point);
+      brw_ENDIF(p);
 
       brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
       brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
@@ -388,7 +383,6 @@ static void emit_primitives( struct brw_clip_compile *c,
 static void emit_unfilled_primitives( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *ccw;
 
    /* Direction culling has already been done.
     */
@@ -402,15 +396,15 @@ static void emit_unfilled_primitives( struct brw_clip_compile *c )
 	      get_element(c->reg.dir, 2),
 	      brw_imm_f(0));
    
-      ccw = brw_IF(p, BRW_EXECUTE_1);
+      brw_IF(p, BRW_EXECUTE_1);
       {
 	 emit_primitives(c, c->key.fill_ccw, c->key.offset_ccw);
       }
-      ccw = brw_ELSE(p, ccw);
+      brw_ELSE(p);
       {
 	 emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
       }
-      brw_ENDIF(p, ccw);
+      brw_ENDIF(p);
    }
    else if (c->key.fill_cw != CLIP_CULL) {
       emit_primitives(c, c->key.fill_cw, c->key.offset_cw);
@@ -426,22 +420,19 @@ static void emit_unfilled_primitives( struct brw_clip_compile *c )
 static void check_nr_verts( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *if_insn;
 
    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.nr_verts, brw_imm_d(3));      
-   if_insn = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       brw_clip_kill_thread(c);
    }
-   brw_ENDIF(p, if_insn);
+   brw_ENDIF(p);
 }
 
 
 void brw_emit_unfilled_clip( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *do_clip;
-   
 
    c->need_direction = ((c->key.offset_ccw || c->key.offset_cw) ||
 			(c->key.fill_ccw != c->key.fill_cw) ||
@@ -488,14 +479,14 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
    
    brw_clip_init_clipmask(c);
    brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_NZ, c->reg.planemask, brw_imm_ud(0));
-   do_clip = brw_IF(p, BRW_EXECUTE_1);
+   brw_IF(p, BRW_EXECUTE_1);
    {
       brw_clip_init_planes(c);
       brw_clip_tri(c);
       check_nr_verts(c);
    }
-   brw_ENDIF(p, do_clip);
-   
+   brw_ENDIF(p);
+
    emit_unfilled_primitives(c);
    brw_clip_kill_thread(c);
 }
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index d2ac123..29aff2d 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -338,11 +338,10 @@ void brw_clip_ff_sync(struct brw_clip_compile *c)
 
     if (intel->needs_ff_sync) {
         struct brw_compile *p = &c->func;
-        struct brw_instruction *need_ff_sync;
 
         brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
         brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1));
-        need_ff_sync = brw_IF(p, BRW_EXECUTE_1);
+        brw_IF(p, BRW_EXECUTE_1);
         {
             brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
             brw_ff_sync(p,
@@ -353,7 +352,7 @@ void brw_clip_ff_sync(struct brw_clip_compile *c)
 			1, /* response length */
 			0 /* eot */);
         }
-        brw_ENDIF(p, need_ff_sync);
+        brw_ENDIF(p);
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
     }
 }
diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c
index aa3f878..c1f2520 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.c
+++ b/src/mesa/drivers/dri/i965/brw_eu.c
@@ -34,6 +34,8 @@
 #include "brw_defines.h"
 #include "brw_eu.h"
 
+#include "../glsl/ralloc.h"
+
 /* Returns the corresponding conditional mod for swapping src0 and
  * src1 in e.g. CMP.
  */
@@ -183,6 +185,12 @@ brw_init_compile(struct brw_context *brw, struct brw_compile *p, void *mem_ctx)
    brw_set_saturate(p, 0);
    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
    brw_set_predicate_control_flag_value(p, 0xff); 
+
+   /* Set up control flow stack */
+   p->if_stack_depth = 0;
+   p->if_stack_array_size = 16;
+   p->if_stack =
+      rzalloc_array(mem_ctx, struct brw_instruction *, p->if_stack_array_size);
 }
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index a0ac17a..72d50ea 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -117,6 +117,14 @@ struct brw_compile {
    bool compressed;
    struct brw_context *brw;
 
+   /* Control flow stacks:
+    * - if_stack contains IF and ELSE instructions which must be patched
+    *   (and popped) once the matching ENDIF instruction is encountered.
+    */
+   struct brw_instruction **if_stack;
+   int if_stack_depth;
+   int if_stack_array_size;
+
    struct brw_glsl_label *first_label;  /**< linked list of labels */
    struct brw_glsl_call *first_call;    /**< linked list of CALs */
 };
@@ -953,12 +961,8 @@ struct brw_instruction *brw_IF(struct brw_compile *p,
 struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional,
 				struct brw_reg src0, struct brw_reg src1);
 
-struct brw_instruction *brw_ELSE(struct brw_compile *p, 
-				 struct brw_instruction *if_insn);
-
-void brw_ENDIF(struct brw_compile *p, 
-	       struct brw_instruction *if_or_else_insn);
-
+void brw_ELSE(struct brw_compile *p);
+void brw_ENDIF(struct brw_compile *p);
 
 /* DO/WHILE loops:
  */
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 83c06f5..7d63228 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -34,8 +34,7 @@
 #include "brw_defines.h"
 #include "brw_eu.h"
 
-
-
+#include "../glsl/ralloc.h"
 
 /***********************************************************************
  * Internal helper for constructing instructions
@@ -858,6 +857,19 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p,
    return insn;
 }
 
+static void
+push_if_stack(struct brw_compile *p, struct brw_instruction *inst)
+{
+   p->if_stack[p->if_stack_depth] = inst;
+
+   p->if_stack_depth++;
+   if (p->if_stack_array_size <= p->if_stack_depth) {
+      p->if_stack_array_size *= 2;
+      p->if_stack = reralloc(p->mem_ctx, p->if_stack, struct brw_instruction *,
+			     p->if_stack_array_size);
+   }
+}
+
 /* EU takes the value from the flag register and pushes it onto some
  * sort of a stack (presumably merging with any flag value already on
  * the stack).  Within an if block, the flags at the top of the stack
@@ -870,8 +882,6 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p,
  *
  * When the matching 'endif' instruction is reached, the flags are
  * popped off.  If the stack is now empty, normal execution resumes.
- *
- * No attempt is made to deal with stack overflow (14 elements?).
  */
 struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
 {
@@ -909,6 +919,7 @@ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size)
 
    p->current->header.predicate_control = BRW_PREDICATE_NONE;
 
+   push_if_stack(p, insn);
    return insn;
 }
 
@@ -933,13 +944,15 @@ gen6_IF(struct brw_compile *p, uint32_t conditional,
    if (!p->single_program_flow)
        insn->header.thread_control = BRW_THREAD_SWITCH;
 
+   push_if_stack(p, insn);
    return insn;
 }
 
-struct brw_instruction *brw_ELSE(struct brw_compile *p, 
-				 struct brw_instruction *if_insn)
+void
+brw_ELSE(struct brw_compile *p)
 {
    struct intel_context *intel = &p->brw->intel;
+   struct brw_instruction *if_insn;
    struct brw_instruction *insn;
    GLuint br = 1;
 
@@ -965,6 +978,7 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
       brw_set_src1(p, insn, retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
    }
 
+   if_insn = p->if_stack[p->if_stack_depth - 1];
    insn->header.compression_control = BRW_COMPRESSION_NONE;
    insn->header.execution_size = if_insn->header.execution_size;
    insn->header.mask_control = BRW_MASK_ENABLE;
@@ -989,15 +1003,19 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
       }
    }
 
-   return insn;
+   /* Replace the IF instruction on the stack with the ELSE instruction */
+   p->if_stack[p->if_stack_depth - 1] = insn;
 }
 
-void brw_ENDIF(struct brw_compile *p, 
-	       struct brw_instruction *patch_insn)
+void
+brw_ENDIF(struct brw_compile *p)
 {
    struct intel_context *intel = &p->brw->intel;
+   struct brw_instruction *patch_insn;
    GLuint br = 1;
 
+   p->if_stack_depth--;
+   patch_insn = p->if_stack[p->if_stack_depth];
    if (intel->gen >= 5)
       br = 2; 
  
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 21eb9e4..994f65a 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -3722,11 +3722,8 @@ fs_visitor::generate_code()
    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);
+   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 =
@@ -3832,26 +3829,18 @@ fs_visitor::generate_code()
       case BRW_OPCODE_IF:
 	 if (inst->src[0].file != BAD_FILE) {
 	    assert(intel->gen >= 6);
-	    if_stack[if_stack_depth] = gen6_IF(p, inst->conditional_mod, src[0], src[1]);
+	    gen6_IF(p, inst->conditional_mod, src[0], src[1]);
 	 } else {
-	    if_stack[if_stack_depth] = brw_IF(p, BRW_EXECUTE_8);
+	    brw_IF(p, BRW_EXECUTE_8);
 	 }
 	 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:
-	 if_stack[if_stack_depth - 1] =
-	    brw_ELSE(p, if_stack[if_stack_depth - 1]);
+	 brw_ELSE(p);
 	 break;
       case BRW_OPCODE_ENDIF:
-	 if_stack_depth--;
-	 brw_ENDIF(p , if_stack[if_stack_depth]);
+	 brw_ENDIF(p);
 	 if_depth_in_loop[loop_stack_depth]--;
 	 break;
 
@@ -3993,7 +3982,6 @@ fs_visitor::generate_code()
       printf("\n");
    }
 
-   ralloc_free(if_stack);
    ralloc_free(loop_stack);
    ralloc_free(if_depth_in_loop);
 
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c
index d3c9756..4b2e26c 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c
@@ -81,7 +81,6 @@ static void copy_bfc( struct brw_sf_compile *c,
 static void do_twoside_color( struct brw_sf_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *if_insn;
    GLuint backface_conditional = c->key.frontface_ccw ? BRW_CONDITIONAL_G : BRW_CONDITIONAL_L;
 
    /* Already done in clip program:
@@ -104,7 +103,7 @@ static void do_twoside_color( struct brw_sf_compile *c )
     */
    brw_push_insn_state(p);
    brw_CMP(p, vec4(brw_null_reg()), backface_conditional, c->det, brw_imm_f(0));
-   if_insn = brw_IF(p, BRW_EXECUTE_4); 
+   brw_IF(p, BRW_EXECUTE_4);
    {
       switch (c->nr_verts) {
       case 3: copy_bfc(c, c->vert[2]);
@@ -112,7 +111,7 @@ static void do_twoside_color( struct brw_sf_compile *c )
       case 1: copy_bfc(c, c->vert[0]);
       }
    }
-   brw_ENDIF(p, if_insn);
+   brw_ENDIF(p);
    brw_pop_insn_state(p);
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index a28cdc0..7267dea 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1039,7 +1039,6 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
 			      struct brw_reg arg0 )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *if_insn;
    struct brw_reg tmp = dst;
    GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
 
@@ -1055,7 +1054,7 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
     * BRW_EXECUTE_1 for all comparisions.
     */
    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,0), brw_imm_f(0));
-   if_insn = brw_IF(p, BRW_EXECUTE_8);
+   brw_IF(p, BRW_EXECUTE_8);
    {
       brw_MOV(p, brw_writemask(dst, WRITEMASK_Y), brw_swizzle1(arg0,0));
 
@@ -1070,8 +1069,7 @@ static void emit_lit_noalias( struct brw_vs_compile *c,
 		 brw_swizzle1(arg0, 3),
 		 BRW_MATH_PRECISION_PARTIAL);      
    }
-
-   brw_ENDIF(p, if_insn);
+   brw_ENDIF(p);
 
    release_tmp(c, tmp);
 }
@@ -1881,8 +1879,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
    const GLuint nr_insns = c->vp->program.Base.NumInstructions;
-   GLuint insn, if_depth = 0, loop_depth = 0;
-   struct brw_instruction *if_inst[MAX_IF_DEPTH], *loop_inst[MAX_LOOP_DEPTH] = { 0 };
+   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;
@@ -2102,23 +2100,20 @@ void brw_vs_emit(struct brw_vs_compile *c )
       case OPCODE_XPD:
 	 emit_xpd(p, dst, args[0], args[1]);
 	 break;
-      case OPCODE_IF:
-	 assert(if_depth < MAX_IF_DEPTH);
-	 if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
+      case OPCODE_IF: {
+	 struct brw_instruction *if_inst = brw_IF(p, BRW_EXECUTE_8);
 	 /* Note that brw_IF smashes the predicate_control field. */
-	 if_inst[if_depth]->header.predicate_control = get_predicate(inst);
+	 if_inst->header.predicate_control = get_predicate(inst);
 	 if_depth_in_loop[loop_depth]++;
-	 if_depth++;
 	 break;
+      }
       case OPCODE_ELSE:
 	 clear_current_const(c);
-	 assert(if_depth > 0);
-	 if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
+	 brw_ELSE(p);
 	 break;
       case OPCODE_ENDIF:
 	 clear_current_const(c);
-         assert(if_depth > 0);
-	 brw_ENDIF(p, if_inst[--if_depth]);
+	 brw_ENDIF(p);
 	 if_depth_in_loop[loop_depth]--;
 	 break;			
       case OPCODE_BGNLOOP:
-- 
1.7.4.4



More information about the mesa-dev mailing list