Mesa (main): zink: make shader cache local to a single program

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 6 18:15:31 UTC 2021


Module: Mesa
Branch: main
Commit: 49caf1a094824df4b6ca6492c339872a95610100
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=49caf1a094824df4b6ca6492c339872a95610100

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Mon May 10 17:34:25 2021 -0400

zink: make shader cache local to a single program

sharing caches makes things complicated and doesn't yield much benefit

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11691>

---

 src/gallium/drivers/zink/zink_program.c | 83 ++++++++-------------------------
 src/gallium/drivers/zink/zink_program.h | 11 ++---
 2 files changed, 22 insertions(+), 72 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index c75193263c5..e34a23233eb 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -69,12 +69,6 @@ debug_describe_zink_shader_module(char *buf, const struct zink_shader_module *pt
    sprintf(buf, "zink_shader_module");
 }
 
-static void
-debug_describe_zink_shader_cache(char* buf, const struct zink_shader_cache *ptr)
-{
-   sprintf(buf, "zink_shader_cache");
-}
-
 /* copied from iris */
 struct keybox {
    uint16_t size;
@@ -240,9 +234,9 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_shader *zs, st
       if (*default_zm)
          return *default_zm;
    }
-   keybox = make_keybox(prog->shader_cache, stage, &key, key.size, &key.base, base_size);
+   keybox = make_keybox(prog, stage, &key, key.size, &key.base, base_size);
    hash = keybox_hash(keybox);
-   struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(prog->shader_cache->shader_cache,
+   struct hash_entry *entry = _mesa_hash_table_search_pre_hashed(&prog->base.shader_cache,
                                                                  hash, keybox);
 
    if (entry) {
@@ -264,7 +258,7 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_shader *zs, st
       }
       zm->shader = mod;
 
-      _mesa_hash_table_insert_pre_hashed(prog->shader_cache->shader_cache, hash, keybox, zm);
+      _mesa_hash_table_insert_pre_hashed(&prog->base.shader_cache, hash, keybox, zm);
       if (key.is_default_variant) {
          /* previously returned */
          *default_zm = zm;
@@ -295,28 +289,12 @@ zink_shader_module_reference(struct zink_screen *screen,
 }
 
 static void
-zink_destroy_shader_cache(struct zink_screen *screen, struct zink_shader_cache *sc)
+destroy_shader_cache(struct zink_screen *screen, struct hash_table *sc)
 {
-   hash_table_foreach(sc->shader_cache, entry) {
+   hash_table_foreach(sc, entry) {
       struct zink_shader_module *zm = entry->data;
       zink_shader_module_reference(screen, &zm, NULL);
-      _mesa_hash_table_remove(sc->shader_cache, entry);
    }
-   _mesa_hash_table_destroy(sc->shader_cache, NULL);
-   ralloc_free(sc);
-}
-
-static inline void
-zink_shader_cache_reference(struct zink_screen *screen,
-                           struct zink_shader_cache **dst,
-                           struct zink_shader_cache *src)
-{
-   struct zink_shader_cache *old_dst = dst ? *dst : NULL;
-
-   if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
-                                (debug_reference_descriptor)debug_describe_zink_shader_cache))
-      zink_destroy_shader_cache(screen, old_dst);
-   if (dst) *dst = src;
 }
 
 static void
@@ -347,12 +325,11 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_
       /* we need to iterate over the stages in pipeline-order here */
       enum pipe_shader_type type = pipe_shader_type_from_mesa(i);
       assert(type < ZINK_SHADER_COUNT);
-      if (dirty[i]) {
+      if (dirty[i] || (stages[type] && !prog->modules[type])) {
          struct zink_shader_module *zm;
-         zm = get_shader_module_for_stage(ctx, dirty[i], prog);
+         zm = get_shader_module_for_stage(ctx, dirty[i] ? dirty[i] : stages[type], prog);
          zink_shader_module_reference(zink_screen(ctx->base.screen), &prog->modules[type], zm);
-      } else if (stages[type] && !disallow_reuse) /* reuse existing shader module */
-         zink_shader_module_reference(zink_screen(ctx->base.screen), &prog->modules[type], ctx->curr_program->modules[type]);
+      }
       if (ctx->gfx_pipeline_state.modules[type] !=
           (prog->modules[type] ? prog->modules[type]->shader : VK_NULL_HANDLE))
          ctx->gfx_pipeline_state.combined_dirty = true;
@@ -470,19 +447,10 @@ init_slot_map(struct zink_context *ctx, struct zink_gfx_program *prog)
    if (needs_new_map || ctx->dirty_shader_stages == existing_shaders || !existing_shaders) {
       /* all shaders are being recompiled: new slot map */
       memset(prog->shader_slot_map, -1, sizeof(prog->shader_slot_map));
-      /* we need the slot map to match up, so we can't reuse the previous cache if we can't guarantee
-       * the slots match up
-       * TOOD: if we compact the slot map table, we can store it on the shader keys and reuse the cache
-       */
-      prog->shader_cache = ralloc(NULL, struct zink_shader_cache);
-      pipe_reference_init(&prog->shader_cache->reference, 1);
-      prog->shader_cache->shader_cache =  _mesa_hash_table_create(NULL, keybox_hash, keybox_equals);
    } else {
       /* at least some shaders are being reused: use existing slot map so locations match up */
       memcpy(prog->shader_slot_map, ctx->curr_program->shader_slot_map, sizeof(prog->shader_slot_map));
       prog->shader_slots_reserved = ctx->curr_program->shader_slots_reserved;
-      /* and then we can also reuse the shader cache since we know the slots are the same */
-      zink_shader_cache_reference(zink_screen(ctx->base.screen), &prog->shader_cache, ctx->curr_program->shader_cache);
    }
 }
 
