diff options
author | Chris Forbes <chrisf@ijw.co.nz> | 2013-08-05 04:18:22 +1200 |
---|---|---|
committer | Chris Forbes <chrisf@ijw.co.nz> | 2013-08-16 07:24:56 +1200 |
commit | cf52f6435e4e64b5f1e43efeeeb83397976806a6 (patch) | |
tree | cb84a4c46e02213e987f6a2323d179cf6474647d /src/mesa/drivers/dri/i965/brw_clip_line.c | |
parent | 2a8a85e1ad7cc8221fb698dce3d188be767543de (diff) | |
download | external_mesa3d-cf52f6435e4e64b5f1e43efeeeb83397976806a6.zip external_mesa3d-cf52f6435e4e64b5f1e43efeeeb83397976806a6.tar.gz external_mesa3d-cf52f6435e4e64b5f1e43efeeeb83397976806a6.tar.bz2 |
i965/clip: Support clip distances for line clipping
This does the same thing as we do for triangle clipping -- select the
appropriate source (either dot(hpos,fixed plane) or a clipdistance
slot).
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_clip_line.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_clip_line.c | 66 |
1 files changed, 47 insertions, 19 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 9001d36..8466b1c 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -85,6 +85,10 @@ static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) i++; } + c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); + c->reg.clipdistance_offset = retype(brw_vec1_grf(i, 1), BRW_REGISTER_TYPE_W); + i++; + if (brw->gen == 5) { c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; @@ -98,7 +102,6 @@ static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) } - /* Line clipping, more or less following the following algorithm: * * for (p=0;p<MAX_PLANES;p++) { @@ -125,8 +128,6 @@ static void brw_clip_line_alloc_regs( struct brw_clip_compile *c ) */ static void clip_and_emit_line( struct brw_clip_compile *c ) { - /* FIXME: use VARYING_SLOT_CLIP_VERTEX if available for user clip planes. */ - struct brw_compile *p = &c->func; struct brw_context *brw = p->brw; struct brw_indirect vtx0 = brw_indirect(0, 0); @@ -136,6 +137,9 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) struct brw_indirect plane_ptr = brw_indirect(4, 0); struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); + GLint clipdist0_offset = c->key.nr_userclip + ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_DIST0) + : 0; brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0])); brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1])); @@ -160,30 +164,52 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_set_predicate_control(p, BRW_PREDICATE_NONE); + /* Set the initial vertex source mask: The first 6 planes are the bounds + * of the view volume; the next 8 planes are the user clipping planes. + */ + brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0x3fc0)); + + /* Set the initial clipdistance offset to be 6 floats before gl_ClipDistance[0]. + * We'll increment 6 times before we start hitting actual user clipping. */ + brw_MOV(p, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float))); + brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, v1_null_ud, c->reg.planemask, brw_imm_ud(1)); - + brw_IF(p, BRW_EXECUTE_1); { - if (c->key.nr_userclip) - brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); - else - brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); - - /* dp = DP4(vtx->position, plane) - */ - brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation); - - /* if (IS_NEGATIVE(dp1)) - */ - brw_set_conditionalmod(p, BRW_CONDITIONAL_L); - brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation); - brw_IF(p, BRW_EXECUTE_1); - { + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, v1_null_ud, c->reg.vertex_src_mask, brw_imm_ud(1)); + brw_IF(p, BRW_EXECUTE_1); + { + /* user clip distance: just fetch the correct float from each vertex */ + struct brw_indirect temp_ptr = brw_indirect(7, 0); + brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx0), c->reg.clipdistance_offset); + brw_MOV(p, c->reg.dp0, deref_1f(temp_ptr, 0)); + brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx1), c->reg.clipdistance_offset); + brw_MOV(p, c->reg.dp1, deref_1f(temp_ptr, 0)); + } + brw_ELSE(p); + { + /* fixed plane: fetch the hpos, dp4 against the plane. */ + if (c->key.nr_userclip) + brw_MOV(p, c->reg.plane_equation, deref_4f(plane_ptr, 0)); + else + brw_MOV(p, c->reg.plane_equation, deref_4b(plane_ptr, 0)); + + brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, hpos_offset), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, hpos_offset), c->reg.plane_equation); + } + brw_ENDIF(p); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, vec1(c->reg.dp1), brw_imm_f(0.0f)); + + brw_IF(p, BRW_EXECUTE_1); + { /* * Both can be negative on GM965/G965 due to RHW workaround * if so, this object should be rejected. @@ -244,6 +270,8 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(1)); + brw_SHR(p, c->reg.vertex_src_mask, c->reg.vertex_src_mask, brw_imm_ud(1)); + brw_ADD(p, c->reg.clipdistance_offset, c->reg.clipdistance_offset, brw_imm_w(sizeof(float))); } brw_WHILE(p); |