mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 11:18:08 +02:00
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>
This commit is contained in:
parent
2748301a09
commit
d786f52f1f
3 changed files with 6 additions and 0 deletions
|
|
@ -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*)) {
|
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*);
|
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) {
|
if (!libs->removed) {
|
||||||
libs->removed = true;
|
libs->removed = true;
|
||||||
simple_mtx_lock(&screen->pipeline_libs_lock[idx]);
|
simple_mtx_lock(&screen->pipeline_libs_lock[idx]);
|
||||||
|
|
|
||||||
|
|
@ -977,6 +977,7 @@ static struct zink_gfx_lib_cache *
|
||||||
create_lib_cache(struct zink_gfx_program *prog, bool generated_tcs)
|
create_lib_cache(struct zink_gfx_program *prog, bool generated_tcs)
|
||||||
{
|
{
|
||||||
struct zink_gfx_lib_cache *libs = rzalloc(NULL, struct zink_gfx_lib_cache);
|
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);
|
simple_mtx_init(&libs->lock, mtx_plain);
|
||||||
if (generated_tcs)
|
if (generated_tcs)
|
||||||
_mesa_set_init(&libs->libs, libs, hash_pipeline_lib_generated_tcs, equals_pipeline_lib_generated_tcs);
|
_mesa_set_init(&libs->libs, libs, hash_pipeline_lib_generated_tcs, equals_pipeline_lib_generated_tcs);
|
||||||
|
|
|
||||||
|
|
@ -1005,6 +1005,7 @@ struct zink_gfx_lib_cache {
|
||||||
struct zink_shader *shaders[ZINK_GFX_SHADER_COUNT];
|
struct zink_shader *shaders[ZINK_GFX_SHADER_COUNT];
|
||||||
unsigned refcount;
|
unsigned refcount;
|
||||||
bool removed; //once removed from cache
|
bool removed; //once removed from cache
|
||||||
|
uint8_t stages_present;
|
||||||
|
|
||||||
simple_mtx_t lock;
|
simple_mtx_t lock;
|
||||||
struct set libs; //zink_gfx_library_key -> VkPipeline
|
struct set libs; //zink_gfx_library_key -> VkPipeline
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue