r300g: Turn the RS block into an atom.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 27 Jan 2010 06:08:11 +0000 (22:08 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 27 Jan 2010 06:08:11 +0000 (22:08 -0800)
At least one extraneous dirty was eliminated, as well as the chance for
avoiding dirty on shader change.

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

index 1460778ecee660e8ff0dea555e779012824dc771..052cc23a77a3c8b2da3c3afb7e51a34c7d528029 100644 (file)
@@ -59,7 +59,7 @@ static void r300_destroy_context(struct pipe_context* context)
 
     FREE(r300->blend_color_state.state);
     FREE(r300->clip_state.state);
-    FREE(r300->rs_block);
+    FREE(r300->rs_block_state.state);
     FREE(r300->scissor_state.state);
     FREE(r300->vertex_format_state.state);
     FREE(r300->viewport_state.state);
@@ -125,6 +125,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(rs, 25);
     R300_INIT_ATOM(scissor, 3);
     R300_INIT_ATOM(viewport, 9);
+    R300_INIT_ATOM(rs_block, 21);
     R300_INIT_ATOM(vertex_format, 26);
 }
 
@@ -175,7 +176,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
     r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state);
-    r300->rs_block = CALLOC_STRUCT(r300_rs_block);
+    r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
     r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
     r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info);
     r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
