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>
This commit is contained in:
Mike Blumenkrantz 2023-10-26 16:22:27 -04:00 committed by Marge Bot
parent 9a3af6e1d8
commit f8909e7d55
2 changed files with 20 additions and 4 deletions

View file

@ -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;
}

View file

@ -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;
};