Mesa (master): r300g: separate the hyperz state and pipelined FB regs out of the FB state

Marek Olšák mareko at kemper.freedesktop.org
Sun Jun 27 06:17:53 PDT 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 27 13:55:59 2010 +0200

r300g: separate the hyperz state and pipelined FB regs out of the FB state

---

 src/gallium/drivers/r300/r300_context.c |   35 +++++++++++++++++++++++++++---
 src/gallium/drivers/r300/r300_context.h |   16 +++++++++++++-
 src/gallium/drivers/r300/r300_emit.c    |   23 +++++++++++++++++--
 src/gallium/drivers/r300/r300_emit.h    |    6 +++++
 src/gallium/drivers/r300/r300_state.c   |    7 +++--
 5 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index c3c4c74..df2874d 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -108,6 +108,7 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300->clip_state.state);
     FREE(r300->fb_state.state);
     FREE(r300->gpu_flush.state);
+    FREE(r300->hyperz_state.state);
     FREE(r300->invariant_state.state);
     FREE(r300->rs_block_state.state);
     FREE(r300->scissor_state.state);
@@ -143,6 +144,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     boolean is_rv350 = r300->screen->caps.is_rv350;
     boolean is_r500 = r300->screen->caps.is_r500;
     boolean has_tcl = r300->screen->caps.has_tcl;
+    boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
 
     /* Create the actual atom list.
      *
@@ -150,12 +152,23 @@ static void r300_setup_atoms(struct r300_context* r300)
      * can affect performance and conformance if not handled with care.
      *
      * Some atoms never change size, others change every emit - those have
-     * the size of 0 here. */
+     * the size of 0 here.
+     *
+     * NOTE: The framebuffer state is split into these atoms:
+     * - gpu_flush          (unpipelined regs)
+     * - aa_state           (unpipelined regs)
+     * - fb_state           (unpipelined regs)
+     * - hyperz_state       (unpipelined regs followed by pipelined ones)
+     * - fb_state_pipelined (pipelined regs)
+     * The motivation behind this is to be able to emit a strict
+     * subset of the regs, and to have reasonable register ordering. */
     make_empty_list(&r300->atom_list);
-    /* GB (unpipelined), RB3D (unpipelined), ZB (unpipelined), US, SC. */
+    /* SC, GB (unpipelined), RB3D (unpipelined), ZB (unpipelined). */
     R300_INIT_ATOM(gpu_flush, 9);
     R300_INIT_ATOM(aa_state, 4);
     R300_INIT_ATOM(fb_state, 0);
+    /* ZB (unpipelined), SC. */
+    R300_INIT_ATOM(hyperz_state, 6);
     R300_INIT_ATOM(ztop_state, 2);
     /* ZB, FG. */
     R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6);
@@ -165,7 +178,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     /* SC. */
     R300_INIT_ATOM(scissor_state, 3);
     /* GB, FG, GA, SU, SC, RB3D. */
-    R300_INIT_ATOM(invariant_state, 18 + (is_rv350 ? 4 : 0));
+    R300_INIT_ATOM(invariant_state, 16 + (is_rv350 ? 4 : 0));
     /* VAP. */
     R300_INIT_ATOM(viewport_state, 9);
     R300_INIT_ATOM(pvs_flush, 2);
@@ -177,6 +190,8 @@ static void r300_setup_atoms(struct r300_context* r300)
     /* VAP, RS, GA, GB, SU, SC. */
     R300_INIT_ATOM(rs_block_state, 0);
     R300_INIT_ATOM(rs_state, 0);
+    /* SC, US. */
+    R300_INIT_ATOM(fb_state_pipelined, 5 + (drm_2_3_0 ? 3 : 0));
     /* US. */
     R300_INIT_ATOM(fs, 0);
     R300_INIT_ATOM(fs_rc_constant_state, 0);
@@ -200,6 +215,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     r300->clip_state.state = CALLOC_STRUCT(r300_clip_state);
     r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
     r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state);
+    r300->hyperz_state.state = CALLOC_STRUCT(r300_hyperz_state);
     r300->invariant_state.state = CALLOC_STRUCT(r300_invariant_state);
     r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
     r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
@@ -214,6 +230,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     }
 
     /* Some non-CSO atoms don't use the state pointer. */
+    r300->fb_state_pipelined.allow_null_state = TRUE;
     r300->fs_rc_constant_state.allow_null_state = TRUE;
     r300->pvs_flush.allow_null_state = TRUE;
     r300->query_start.allow_null_state = TRUE;
@@ -244,6 +261,8 @@ static void r300_init_states(struct pipe_context *pipe)
             (struct r300_vap_invariant_state*)r300->vap_invariant_state.state;
     struct r300_invariant_state *invariant =
             (struct r300_invariant_state*)r300->invariant_state.state;
+    struct r300_hyperz_state *hyperz =
+            (struct r300_hyperz_state*)r300->hyperz_state.state;
     CB_LOCALS;
 
     pipe->set_blend_color(pipe, &bc);
