radeonsi: Simplify shader PM4 state handling
authorMichel Dänzer <michel.daenzer@amd.com>
Fri, 17 Jan 2014 00:53:14 +0000 (09:53 +0900)
committerMichel Dänzer <michel@daenzer.net>
Wed, 29 Jan 2014 02:08:21 +0000 (11:08 +0900)
Just always bind the current states before drawing.

Besides the simplification, as a bonus this makes sure the VS hardware
shader stage always uses the GS copy shader when a geometry shader is
active, fixing a number of GS related piglit tests.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c

index d089fdd230aa676e4d2299b2e473f4ceeb368441..aa151238c2829b86b26db1fbe960ef15da119a93 100644 (file)
@@ -2217,11 +2217,9 @@ static INLINE void si_shader_selector_key(struct pipe_context *ctx,
        }
 }
 
-/* Select the hw shader variant depending on the current state.
- * (*dirty) is set to 1 if current variant was changed */
+/* Select the hw shader variant depending on the current state. */
 int si_shader_select(struct pipe_context *ctx,
-                    struct si_pipe_shader_selector *sel,
-                    unsigned *dirty)
+                    struct si_pipe_shader_selector *sel)
 {
        union si_shader_key key;
        struct si_pipe_shader * shader = NULL;
@@ -2273,10 +2271,6 @@ int si_shader_select(struct pipe_context *ctx,
                sel->num_shaders++;
        }
 
-       if (dirty)
-               *dirty = 1;
-
-
        return 0;
 }
 
@@ -2298,7 +2292,7 @@ static void *si_create_shader_state(struct pipe_context *ctx,
                sel->fs_write_all = info.color0_writes_all_cbufs;
        }
 
-       r = si_shader_select(ctx, sel, NULL);
+       r = si_shader_select(ctx, sel);
        if (r) {
            free(sel);
            return NULL;
@@ -2341,9 +2335,6 @@ static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
                return;
 
        sctx->vs_shader = sel;
-       si_pm4_bind_state(sctx, vs, sel->current->pm4);
-       sctx->b.streamout.stride_in_dw = sel->so.stride;
-       sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
 #if HAVE_LLVM >= 0x0305
@@ -2357,12 +2348,6 @@ static void si_bind_gs_shader(struct pipe_context *ctx, void *state)
                return;
 
        sctx->gs_shader = sel;
-
-       if (sel && sel->current) {
-               si_pm4_bind_state(sctx, gs, sel->current->pm4);
-               sctx->b.streamout.stride_in_dw = sel->so.stride;
-               sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
-       }
 }
 
 #endif
@@ -2379,8 +2364,6 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
                sel = sctx->dummy_pixel_shader;
 
        sctx->ps_shader = sel;
-       si_pm4_bind_state(sctx, ps, sel->current->pm4);
-       sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
 static void si_delete_shader_selector(struct pipe_context *ctx,
index 9acda3f5f146e03de8c127883eeb36b0d93391ff..e24c0bb0cce4e67db4f8def6c2069aef07c7e690 100644 (file)
@@ -222,8 +222,7 @@ boolean si_is_format_supported(struct pipe_screen *screen,
                                unsigned sample_count,
                                unsigned usage);
 int si_shader_select(struct pipe_context *ctx,
-                    struct si_pipe_shader_selector *sel,
-                    unsigned *dirty);
+                    struct si_pipe_shader_selector *sel);
 void si_init_state_functions(struct si_context *sctx);
 void si_init_config(struct si_context *sctx);
 
index e4045cd85a6b43d5d828075466f2ae6ea3f569b4..7ccfb58d702ca377249dcc9cc77ed9532f725a21 100644 (file)
@@ -76,7 +76,6 @@ static void si_pipe_shader_es(struct pipe_context *ctx, struct si_pipe_shader *s
        si_pm4_set_reg(pm4, R_00B32C_SPI_SHADER_PGM_RSRC2_ES,
                       S_00B32C_USER_SGPR(num_user_sgprs));
 
-       si_pm4_bind_state(sctx, es, shader->pm4);
        sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
@@ -149,7 +148,6 @@ static void si_pipe_shader_gs(struct pipe_context *ctx, struct si_pipe_shader *s
        si_pm4_set_reg(pm4, R_00B22C_SPI_SHADER_PGM_RSRC2_GS,
                       S_00B22C_USER_SGPR(num_user_sgprs));
 
-       si_pm4_bind_state(sctx, gs, shader->pm4);
        sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
@@ -226,7 +224,6 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
                       S_00B12C_SO_BASE3_EN(!!shader->selector->so.stride[3]) |
                       S_00B12C_SO_EN(!!shader->selector->so.num_outputs));
 
-       si_pm4_bind_state(sctx, vs, shader->pm4);
        sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
@@ -342,7 +339,6 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
 
        shader->cb0_is_integer = sctx->fb_cb0_is_integer;
        shader->sprite_coord_enable = sctx->sprite_coord_enable;
-       si_pm4_bind_state(sctx, ps, shader->pm4);
        sctx->b.flags |= R600_CONTEXT_INV_SHADER_CACHE;
 }
 
