* a comparison of it to zero with the condition `cond`.
*
* - If using a fixed plane, the distance is dot(hpos, plane).
- * - If using a user clip plane, the distance is dot(clipvertex, plane).
- * Elsewhere we arrange for clipvertex to be mapped to hpos if no
- * explicit clipvertex value was provided by the previous shader.
+ * - If using a user clip plane, the distance is directly available in the vertex.
*/
static inline void
load_clip_distance(struct brw_clip_compile *c, struct brw_indirect vtx,
- struct brw_reg dst, GLuint hpos_offset, GLuint clip_offset,
- int cond)
+ struct brw_reg dst, GLuint hpos_offset, int cond)
{
struct brw_compile *p = &c->func;
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));
+ struct brw_indirect temp_ptr = brw_indirect(7, 0);
+ brw_ADD(p, get_addr_reg(temp_ptr), get_addr_reg(vtx), c->reg.clipdistance_offset);
+ brw_MOV(p, vec1(dst), deref_1f(temp_ptr, 0));
}
brw_ELSE(p);
{
brw_MOV(p, dst, deref_4f(vtx, hpos_offset));
+ brw_DP4(p, dst, dst, c->reg.plane_equation);
}
brw_ENDIF(p);
brw_set_conditionalmod(p, cond);
- brw_DP4(p, dst, dst, c->reg.plane_equation);
+ brw_CMP(p, brw_null_reg(), cond, vec1(dst), brw_imm_f(0.0f));
}
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;
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(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.
+ * of the view volume; the next 8 planes are the user clipping planes.
*/
- brw_MOV(p, c->reg.vertex_src_mask, brw_imm_ud(0xfc0));
+ 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, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
- load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, clipvert_offset,
- BRW_CONDITIONAL_L);
+ load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, BRW_CONDITIONAL_L);
/* IS_NEGATIVE(prev) */
brw_IF(p, BRW_EXECUTE_1);
{
- load_clip_distance(c, vtx, c->reg.dp, hpos_offset, clipvert_offset,
- BRW_CONDITIONAL_GE);
+ load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
/* IS_POSITIVE(next)
*/
brw_IF(p, BRW_EXECUTE_1);
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_clip_distance(c, vtx, c->reg.dp, hpos_offset, clipvert_offset,
- BRW_CONDITIONAL_L);
+ load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_L);
/* IS_NEGATIVE(next)
*/
brw_IF(p, BRW_EXECUTE_1);
brw_MOV(p, get_addr_reg(vptr), brw_address(c->reg.inlist));
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
- brw_clip_emit_vue(c, v0, 1, 0,
+ brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
| URB_WRITE_PRIM_START));
brw_DO(p, BRW_EXECUTE_1);
{
- brw_clip_emit_vue(c, v0, 1, 0,
+ brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
(_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT));
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
}
brw_WHILE(p);
- brw_clip_emit_vue(c, v0, 0, 1,
+ brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
| URB_WRITE_PRIM_END));
}