Merge branch 'zombies-ate-my-shaders' into 'main'

mesa/st: fix zombie shader handling for non-current programs

Closes #11122

See merge request mesa/mesa!29680
This commit is contained in:
Mike Blumenkrantz 2024-06-17 11:18:51 +00:00
commit 14449940d8
3 changed files with 22 additions and 12 deletions

View File

@ -211,7 +211,8 @@ st_save_zombie_sampler_view(struct st_context *st,
void
st_save_zombie_shader(struct st_context *st,
enum pipe_shader_type type,
struct pipe_shader_state *shader)
void *shader,
bool prog_is_active)
{
struct st_zombie_shader_node *entry;
@ -224,6 +225,7 @@ st_save_zombie_shader(struct st_context *st,
entry->shader = shader;
entry->type = type;
entry->prog_is_active = prog_is_active;
/* We need a mutex since this function may be called from one thread
* while free_zombie_shaders() is called from another.
@ -284,27 +286,33 @@ free_zombie_shaders(struct st_context *st)
switch (entry->type) {
case PIPE_SHADER_VERTEX:
st->pipe->bind_vs_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_vs_state(st->pipe, NULL);
st->pipe->delete_vs_state(st->pipe, entry->shader);
break;
case PIPE_SHADER_FRAGMENT:
st->pipe->bind_fs_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_fs_state(st->pipe, NULL);
st->pipe->delete_fs_state(st->pipe, entry->shader);
break;
case PIPE_SHADER_GEOMETRY:
st->pipe->bind_gs_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_gs_state(st->pipe, NULL);
st->pipe->delete_gs_state(st->pipe, entry->shader);
break;
case PIPE_SHADER_TESS_CTRL:
st->pipe->bind_tcs_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_tcs_state(st->pipe, NULL);
st->pipe->delete_tcs_state(st->pipe, entry->shader);
break;
case PIPE_SHADER_TESS_EVAL:
st->pipe->bind_tes_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_tes_state(st->pipe, NULL);
st->pipe->delete_tes_state(st->pipe, entry->shader);
break;
case PIPE_SHADER_COMPUTE:
st->pipe->bind_compute_state(st->pipe, NULL);
if (entry->prog_is_active)
st->pipe->bind_compute_state(st->pipe, NULL);
st->pipe->delete_compute_state(st->pipe, entry->shader);
break;
default:

View File

@ -117,6 +117,7 @@ struct st_zombie_shader_node
{
void *shader;
enum pipe_shader_type type;
bool prog_is_active;
struct list_head node;
};
@ -477,7 +478,8 @@ st_save_zombie_sampler_view(struct st_context *st,
extern void
st_save_zombie_shader(struct st_context *st,
enum pipe_shader_type type,
struct pipe_shader_state *shader);
void *shader,
bool prog_is_active);
void

View File

@ -215,7 +215,7 @@ st_set_prog_affected_state_flags(struct gl_program *prog)
* the linked list.
*/
static void
delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
delete_variant(struct st_context *st, struct st_variant *v, GLenum target, bool prog_is_active)
{
if (v->driver_shader) {
if (target == GL_VERTEX_PROGRAM_ARB &&
@ -255,7 +255,7 @@ delete_variant(struct st_context *st, struct st_variant *v, GLenum target)
enum pipe_shader_type type =
pipe_shader_type_from_mesa(_mesa_program_enum_to_shader_stage(target));
st_save_zombie_shader(v->st, type, v->driver_shader);
st_save_zombie_shader(v->st, type, v->driver_shader, prog_is_active);
}
}
@ -314,7 +314,7 @@ st_release_variants(struct st_context *st, struct gl_program *p)
for (v = p->variants; v; ) {
struct st_variant *next = v->next;
delete_variant(st, v, p->Target);
delete_variant(st, v, p->Target, p->shader_program == st->ctx->Shader.ActiveProgram);
v = next;
}
@ -1213,7 +1213,7 @@ destroy_program_variants(struct st_context *st, struct gl_program *p)
/* unlink from list */
*prevPtr = next;
/* destroy this variant */
delete_variant(st, v, p->Target);
delete_variant(st, v, p->Target, p->shader_program == st->ctx->Shader.ActiveProgram);
}
else {
prevPtr = &v->next;