[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