mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
i965: fix for RHW workaround
It is possible that an object whose vertices all are outside of a view plane is passed to clip thread due to the RHW workaround. This object should be rejected by clip thread. Fix bug #19879
This commit is contained in:
parent
160c3617fc
commit
68915fd6fa
2 changed files with 97 additions and 41 deletions
|
|
@ -181,34 +181,54 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
|
|||
brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
|
||||
is_negative = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
|
||||
/*
|
||||
* Both can be negative on GM965/G965 due to RHW workaround
|
||||
* if so, this object should be rejected.
|
||||
*/
|
||||
if (!BRW_IS_G4X(p->brw)) {
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
|
||||
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
brw_ENDIF(p, is_neg2);
|
||||
}
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
|
||||
brw_MOV(p, c->reg.t1, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_ADD(p, c->reg.t, c->reg.dp1, negate(c->reg.dp0));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp1);
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t1 );
|
||||
brw_MOV(p, c->reg.t1, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
is_negative = brw_ELSE(p, is_negative);
|
||||
{
|
||||
/* Coming back in. We know that both cannot be negative
|
||||
* because the line would have been culled in that case.
|
||||
*/
|
||||
/* Coming back in. We know that both cannot be negative
|
||||
* because the line would have been culled in that case.
|
||||
*/
|
||||
|
||||
/* If both are positive, do nothing */
|
||||
/* Only on GM965/G965 */
|
||||
if (!BRW_IS_G4X(p->brw)) {
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
|
||||
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
|
||||
}
|
||||
|
||||
/* If both are positive, do nothing */
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
|
||||
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
|
||||
brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1));
|
||||
brw_math_invert(p, c->reg.t, c->reg.t);
|
||||
brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0);
|
||||
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
|
||||
brw_MOV(p, c->reg.t0, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
brw_ENDIF(p, is_neg2);
|
||||
}
|
||||
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 );
|
||||
brw_MOV(p, c->reg.t0, c->reg.t);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
}
|
||||
|
||||
if (!BRW_IS_G4X(p->brw)) {
|
||||
brw_ENDIF(p, is_neg2);
|
||||
}
|
||||
}
|
||||
brw_ENDIF(p, is_negative);
|
||||
}
|
||||
brw_ENDIF(p, plane_active);
|
||||
|
|
|
|||
|
|
@ -455,6 +455,8 @@ static void brw_clip_test( struct brw_clip_compile *c )
|
|||
struct brw_indirect vt2 = brw_indirect(2, 0);
|
||||
|
||||
struct brw_compile *p = &c->func;
|
||||
struct brw_instruction *is_outside;
|
||||
struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
|
||||
|
||||
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]));
|
||||
|
|
@ -462,53 +464,87 @@ static void brw_clip_test( struct brw_clip_compile *c )
|
|||
brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
|
||||
brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
|
||||
|
||||
/* test nearz, xmin, ymin plane */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3));
|
||||
/* clip.xyz < -clip.w */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, negate(get_element(v0, 3)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3));
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, negate(get_element(v1, 3)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3));
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, negate(get_element(v2, 3)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* All vertices are outside of a plane, rejected */
|
||||
brw_AND(p, t, t1, t2);
|
||||
brw_AND(p, t, t, t3);
|
||||
brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
|
||||
brw_OR(p, tmp0, tmp0, get_element(t, 2));
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
|
||||
is_outside = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
brw_ENDIF(p, is_outside);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* some vertices are inside a plane, some are outside,need to clip */
|
||||
brw_XOR(p, t, t1, t2);
|
||||
brw_XOR(p, t1, t2, t3);
|
||||
brw_OR(p, t, t, t1);
|
||||
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_AND(p, t, t, brw_imm_ud(0x1));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* test farz, xmax, ymax plane */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3));
|
||||
/* clip.xyz > clip.w */
|
||||
brw_CMP(p, t1, BRW_CONDITIONAL_G, v0, get_element(v0, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3));
|
||||
brw_CMP(p, t2, BRW_CONDITIONAL_G, v1, get_element(v1, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3));
|
||||
brw_CMP(p, t3, BRW_CONDITIONAL_G, v2, get_element(v2, 3));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* All vertices are outside of a plane, rejected */
|
||||
brw_AND(p, t, t1, t2);
|
||||
brw_AND(p, t, t, t3);
|
||||
brw_OR(p, tmp0, get_element(t, 0), get_element(t, 1));
|
||||
brw_OR(p, tmp0, tmp0, get_element(t, 2));
|
||||
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
|
||||
brw_AND(p, brw_null_reg(), tmp0, brw_imm_ud(0x1));
|
||||
is_outside = brw_IF(p, BRW_EXECUTE_1);
|
||||
{
|
||||
brw_clip_kill_thread(c);
|
||||
}
|
||||
brw_ENDIF(p, is_outside);
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
/* some vertices are inside a plane, some are outside,need to clip */
|
||||
brw_XOR(p, t, t1, t2);
|
||||
brw_XOR(p, t1, t2, t3);
|
||||
brw_OR(p, t, t, t1);
|
||||
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_AND(p, t, t, brw_imm_ud(0x1));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 0), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 1), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ,
|
||||
get_element(t, 2), brw_imm_ud(0));
|
||||
brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0)));
|
||||
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue