summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_state.c
diff options
context:
space:
mode:
authorJerome Glisse <[email protected]>2013-02-08 16:02:32 -0500
committerJerome Glisse <[email protected]>2013-02-12 17:03:56 -0500
commit974b482acaf62ced1e8981761a8bda252bd51fe1 (patch)
treea264943597a145f582934fbad15b7e776aa12553 /src/gallium/drivers/r600/r600_state.c
parent496928a442cec980b534bc5da2523b3632b21b61 (diff)
r600g: fix lockup when hyperz & alpha test are enabled together. v3
Seems that alpha test being enabled confuse the GPU on the order in which it should perform the Z testing. So force the order programmed throught db shader control. v2: Only force z order when alpha test is enabled v3: Update db shader when binding new dsa + spelling fix Signed-off-by: Jerome Glisse <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_state.c')
-rw-r--r--src/gallium/drivers/r600/r600_state.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 532285024f1..3f359fb0dd7 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1966,6 +1966,13 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
if (rctx->db_state.rsurf && rctx->db_state.rsurf->htile_enabled) {
/* FORCE_OFF means HiZ/HiS are determined by DB_SHADER_CONTROL */
db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_OFF);
+ /* This is to fix a lockup when hyperz and alpha test are enabled at
+ * the same time somehow GPU get confuse on which order to pick for
+ * z test
+ */
+ if (rctx->alphatest_state.sx_alpha_test_control) {
+ db_render_override |= S_028D10_FORCE_SHADER_Z_ORDER(1);
+ }
} else {
db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE);
}
@@ -2774,7 +2781,7 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad
tmp);
}
- db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
+ db_shader_control = 0;
for (i = 0; i < rshader->noutput; i++) {
if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
z_export = 1;
@@ -2969,6 +2976,19 @@ void r600_update_db_shader_control(struct r600_context * rctx)
unsigned db_shader_control = rctx->ps_shader->current->db_shader_control |
S_02880C_DUAL_EXPORT_ENABLE(dual_export);
+ /* When alpha test is enabled we can't trust the hw to make the proper
+ * decision on the order in which ztest should be run related to fragment
+ * shader execution.
+ *
+ * If alpha test is enabled perform z test after fragment. RE_Z (early
+ * z test but no write to the zbuffer) seems to cause lockup on r6xx/r7xx
+ */
+ if (rctx->alphatest_state.sx_alpha_test_control) {
+ db_shader_control |= S_02880C_Z_ORDER(V_02880C_LATE_Z);
+ } else {
+ db_shader_control |= S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
+ }
+
if (db_shader_control != rctx->db_misc_state.db_shader_control) {
rctx->db_misc_state.db_shader_control = db_shader_control;
rctx->db_misc_state.atom.dirty = true;