diff options
author | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2023-10-26 16:22:27 -0400 |
---|---|---|
committer | Eric Engestrom <eric@engestrom.ch> | 2023-10-30 15:48:29 +0000 |
commit | e8e6ad5692e1a1fa5194e8f45f7122f69caa650b (patch) | |
tree | f65b8f16583c01838712b3321514c589038cb3b3 | |
parent | 423202cae44eb2c12ad3a28bd4e9b9eb91447ccf (diff) |
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>
(cherry picked from commit f8909e7d55e86c7db55f4b9482f94c993f5e2529)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_program.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/zink/zink_types.h | 2 |
3 files changed, 21 insertions, 5 deletions
diff --git a/.pick_status.json b/.pick_status.json index 55fc119d5a8..4557a56782f 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -654,7 +654,7 @@ "description": "zink: add more locking for compute pipelines", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null 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 29d921f3f4f..6aa00b86c2b 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1148,6 +1148,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; }; |