Mesa (master): r300g: optimize emission of fragment shader constants

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


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Jun 13 06:39:58 2010 +0200

r300g: optimize emission of fragment shader constants

---

 src/gallium/drivers/r300/r300_context.h |    2 +-
 src/gallium/drivers/r300/r300_emit.c    |   35 ++++++++++--------------------
 src/gallium/drivers/r300/r300_state.c   |   16 +++++++++++--
 3 files changed, 26 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 64d6981..05948f9 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -231,7 +231,7 @@ struct r300_ztop_state {
 
 struct r300_constant_buffer {
     /* Buffer of constants */
-    float constants[256][4];
+    uint32_t constants[256][4];
     /* Total number of constants */
     unsigned count;
 };
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 658880a..8e8b752 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -169,25 +169,16 @@ void r300_emit_fs(struct r300_context* r300, unsigned size, void *state)
 void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
 {
     struct r300_fragment_shader *fs = r300_fs(r300);
-    struct rc_constant_list *constants = &fs->shader->code.constants;
     struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
-    unsigned i, count = fs->shader->externals_count;
+    unsigned count = fs->shader->externals_count * 4;
     CS_LOCALS(r300);
 
     if (count == 0)
         return;
 
     BEGIN_CS(size);
-    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4);
-    for(i = 0; i < count; ++i) {
-        const float *data;
-        assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
-        data = buf->constants[i];
-        OUT_CS(pack_float24(data[0]));
-        OUT_CS(pack_float24(data[1]));
-        OUT_CS(pack_float24(data[2]));
-        OUT_CS(pack_float24(data[3]));
-    }
+    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count);
+    OUT_CS_TABLE(buf->constants, count);
     END_CS;
 }
 
@@ -199,6 +190,8 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
     unsigned count = fs->shader->rc_state_count;
     unsigned first = fs->shader->externals_count;
     unsigned end = constants->Count;
+    uint32_t cdata[4];
+    unsigned j;
     CS_LOCALS(r300);
 
     if (count == 0)
@@ -210,11 +203,11 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
             const float *data =
                     get_rc_constant_state(r300, &constants->Constants[i]);
 
+            for (j = 0; j < 4; j++)
+                cdata[i] = pack_float24(data[i]);
+
             OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4);
-            OUT_CS(pack_float24(data[0]));
-            OUT_CS(pack_float24(data[1]));
-            OUT_CS(pack_float24(data[2]));
-            OUT_CS(pack_float24(data[3]));
+            OUT_CS_TABLE(cdata, 4);
         }
     }
     END_CS;
@@ -231,9 +224,8 @@ void r500_emit_fs(struct r300_context* r300, unsigned size, void *state)
 void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state)
 {
     struct r300_fragment_shader *fs = r300_fs(r300);
-    struct rc_constant_list *constants = &fs->shader->code.constants;
     struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
-    unsigned i, count = fs->shader->externals_count;
+    unsigned count = fs->shader->externals_count * 4;
     CS_LOCALS(r300);
 
     if (count == 0)
@@ -241,11 +233,8 @@ void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *stat
 
     BEGIN_CS(size);
     OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
-    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4);
-    for(i = 0; i < count; ++i) {
-        assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
-    }
-    OUT_CS_TABLE(buf->constants, count * 4);
+    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count);
+    OUT_CS_TABLE(buf->constants, count);
     END_CS;
 }
 
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 4892a1d..0772c1f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -1553,7 +1553,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     struct r300_context* r300 = r300_context(pipe);
     struct r300_constant_buffer *cbuf;
     struct pipe_transfer *tr;
-    void *mapped;
+    float *mapped;
     int max_size = 0, max_size_bytes = 0, clamped_size = 0;
 
     switch (shader) {
@@ -1592,10 +1592,20 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             fprintf(stderr, "r300: Max size of the constant buffer is "
                           "%i*4 floats.\n", max_size);
         }
-        clamped_size = MIN2(buf->width0, max_size_bytes);
 
-        memcpy(cbuf->constants, mapped, clamped_size);
+        clamped_size = MIN2(buf->width0, max_size_bytes);
         cbuf->count = clamped_size / (4 * sizeof(float));
+
+        if (shader == PIPE_SHADER_FRAGMENT && !r300->screen->caps.is_r500) {
+            unsigned i,j;
+
+            /* Convert constants to float24. */
+            for (i = 0; i < cbuf->count; i++)
+                for (j = 0; j < 4; j++)
+                    cbuf->constants[i][j] = pack_float24(mapped[i*4+j]);
+        } else {
+            memcpy(cbuf->constants, mapped, clamped_size);
+        }
     }
 
     if (shader == PIPE_SHADER_VERTEX) {



More information about the mesa-commit mailing list