diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_clip.h | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_clip_line.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_clip_tri.c | 48 |
3 files changed, 55 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index c6581adcf0a..26bcb3a25f9 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -100,6 +100,15 @@ struct brw_clip_compile { struct brw_reg plane_equation; struct brw_reg ff_sync; + + /* Bitmask indicating which coordinate attribute should be used for + * comparison to each clipping plane. A 0 indicates that VARYING_SLOT_POS + * should be used, because it's one of the fixed +/- x/y/z planes that + * constitute the bounds of the view volume. A 1 indicates that + * VARYING_SLOT_CLIP_VERTEX should be used (if available) since it's a user- + * defined clipping plane. + */ + struct brw_reg vertex_src_mask; } reg; /* Number of registers storing VUE data */ diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 80f8eb4a67f..508fa29091f 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -125,6 +125,8 @@ 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); diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 05959f66f86..b2062d46c0b 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -119,6 +119,9 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, i++; } + c->reg.vertex_src_mask = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); + i++; + if (intel->needs_ff_sync) { c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD); i++; @@ -219,6 +222,31 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c ) } +static inline void +load_vertex_pos(struct brw_clip_compile *c, struct brw_indirect vtx, + struct brw_reg dst, + GLuint hpos_offset, GLuint clip_offset) +{ + struct brw_compile *p = &c->func; + + /* + * Roughly: + * dst = (vertex_src_mask & 1) ? src.hpos : src.clipvertex; + */ + + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, vec1(brw_null_reg()), c->reg.vertex_src_mask, brw_imm_ud(1)); + brw_IF(p, BRW_EXECUTE_1); + { + brw_MOV(p, dst, deref_4f(vtx, clip_offset)); + } + brw_ELSE(p); + { + brw_MOV(p, dst, deref_4f(vtx, hpos_offset)); + } + brw_ENDIF(p); +} + /* Use mesa's clipping algorithms, translated to GEN4 assembly. */ @@ -233,7 +261,10 @@ 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); GLuint hpos_offset = brw_varying_to_offset(&c->vue_map, VARYING_SLOT_POS); - + GLuint clipvert_offset = brw_clip_have_varying(c, VARYING_SLOT_CLIP_VERTEX) + ? brw_varying_to_offset(&c->vue_map, VARYING_SLOT_CLIP_VERTEX) + : hpos_offset; + 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)); brw_MOV(p, get_addr_reg(inlist_ptr), brw_address(c->reg.inlist)); @@ -241,6 +272,11 @@ void brw_clip_tri( struct brw_clip_compile *c ) brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) ); + /* Set the initial vertex source mask: The first 6 planes are the bounds + * of the view volume; the next 6 planes are the user clipping planes. + */ + brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0xfc0)); + brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) @@ -269,15 +305,17 @@ void brw_clip_tri( struct brw_clip_compile *c ) */ brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0)); + load_vertex_pos(c, vtxPrev, vec4(c->reg.dpPrev), hpos_offset, clipvert_offset); /* IS_NEGATIVE(prev) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_L); - brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, hpos_offset), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dpPrev), vec4(c->reg.dpPrev), c->reg.plane_equation); brw_IF(p, BRW_EXECUTE_1); { + load_vertex_pos(c, vtx, vec4(c->reg.dp), hpos_offset, clipvert_offset); /* IS_POSITIVE(next) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_GE); - brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dp), vec4(c->reg.dp), c->reg.plane_equation); brw_IF(p, BRW_EXECUTE_1); { @@ -316,10 +354,11 @@ void brw_clip_tri( struct brw_clip_compile *c ) brw_ADD(p, get_addr_reg(outlist_ptr), get_addr_reg(outlist_ptr), brw_imm_uw(sizeof(short))); brw_ADD(p, c->reg.nr_verts, c->reg.nr_verts, brw_imm_ud(1)); + load_vertex_pos(c, vtx, vec4(c->reg.dp), hpos_offset, clipvert_offset); /* IS_NEGATIVE(next) */ brw_set_conditionalmod(p, BRW_CONDITIONAL_L); - brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, hpos_offset), c->reg.plane_equation); + brw_DP4(p, vec4(c->reg.dp), vec4(c->reg.dp), c->reg.plane_equation); brw_IF(p, BRW_EXECUTE_1); { /* Going out of bounds. Avoid division by zero as we @@ -392,6 +431,7 @@ void brw_clip_tri( 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_WHILE(p); } |