Mesa (master): r300g: turn depth stencil state into a CB

Marek Olšák mareko at kemper.freedesktop.org
Sun Jun 13 10:17:52 PDT 2010


Module: Mesa
Branch: master
Commit: 0a44efaeb91c7cef9b244ae86c4977b019a63c54
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0a44efaeb91c7cef9b244ae86c4977b019a63c54

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 13 05:31:48 2010 +0200

r300g: turn depth stencil state into a CB

---

 src/gallium/drivers/r300/r300_context.h |    8 +++++-
 src/gallium/drivers/r300/r300_emit.c    |   18 +------------
 src/gallium/drivers/r300/r300_state.c   |   39 +++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index a8e8130..64d6981 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -77,13 +77,19 @@ struct r300_clip_state {
 };
 
 struct r300_dsa_state {
+    /* This is actually a command buffer with named dwords. */
+    uint32_t cb_begin;
     uint32_t alpha_function;    /* R300_FG_ALPHA_FUNC: 0x4bd4 */
-    uint32_t alpha_reference;   /* R500_FG_ALPHA_VALUE: 0x4be0 */
+    uint32_t cb_reg_seq;
     uint32_t z_buffer_control;  /* R300_ZB_CNTL: 0x4f00 */
     uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */
     uint32_t stencil_ref_mask;  /* R300_ZB_STENCILREFMASK: 0x4f08 */
+    uint32_t cb_reg;
     uint32_t stencil_ref_bf;    /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */
 
+    /* The second command buffer disables zbuffer reads and writes. */
+    uint32_t cb_no_readwrite[8];
+
     /* Whether a two-sided stencil is enabled. */
     boolean two_sided;
     /* Whether a fallback should be used for a two-sided stencil ref value. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index e2e1074..f501c1f 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -73,27 +73,13 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
     struct r300_dsa_state* dsa = (struct r300_dsa_state*)state;
     struct pipe_framebuffer_state* fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
-    struct pipe_stencil_ref stencil_ref = r300->stencil_ref;
     CS_LOCALS(r300);
 
-    BEGIN_CS(size);
-    OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
-    OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
-
     if (fb->zsbuf) {
-        OUT_CS(dsa->z_buffer_control);
-        OUT_CS(dsa->z_stencil_control);
+        WRITE_CS_TABLE(&dsa->cb_begin, size);
     } else {
-        OUT_CS(0);
-        OUT_CS(0);
+        WRITE_CS_TABLE(dsa->cb_no_readwrite, size);
     }
-
-    OUT_CS(dsa->stencil_ref_mask | stencil_ref.ref_value[0]);
-
-    if (r300->screen->caps.is_r500) {
-        OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf | stencil_ref.ref_value[1]);
-    }
-    END_CS;
 }
 
 static const float * get_rc_constant_state(
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index c4b7d73..8176bf4 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -463,6 +463,7 @@ static void*
 {
     struct r300_capabilities *caps = &r300_screen(pipe->screen)->caps;
     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
+    CB_LOCALS;
 
     /* Depth test setup. */
     if (state->depth.enabled) {
@@ -535,9 +536,43 @@ static void*
             dsa->alpha_function |= R500_FG_ALPHA_FUNC_8BIT;
     }
 
+    BEGIN_CB(&dsa->cb_begin, 8);
+    OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
+    OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
+    OUT_CB(dsa->z_buffer_control);
+    OUT_CB(dsa->z_stencil_control);
+    OUT_CB(dsa->stencil_ref_mask);
+    OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf);
+    END_CB;
+
+    BEGIN_CB(dsa->cb_no_readwrite, 8);
+    OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function);
+    OUT_CB_REG_SEQ(R300_ZB_CNTL, 3);
+    OUT_CB(0);
+    OUT_CB(0);
+    OUT_CB(0);
+    OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0);
+    END_CB;
+
     return (void*)dsa;
 }
 
+static void r300_dsa_inject_stencilref(struct r300_context *r300)
+{
+    struct r300_dsa_state *dsa =
+            (struct r300_dsa_state*)r300->dsa_state.state;
+
+    if (!dsa)
+        return;
+
+    dsa->stencil_ref_mask =
+        (dsa->stencil_ref_mask & ~R300_STENCILREF_MASK) |
+        r300->stencil_ref.ref_value[0];
+    dsa->stencil_ref_bf =
+        (dsa->stencil_ref_bf & ~R300_STENCILREF_MASK) |
+        r300->stencil_ref.ref_value[1];
+}
+
 /* Bind DSA state. */
 static void r300_bind_dsa_state(struct pipe_context* pipe,
                                 void* state)
@@ -549,6 +584,8 @@ static void r300_bind_dsa_state(struct pipe_context* pipe,
     }
 
     UPDATE_STATE(state, r300->dsa_state);
+
+    r300_dsa_inject_stencilref(r300);
 }
 
 /* Free DSA state. */
@@ -564,6 +601,8 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
 
     r300->stencil_ref = *sr;
+
+    r300_dsa_inject_stencilref(r300);
     r300->dsa_state.dirty = TRUE;
 }
 



More information about the mesa-commit mailing list