index 407891e17524d0c88235d84d441aa4212b7b2443..c4c137d6f8502f0e86de1e594fd6da35e8dcf585 100644 (file)
@@ -142,7 +142,6 @@ struct r300_ztop_state {
 #define R300_NEW_FRAMEBUFFERS    0x00000010
 #define R300_NEW_FRAGMENT_SHADER 0x00000020
 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS    0x00000040
-#define R300_NEW_RS_BLOCK        0x00000100
 #define R300_NEW_SAMPLER         0x00000200
 #define R300_ANY_NEW_SAMPLERS    0x0001fe00
 #define R300_NEW_TEXTURE         0x00040000
@@ -294,7 +293,7 @@ struct r300_context {
     /* Rasterizer state. */
     struct r300_atom rs_state;
     /* RS block state. */
-    struct r300_rs_block* rs_block;
+    struct r300_atom rs_block_state;
     /* Sampler states. */
     struct r300_sampler_state* sampler_states[8];
     int sampler_count;
index 8081f1d95692ee4b7f3ad0c44b07d5de6c039757..8bc9da9361f81bd15d75cdafde3f85bcf6c632a2 100644 (file)
@@ -627,10 +627,10 @@ void r300_emit_rs_state(struct r300_context* r300, void* state)
     END_CS;
 }
 
-void r300_emit_rs_block_state(struct r300_context* r300,
-                              struct r300_rs_block* rs)
+void r300_emit_rs_block_state(struct r300_context* r300, void* state)
 {
-    int i;
+    struct r300_rs_block* rs = (struct r300_rs_block*)state;
+    unsigned i;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     CS_LOCALS(r300);
 
@@ -1142,11 +1142,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
         r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
     }
 
-    if (r300->dirty_state & R300_NEW_RS_BLOCK) {
-        r300_emit_rs_block_state(r300, r300->rs_block);
-        r300->dirty_state &= ~R300_NEW_RS_BLOCK;
-    }
-
     /* Samplers and textures are tracked separately but emitted together. */
     if (r300->dirty_state &
             (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) {
index 6788e3d655d40cc34c4c98e4689c302097d56a06..c6dbc5af1e3dbf29ab47da115520dda69c7b8569 100644 (file)
@@ -61,8 +61,7 @@ void r300_emit_query_end(struct r300_context* r300);
 
 void r300_emit_rs_state(struct r300_context* r300, void* state);
 
-void r300_emit_rs_block_state(struct r300_context* r300,
-                              struct r300_rs_block* rs);
+void r300_emit_rs_block_state(struct r300_context* r300, void* state);
 
 void r300_emit_scissor_state(struct r300_context* r300, void* state);
 
index 7068a5a4ecdda5fe8b4dc9bdd7565fb0a0397ff0..f3acd1657938711f8a3b7165c72a682199e7dce2 100644 (file)
@@ -720,7 +720,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
     r300->viewport_state.dirty = TRUE;
 
     /* XXX Clean these up when we move to atom emits */
-    r300->dirty_state |= R300_NEW_RS_BLOCK;
     if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
         r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
     }
index 1a1eabe5fb25c78c4a2259b490f9863497316e29..a351c9d01b96b6a990ffdc39a16d05738597ddeb 100644 (file)
@@ -305,7 +305,7 @@ static void r300_update_rs_block(struct r300_context* r300,
                                  struct r300_shader_semantics* vs_outputs,
                                  struct r300_shader_semantics* fs_inputs)
 {
-    struct r300_rs_block* rs = r300->rs_block;
+    struct r300_rs_block rs = { 0 };
     int i, col_count = 0, tex_count = 0, fp_offset = 0;
     void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean);
     void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
@@ -332,11 +332,11 @@ static void r300_update_rs_block(struct r300_context* r300,
             vs_outputs->color[1] != ATTR_UNUSED) {
             /* Always rasterize if it's written by the VS,
              * otherwise it locks up. */
-            rX00_rs_col(rs, col_count, i, FALSE);
+            rX00_rs_col(&rs, col_count, i, FALSE);
 
             /* Write it to the FS input register if it's used by the FS. */
             if (fs_inputs->color[i] != ATTR_UNUSED) {
-                rX00_rs_col_write(rs, col_count, fp_offset);
+                rX00_rs_col_write(&rs, col_count, fp_offset);
                 fp_offset++;
             }
             col_count++;
@@ -354,11 +354,11 @@ static void r300_update_rs_block(struct r300_context* r300,
         if (vs_outputs->generic[i] != ATTR_UNUSED) {
             /* Always rasterize if it's written by the VS,
              * otherwise it locks up. */
-            rX00_rs_tex(rs, tex_count, tex_count, FALSE);
+            rX00_rs_tex(&rs, tex_count, tex_count, FALSE);
 
             /* Write it to the FS input register if it's used by the FS. */
             if (fs_inputs->generic[i] != ATTR_UNUSED) {
-                rX00_rs_tex_write(rs, tex_count, fp_offset);
+                rX00_rs_tex_write(&rs, tex_count, fp_offset);
                 fp_offset++;
             }
             tex_count++;
@@ -375,11 +375,11 @@ static void r300_update_rs_block(struct r300_context* r300,
     if (vs_outputs->fog != ATTR_UNUSED) {
         /* Always rasterize if it's written by the VS,
          * otherwise it locks up. */
-        rX00_rs_tex(rs, tex_count, tex_count, TRUE);
+        rX00_rs_tex(&rs, tex_count, tex_count, TRUE);
 
         /* Write it to the FS input register if it's used by the FS. */
         if (fs_inputs->fog != ATTR_UNUSED) {
-            rX00_rs_tex_write(rs, tex_count, fp_offset);
+            rX00_rs_tex_write(&rs, tex_count, fp_offset);
             fp_offset++;
         }
         tex_count++;
@@ -394,8 +394,8 @@ static void r300_update_rs_block(struct r300_context* r300,
     /* Rasterize WPOS. */
     /* If the FS doesn't need it, it's not written by the VS. */
     if (fs_inputs->wpos != ATTR_UNUSED) {
-        rX00_rs_tex(rs, tex_count, tex_count, FALSE);
-        rX00_rs_tex_write(rs, tex_count, fp_offset);
+        rX00_rs_tex(&rs, tex_count, tex_count, FALSE);
+        rX00_rs_tex_write(&rs, tex_count, fp_offset);
 
         fp_offset++;
         tex_count++;
@@ -403,17 +403,23 @@ static void r300_update_rs_block(struct r300_context* r300,
 
     /* Rasterize at least one color, or bad things happen. */
     if (col_count == 0 && tex_count == 0) {
-        rX00_rs_col(rs, 0, 0, TRUE);
+        rX00_rs_col(&rs, 0, 0, TRUE);
         col_count++;
     }
 
-    rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
+    rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
         R300_HIRES_EN;
 
-    rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0);
+    rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0);
+
+    /* Now, after all that, see if we actually need to update the state. */
+    if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) {
+        memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block));
+        r300->rs_block_state.dirty = TRUE;
+    }
 }
 
-/* Update the vertex format. */
+/* Update the shader-dependant states. */
 static void r300_update_derived_shader_state(struct r300_context* r300)
 {
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
@@ -421,8 +427,6 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
         (struct r300_vertex_info*)r300->vertex_format_state.state;
     struct vertex_info* vinfo = &vformat->vinfo;
 
-    /* Reset structures */
-    memset(r300->rs_block, 0, sizeof(struct r300_rs_block));
     /* Mmm, delicious hax */
     memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info));
     memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
@@ -437,8 +441,6 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
             (struct vertex_info*)r300->vertex_format_state.state);
         r300_swtcl_vertex_psc(r300);
     }
-
-    r300->dirty_state |= R300_NEW_RS_BLOCK;
 }
 
 static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)