r300g: atomize FS constant buffer
authorMarek Olšák <maraeo@gmail.com>
Mon, 12 Apr 2010 02:12:27 +0000 (04:12 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 12 Apr 2010 02:16:08 +0000 (04:16 +0200)
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_defines.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
src/gallium/drivers/r300/r300_state.c

index 061322b75fd53da9aa005afb7331204aabe21345..bdc1ebedcc05f83b2726f7473bac960cdf92f12d 100644 (file)
@@ -66,6 +66,7 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300->vap_output_state.state);
     FREE(r300->viewport_state.state);
     FREE(r300->ztop_state.state);
+    FREE(r300->fs_constants.state);
     FREE(r300);
 }
 
@@ -117,11 +118,13 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(textures_state, 0);
     R300_INIT_ATOM(fs, 0);
     R300_INIT_ATOM(fs_rc_constant_state, 0);
+    R300_INIT_ATOM(fs_constants, 0);
 
     /* Replace emission functions for r500. */
     if (r300->screen->caps.is_r500) {
         r300->fs.emit = r500_emit_fs;
         r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state;
+        r300->fs_constants.emit = r500_emit_fs_constants;
     }
 
     /* Some non-CSO atoms need explicit space to store the state locally. */
@@ -134,6 +137,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
     r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
     r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
+    r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
index 2e248a4d6cdd1fb8fe658fd57208f60d87561462..d8bed53a6d5e2f10fe7b0895fd77e14eb2f655e0 100644 (file)
@@ -360,6 +360,8 @@ struct r300_context {
     struct r300_atom fs;
     /* Fragment shader RC_CONSTANT_STATE variables. */
     struct r300_atom fs_rc_constant_state;
+    /* Fragment shader constant buffer. */
+    struct r300_atom fs_constants;
     /* Framebuffer state. */
     struct r300_atom fb_state;
     /* Rasterizer state. */
index 2bcf298c41455b2adaf425fb3b4d04deffbafc09..da85137625c2f482a5395d8bcd745a062ac453aa 100644 (file)
@@ -31,7 +31,6 @@
 #define R300_RESOURCE_FLAG_TRANSFER     PIPE_RESOURCE_FLAG_DRV_PRIV
 
 /* Non-atom dirty state flags. */
-#define R300_NEW_FRAGMENT_SHADER_CONSTANTS      0x00000040
 #define R300_NEW_VERTEX_SHADER_CONSTANTS        0x10000000
 #define R300_NEW_QUERY                          0x40000000
 #define R300_NEW_KITCHEN_SINK                   0x7fffffff
index fd857a4ac1954f129d26b363453cfce8267a0378..d0f227f9424f4603026b4d254a12c0760255011d 100644 (file)
@@ -320,22 +320,22 @@ void r300_emit_fs(struct r300_context* r300, unsigned size, void *state)
     END_CS;
 }
 
-void r300_emit_fs_constant_buffer(struct r300_context* r300,
-                                  struct rc_constant_list* constants)
+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;
     CS_LOCALS(r300);
 
     if (count == 0)
         return;
 
-    BEGIN_CS(count * 4 + 1);
+    BEGIN_CS(size);
     OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4);
     for(i = 0; i < count; ++i) {
         assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
-        const float *data =
-            r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i];
+        const float *data = buf->constants[i];
         OUT_CS(pack_float24(data[0]));
         OUT_CS(pack_float24(data[1]));
         OUT_CS(pack_float24(data[2]));
@@ -439,10 +439,11 @@ void r500_emit_fs(struct r300_context* r300, unsigned size, void *state)
     END_CS;
 }
 
-void r500_emit_fs_constant_buffer(struct r300_context* r300,
-                                  struct rc_constant_list* constants)
+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;
     CS_LOCALS(r300);
 
@@ -454,8 +455,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
     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);
-        const float *data =
-            r300->shader_constants[PIPE_SHADER_FRAGMENT].constants[i];
+        const float *data = buf->constants[i];
 
         OUT_CS_32F(data[0]);
         OUT_CS_32F(data[1]);
@@ -1211,17 +1211,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
         }
     }
 
