}
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) {
brw_IF(p, BRW_EXECUTE_1);
{
- brw_clip_copy_colors(c, 1, 0);
- brw_clip_copy_colors(c, 2, 0);
+ brw_clip_copy_flatshaded_attributes(c, 1, 0);
+ brw_clip_copy_flatshaded_attributes(c, 2, 0);
}
brw_ELSE(p);
{
brw_imm_ud(_3DPRIM_TRIFAN));
brw_IF(p, BRW_EXECUTE_1);
{
- brw_clip_copy_colors(c, 0, 1);
- brw_clip_copy_colors(c, 2, 1);
+ brw_clip_copy_flatshaded_attributes(c, 0, 1);
+ brw_clip_copy_flatshaded_attributes(c, 2, 1);
}
brw_ELSE(p);
{
- brw_clip_copy_colors(c, 1, 0);
- brw_clip_copy_colors(c, 2, 0);
+ brw_clip_copy_flatshaded_attributes(c, 1, 0);
+ brw_clip_copy_flatshaded_attributes(c, 2, 0);
}
brw_ENDIF(p);
}
else {
- brw_clip_copy_colors(c, 0, 2);
- brw_clip_copy_colors(c, 1, 2);
+ brw_clip_copy_flatshaded_attributes(c, 0, 2);
+ brw_clip_copy_flatshaded_attributes(c, 1, 2);
}
}
brw_ENDIF(p);
}
+/**
+ * Loads the clip distance for a vertex into `dst`, and ends with
+ * 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 directly available in the vertex.
+ */
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)
+load_clip_distance(struct brw_clip_compile *c, struct brw_indirect vtx,
+ struct brw_reg dst, GLuint hpos_offset, int cond)
{
struct brw_compile *p = &c->func;
- /*
- * Roughly:
- * dst = (vertex_src_mask & 1) ? src.hpos : src.clipvertex;
- */
-
+ dst = vec4(dst);
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));
+ 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_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(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(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, c->reg.clipdistance_offset, brw_imm_d(clipdist0_offset - 6*sizeof(float)));
brw_DO(p, BRW_EXECUTE_1);
{
*/
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);
+ load_clip_distance(c, vtxPrev, c->reg.dpPrev, hpos_offset, BRW_CONDITIONAL_L);
/* IS_NEGATIVE(prev) */
- brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
- 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);
+ load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_GE);
/* IS_POSITIVE(next)
*/
- brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
- brw_DP4(p, vec4(c->reg.dp), vec4(c->reg.dp), c->reg.plane_equation);
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_vertex_pos(c, vtx, vec4(c->reg.dp), hpos_offset, clipvert_offset);
+ load_clip_distance(c, vtx, c->reg.dp, hpos_offset, BRW_CONDITIONAL_L);
/* IS_NEGATIVE(next)
*/
- brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
- 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
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);
}
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));
}
* flatshading, need to apply the flatshade here because we don't
* respect the PV when converting to trifan for emit:
*/
- if (c->key.do_flat_shading)
+ if (c->has_flat_shading)
brw_clip_tri_flat_shade(c);
if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||