Mesa (master): r300g: split constant buffer and shader emittion

Corbin Simpson csimpson at kemper.freedesktop.org
Sun Nov 1 19:05:03 UTC 2009


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

Author: Maciej Cencora <m.cencora at gmail.com>
Date:   Wed Oct 21 21:17:43 2009 +0200

r300g: split constant buffer and shader emittion

---

 src/gallium/drivers/r300/r300_context.c |    2 -
 src/gallium/drivers/r300/r300_context.h |   16 ++--
 src/gallium/drivers/r300/r300_emit.c    |  157 ++++++++++++++++++++-----------
 src/gallium/drivers/r300/r300_emit.h    |   21 +++-
 src/gallium/drivers/r300/r300_state.c   |   54 ++++++------
 5 files changed, 152 insertions(+), 98 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 02f201b..f974147 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -22,8 +22,6 @@
 
 #include "draw/draw_context.h"
 
-#include "pipe/p_inlines.h"
-
 #include "tgsi/tgsi_scan.h"
 
 #include "util/u_hash_table.h"
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index cee0734..b173845 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -26,6 +26,7 @@
 #include "draw/draw_vertex.h"
 
 #include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
 
 struct r300_fragment_shader;
 struct r300_vertex_shader;
@@ -119,10 +120,10 @@ struct r300_ztop_state {
 #define R300_NEW_BLEND           0x00000001
 #define R300_NEW_BLEND_COLOR     0x00000002
 #define R300_NEW_CLIP            0x00000004
-#define R300_NEW_CONSTANTS       0x00000008
-#define R300_NEW_DSA             0x00000010
-#define R300_NEW_FRAMEBUFFERS    0x00000020
-#define R300_NEW_FRAGMENT_SHADER 0x00000040
+#define R300_NEW_DSA             0x00000008
+#define R300_NEW_FRAMEBUFFERS    0x00000010
+#define R300_NEW_FRAGMENT_SHADER 0x00000020
+#define R300_NEW_FRAGMENT_SHADER_CONSTANTS    0x00000040
 #define R300_NEW_RASTERIZER      0x00000080
 #define R300_NEW_RS_BLOCK        0x00000100
 #define R300_NEW_SAMPLER         0x00000200
@@ -132,9 +133,10 @@ struct r300_ztop_state {
 #define R300_ANY_NEW_TEXTURES    0x03fc0000
 #define R300_NEW_VERTEX_FORMAT   0x04000000
 #define R300_NEW_VERTEX_SHADER   0x08000000
-#define R300_NEW_VIEWPORT        0x10000000
-#define R300_NEW_QUERY           0x20000000
-#define R300_NEW_KITCHEN_SINK    0x3fffffff
+#define R300_NEW_VERTEX_SHADER_CONSTANTS    0x10000000
+#define R300_NEW_VIEWPORT        0x20000000
+#define R300_NEW_QUERY           0x40000000
+#define R300_NEW_KITCHEN_SINK    0x7fffffff
 
 /* The next several objects are not pure Radeon state; they inherit from
  * various Gallium classes. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 22cf9ca..de27f09 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -178,18 +178,15 @@ static uint32_t pack_float24(float f)
 }
 
 void r300_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code,
-                                     struct r300_constant_buffer* externals)
+                                     struct rX00_fragment_program_code* generic_code)
 {
     struct r300_fragment_program_code * code = &generic_code->code.r300;
-    struct rc_constant_list * constants = &generic_code->constants;
     int i;
     CS_LOCALS(r300);
 
     BEGIN_CS(15 +
              code->alu.length * 4 +
-             (code->tex.length ? (1 + code->tex.length) : 0) +
-             (constants->Count ? (1 + constants->Count * 4) : 0));
+             (code->tex.length ? (1 + code->tex.length) : 0));
 
     OUT_CS_REG(R300_US_CONFIG, code->config);
     OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
@@ -221,32 +218,41 @@ void r300_emit_fragment_program_code(struct r300_context* r300,
             OUT_CS(code->tex.inst[i]);
     }
 
-    if (constants->Count) {
-        OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
-        for(i = 0; i < constants->Count; ++i) {
-            const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
-            OUT_CS(pack_float24(data[0]));
-            OUT_CS(pack_float24(data[1]));
-            OUT_CS(pack_float24(data[2]));
-            OUT_CS(pack_float24(data[3]));
-        }
-    }
+    END_CS;
+}
+
+void r300_emit_fs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants)
+{
+    int i;
+    CS_LOCALS(r300);
+
+    if (constants->Count == 0)
+        return;
 
+    BEGIN_CS(constants->Count * 4 + 1);
+    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, constants->Count * 4);
+    for(i = 0; i < constants->Count; ++i) {
+        const float * data = get_shader_constant(r300,
+                                                 &constants->Constants[i],
+                                                 &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+        OUT_CS(pack_float24(data[0]));
+        OUT_CS(pack_float24(data[1]));
+        OUT_CS(pack_float24(data[2]));
+        OUT_CS(pack_float24(data[3]));
+    }
     END_CS;
 }
 
 void r500_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code,
-                                     struct r300_constant_buffer* externals)
+                                     struct rX00_fragment_program_code* generic_code)
 {
     struct r500_fragment_program_code * code = &generic_code->code.r500;
-    struct rc_constant_list * constants = &generic_code->constants;
     int i;
     CS_LOCALS(r300);
 
     BEGIN_CS(13 +
-             ((code->inst_end + 1) * 6) +
-             (constants->Count ? (3 + (constants->Count * 4)) : 0));
+             ((code->inst_end + 1) * 6));
     OUT_CS_REG(R500_US_CONFIG, 0);
     OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
     OUT_CS_REG(R500_US_CODE_RANGE,
@@ -266,18 +272,30 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
         OUT_CS(code->inst[i].inst5);
     }
 
-    if (constants->Count) {
-        OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
-        OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
-        for (i = 0; i < constants->Count; i++) {
-            const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
-            OUT_CS_32F(data[0]);
-            OUT_CS_32F(data[1]);
-            OUT_CS_32F(data[2]);
-            OUT_CS_32F(data[3]);
-        }
-    }
+    END_CS;
+}
+
+void r500_emit_fs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants)
+{
+    int i;
+    CS_LOCALS(r300);
+
+    if (constants->Count == 0)
+        return;
 
+    BEGIN_CS(constants->Count * 4 + 2);
+    OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
+    OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
+    for (i = 0; i < constants->Count; i++) {
+        const float * data = get_shader_constant(r300,
+                                                 &constants->Constants[i],
+                                                 &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+        OUT_CS_32F(data[0]);
+        OUT_CS_32F(data[1]);
+        OUT_CS_32F(data[2]);
+        OUT_CS_32F(data[3]);
+    }
     END_CS;
 }
 
@@ -621,8 +639,7 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
 }
 
 void r300_emit_vertex_program_code(struct r300_context* r300,
-                                   struct r300_vertex_program_code* code,
-                                   struct r300_constant_buffer* constants)
+                                   struct r300_vertex_program_code* code)
 {
     int i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
@@ -635,12 +652,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
         return;
     }
 
-    if (code->constants.Count) {
-        BEGIN_CS(14 + code->length + (code->constants.Count * 4));
-    } else {
-        BEGIN_CS(11 + code->length);
-    }
-
+    BEGIN_CS(11 + code->length);
     /* R300_VAP_PVS_CODE_CNTL_0
      * R300_VAP_PVS_CONST_CNTL
      * R300_VAP_PVS_CODE_CNTL_1
@@ -658,20 +670,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
     for (i = 0; i < code->length; i++)
         OUT_CS(code->body.d[i]);
 
-    if (code->constants.Count) {
-        OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-                (r300screen->caps->is_r500 ?
-                 R500_PVS_CONST_START : R300_PVS_CONST_START));
-        OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
-        for (i = 0; i < code->constants.Count; i++) {
-            const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
-            OUT_CS_32F(data[0]);
-            OUT_CS_32F(data[1]);
-            OUT_CS_32F(data[2]);
-            OUT_CS_32F(data[3]);
-        }
-    }
-
     OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(10) |
             R300_PVS_NUM_CNTLRS(5) |
             R300_PVS_NUM_FPUS(r300screen->caps->num_vert_fpus) |
@@ -683,7 +681,40 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
 void r300_emit_vertex_shader(struct r300_context* r300,
                              struct r300_vertex_shader* vs)
 {
-    r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
+    r300_emit_vertex_program_code(r300, &vs->code);
+}
+
+void r300_emit_vs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants)
+{
+    int i;
+    struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    CS_LOCALS(r300);
+
+    if (!r300screen->caps->has_tcl) {
+        debug_printf("r300: Implementation error: emit_vertex_shader called,"
+        " but has_tcl is FALSE!\n");
+        return;
+    }
+
+    if (constants->Count == 0)
+        return;
+
+    BEGIN_CS(constants->Count * 4 + 3);
+    OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+               (r300screen->caps->is_r500 ?
+               R500_PVS_CONST_START : R300_PVS_CONST_START));
+    OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4);
+    for (i = 0; i < constants->Count; i++) {
+        const float * data = get_shader_constant(r300,
+                                                 &constants->Constants[i],
+                                                 &r300->shader_constants[PIPE_SHADER_VERTEX]);
+        OUT_CS_32F(data[0]);
+        OUT_CS_32F(data[1]);
+        OUT_CS_32F(data[2]);
+        OUT_CS_32F(data[3]);
+    }
+    END_CS;
 }
 
 void r300_emit_viewport_state(struct r300_context* r300,
@@ -822,13 +853,22 @@ validate:
 
     if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
         if (r300screen->caps->is_r500) {
-            r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+            r500_emit_fragment_program_code(r300, &r300->fs->code);
         } else {
-            r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
+            r300_emit_fragment_program_code(r300, &r300->fs->code);
         }
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
     }
 
+    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
+        if (r300screen->caps->is_r500) {
+            r500_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+        } else {
+            r300_emit_fs_constant_buffer(r300, &r300->fs->code.constants);
+        }
+        r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+    }
+
     if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {
         r300_emit_fb_state(r300, &r300->framebuffer_state);
         r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
@@ -887,6 +927,11 @@ validate:
         r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;
     }
 
+    if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
+        r300_emit_vs_constant_buffer(r300, &r300->vs->code.constants);
+        r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
+    }
+
     /* XXX
     assert(r300->dirty_state == 0);
     */
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 02ac5be..6befca7 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -23,6 +23,9 @@
 #ifndef R300_EMIT_H
 #define R300_EMIT_H
 
+#include "r300_context.h"
+#include "radeon_code.h"
+
 struct rX00_fragment_program_code;
 struct r300_vertex_program_code;
 
@@ -39,12 +42,16 @@ void r300_emit_dsa_state(struct r300_context* r300,
                          struct r300_dsa_state* dsa);
 
 void r300_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code,
-                                     struct r300_constant_buffer* externals);
+                                     struct rX00_fragment_program_code* generic_code);
+
+void r300_emit_fs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants);
 
 void r500_emit_fragment_program_code(struct r300_context* r300,
-                                     struct rX00_fragment_program_code* generic_code,
-                                     struct r300_constant_buffer* externals);
+                                     struct rX00_fragment_program_code* generic_code);
+
+void r500_emit_fs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants);
 
 void r300_emit_fb_state(struct r300_context* r300,
                         struct pipe_framebuffer_state* fb);
