radeonsi: program VGT_SHADER_STAGES_EN for tessellation
authorMarek Olšák <marek.olsak@amd.com>
Thu, 18 Sep 2014 22:16:12 +0000 (00:16 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 22 Jul 2015 22:59:32 +0000 (00:59 +0200)
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index 0878b8887c9dc52149a80956effc3584739bca21..25dc4e7a96d5fc8884c0164e09ceac0e48009b25 100644 (file)
@@ -36,6 +36,7 @@
 static void si_destroy_context(struct pipe_context *context)
 {
        struct si_context *sctx = (struct si_context *)context;
+       int i;
 
        si_release_all_descriptors(sctx);
 
@@ -48,8 +49,8 @@ static void si_destroy_context(struct pipe_context *context)
 
        si_pm4_free_state(sctx, sctx->init_config, ~0);
        si_pm4_delete_state(sctx, gs_rings, sctx->gs_rings);
-       si_pm4_delete_state(sctx, gs_onoff, sctx->gs_on);
-       si_pm4_delete_state(sctx, gs_onoff, sctx->gs_off);
+       for (i = 0; i < Elements(sctx->vgt_shader_config); i++)
+               si_pm4_delete_state(sctx, vgt_shader_config, sctx->vgt_shader_config[i]);
 
        if (sctx->pstipple_sampler_state)
                sctx->b.b.delete_sampler_state(&sctx->b.b, sctx->pstipple_sampler_state);
index 2eaff1cd24d16fb86826f920e515d15ead1ba827..880f7beaa199c8cf884f95f742d2fef77906297b 100644 (file)
@@ -196,11 +196,12 @@ struct si_context {
        /* With rasterizer discard, there doesn't have to be a pixel shader.
         * In that case, we bind this one: */
        void                    *dummy_pixel_shader;
-       struct si_pm4_state     *gs_on;
-       struct si_pm4_state     *gs_off;
-       struct si_pm4_state     *gs_rings;
        struct r600_atom        cache_flush;
        struct pipe_constant_buffer null_const_buf; /* used for set_constant_buffer(NULL) on CIK */
+
+       /* VGT states. */
+       struct si_pm4_state     *vgt_shader_config[4];
+       struct si_pm4_state     *gs_rings;
        struct pipe_resource    *esgs_ring;
        struct pipe_resource    *gsvs_ring;
 
index edee6d413282ebadcded202bae22189d99f6fe2c..6174dad7190f2e36c8d6bb50b4a686edb716cb1c 100644 (file)
@@ -105,7 +105,7 @@ union si_state {
                struct si_pm4_state             *es;
                struct si_pm4_state             *gs;
                struct si_pm4_state             *gs_rings;
-               struct si_pm4_state             *gs_onoff;
+               struct si_pm4_state             *vgt_shader_config;
                struct si_pm4_state             *vs;
                struct si_pm4_state             *ps;
                struct si_pm4_state             *spi;
index 88edc908f729efc97dd0fcbb1e5eb93514f3581a..3eec217fbd2d799b4bb2d9d0546c65c11c67175f 100644 (file)
@@ -922,6 +922,41 @@ static void si_update_spi_tmpring_size(struct si_context *sctx)
                                S_0286E8_WAVESIZE(scratch_bytes_per_wave >> 10);
 }
 
+static void si_update_vgt_shader_config(struct si_context *sctx)
+{
+       /* Calculate the index of the config.
+        * 0 = VS, 1 = VS+GS, 2 = VS+Tess, 3 = VS+Tess+GS */
+       unsigned index = 2*!!sctx->tes_shader + !!sctx->gs_shader;
+       struct si_pm4_state **pm4 = &sctx->vgt_shader_config[index];
+
+       if (!*pm4) {
+               uint32_t stages = 0;
+
+               *pm4 = CALLOC_STRUCT(si_pm4_state);
+
+               if (sctx->tes_shader) {
+                       stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) |
+                                 S_028B54_HS_EN(1);
+
+                       if (sctx->gs_shader)
+                               stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS) |
+                                         S_028B54_GS_EN(1) |
+                                         S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
+                       else
+                               stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_DS);
+               } else if (sctx->gs_shader) {
+                       stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) |
+                                 S_028B54_GS_EN(1) |
+                                 S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
+               }
+
+               si_pm4_set_reg(*pm4, R_028B54_VGT_SHADER_STAGES_EN, stages);
+               if (!sctx->gs_shader)
+                       si_pm4_set_reg(*pm4, R_028A40_VGT_GS_MODE, 0);
+       }
+       si_pm4_bind_state(sctx, vgt_shader_config, *pm4);
+}
+
 void si_update_shaders(struct si_context *sctx)
 {
        struct pipe_context *ctx = (struct pipe_context*)sctx;
@@ -948,34 +983,19 @@ void si_update_shaders(struct si_context *sctx)
                                   sctx->gs_shader->gs_max_out_vertices *
                                   sctx->gs_shader->info.num_outputs * 16,
                                   64, true, true, 4, 16);
-
-               if (!sctx->gs_on) {
-                       sctx->gs_on = CALLOC_STRUCT(si_pm4_state);
-
-                       si_pm4_set_reg(sctx->gs_on, R_028B54_VGT_SHADER_STAGES_EN,
-                                      S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) |
-                                      S_028B54_GS_EN(1) |
-                                      S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER));
-               }
-               si_pm4_bind_state(sctx, gs_onoff, sctx->gs_on);
        } else {
                si_shader_select(ctx, sctx->vs_shader);
                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 = CALLOC_STRUCT(si_pm4_state);
-
-                       si_pm4_set_reg(sctx->gs_off, R_028A40_VGT_GS_MODE, 0);
-                       si_pm4_set_reg(sctx->gs_off, R_028B54_VGT_SHADER_STAGES_EN, 0);
-               }
-               si_pm4_bind_state(sctx, gs_onoff, sctx->gs_off);
                si_pm4_bind_state(sctx, gs_rings, NULL);
                si_pm4_bind_state(sctx, gs, NULL);
                si_pm4_bind_state(sctx, es, NULL);
        }
 
+       si_update_vgt_shader_config(sctx);
+
        si_shader_select(ctx, sctx->ps_shader);
 
        if (!sctx->ps_shader->current) {