radeonsi: refactor si_update_vgt_shader_config
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Fri, 21 Sep 2018 13:38:42 +0000 (15:38 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 25 Jun 2019 01:04:10 +0000 (21:04 -0400)
We'll have to extend this at some point, and using a bitfield union in
this way makes it easier to get the right index without excessive
branching.

Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index d32feab52c2614bb99dbc22895855c48f6b7db41..368cb4e473d3f7a83f83966eaf9c9a2705e93250 100644 (file)
@@ -767,6 +767,27 @@ union si_vgt_param_key {
        uint32_t index;
 };
 
+#define SI_NUM_VGT_STAGES_KEY_BITS 2
+#define SI_NUM_VGT_STAGES_STATES (1 << SI_NUM_VGT_STAGES_KEY_BITS)
+
+/* The VGT_SHADER_STAGES key used to index the table of precomputed values.
+ * Some fields are set by state-change calls, most are set by draw_vbo.
+ */
+union si_vgt_stages_key {
+       struct {
+#ifdef PIPE_ARCH_LITTLE_ENDIAN
+               unsigned tess:1;
+               unsigned gs:1;
+               unsigned _pad:32 - SI_NUM_VGT_STAGES_KEY_BITS;
+#else /* PIPE_ARCH_BIG_ENDIAN */
+               unsigned _pad:32 - SI_NUM_VGT_STAGES_KEY_BITS;
+               unsigned gs:1;
+               unsigned tess:1;
+#endif
+       } u;
+       uint32_t index;
+};
+
 struct si_texture_handle
 {
        unsigned                        desc_slot;
@@ -921,7 +942,7 @@ struct si_context {
        struct si_pm4_state             *init_config;
        struct si_pm4_state             *init_config_gs_rings;
        bool                            init_config_has_vgt_flush;
-       struct si_pm4_state             *vgt_shader_config[4];
+       struct si_pm4_state             *vgt_shader_config[SI_NUM_VGT_STAGES_STATES];
 
        /* shaders */
        struct si_shader_ctx_state      ps_shader;
index fab2e255742155a19413a844dbaff7ccc59b99bf..0e3a1c3a776e52de486372c3bc82ba3815d0d153 100644 (file)
@@ -3318,39 +3318,43 @@ static void si_init_tess_factor_ring(struct si_context *sctx)
        si_flush_gfx_cs(sctx, RADEON_FLUSH_ASYNC_START_NEXT_GFX_IB_NOW, NULL);
 }
 
-static void si_update_vgt_shader_config(struct si_context *sctx)
+static struct si_pm4_state *si_build_vgt_shader_config(struct si_screen *screen,
+                                                      union si_vgt_stages_key key)
 {
-       /* Calculate the index of the config.
-        * 0 = VS, 1 = VS+GS, 2 = VS+Tess, 3 = VS+Tess+GS */
-       unsigned index = 2*!!sctx->tes_shader.cso + !!sctx->gs_shader.cso;
-       struct si_pm4_state **pm4 = &sctx->vgt_shader_config[index];
+       struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+       uint32_t stages = 0;
 
-       if (!*pm4) {
-               uint32_t stages = 0;
+       if (key.u.tess) {
+               stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) |
+                         S_028B54_HS_EN(1) | S_028B54_DYNAMIC_HS(1);
 
-               *pm4 = CALLOC_STRUCT(si_pm4_state);
+               if (key.u.gs)
+                       stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_DS) |
+                                 S_028B54_GS_EN(1);
+               else
+                       stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_DS);
+       } else if (key.u.gs) {
+               stages |= S_028B54_ES_EN(V_028B54_ES_STAGE_REAL) |
+                         S_028B54_GS_EN(1);
+       }
 
-               if (sctx->tes_shader.cso) {
-                       stages |= S_028B54_LS_EN(V_028B54_LS_STAGE_ON) |
-                                 S_028B54_HS_EN(1) | S_028B54_DYNAMIC_HS(1);
+       if (key.u.gs)
+               stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
 
-                       if (sctx->gs_shader.cso)
-                               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.cso) {
-                       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);
-               }
+       if (screen->info.chip_class >= GFX9)
+               stages |= S_028B54_MAX_PRIMGRP_IN_WAVE(2);
 
-               if (sctx->chip_class >= GFX9)
-                       stages |= S_028B54_MAX_PRIMGRP_IN_WAVE(2);
+       si_pm4_set_reg(pm4, R_028B54_VGT_SHADER_STAGES_EN, stages);
+       return pm4;
+}
 
-               si_pm4_set_reg(*pm4, R_028B54_VGT_SHADER_STAGES_EN, stages);
-       }
+static void si_update_vgt_shader_config(struct si_context *sctx,
+                                       union si_vgt_stages_key key)
+{
+       struct si_pm4_state **pm4 = &sctx->vgt_shader_config[key.index];
+
+       if (unlikely(!*pm4))
+               *pm4 = si_build_vgt_shader_config(sctx->screen, key);
        si_pm4_bind_state(sctx, vgt_shader_config, *pm4);
 }
 
@@ -3362,6 +3366,7 @@ bool si_update_shaders(struct si_context *sctx)
        struct si_shader *old_vs = si_get_vs_state(sctx);
        bool old_clip_disable = old_vs ? old_vs->key.opt.clip_disable : false;
        struct si_shader *old_ps = sctx->ps_shader.current;
+       union si_vgt_stages_key key;
        unsigned old_spi_shader_col_format =
                old_ps ? old_ps->key.part.ps.epilog.spi_shader_col_format : 0;
        int r;
@@ -3370,8 +3375,12 @@ bool si_update_shaders(struct si_context *sctx)
        compiler_state.debug = sctx->debug;
        compiler_state.is_debug_context = sctx->is_debug;
 
+       key.index = 0;
+
        /* Update stages before GS. */
        if (sctx->tes_shader.cso) {
+               key.u.tess = 1;
+
                if (!sctx->tess_rings) {
                        si_init_tess_factor_ring(sctx);
                        if (!sctx->tess_rings)
@@ -3450,6 +3459,8 @@ bool si_update_shaders(struct si_context *sctx)
 
        /* Update GS. */
        if (sctx->gs_shader.cso) {
+               key.u.gs = 1;
+
                r = si_shader_select(ctx, &sctx->gs_shader, &compiler_state);
                if (r)
                        return false;
@@ -3464,7 +3475,7 @@ bool si_update_shaders(struct si_context *sctx)
                        si_pm4_bind_state(sctx, es, NULL);
        }
 
-       si_update_vgt_shader_config(sctx);
+       si_update_vgt_shader_config(sctx, key);
 
        if (old_clip_disable != si_get_vs_state(sctx)->key.opt.clip_disable)
                si_mark_atom_dirty(sctx, &sctx->atoms.s.clip_regs);