r300g: improve the ZTOP condition
authorMarek Olšák <maraeo@gmail.com>
Sat, 19 Jun 2010 02:44:34 +0000 (04:44 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 19 Jun 2010 03:14:31 +0000 (05:14 +0200)
The real difference here is that ZTOP is now enabled if all stencil ops
are set to KEEP. This improves performance.

src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_hyperz.c
src/gallium/drivers/r300/r300_state.c

index 0d7ff2e061c66a332105b4fc985b5b5b4d67dbb6..8e9742fe82f22524f0f9e65298d344a6b7ac853b 100644 (file)
@@ -77,6 +77,8 @@ struct r300_clip_state {
 };
 
 struct r300_dsa_state {
+    struct pipe_depth_stencil_alpha_state dsa;
+
     /* This is actually a command buffer with named dwords. */
     uint32_t cb_begin;
     uint32_t alpha_function;    /* R300_FG_ALPHA_FUNC: 0x4bd4 */
index b41b6b1508d88086354f57dbd6c28fe0c1f5af26..6358d98b8381190245512b6d424ee9e2e2e677e9 100644 (file)
 /* The ZTOP state                                                            */
 /*****************************************************************************/
 
-static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
+static boolean r300_dsa_writes_stencil(
+        struct pipe_stencil_state *s)
 {
-    /* We are interested only in the cases when a new depth or stencil value
-     * can be written and changed. */
+    return s->enabled && s->writemask &&
+           (s->fail_op  != PIPE_STENCIL_OP_KEEP ||
+            s->zfail_op != PIPE_STENCIL_OP_KEEP ||
+            s->zpass_op != PIPE_STENCIL_OP_KEEP);
+}
+
+static boolean r300_dsa_writes_depth_stencil(
+        struct pipe_depth_stencil_alpha_state *dsa)
+{
+    /* We are interested only in the cases when a depth or stencil value
+     * can be changed. */
+
+    if (dsa->depth.enabled && dsa->depth.writemask &&
+        dsa->depth.func != PIPE_FUNC_NEVER)
+        return TRUE;
+
+    if (r300_dsa_writes_stencil(&dsa->stencil[0]) ||
+        r300_dsa_writes_stencil(&dsa->stencil[1]))
+        return TRUE;
 
-    /* We might optionally check for [Z func: never] and inspect the stencil
-     * state in a similar fashion, but it's not terribly important. */
-    return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
-           (dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
-           ((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
-            (dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
+    return FALSE;
 }
 
-static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
+static boolean r300_dsa_alpha_test_enabled(
+        struct pipe_depth_stencil_alpha_state *dsa)
 {
     /* We are interested only in the cases when alpha testing can kill
      * a fragment. */
-    uint32_t af = dsa->alpha_function;
 
-    return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
-           (af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
+    return dsa->alpha.enabled && dsa->alpha.func != PIPE_FUNC_ALWAYS;
 }
 
 static void r300_update_ztop(struct r300_context* r300)
index e1149d738686a7838b2bc1bda7a4051ee894ca4a..9799f0c52235c62deee0c1f97d85f9f1c8beed81 100644 (file)
@@ -465,6 +465,8 @@ static void*
     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
     CB_LOCALS;
 
+    dsa->dsa = *state;
+
     /* Depth test setup. */
     if (state->depth.enabled) {
         dsa->z_buffer_control |= R300_Z_ENABLE;