radeonsi: move patch_vertices-related tessellation updates out of si_draw
authorMarek Olšák <marek.olsak@amd.com>
Tue, 23 Aug 2022 21:51:49 +0000 (17:51 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 30 Aug 2022 04:57:43 +0000 (04:57 +0000)
This only depends on the patch_vertices and the TCS.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18195>

src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.cpp
src/gallium/drivers/radeonsi/si_state_shaders.cpp

index 4afee51..42184c1 100644 (file)
@@ -5314,7 +5314,10 @@ static void si_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertic
 {
    struct si_context *sctx = (struct si_context *)ctx;
 
-   sctx->patch_vertices = patch_vertices;
+   if (sctx->patch_vertices != patch_vertices) {
+      sctx->patch_vertices = patch_vertices;
+      si_update_tess_in_out_patch_vertices(sctx);
+   }
 }
 
 static void si_texture_barrier(struct pipe_context *ctx, unsigned flags)
index fa60be4..f9d1a81 100644 (file)
@@ -598,6 +598,7 @@ bool si_update_gs_ring_buffers(struct si_context *sctx);
 bool si_update_spi_tmpring_size(struct si_context *sctx, unsigned bytes);
 unsigned si_get_shader_prefetch_size(struct si_shader *shader);
 bool si_set_tcs_to_fixed_func_shader(struct si_context *sctx);
+void si_update_tess_in_out_patch_vertices(struct si_context *sctx);
 
 /* si_state_draw.cpp */
 void si_cp_dma_prefetch(struct si_context *sctx, struct pipe_resource *buf,
index 3773770..a6b2444 100644 (file)
@@ -2148,48 +2148,6 @@ static void si_draw(struct pipe_context *ctx,
    si_decompress_textures(sctx, u_bit_consecutive(0, SI_NUM_GRAPHICS_SHADERS));
    si_need_gfx_cs_space(sctx, num_draws);
 
-   if (HAS_TESS) {
-      if (sctx->is_user_tcs) {
-         struct si_shader_selector *tcs = sctx->shader.tcs.cso;
-
-         bool same_patch_vertices =
-            GFX_VERSION >= GFX9 &&
-            sctx->patch_vertices == tcs->info.base.tess.tcs_vertices_out;
-
-         if (sctx->shader.tcs.key.ge.opt.same_patch_vertices != same_patch_vertices) {
-            sctx->shader.tcs.key.ge.opt.same_patch_vertices = same_patch_vertices;
-            sctx->do_update_shaders = true;
-         }
-
-         if (GFX_VERSION == GFX9 && sctx->screen->info.has_ls_vgpr_init_bug) {
-            /* Determine whether the LS VGPR fix should be applied.
-             *
-             * It is only required when num input CPs > num output CPs,
-             * which cannot happen with the fixed function TCS.
-             */
-            bool ls_vgpr_fix =
-               sctx->patch_vertices > tcs->info.base.tess.tcs_vertices_out;
-
-            if (ls_vgpr_fix != sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix) {
-               sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = ls_vgpr_fix;
-               sctx->do_update_shaders = true;
-            }
-         }
-      } else {
-         /* These fields are static for fixed function TCS. So no need to set
-          * do_update_shaders between fixed-TCS draws. As fixed-TCS to user-TCS
-          * or opposite, do_update_shaders should already be set by bind state.
-          */
-         sctx->shader.tcs.key.ge.opt.same_patch_vertices = GFX_VERSION >= GFX9;
-         sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = false;
-
-         /* User may only change patch vertices, needs to update fixed func TCS. */
-         if (sctx->shader.tcs.cso &&
-             sctx->shader.tcs.cso->info.base.tess.tcs_vertices_out != sctx->patch_vertices)
-            sctx->do_update_shaders = true;
-      }
-   }
-
    unsigned instance_count = info->instance_count;
 
    /* GFX6-GFX7 treat instance_count==0 as instance_count==1. There is
index 8d33e9b..7a72edb 100644 (file)
@@ -3491,6 +3491,7 @@ static void si_bind_tcs_shader(struct pipe_context *ctx, void *state)
    sctx->shader.tcs.key.ge.part.tcs.epilog.invoc0_tess_factors_are_def =
       sel ? sel->info.tessfactors_are_def_in_all_invocs : 0;
    si_update_tess_uses_prim_id(sctx);
+   si_update_tess_in_out_patch_vertices(sctx);
 
    si_update_common_shader_state(sctx, sel, PIPE_SHADER_TESS_CTRL);
 
@@ -4284,6 +4285,49 @@ bool si_set_tcs_to_fixed_func_shader(struct si_context *sctx)
    return true;
 }
 
+void si_update_tess_in_out_patch_vertices(struct si_context *sctx)
+{
+   if (sctx->is_user_tcs) {
+      struct si_shader_selector *tcs = sctx->shader.tcs.cso;
+
+      bool same_patch_vertices =
+         sctx->gfx_level >= GFX9 &&
+         sctx->patch_vertices == tcs->info.base.tess.tcs_vertices_out;
+
+      if (sctx->shader.tcs.key.ge.opt.same_patch_vertices != same_patch_vertices) {
+         sctx->shader.tcs.key.ge.opt.same_patch_vertices = same_patch_vertices;
+         sctx->do_update_shaders = true;
+      }
+
+      if (sctx->gfx_level == GFX9 && sctx->screen->info.has_ls_vgpr_init_bug) {
+         /* Determine whether the LS VGPR fix should be applied.
+          *
+          * It is only required when num input CPs > num output CPs,
+          * which cannot happen with the fixed function TCS.
+          */
+         bool ls_vgpr_fix =
+            sctx->patch_vertices > tcs->info.base.tess.tcs_vertices_out;
+
+         if (ls_vgpr_fix != sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix) {
+            sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = ls_vgpr_fix;
+            sctx->do_update_shaders = true;
+         }
+      }
+   } else {
+      /* These fields are static for fixed function TCS. So no need to set
+       * do_update_shaders between fixed-TCS draws. As fixed-TCS to user-TCS
+       * or opposite, do_update_shaders should already be set by bind state.
+       */
+      sctx->shader.tcs.key.ge.opt.same_patch_vertices = sctx->gfx_level >= GFX9;
+      sctx->shader.tcs.key.ge.part.tcs.ls_prolog.ls_vgpr_fix = false;
+
+      /* User may only change patch vertices, needs to update fixed func TCS. */
+      if (sctx->shader.tcs.cso &&
+          sctx->shader.tcs.cso->info.base.tess.tcs_vertices_out != sctx->patch_vertices)
+         sctx->do_update_shaders = true;
+   }
+}
+
 void si_init_screen_live_shader_cache(struct si_screen *sscreen)
 {
    util_live_shader_cache_init(&sscreen->live_shader_cache, si_create_shader_selector,