r300g: Atomize vertex shader.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Thu, 25 Feb 2010 04:02:59 +0000 (20:02 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Thu, 25 Feb 2010 04:02:59 +0000 (20:02 -0800)
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_vs.c

index eb9b0beeb5a9589b803b1fb2796e3f2a90f1fa83..187b4bf384ef65015a2497980e212d40dbea85f8 100644 (file)
@@ -33,7 +33,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
     util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref));
     util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state);
     util_blitter_save_fragment_shader(r300->blitter, r300->fs);
-    util_blitter_save_vertex_shader(r300->blitter, r300->vs);
+    util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
 }
 
 /* Clear currently bound buffers. */
index 925873ad53d3c31bec79b4ccc68c6051d056203e..47883589a76ffe2fdfe71cd859ec4b3077ca24ed 100644 (file)
@@ -126,6 +126,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(viewport, 9);
     R300_INIT_ATOM(rs_block, 21);
     R300_INIT_ATOM(vertex_format, 26);
+    R300_INIT_ATOM(vs, 1031);
 
     /* Some non-CSO atoms need explicit space to store the state locally. */
     r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
index 443af4ec2e346aa127e1222167c70f7b11ca24f9..3d4f6524e5b625945afb91cf23e3f35875fa311a 100644 (file)
@@ -155,7 +155,6 @@ struct r300_ztop_state {
 #define R300_ANY_NEW_SAMPLERS    0x0001fe00
 #define R300_NEW_TEXTURE         0x00040000
 #define R300_ANY_NEW_TEXTURES    0x03fc0000
-#define R300_NEW_VERTEX_SHADER   0x08000000
 #define R300_NEW_VERTEX_SHADER_CONSTANTS    0x10000000
 #define R300_NEW_QUERY           0x40000000
 #define R300_NEW_KITCHEN_SINK    0x7fffffff
@@ -315,7 +314,7 @@ struct r300_context {
     struct r300_texture* textures[8];
     int texture_count;
     /* Vertex shader. */
-    struct r300_vertex_shader* vs;
+    struct r300_atom vs_state;
     /* Viewport state. */
     struct r300_atom viewport_state;
     /* ZTOP state. */
index 2d8801c08ad91d98061421c286c1c3ba2528fe1f..3037a38989aeae4d2fca317697a56e821b2dabfb 100644 (file)
@@ -843,21 +843,31 @@ void r300_emit_vertex_format_state(struct r300_context* r300, void* state)
     END_CS;
 }
 
+static void r300_flush_pvs(struct r300_context* r300)
+{
+    CS_LOCALS(r300);
+
+    BEGIN_CS(2);
+    OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
+    END_CS;
+}
 
-void r300_emit_vertex_program_code(struct r300_context* r300,
-                                   struct r300_vertex_program_code* code)
+void r300_emit_vs_state(struct r300_context* r300, void* state)
 {
-    int i;
+    struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state;
+    struct r300_vertex_program_code* code = &vs->code;
     struct r300_screen* r300screen = r300_screen(r300->context.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);
+    unsigned output_count = MAX2(util_bitcount(code->OutputsWritten), 1);
+    unsigned temp_count = MAX2(code->num_temporaries, 1);
 
-    int vtx_mem_size = r300screen->caps->is_r500 ? 128 : 72;
-    int input_count = MAX2(util_bitcount(code->InputsRead), 1);
-    int output_count = MAX2(util_bitcount(code->OutputsWritten), 1);
-    int temp_count = MAX2(code->num_temporaries, 1);
-    int pvs_num_slots = MIN3(vtx_mem_size / input_count,
-                             vtx_mem_size / output_count, 10);
-    int pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6);
+    unsigned pvs_num_slots = MIN3(vtx_mem_size / input_count,
+                                  vtx_mem_size / output_count, 10);
+    unsigned pvs_num_controllers = MIN2(vtx_mem_size / temp_count, 6);
 
     CS_LOCALS(r300);
 
@@ -867,6 +877,8 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
         return;
     }
 
