zink: promote gpl libs freeing during shader destroy out of prog loop
now that zink_gfx_lib_cache::stages_present exists (and is correct),
this value can be used directly to effect cache eviction instead of depending
on the prog->stages_present value, which may not even be the same prog that
owns a given zink_gfx_lib_cache instance
this fixes the case where a shader used in multiple progs with differing shader
masks would never have all its gpl pipelines freed
fixes leaks with caselist:
KHR-Single-GL46.arrays_of_arrays_gl.InteractionUniformBuffers1
KHR-Single-GL46.subgroups.quad.framebuffer.subgroupquadbroadcast_3_float_vertex
Fixes: d786f52f1f
("zink: prevent crash when freeing")
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27358>
This commit is contained in:
@@ -5764,20 +5764,6 @@ zink_gfx_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]);
|
||||
_mesa_set_remove_key(&screen->pipeline_libs[idx], libs);
|
||||
simple_mtx_unlock(&screen->pipeline_libs_lock[idx]);
|
||||
}
|
||||
zink_gfx_lib_cache_unref(screen, libs);
|
||||
}
|
||||
if (stage == MESA_SHADER_FRAGMENT || !shader->non_fs.is_generated) {
|
||||
prog->shaders[stage] = NULL;
|
||||
prog->stages_remaining &= ~BITFIELD_BIT(stage);
|
||||
@@ -5793,6 +5779,17 @@ zink_gfx_shader_free(struct zink_screen *screen, struct zink_shader *shader)
|
||||
}
|
||||
zink_gfx_program_reference(screen, &prog, NULL);
|
||||
}
|
||||
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*);
|
||||
if (!libs->removed) {
|
||||
libs->removed = true;
|
||||
unsigned idx = zink_program_cache_stages(libs->stages_present);
|
||||
simple_mtx_lock(&screen->pipeline_libs_lock[idx]);
|
||||
_mesa_set_remove_key(&screen->pipeline_libs[idx], libs);
|
||||
simple_mtx_unlock(&screen->pipeline_libs_lock[idx]);
|
||||
}
|
||||
zink_gfx_lib_cache_unref(screen, libs);
|
||||
}
|
||||
if (shader->info.stage == MESA_SHADER_TESS_EVAL &&
|
||||
shader->non_fs.generated_tcs) {
|
||||
/* automatically destroy generated tcs shaders when tes is destroyed */
|
||||
|
Reference in New Issue
Block a user