Mesa (master): r300g: try and use all of vertex constant space

Marek Olšák mareko at kemper.freedesktop.org
Sun Dec 5 05:56:20 UTC 2010


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Dec  3 20:53:39 2010 +1000

r300g: try and use all of vertex constant space

Finished up by Marek Olšák.

We can set the constant space to use a different area per-call to the shader,
we can avoid flushing the PVS as often as we do by spreading out the constants
across the whole constant space.

Signed-off-by: Marek Olšák <maraeo at gmail.com>

---

 src/gallium/drivers/r300/r300_context.h |    5 ++
 src/gallium/drivers/r300/r300_emit.c    |   71 +++++++++++++++----------------
 src/gallium/drivers/r300/r300_reg.h     |    3 +-
 src/gallium/drivers/r300/r300_state.c   |   30 +++++++++----
 4 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index b543ad6..bb5906a 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -258,6 +258,8 @@ struct r300_constant_buffer {
     uint32_t *ptr;
     /* Remapping table. */
     unsigned *remap_table;
+    /* const buffer base */
+    uint32_t buffer_base;
 };
 
 /* Query object.
@@ -606,6 +608,9 @@ struct r300_context {
 
     /* Stat counter. */
     uint64_t flush_counter;
+
+    /* const tracking for VS */
+    int vs_const_base;
 };
 
 /* Convenience cast wrappers. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 2b13727..3ff5b13 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -924,7 +924,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
     struct r300_vertex_program_code* code = &vs->code;
     struct r300_screen* r300screen = r300->screen;
     unsigned instruction_count = code->length / 4;
-    unsigned i;
 
     unsigned vtx_mem_size = r300screen->caps.is_r500 ? 128 : 72;
     unsigned input_count = MAX2(util_bitcount(code->InputsRead), 1);
@@ -935,10 +934,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
                                   vtx_mem_size / output_count, 10);
     unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 5);
 
-    unsigned imm_first = vs->externals_count;
-    unsigned imm_end = vs->code.constants.Count;
-    unsigned imm_count = vs->immediates_count;
-
     CS_LOCALS(r300);
 
     BEGIN_CS(size);
@@ -947,12 +942,10 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
      * R300_VAP_PVS_CONST_CNTL
      * R300_VAP_PVS_CODE_CNTL_1
      * See the r5xx docs for instructions on how to use these. */
-    OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
-    OUT_CS(R300_PVS_FIRST_INST(0) |
-            R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
-            R300_PVS_LAST_INST(instruction_count - 1));
-    OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1));
-    OUT_CS(instruction_count - 1);
+    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) |
+	       R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
+	       R300_PVS_LAST_INST(instruction_count - 1));
+    OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, instruction_count - 1);
 
     OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
     OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
@@ -964,19 +957,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
             R300_PVS_VF_MAX_VTX_NUM(12) |
             (r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0));
 