+    r300_flush_pvs(r300);
+
     BEGIN_CS(9 + code->length);
     /* R300_VAP_PVS_CODE_CNTL_0
      * R300_VAP_PVS_CONST_CNTL
@@ -881,8 +893,9 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
 
     OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
     OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
-    for (i = 0; i < code->length; i++)
+    for (i = 0; i < code->length; i++) {
         OUT_CS(code->body.d[i]);
+    }
 
     OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(pvs_num_slots) |
             R300_PVS_NUM_CNTLRS(pvs_num_controllers) |
@@ -892,12 +905,6 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
     END_CS;
 }
 
-void r300_emit_vertex_shader(struct r300_context* r300,
-                             struct r300_vertex_shader* vs)
-{
-    r300_emit_vertex_program_code(r300, &vs->code);
-}
-
 void r300_emit_vs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants)
 {
@@ -994,15 +1001,6 @@ void r300_flush_textures(struct r300_context* r300)
     END_CS;
 }
 
-static void r300_flush_pvs(struct r300_context* r300)
-{
-    CS_LOCALS(r300);
-
-    BEGIN_CS(2);
-    OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
-    END_CS;
-}
-
 void r300_emit_buffer_validate(struct r300_context *r300)
 {
     struct pipe_framebuffer_state* fb =
@@ -1088,7 +1086,7 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300)
     }
 
     /* XXX This is the compensation for the non-atomized states. */
-    dwords += 2048;
+    dwords += 1024;
 
     return dwords;
 }
@@ -1160,17 +1158,13 @@ void r300_emit_dirty_state(struct r300_context* r300)
         r300_flush_textures(r300);
     }
 
-    if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) {
+    if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS || r300->vs_state.dirty) {
         r300_flush_pvs(r300);
     }
 
-    if (r300->dirty_state & R300_NEW_VERTEX_SHADER) {
-        r300_emit_vertex_shader(r300, r300->vs);
-        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);
+        struct r300_vertex_shader* vs = r300->vs_state.state;
+        r300_emit_vs_constant_buffer(r300, &vs->code.constants);
         r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
     }
 
index ff709a059570af0d356b29ebbc827d1eeee7bb15..f27cf5f32d272b8f0a9d14cdc831af5f63ec7c16 100644 (file)
@@ -79,8 +79,7 @@ void r300_emit_vertex_program_code(struct r300_context* r300,
 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);
+void r300_emit_vs_state(struct r300_context* r300, void* state);
 
 void r300_emit_viewport_state(struct r300_context* r300, void* state);
 
index 34bf81c1930cb05b0fa023fdd6904a4c208742f5..0f14ccc53e59766857e8d57b9fe0341f4e796d83 100644 (file)
@@ -658,9 +658,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
     r300->fs = fs;
     r300_pick_fragment_shader(r300);
 
-    if (r300->vs && r300_vertex_shader_setup_wpos(r300)) {
-        r300->vertex_format_state.dirty = TRUE;
-    }
+    r300->vertex_format_state.dirty = TRUE;
 
     r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
 }
@@ -1107,21 +1105,23 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
         struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
 
         if (vs == NULL) {
-            r300->vs = NULL;
+            r300->vs_state.state = NULL;
             return;
         } else if (!vs->translated) {
             r300_translate_vertex_shader(r300, vs);
         }
 
-        r300->vs = vs;
+        r300->vs_state.state = vs;
+        r300->vs_state.size = vs->code.length + 11;
+        r300->vs_state.dirty = TRUE;
+
+        r300->vertex_format_state.dirty = TRUE;
+
         if (r300->fs) {
             r300_vertex_shader_setup_wpos(r300);
         }
 
