zink: be even more granular with optimal_key program updates
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 2 Sep 2022 15:13:44 +0000 (11:13 -0400)
committerMarge Bot <emma+marge@anholt.net>
Mon, 26 Sep 2022 17:12:31 +0000 (17:12 +0000)
since the bits of each key are easily and efficiently comparable,
the draw-time updating here can be made extremely granular to
update exactly the stages that have changed since the last
time the program was used, further reducing overhead instead of
updating every possible key value

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18786>

src/gallium/drivers/zink/zink_program.c
src/gallium/drivers/zink/zink_shader_keys.h

index 391c471..73dfa01 100644 (file)
@@ -571,13 +571,16 @@ zink_gfx_program_update(struct zink_context *ctx)
          if (screen->optimal_keys) {
             ctx->gfx_pipeline_state.optimal_key = ctx->gfx_pipeline_state.shader_keys_optimal.key.val;
             if (ctx->gfx_pipeline_state.optimal_key != prog->last_variant_hash) {
-               ctx->dirty_gfx_stages |= BITFIELD_BIT(ctx->last_vertex_stage->nir->info.stage);
-               ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
-               if (prog->shaders[MESA_SHADER_TESS_CTRL] && prog->shaders[MESA_SHADER_TESS_CTRL]->is_generated)
+               const union zink_shader_key_optimal *optimal_key = (union zink_shader_key_optimal*)&prog->last_variant_hash;
+               uint8_t dirty = ctx->dirty_gfx_stages & prog->stages_present;
+               if (ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_bits != optimal_key->vs_bits)
+                  ctx->dirty_gfx_stages |= BITFIELD_BIT(ctx->last_vertex_stage->nir->info.stage);
+               if (ctx->gfx_pipeline_state.shader_keys_optimal.key.fs_bits != optimal_key->fs_bits)
+                  ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
+               if (prog->shaders[MESA_SHADER_TESS_CTRL] && prog->shaders[MESA_SHADER_TESS_CTRL]->is_generated &&
+                   ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs_bits != optimal_key->tcs_bits)
                   ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_TESS_CTRL);
-               update_gfx_shader_modules_optimal(ctx, screen, prog,
-                                                 ctx->dirty_gfx_stages & prog->stages_present,
-                                                 &ctx->gfx_pipeline_state);
+               update_gfx_shader_modules_optimal(ctx, screen, prog, dirty, &ctx->gfx_pipeline_state);
             }
          } else {
             for (unsigned i = 0; i < ZINK_GFX_SHADER_COUNT; i++) {
index 4ca0139..295cbe3 100644 (file)
@@ -99,6 +99,11 @@ union zink_shader_key_optimal {
       struct zink_tcs_key tcs;
       struct zink_fs_key fs;
    };
+   struct {
+      uint8_t vs_bits;
+      uint8_t tcs_bits;
+      uint16_t fs_bits;
+   };
    uint32_t val;
 };