@@ -584,7 +580,6 @@ static void si_init_gs_rings(struct si_context *sctx)
 static void si_update_derived_state(struct si_context *sctx)
 {
        struct pipe_context * ctx = (struct pipe_context*)sctx;
-       unsigned vs_dirty = 0, ps_dirty = 0;
 
        if (!sctx->blitter->running) {
                /* Flush depth textures which need to be flushed. */
@@ -599,33 +594,25 @@ static void si_update_derived_state(struct si_context *sctx)
        }
 
        if (sctx->gs_shader) {
-               unsigned es_dirty = 0, gs_dirty = 0;
-
-               si_shader_select(ctx, sctx->gs_shader, &gs_dirty);
+               si_shader_select(ctx, sctx->gs_shader);
 
                if (!sctx->gs_shader->current->pm4) {
                        si_pipe_shader_gs(ctx, sctx->gs_shader->current);
                        si_pipe_shader_vs(ctx,
                                          sctx->gs_shader->current->gs_copy_shader);
-                       gs_dirty = 0;
                }
 
-               if (gs_dirty) {
-                       si_pm4_bind_state(sctx, gs, sctx->gs_shader->current->pm4);
-                       si_pm4_bind_state(sctx, vs,
-                                         sctx->gs_shader->current->gs_copy_shader->pm4);
-               }
+               si_pm4_bind_state(sctx, gs, sctx->gs_shader->current->pm4);
+               si_pm4_bind_state(sctx, vs, sctx->gs_shader->current->gs_copy_shader->pm4);
+
+               sctx->b.streamout.stride_in_dw = sctx->gs_shader->so.stride;
 
-               si_shader_select(ctx, sctx->vs_shader, &es_dirty);
+               si_shader_select(ctx, sctx->vs_shader);
 
-               if (!sctx->vs_shader->current->pm4) {
+               if (!sctx->vs_shader->current->pm4)
                        si_pipe_shader_es(ctx, sctx->vs_shader->current);
-                       es_dirty = 0;
-               }
 
-               if (es_dirty) {
-                       si_pm4_bind_state(sctx, es, sctx->vs_shader->current->pm4);
-               }
+               si_pm4_bind_state(sctx, es, sctx->vs_shader->current->pm4);
 
                if (!sctx->gs_rings)
                        si_init_gs_rings(sctx);
@@ -648,16 +635,14 @@ static void si_update_derived_state(struct si_context *sctx)
                }
                si_pm4_bind_state(sctx, gs_onoff, sctx->gs_on);
        } else {
-               si_shader_select(ctx, sctx->vs_shader, &vs_dirty);
+               si_shader_select(ctx, sctx->vs_shader);
 
-               if (!sctx->vs_shader->current->pm4) {
+               if (!sctx->vs_shader->current->pm4)
                        si_pipe_shader_vs(ctx, sctx->vs_shader->current);
-                       vs_dirty = 0;
-               }
 
-               if (vs_dirty) {
-                       si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4);
-               }
+               si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4);
+
+               sctx->b.streamout.stride_in_dw = sctx->vs_shader->so.stride;
 
                if (!sctx->gs_off) {
                        sctx->gs_off = si_pm4_alloc_state(sctx);
@@ -671,20 +656,13 @@ static void si_update_derived_state(struct si_context *sctx)
                si_pm4_bind_state(sctx, es, NULL);
        }
 
-       si_shader_select(ctx, sctx->ps_shader, &ps_dirty);
+       si_shader_select(ctx, sctx->ps_shader);
 
-       if (!sctx->ps_shader->current->pm4) {
-               si_pipe_shader_ps(ctx, sctx->ps_shader->current);
-               ps_dirty = 0;
-       }
-       if (sctx->ps_shader->current->cb0_is_integer != sctx->fb_cb0_is_integer) {
+       if (!sctx->ps_shader->current->pm4 ||
+           sctx->ps_shader->current->cb0_is_integer != sctx->fb_cb0_is_integer)
                si_pipe_shader_ps(ctx, sctx->ps_shader->current);
-               ps_dirty = 0;
-       }
 
-       if (ps_dirty) {
-               si_pm4_bind_state(sctx, ps, sctx->ps_shader->current->pm4);
-       }
+       si_pm4_bind_state(sctx, ps, sctx->ps_shader->current->pm4);
 
        if (si_pm4_state_changed(sctx, ps) || si_pm4_state_changed(sctx, vs)) {
                /* XXX: Emitting the PS state even when only the VS changed