radeonsi: don't use NGG passthrough if culling is possible for better perf
authorMarek Olšák <marek.olsak@amd.com>
Wed, 25 Aug 2021 19:47:20 +0000 (15:47 -0400)
committerMarge Bot <eric+marge@anholt.net>
Fri, 10 Sep 2021 23:32:03 +0000 (23:32 +0000)
Switching NGG passthrough on/off decreases performance because it causes
context rolls.

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

src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state_shaders.c

index 220e4ec..acb5d6f 100644 (file)
@@ -882,6 +882,7 @@ char *si_finalize_nir(struct pipe_screen *screen, void *nirptr);
 /* si_state_shaders.c */
 void gfx9_get_gs_info(struct si_shader_selector *es, struct si_shader_selector *gs,
                       struct gfx9_gs_info *out);
+bool gfx10_is_ngg_passthrough(struct si_shader *shader);
 
 /* Inline helpers. */
 
@@ -900,15 +901,6 @@ static inline struct si_shader **si_get_main_shader_part(struct si_shader_select
    return &sel->main_shader_part;
 }
 
-static inline bool gfx10_is_ngg_passthrough(struct si_shader *shader)
-{
-   struct si_shader_selector *sel = shader->selector;
-
-   return sel->info.stage != MESA_SHADER_GEOMETRY && !sel->so.num_outputs && !sel->info.writes_edgeflag &&
-          !shader->key.opt.ngg_culling &&
-          (sel->info.stage != MESA_SHADER_VERTEX || !shader->key.mono.u.vs_export_prim_id);
-}
-
 static inline bool si_shader_uses_bindless_samplers(struct si_shader_selector *selector)
 {
    return selector ? selector->info.uses_bindless_samplers : false;
index 567309b..ccbc419 100644 (file)
@@ -78,6 +78,11 @@ void si_get_ir_cache_key(struct si_shader_selector *sel, bool ngg, bool es,
        sel->info.base.fs.uses_discard &&
        sel->screen->debug_flags & DBG(FS_CORRECT_DERIVS_AFTER_KILL))
       shader_variant_flags |= 1 << 3;
+   /* use_ngg_culling disables NGG passthrough for non-culling shaders to reduce context
+    * rolls, which can be changed with AMD_DEBUG=nonggc or AMD_DEBUG=nggc.
+    */
+   if (sel->screen->use_ngg_culling)
+      shader_variant_flags |= 1 << 4;
 
    /* bit gap */
 
@@ -987,6 +992,21 @@ static void gfx10_emit_ge_pc_alloc(struct si_context *sctx, unsigned value)
    }
 }
 
+bool gfx10_is_ngg_passthrough(struct si_shader *shader)
+{
+   struct si_shader_selector *sel = shader->selector;
+
+   /* Never use NGG passthrough if culling is possible even when it's not used by this shader,
+    * so that we don't get context rolls when enabling and disabling NGG passthrough.
+    */
+   if (sel->screen->use_ngg_culling)
+      return false;
+
+   return sel->info.stage != MESA_SHADER_GEOMETRY && !sel->so.num_outputs && !sel->info.writes_edgeflag &&
+          !shader->key.opt.ngg_culling &&
+          (sel->info.stage != MESA_SHADER_VERTEX || !shader->key.mono.u.vs_export_prim_id);
+}
+
 /* Common tail code for NGG primitive shaders. */
 static void gfx10_emit_shader_ngg_tail(struct si_context *sctx, struct si_shader *shader)
 {