aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_state.c10
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c36
2 files changed, 36 insertions, 10 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 95e2943baa5..8359850966b 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -190,7 +190,6 @@ static void*
r300_create_dsa_state(struct pipe_context* pipe,
const struct pipe_depth_stencil_alpha_state* state)
{
- struct r300_context* r300 = r300_context(pipe);
struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
/* Depth test setup. */
@@ -250,15 +249,6 @@ static void*
0, 1023);
}
- dsa->z_buffer_top = R300_ZTOP_ENABLE;
- /* XXX TODO: add frag prog rules for ztop disable */
- if (r300_fragment_shader_writes_depth(r300->fs))
- dsa->z_buffer_top = R300_ZTOP_DISABLE;
- if (state->alpha.enabled && state->alpha.func != PIPE_FUNC_ALWAYS)
- dsa->z_buffer_top = R300_ZTOP_DISABLE;
- if (r300->query_current)
- dsa->z_buffer_top = R300_ZTOP_DISABLE;
-
return (void*)dsa;
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 335b54820aa..5d323a26b14 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -444,6 +444,37 @@ static void r300_update_rs_block(struct r300_context* r300)
rs->inst_count = MAX2(MAX2(col_count - 1, tex_count - 1), 0);
}
+static void r300_update_ztop(struct r300_context* r300)
+{
+ r300->dsa_state->z_buffer_top = R300_ZTOP_ENABLE;
+
+ /* This is important enough that I felt it warranted a comment.
+ *
+ * According to the docs, these are the conditions where ZTOP must be
+ * disabled:
+ * 1) Alpha testing enabled
+ * 2) Texture kill instructions in fragment shader
+ * 3) Chroma key culling enabled
+ * 4) W-buffering enabled
+ *
+ * The docs claim that for the first three cases, if no ZS writes happen,
+ * then ZTOP can be used.
+ *
+ * Additionally, the following conditions require disabled ZTOP:
+ * ~) Depth writes in fragment shader
+ * ~) Outstanding occlusion queries
+ *
+ * ~C.
+ */
+ if (r300->dsa_state->alpha_function) {
+ r300->dsa_state->z_buffer_top = R300_ZTOP_DISABLE;
+ } else if (r300_fragment_shader_writes_depth(r300->fs)) {
+ r300->dsa_state->z_buffer_top = R300_ZTOP_DISABLE;
+ } else if (r300->query_current) {
+ r300->dsa_state->z_buffer_top = R300_ZTOP_DISABLE;
+ }
+}
+
void r300_update_derived_state(struct r300_context* r300)
{
if (r300->dirty_state &
@@ -455,4 +486,9 @@ void r300_update_derived_state(struct r300_context* r300)
r300_update_fs_tab(r300);
r300_update_rs_block(r300);
}
+
+ if (r300->dirty_state &
+ (R300_NEW_DSA | R300_NEW_FRAGMENT_SHADER | R300_NEW_QUERY)) {
+ r300_update_ztop(r300);
+ }
}