summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2023-10-26 16:22:27 -0400
committerEric Engestrom <eric@engestrom.ch>2023-10-30 15:48:29 +0000
commite8e6ad5692e1a1fa5194e8f45f7122f69caa650b (patch)
treef65b8f16583c01838712b3321514c589038cb3b3
parent423202cae44eb2c12ad3a28bd4e9b9eb91447ccf (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.json2
-rw-r--r--src/gallium/drivers/zink/zink_program.c22
-rw-r--r--src/gallium/drivers/zink/zink_types.h2
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;
};