Module: Mesa Branch: main Commit: f8909e7d55e86c7db55f4b9482f94c993f5e2529 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f8909e7d55e86c7db55f4b9482f94c993f5e2529
Author: Mike Blumenkrantz <michael.blumenkra...@gmail.com> Date: Thu Oct 26 16:22:27 2023 -0400 zink: add more locking for compute pipelines if multiple contexts are accessing this all at once then this needs more locking to avoid unsynchronized cache access cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25929> --- src/gallium/drivers/zink/zink_program.c | 22 ++++++++++++++++++---- src/gallium/drivers/zink/zink_types.h | 2 ++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 796cc258a4f..024e19088e8 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -1367,6 +1367,7 @@ create_compute_program(struct zink_context *ctx, nir_shader *nir) struct zink_compute_program *comp = create_program(ctx, true); if (!comp) return NULL; + simple_mtx_init(&comp->cache_lock, mtx_plain); comp->scratch_size = nir->scratch_size; comp->nir = nir; comp->num_inlinable_uniforms = nir->info.num_inlinable_uniforms; @@ -1595,6 +1596,7 @@ zink_get_compute_pipeline(struct zink_screen *screen, struct zink_compute_pipeline_state *state) { struct hash_entry *entry = NULL; + struct compute_pipeline_cache_entry *cache_entry; if (!state->dirty && !state->module_changed) return state->pipeline; @@ -1617,30 +1619,42 @@ zink_get_compute_pipeline(struct zink_screen *screen, entry = _mesa_hash_table_search_pre_hashed(&comp->pipelines, state->final_hash, state); if (!entry) { + simple_mtx_lock(&comp->cache_lock); + entry = _mesa_hash_table_search_pre_hashed(&comp->pipelines, state->final_hash, state); + if (entry) { + simple_mtx_unlock(&comp->cache_lock); + goto out; + } VkPipeline pipeline = zink_create_compute_pipeline(screen, comp, state); - if (pipeline == VK_NULL_HANDLE) + if (pipeline == VK_NULL_HANDLE) { + simple_mtx_unlock(&comp->cache_lock); return VK_NULL_HANDLE; + } zink_screen_update_pipeline_cache(screen, &comp->base, false); if (compute_can_shortcut(comp)) { + simple_mtx_unlock(&comp->cache_lock); /* don't add base pipeline to cache */ state->pipeline = comp->base_pipeline = pipeline; return state->pipeline; } struct compute_pipeline_cache_entry *pc_entry = CALLOC_STRUCT(compute_pipeline_cache_entry); - if (!pc_entry) + if (!pc_entry) { + simple_mtx_unlock(&comp->cache_lock); return VK_NULL_HANDLE; + } memcpy(&pc_entry->state, state, sizeof(*state)); pc_entry->pipeline = pipeline; entry = _mesa_hash_table_insert_pre_hashed(&comp->pipelines, state->final_hash, pc_entry, pc_entry); assert(entry); + simple_mtx_unlock(&comp->cache_lock); } - - struct compute_pipeline_cache_entry *cache_entry = entry->data; +out: + cache_entry = entry->data; state->pipeline = cache_entry->pipeline; return state->pipeline; } diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 865fa7492c1..eabe85b183e 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1160,6 +1160,8 @@ struct zink_compute_program { struct zink_shader *shader; struct hash_table pipelines; + simple_mtx_t cache_lock; //extra lock because threads are insane and sand was not meant to think + VkPipeline base_pipeline; };