radeonsi: reduce NGG culling on/off transitions by keeping it enabled
authorMarek Olšák <marek.olsak@amd.com>
Thu, 23 Sep 2021 12:06:34 +0000 (08:06 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 28 Sep 2021 17:30:06 +0000 (17:30 +0000)
When it's enabled, it stays enabled until the next shader change
or an incompatible primitive type, etc.

This improves performance for viewperf/snx.

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

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

index 73eaa2d..4808033 100644 (file)
@@ -2158,7 +2158,13 @@ static void si_draw_vbo(struct pipe_context *ctx,
           /* Tessellation sets ngg_cull_vert_threshold to UINT_MAX if the prim type
            * is not triangles, so this check is only needed without tessellation. */
           (HAS_TESS || sctx->current_rast_prim == PIPE_PRIM_TRIANGLES) &&
-          total_direct_count > hw_vs->ngg_cull_vert_threshold) {
+          /* Only the first draw for a shader starts with culling disabled and it's disabled
+           * until we pass the total_direct_count check and then it stays enabled until
+           * the shader is changed. This eliminates most culling on/off state changes. */
+          (old_ngg_culling || total_direct_count > hw_vs->ngg_cull_vert_threshold)) {
+         /* Check that the current shader allows culling. */
+         assert(hw_vs->ngg_cull_vert_threshold != UINT_MAX);
+
          uint8_t ngg_culling = sctx->viewport0_y_inverted ? rs->ngg_cull_flags_y_inverted :
                                                             rs->ngg_cull_flags;
 
index c88b11d..eaabcb4 100644 (file)
@@ -3154,6 +3154,9 @@ static void si_update_common_shader_state(struct si_context *sctx, struct si_sha
                                 si_shader_uses_bindless_images(sctx->shader.tcs.cso) ||
                                 si_shader_uses_bindless_images(sctx->shader.tes.cso);
 
+   if (type == PIPE_SHADER_VERTEX || type == PIPE_SHADER_TESS_EVAL || type == PIPE_SHADER_GEOMETRY)
+      sctx->ngg_culling = 0; /* this will be enabled on the first draw if needed */
+
    si_invalidate_inlinable_uniforms(sctx, type);
    sctx->do_update_shaders = true;
 }