-    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER_CONSTANTS) {
-        if (r300screen->caps.is_r500) {
-            r500_emit_fs_constant_buffer(r300,
-                                         &r300_fs(r300)->shader->code.constants);
-        } else {
-            r300_emit_fs_constant_buffer(r300,
-                                         &r300_fs(r300)->shader->code.constants);
-        }
-        r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
-    }
-
     if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
         struct r300_vertex_shader* vs = r300->vs_state.state;
         if (vs->code.constants.Count) {
index 09737fbb5975d56b95b0fa5bdf03aa6d6e98f5b4..d275bb211a81dd6b0f1ef0326097b53307e9ba66 100644 (file)
@@ -47,8 +47,7 @@ unsigned r300_get_fs_atom_size(struct r300_context *r300);
 
 void r300_emit_fs(struct r300_context* r300, unsigned size, void *state);
 
-void r300_emit_fs_constant_buffer(struct r300_context* r300,
-                                  struct rc_constant_list* constants);
+void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state);
 
 void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state);
 
@@ -56,8 +55,7 @@ unsigned r500_get_fs_atom_size(struct r300_context *r300);
 
 void r500_emit_fs(struct r300_context* r300, unsigned size, void *state);
 
-void r500_emit_fs_constant_buffer(struct r300_context* r300,
-                                  struct rc_constant_list* constants);
+void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *state);
 
 void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, void *state);
 
index aacaa4e6afe45b66d56db69893d0fb5214527fe1..f1a062333a61dc69981aa42a6412938abb3a8539 100644 (file)
@@ -689,16 +689,17 @@ static void r300_mark_fs_code_dirty(struct r300_context *r300)
 
     r300->fs.dirty = TRUE;
     r300->fs_rc_constant_state.dirty = TRUE;
+    r300->fs_constants.dirty = TRUE;
 
     if (r300->screen->caps.is_r500) {
         r300->fs.size = r500_get_fs_atom_size(r300);
         r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 7;
+        r300->fs_constants.size = fs->shader->externals_count * 4 + 3;
     } else {
         r300->fs.size = r300_get_fs_atom_size(r300);
         r300->fs_rc_constant_state.size = fs->shader->rc_state_count * 5;
+        r300->fs_constants.size = fs->shader->externals_count * 4 + 1;
     }
-
-    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
 
 /* Bind fragment shader state. */
@@ -1379,25 +1380,18 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
                                      struct pipe_resource *buf)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_constant_buffer *cbuf;
     struct pipe_transfer *tr;
     void *mapped;
     int max_size = 0;
 
-    if (buf == NULL || buf->width0 == 0 ||
-        (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
-    {
-        r300->shader_constants[shader].count = 0;
-        return;
-    }
-
-    assert((buf->width0 % 4 * sizeof(float)) == 0);
-
-    /* Check the size of the constant buffer. */
     switch (shader) {
         case PIPE_SHADER_VERTEX:
+            cbuf = &r300->shader_constants[PIPE_SHADER_VERTEX];
             max_size = 256;
             break;
         case PIPE_SHADER_FRAGMENT:
+            cbuf = (struct r300_constant_buffer*)r300->fs_constants.state;
             if (r300->screen->caps.is_r500) {
                 max_size = 256;
             } else {
@@ -1408,6 +1402,16 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             assert(0);
     }
 
+    if (buf == NULL || buf->width0 == 0 ||
+        (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
+    {
+        cbuf->count = 0;
+        return;
+    }
+
+    assert((buf->width0 % 4 * sizeof(float)) == 0);
+
+    /* Check the size of the constant buffer. */
     /* XXX Subtract immediates and RC_STATE_* variables. */
     if (buf->width0 > (sizeof(float) * 4 * max_size)) {
         fprintf(stderr, "r300: Max size of the constant buffer is "
@@ -1415,8 +1419,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
         abort();
     }
 
-    memcpy(r300->shader_constants[shader].constants, mapped, buf->width0);
-    r300->shader_constants[shader].count = buf->width0 / (4 * sizeof(float));
+    memcpy(cbuf->constants, mapped, buf->width0);
+    cbuf->count = buf->width0 / (4 * sizeof(float));
     pipe_buffer_unmap(pipe, buf, tr);
 
     if (shader == PIPE_SHADER_VERTEX) {
@@ -1425,11 +1429,11 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             r300->pvs_flush.dirty = TRUE;
         } else if (r300->draw) {
             draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
-                0, r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+                0, cbuf->constants,
                 buf->width0);
         }
     } else if (shader == PIPE_SHADER_FRAGMENT) {
-        r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+        r300->fs_constants.dirty = TRUE;
     }
 }