-        r300->vertex_format_state.dirty = TRUE;
-
-        r300->dirty_state |=
-            R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
+        r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
     } else {
         draw_flush(r300->draw);
         draw_bind_vertex_shader(r300->draw,
index 2cbce9210a7e35ae48205558297e66979935cba0..b33d44990a94008f0f5aa78e7cd135757de74ae5 100644 (file)
@@ -42,7 +42,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300,
                                   enum interp_mode interp,
                                   int index)
 {
-    struct tgsi_shader_info* info = &r300->vs->info;
+    struct r300_vertex_shader* vs = r300->vs_state.state;
+    struct tgsi_shader_info* info = &vs->info;
     int output;
 
     output = draw_find_shader_output(r300->draw,
@@ -55,7 +56,8 @@ static void r300_draw_emit_attrib(struct r300_context* r300,
 
 static void r300_draw_emit_all_attribs(struct r300_context* r300)
 {
-    struct r300_shader_semantics* vs_outputs = &r300->vs->outputs;
+    struct r300_vertex_shader* vs = r300->vs_state.state;
+    struct r300_shader_semantics* vs_outputs = &vs->outputs;
     int i, gen_count;
 
     /* Position. */
@@ -106,6 +108,7 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
 /* Update the PSC tables. */
 static void r300_vertex_psc(struct r300_context* r300)
 {
+    struct r300_vertex_shader* vs = r300->vs_state.state;
     struct r300_vertex_info *vformat =
         (struct r300_vertex_info*)r300->vertex_format_state.state;
     uint16_t type, swizzle;
@@ -117,7 +120,7 @@ static void r300_vertex_psc(struct r300_context* r300)
     /* If TCL is bypassed, map vertex streams to equivalent VS output
      * locations. */
     if (r300->tcl_bypass) {
-        stream_tab = r300->vs->stream_loc_notcl;
+        stream_tab = vs->stream_loc_notcl;
     } else {
         stream_tab = identity;
     }
@@ -127,7 +130,7 @@ static void r300_vertex_psc(struct r300_context* r300)
      * and not on attrib information. */
     DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
             " in psc\n",
-            r300->vs->info.num_inputs,
+            vs->info.num_inputs,
             r300->vertex_element_count);
 
     for (i = 0; i < r300->vertex_element_count; i++) {
@@ -159,13 +162,14 @@ static void r300_vertex_psc(struct r300_context* r300)
 /* Update the PSC tables for SW TCL, using Draw. */
 static void r300_swtcl_vertex_psc(struct r300_context* r300)
 {
+    struct r300_vertex_shader* vs = r300->vs_state.state;
     struct r300_vertex_info *vformat =
         (struct r300_vertex_info*)r300->vertex_format_state.state;
     struct vertex_info* vinfo = &vformat->vinfo;
     uint16_t type, swizzle;
     enum pipe_format format;
     unsigned i, attrib_count;
-    int* vs_output_tab = r300->vs->stream_loc_notcl;
+    int* vs_output_tab = vs->stream_loc_notcl;
 
     /* For each Draw attribute, route it to the fragment shader according
      * to the vs_output_tab. */
@@ -424,6 +428,7 @@ static void r300_update_rs_block(struct r300_context* r300,
 /* Update the shader-dependant states. */
 static void r300_update_derived_shader_state(struct r300_context* r300)
 {
+    struct r300_vertex_shader* vs = r300->vs_state.state;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct r300_vertex_info *vformat =
         (struct r300_vertex_info*)r300->vertex_format_state.state;
@@ -431,9 +436,9 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
 
     /* Mmm, delicious hax */
     memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info));
-    memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
+    memcpy(vinfo->hwfmt, vs->hwfmt, sizeof(uint)*4);
 
-    r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs);
+    r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
 
     if (r300screen->caps->has_tcl) {
         r300_vertex_psc(r300);
@@ -519,9 +524,9 @@ static void r300_update_ztop(struct r300_context* r300)
 void r300_update_derived_state(struct r300_context* r300)
 {
     /* XXX */
-    if (r300->dirty_state &
-        (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) ||
-        r300->vertex_format_state.dirty || r300->rs_state.dirty) {
+    if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER ||
+        r300->vs_state.dirty || r300->vertex_format_state.dirty ||
+        r300->rs_state.dirty) {
         r300_update_derived_shader_state(r300);
     }
 
index a6786c321c615a3fadc4b0938e33e7e7ac07930d..60a04bbfeda1f2d1a58c4ae307f28e953fdab931 100644 (file)
@@ -368,8 +368,8 @@ void r300_translate_vertex_shader(struct r300_context* r300,
 
 boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
 {
-    struct r300_vertex_shader* vs = r300->vs;
-    int tex_output = r300->vs->wpos_tex_output;
+    struct r300_vertex_shader* vs = r300->vs_state.state;
+    int tex_output = vs->wpos_tex_output;
     uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
     uint32_t* hwfmt = vs->hwfmt;