@@ -72,8 +79,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
 void r300_emit_vertex_format_state(struct r300_context* r300);
 
 void r300_emit_vertex_program_code(struct r300_context* r300,
-                                   struct r300_vertex_program_code* code,
-                                   struct r300_constant_buffer* constants);
+                                   struct r300_vertex_program_code* code);
+
+void r300_emit_vs_constant_buffer(struct r300_context* r300,
+                                  struct rc_constant_list* constants);
 
 void r300_emit_vertex_shader(struct r300_context* r300,
                              struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 3ac627e..4cf0138 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -166,31 +166,6 @@ static void r300_set_clip_state(struct pipe_context* pipe,
     }
 }
 
-static void
-    r300_set_constant_buffer(struct pipe_context* pipe,
-                             uint shader, uint index,
-                             const struct pipe_constant_buffer* buffer)
-{
-    struct r300_context* r300 = r300_context(pipe);
-
-    /* This entire chunk of code seems ever-so-slightly baked.
-     * It's as if I've got pipe_buffer* matryoshkas... */
-    if (buffer && buffer->buffer && buffer->buffer->size) {
-        void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer,
-                                             PIPE_BUFFER_USAGE_CPU_READ);
-        memcpy(r300->shader_constants[shader].constants,
-            map, buffer->buffer->size);
-        pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer);
-
-        r300->shader_constants[shader].count =
-            buffer->buffer->size / (sizeof(float) * 4);
-    } else {
-        r300->shader_constants[shader].count = 0;
-    }
-
-    r300->dirty_state |= R300_NEW_CONSTANTS;
-}
-
 /* Create a new depth, stencil, and alpha state based on the CSO dsa state.
  *
  * This contains the depth buffer, stencil buffer, alpha test, and such.
@@ -345,7 +320,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
 
     r300->fs = fs;
 
-    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
+    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
 
 /* Delete fragment shader state. */