-    /* Emit immediates. */
-    if (imm_count) {
-        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-                   (r300->screen->caps.is_r500 ?
-                   R500_PVS_CONST_START : R300_PVS_CONST_START) +
-                   imm_first);
-        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4);
-        for (i = imm_first; i < imm_end; i++) {
-            const float *data = vs->code.constants.Constants[i].u.Immediate;
-            OUT_CS_TABLE(data, 4);
-        }
-    }
-
     /* Emit flow control instructions. */
     if (code->num_fc_ops) {
 
@@ -1001,24 +981,43 @@ void r300_emit_vs_constants(struct r300_context* r300,
     unsigned count =
         ((struct r300_vertex_shader*)r300->vs_state.state)->externals_count;
     struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
+    struct r300_vertex_shader *vs = (struct r300_vertex_shader*)r300->vs_state.state;
     unsigned i;
+    int imm_first = vs->externals_count;
+    int imm_end = vs->code.constants.Count;
+    int imm_count = vs->immediates_count;
     CS_LOCALS(r300);
 
-    if (!count)
-        return;
-
     BEGIN_CS(size);
-    OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-               (r300->screen->caps.is_r500 ?
-               R500_PVS_CONST_START : R300_PVS_CONST_START));
-    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
-    if (buf->remap_table){
-        for (i = 0; i < count; i++) {
-            uint32_t *data = &buf->ptr[buf->remap_table[i]*4];
+    OUT_CS_REG(R300_VAP_PVS_CONST_CNTL,
+               R300_PVS_CONST_BASE_OFFSET(buf->buffer_base) |
+               R300_PVS_MAX_CONST_ADDR(MAX2(imm_end - 1, 0)));
+    if (vs->externals_count) {
+        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+                   (r300->screen->caps.is_r500 ?
+                   R500_PVS_CONST_START : R300_PVS_CONST_START) + buf->buffer_base);
+        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
+        if (buf->remap_table){
+            for (i = 0; i < count; i++) {
+                uint32_t *data = &buf->ptr[buf->remap_table[i]*4];
+                OUT_CS_TABLE(data, 4);
+            }
+        } else {
+            OUT_CS_TABLE(buf->ptr, count * 4);
+        }
+    }
+
+    /* Emit immediates. */
+    if (imm_count) {
+        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+                   (r300->screen->caps.is_r500 ?
+                   R500_PVS_CONST_START : R300_PVS_CONST_START) +
+                   buf->buffer_base + imm_first);
+        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, imm_count * 4);
+        for (i = imm_first; i < imm_end; i++) {
+            const float *data = vs->code.constants.Constants[i].u.Immediate;
             OUT_CS_TABLE(data, 4);
         }
-    } else {
-        OUT_CS_TABLE(buf->ptr, count * 4);
     }
     END_CS;
 }
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 788c513..613186e 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -427,7 +427,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #       define R300_PVS_CONST_START          512
 #       define R500_PVS_CONST_START          1024
 #       define R300_MAX_PVS_CONST_VECS       256
-#       define R500_MAX_PVS_CONST_VECS       1024
+#       define R500_MAX_PVS_CONST_VECS       256
 #       define R300_PVS_UCP_START            1024
 #       define R500_PVS_UCP_START            1536
 #       define R300_POINT_VPORT_SCALE_OFFSET 1030
@@ -553,6 +553,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Addresses are relative to the vertex program parameters area. */
 #define R300_VAP_PVS_CONST_CNTL             0x22D4
 #       define R300_PVS_CONST_BASE_OFFSET_SHIFT  0
+#       define R300_PVS_CONST_BASE_OFFSET(x)     (x)
 #       define R300_PVS_MAX_CONST_ADDR_SHIFT     16
 #       define R300_PVS_MAX_CONST_ADDR(x)        ((x) << 16)
 #define R300_VAP_PVS_CODE_CNTL_1	    0x22D8
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 5689275..4eef9da 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1765,15 +1765,13 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
         r300->vs_state.dirty = TRUE;
         r300->vs_state.size =
                 vs->code.length + 9 +
-                (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0) +
         (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0);
 
-        if (vs->externals_count) {
-            r300->vs_constants.dirty = TRUE;
-            r300->vs_constants.size = vs->externals_count * 4 + 3;
-        } else {
-            r300->vs_constants.size = 0;
-        }
+        r300->vs_constants.dirty = TRUE;
+        r300->vs_constants.size =
+                2 +
+                (vs->externals_count ? vs->externals_count * 4 + 3 : 0) +
+                (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0);
 
         ((struct r300_constant_buffer*)r300->vs_constants.state)->remap_table =
                 vs->code.constants_remap_table;
@@ -1835,10 +1833,22 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
 
     if (shader == PIPE_SHADER_VERTEX) {
         if (r300->screen->caps.has_tcl) {
-            if (r300->vs_constants.size) {
-                r300->vs_constants.dirty = TRUE;
+            struct r300_vertex_shader *vs =
+                    (struct r300_vertex_shader*)r300->vs_state.state;
+
+            if (!vs) {
+                cbuf->buffer_base = 0;
+                return;
             }
-            r300->pvs_flush.dirty = TRUE;
+
+            cbuf->buffer_base = r300->vs_const_base;
+            r300->vs_const_base += vs->code.constants.Count;
+            if (r300->vs_const_base > R500_MAX_PVS_CONST_VECS) {
+                r300->vs_const_base = vs->code.constants.Count;
+                cbuf->buffer_base = 0;
+                r300->pvs_flush.dirty = TRUE;
+            }
+            r300->vs_constants.dirty = TRUE;
         } else if (r300->draw) {
             draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
                 0, mapped, buf->width0);




More information about the mesa-commit mailing list