@@ -539,6 +507,7 @@ zink_create_gfx_program(struct zink_context *ctx,
       goto fail;
 
    pipe_reference_init(&prog->base.reference, 1);
+   _mesa_hash_table_init(&prog->base.shader_cache, prog, keybox_hash, keybox_equals);
 
    init_slot_map(ctx, prog);
 
@@ -625,29 +594,15 @@ zink_create_compute_program(struct zink_context *ctx, struct zink_shader *shader
 
    pipe_reference_init(&comp->base.reference, 1);
    comp->base.is_compute = true;
+   /* TODO: cs shader keys placeholder for now */
+   _mesa_hash_table_init(&comp->base.shader_cache, comp, _mesa_hash_u32, _mesa_key_u32_equal);
 
-   if (!ctx->curr_compute || !ctx->curr_compute->shader_cache) {
-      /* TODO: cs shader keys placeholder for now */
-      comp->shader_cache = ralloc(NULL, struct zink_shader_cache);
-      pipe_reference_init(&comp->shader_cache->reference, 1);
-      comp->shader_cache->shader_cache = _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);
-   } else
-      zink_shader_cache_reference(zink_screen(ctx->base.screen), &comp->shader_cache, ctx->curr_compute->shader_cache);
-
-   if (ctx->dirty_shader_stages & (1 << PIPE_SHADER_COMPUTE)) {
-      struct hash_entry *he = _mesa_hash_table_search(comp->shader_cache->shader_cache, &shader->shader_id);
-      if (he)
-         comp->module = he->data;
-      else {
-         comp->module = CALLOC_STRUCT(zink_shader_module);
-         assert(comp->module);
-         pipe_reference_init(&comp->module->reference, 1);
-         comp->module->shader = zink_shader_compile(screen, shader, NULL, NULL, NULL);
-         assert(comp->module->shader);
-         _mesa_hash_table_insert(comp->shader_cache->shader_cache, &shader->shader_id, comp->module);
-      }
-   } else
-     comp->module = ctx->curr_compute->module;
+   comp->module = CALLOC_STRUCT(zink_shader_module);
+   assert(comp->module);
+   pipe_reference_init(&comp->module->reference, 1);
+   comp->module->shader = zink_shader_compile(screen, shader, NULL, NULL, NULL);
+   assert(comp->module->shader);
+   _mesa_hash_table_insert(&comp->base.shader_cache, &shader->shader_id, comp->module);
 
    struct zink_shader_module *zm = NULL;
    zink_shader_module_reference(zink_screen(ctx->base.screen), &zm, comp->module);
@@ -798,7 +753,7 @@ zink_destroy_gfx_program(struct zink_screen *screen,
       }
       _mesa_hash_table_destroy(prog->pipelines[i], NULL);
    }
-   zink_shader_cache_reference(screen, &prog->shader_cache, NULL);
+   destroy_shader_cache(screen, &prog->base.shader_cache);
    if (prog->base.pipeline_cache)
       vkDestroyPipelineCache(screen->dev, prog->base.pipeline_cache, NULL);
    screen->descriptor_program_deinit(screen, &prog->base);
@@ -825,7 +780,7 @@ zink_destroy_compute_program(struct zink_screen *screen,
       free(pc_entry);
    }
    _mesa_hash_table_destroy(comp->pipelines, NULL);
-   zink_shader_cache_reference(screen, &comp->shader_cache, NULL);
+   destroy_shader_cache(screen, &comp->base.shader_cache);
    if (comp->base.pipeline_cache)
       vkDestroyPipelineCache(screen->dev, comp->base.pipeline_cache, NULL);
    screen->descriptor_program_deinit(screen, &comp->base);
diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h
index d8221c878da..72cf610ad12 100644
--- a/src/gallium/drivers/zink/zink_program.h
+++ b/src/gallium/drivers/zink/zink_program.h
@@ -68,12 +68,6 @@ struct zink_shader_module {
    VkShaderModule shader;
 };
 
-/* the shader cache stores a mapping of zink_shader_key::VkShaderModule */
-struct zink_shader_cache {
-   struct pipe_reference reference;
-   struct hash_table *shader_cache;
-};
-
 struct zink_program {
    struct pipe_reference reference;
    unsigned char sha1[20];
@@ -88,6 +82,9 @@ struct zink_program {
    VkPipelineLayout layout;
    VkDescriptorSetLayout dsl[ZINK_DESCRIPTOR_TYPES + 1]; // one for each type + push
    unsigned num_dsl;
+
+   /* the shader cache stores a mapping of zink_shader_key::VkShaderModule */
+   struct hash_table shader_cache;
 };
 
 struct zink_gfx_program {
@@ -98,7 +95,6 @@ struct zink_gfx_program {
    struct zink_shader_module *default_variants[ZINK_SHADER_COUNT][2]; //[default, no streamout]
    const void *default_variant_key[ZINK_SHADER_COUNT];
    struct zink_shader *shaders[ZINK_SHADER_COUNT];
-   struct zink_shader_cache *shader_cache;
    unsigned char shader_slot_map[VARYING_SLOT_MAX];
    unsigned char shader_slots_reserved;
    struct hash_table *pipelines[11]; // number of draw modes we support
@@ -109,7 +105,6 @@ struct zink_compute_program {
 
    struct zink_shader_module *module;
    struct zink_shader *shader;
-   struct zink_shader_cache *shader_cache;
    struct hash_table *pipelines;
 };
 



More information about the mesa-commit mailing list