@@ -702,7 +677,7 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
 
         draw_bind_vertex_shader(r300->draw, vs->draw);
         r300->vs = vs;
-        r300->dirty_state |= R300_NEW_VERTEX_SHADER;
+        r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
     } else {
         draw_bind_vertex_shader(r300->draw,
                 (struct draw_vertex_shader*)shader);
@@ -726,6 +701,31 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
     }
 }
 
+static void r300_set_constant_buffer(struct pipe_context *pipe,
+                                     uint shader, uint index,
+                                     const struct pipe_constant_buffer *buf)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    void *mapped;
+
+    if (buf == NULL || buf->buffer->size == 0 ||
+        (mapped = pipe_buffer_map(pipe->screen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)) == NULL)
+    {
+        r300->shader_constants[shader].count = 0;
+        return;
+    }
+
+    assert((buf->buffer->size % 4 * sizeof(float)) == 0);
+    memcpy(r300->shader_constants[shader].constants, mapped, buf->buffer->size);
+    r300->shader_constants[shader].count = buf->buffer->size / (4 * sizeof(float));
+    pipe_buffer_unmap(pipe->screen, buf->buffer);
+
+    if (shader == PIPE_SHADER_VERTEX)
+        r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+    else if (shader == PIPE_SHADER_FRAGMENT)
+        r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+}
+
 void r300_init_state_functions(struct r300_context* r300)
 {
     r300->context.create_blend_state = r300_create_blend_state;




More information about the mesa-commit mailing list