From 5936d96d33e767aa99f6afa92f2a6582ff04df23 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 16 May 2011 12:25:18 -0700 Subject: [PATCH] i965: Move IF stack handling into the EU abstraction layer/brw_compile. 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 Reviewed-by: Eric Anholt --- 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(-) diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 4b9117bb0b1..d771853f421 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 cb58d1da9fe..0dca05d0361 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 afd93f8be0b..e761980284c 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 d2ac1235e46..29aff2d9905 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 aa3f878364a..c1f2520eed8 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 a0ac17ac30c..72d50eadbce 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 83c06f5e3a7..7d63228bd06 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 21eb9e4e5e1..994f65a8c32 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 d3c975690ce..4b2e26cbed7 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 a28cdc0bfe9..7267deaa534 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: -- 2.30.2