summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorantonino <antonino.maniscalco@collabora.com>2023-02-22 17:24:57 +0100
committerMarge Bot <emma+marge@anholt.net>2023-03-29 19:18:40 +0000
commitd786f52f1ff10fba42e87530933a2a4c68de49a8 (patch)
tree42b235fb726726d202de0f8b82632fc8e7519136 /src/gallium/drivers
parent2748301a09dc2d5c9e31366bbc42335e49b56750 (diff)
zink: prevent crash when freeing
If the same vertex shader is used for more than one pipeline where for some a gs is generated but not for others then the logic to free pipeline libraries might use the incorrect stage_mask and try to free a non existing gs. Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21238>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/zink/zink_compiler.c4
-rw-r--r--src/gallium/drivers/zink/zink_program.c1
-rw-r--r--src/gallium/drivers/zink/zink_types.h1
3 files changed, 6 insertions, 0 deletions
diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c
index c8d84ca0088..e15967f83b8 100644
--- a/src/gallium/drivers/zink/zink_compiler.c
+++ b/src/gallium/drivers/zink/zink_compiler.c
@@ -4726,6 +4726,10 @@ zink_shader_free(struct zink_screen *screen, struct zink_shader *shader)
while (util_dynarray_contains(&shader->pipeline_libs, struct zink_gfx_lib_cache*)) {
struct zink_gfx_lib_cache *libs = util_dynarray_pop(&shader->pipeline_libs, struct zink_gfx_lib_cache*);
+ //this condition is equivalent to verifying that, for each bit stages_present_i in stages_present,
+ //stages_present_i implies libs->stages_present_i
+ if ((stages_present & ~(libs->stages_present & stages_present)) != 0)
+ continue;
if (!libs->removed) {
libs->removed = true;
simple_mtx_lock(&screen->pipeline_libs_lock[idx]);
diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index 3075edf2aae..fc717f8bd49 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -977,6 +977,7 @@ static struct zink_gfx_lib_cache *
create_lib_cache(struct zink_gfx_program *prog, bool generated_tcs)
{
struct zink_gfx_lib_cache *libs = rzalloc(NULL, struct zink_gfx_lib_cache);
+ libs->stages_present = prog->stages_present;
simple_mtx_init(&libs->lock, mtx_plain);
if (generated_tcs)
_mesa_set_init(&libs->libs, libs, hash_pipeline_lib_generated_tcs, equals_pipeline_lib_generated_tcs);
diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h
index ff49bf21fe0..ee7da9a80b7 100644
--- a/src/gallium/drivers/zink/zink_types.h
+++ b/src/gallium/drivers/zink/zink_types.h
@@ -1005,6 +1005,7 @@ struct zink_gfx_lib_cache {
struct zink_shader *shaders[ZINK_GFX_SHADER_COUNT];
unsigned refcount;
bool removed; //once removed from cache
+ uint8_t stages_present;
simple_mtx_t lock;
struct set libs; //zink_gfx_library_key -> VkPipeline