r300g: optimize emission of fragment shader constants
authorMarek Olšák <maraeo@gmail.com>
Sun, 13 Jun 2010 04:39:58 +0000 (06:39 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 13 Jun 2010 15:43:39 +0000 (17:43 +0200)
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c

index 64d69817a0f1a146638f6c8988c0f46d39fa35cc..05948f9ada697943dd98e7ca8243ced2d75de7a7 100644 (file)
@@ -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;
 };
index 658880aebccbb97906c501578884045f0c6a5965..8e8b75257719eb7dc091124d7aeeca6101093d80 100644 (file)
@@ -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;
 }
 
index 4892a1d7a34a1d4c59612ea0491cf1d97d861397..0772c1fa53775b5ba19f81dc9d6a76802d65711c 100644 (file)
@@ -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) {