@@ -300,7 +319,6 @@ static void r300_init_states(struct pipe_context *pipe)
         OUT_CB_REG(R300_SU_TEX_WRAP, 0);
         OUT_CB_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF);
         OUT_CB_REG(R300_SU_DEPTH_OFFSET, 0);
-        OUT_CB_REG(R300_SC_HYPERZ, 0x1C);
         OUT_CB_REG(R300_SC_EDGERULE, 0x2DA49525);
 
         if (r300->screen->caps.is_rv350) {
@@ -309,6 +327,15 @@ static void r300_init_states(struct pipe_context *pipe)
         }
         END_CB;
     }
+
+    /* Initialize the hyperz state. */
+    {
+        BEGIN_CB(&hyperz->cb_begin, 6);
+        OUT_CB_REG(R300_ZB_BW_CNTL, 0);
+        OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0);
+        OUT_CB_REG(R300_SC_HYPERZ, 0x1C);
+        END_CB;
+    }
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 760336c..50dcd0f 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -105,6 +105,16 @@ struct r300_dsa_state {
     boolean two_sided_stencil_ref;
 };
 
+struct r300_hyperz_state {
+    /* This is actually a command buffer with named dwords. */
+    uint32_t cb_begin;
+    uint32_t zb_bw_cntl;            /* R300_ZB_BW_CNTL */
+    uint32_t cb_reg1;
+    uint32_t zb_depthclearvalue;    /* R300_ZB_DEPTHCLEARVALUE */
+    uint32_t cb_reg2;
+    uint32_t sc_hyperz;             /* R300_SC_HYPERZ */
+};
+
 struct r300_gpu_flush {
     uint32_t cb_flush_clean[6];
 };
@@ -211,7 +221,7 @@ struct r300_vertex_stream_state {
 };
 
 struct r300_invariant_state {
-    uint32_t cb[22];
+    uint32_t cb[20];
 };
 
 struct r300_vap_invariant_state {
@@ -443,6 +453,10 @@ struct r300_context {
     struct r300_atom fs_constants;
     /* Framebuffer state. */
     struct r300_atom fb_state;
+    /* Framebuffer state (pipelined regs). */
+    struct r300_atom fb_state_pipelined;
+    /* HyperZ state (various SC/ZB bits). */
+    struct r300_atom hyperz_state;
     /* Occlusion query. */
     struct r300_atom query_start;
     /* Rasterizer state. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d72b6d9..014b382 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -349,7 +349,6 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         surf = r300_surface(fb->zsbuf);
 
         OUT_CS_REG(R300_ZB_FORMAT, surf->format);
-        OUT_CS_REG(R300_ZB_BW_CNTL, 0);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
         OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain, 0);
@@ -357,8 +356,6 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
         OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
 
-        OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0);
-
         /* HiZ RAM. */
         if (r300->screen->caps.has_hiz) {
             OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0);
@@ -370,6 +367,26 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0);
     }
 
+    END_CS;
+}
+
+void r300_emit_hyperz_state(struct r300_context *r300,
+                            unsigned size, void *state)
+{
+    CS_LOCALS(r300);
+    WRITE_CS_TABLE(state, size);
+}
+
+void r300_emit_fb_state_pipelined(struct r300_context *r300,
+                                  unsigned size, void *state)
+{
+    struct pipe_framebuffer_state* fb =
+            (struct pipe_framebuffer_state*)r300->fb_state.state;
+    unsigned i;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(size);
+
     /* Colorbuffer format in the US block.
      * (must be written after unpipelined regs) */
     OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4);
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 44fad23..586ccda 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -59,8 +59,14 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
 
 void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state);
 
+void r300_emit_fb_state_pipelined(struct r300_context *r300,
+                                  unsigned size, void *state);
+
 void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state);
 
+void r300_emit_hyperz_state(struct r300_context *r300,
+                            unsigned size, void *state);
+
 void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state);
 
 void r300_emit_query_start(struct r300_context *r300, unsigned size, void *state);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 567774c..6177ab3 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -708,6 +708,8 @@ static void
     r300->gpu_flush.dirty = TRUE;
     r300->aa_state.dirty = TRUE;
     r300->fb_state.dirty = TRUE;
+    r300->hyperz_state.dirty = TRUE;
+    r300->fb_state_pipelined.dirty = TRUE;
 
     /* If nr_cbufs is changed from zero to non-zero or vice versa... */
     if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
@@ -724,10 +726,9 @@ static void
     copy_framebuffer_state(r300->fb_state.state, state);
 
     r300->fb_state.size =
-            7 +
+            2 +
             (8 * state->nr_cbufs) +
-            (state->zsbuf ? (r300->screen->caps.has_hiz ? 22 : 18) : 0) +
-            (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0) ? 3 : 0);
+            (state->zsbuf ? (r300->screen->caps.has_hiz ? 18 : 14) : 0);
 
     /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {



More information about the mesa-commit mailing list