void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
GLuint nr_verts )
{
- struct intel_context *intel = &c->func.brw->intel;
+ struct brw_context *brw = c->func.brw;
GLuint i = 0,j;
/* Register usage is static, precompute here:
i++;
}
- if (intel->needs_ff_sync) {
+ 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++;
}
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_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;
+
+ 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);
+ {
+ 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));
+}
+
/* Use mesa's clipping algorithms, translated to GEN4 assembly.
*/
struct brw_indirect inlist_ptr = brw_indirect(4, 0);
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 *vertex_loop;
- GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
- VERT_RESULT_HPOS);
-
+ 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(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));
brw_MOV(p, get_addr_reg(freelist_ptr), brw_address(c->reg.vertex[3]) );
- plane_loop = brw_DO(p, BRW_EXECUTE_1);
+ /* 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_MOV(p, c->reg.loopcount, c->reg.nr_verts);
brw_MOV(p, c->reg.nr_verts, brw_imm_ud(0));
- vertex_loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
/* vtx = *input_ptr;
*/
brw_MOV(p, get_addr_reg(vtx), deref_1uw(inlist_ptr, 0));
+ 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), deref_4f(vtxPrev, hpos_offset), c->reg.plane_equation);
brw_IF(p, BRW_EXECUTE_1);
{
+ 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), deref_4f(vtx, hpos_offset), 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_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), deref_4f(vtx, hpos_offset), 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_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, vertex_loop);
+ brw_WHILE(p);
/* vtxPrev = *(outlist_ptr-1) OR: outlist[nr_verts-1]
* inlist = outlist
*/
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, plane_loop);
+ brw_WHILE(p);
}
void brw_clip_tri_emit_polygon(struct brw_clip_compile *c)
{
struct brw_compile *p = &c->func;
- struct brw_instruction *loop;
/* for (loopcount = nr_verts-2; loopcount > 0; loopcount--)
*/
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, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_START));
+ brw_clip_emit_vue(c, v0, BRW_URB_WRITE_ALLOCATE_COMPLETE,
+ ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
+ | URB_WRITE_PRIM_START));
brw_ADD(p, get_addr_reg(vptr), get_addr_reg(vptr), brw_imm_uw(2));
brw_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
- loop = brw_DO(p, BRW_EXECUTE_1);
+ brw_DO(p, BRW_EXECUTE_1);
{
- brw_clip_emit_vue(c, v0, 1, 0, (_3DPRIM_TRIFAN << 2));
+ 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_MOV(p, get_addr_reg(v0), deref_1uw(vptr, 0));
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_ADD(p, c->reg.loopcount, c->reg.loopcount, brw_imm_d(-1));
}
- brw_WHILE(p, loop);
+ brw_WHILE(p);
- brw_clip_emit_vue(c, v0, 0, 1, ((_3DPRIM_TRIFAN << 2) | R02_PRIM_END));
+ brw_clip_emit_vue(c, v0, BRW_URB_WRITE_EOT_COMPLETE,
+ ((_3DPRIM_TRIFAN << URB_WRITE_PRIM_TYPE_SHIFT)
+ | URB_WRITE_PRIM_END));
}
brw_ENDIF(p);
}
struct brw_compile *p = &c->func;
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
- GLuint hpos_offset = brw_vert_result_to_offset(&c->vue_map,
- VERT_RESULT_HPOS);
+ GLuint hpos_offset = brw_varying_to_offset(&c->vue_map,
+ VARYING_SLOT_POS);
brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
* 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) ||