zink: unset ctx->program pointers when an unref destroys the object

if we destroy a program object which is currently the "active" program then
we need to unset the pointer to avoid invalid access

also unset injected tcs pointers where appropriate

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9470>
This commit is contained in:
Mike Blumenkrantz 2020-12-13 17:47:26 -05:00 committed by Marge Bot
parent ddb807e5c9
commit 46b356ca2d
2 changed files with 22 additions and 6 deletions

View File

@ -65,10 +65,14 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
set_foreach(batch->programs, entry) {
if (batch->batch_id == ZINK_COMPUTE_BATCH_ID) {
struct zink_compute_program *comp = (struct zink_compute_program*)entry->key;
zink_compute_program_reference(screen, &comp, NULL);
bool in_use = comp == ctx->curr_compute;
if (zink_compute_program_reference(screen, &comp, NULL) && in_use)
ctx->curr_compute = NULL;
} else {
struct zink_gfx_program *prog = (struct zink_gfx_program*)entry->key;
zink_gfx_program_reference(screen, &prog, NULL);
bool in_use = prog == ctx->curr_program;
if (zink_gfx_program_reference(screen, &prog, NULL) && in_use)
ctx->curr_program = NULL;
}
_mesa_set_remove(batch->programs, entry);
}

View File

@ -711,15 +711,27 @@ zink_shader_free(struct zink_context *ctx, struct zink_shader *shader)
struct zink_compute_program *comp = (void*)entry->key;
_mesa_hash_table_remove_key(ctx->compute_program_cache, &comp->shader->shader_id);
comp->shader = NULL;
zink_compute_program_reference(screen, &comp, NULL);
bool in_use = comp == ctx->curr_compute;
if (in_use)
ctx->compute_stage = NULL;
if (zink_compute_program_reference(screen, &comp, NULL) && in_use)
ctx->curr_compute = NULL;
} else {
struct zink_gfx_program *prog = (void*)entry->key;
_mesa_hash_table_remove_key(ctx->program_cache, prog->shaders);
prog->shaders[pipe_shader_type_from_mesa(shader->nir->info.stage)] = NULL;
enum pipe_shader_type pstage = pipe_shader_type_from_mesa(shader->nir->info.stage);
bool in_use = prog == ctx->curr_program;
if (shader->nir->info.stage != MESA_SHADER_TESS_CTRL || !shader->is_generated)
_mesa_hash_table_remove_key(ctx->program_cache, prog->shaders);
prog->shaders[pstage] = NULL;
if (shader->nir->info.stage == MESA_SHADER_TESS_EVAL && shader->generated)
/* automatically destroy generated tcs shaders when tes is destroyed */
zink_shader_free(ctx, shader->generated);
zink_gfx_program_reference(screen, &prog, NULL);
if (in_use) {
ctx->gfx_pipeline_state.modules[pstage] = VK_NULL_HANDLE;
ctx->gfx_stages[pstage] = NULL;
}
if (zink_gfx_program_reference(screen, &prog, NULL) && in_use)
ctx->curr_program = NULL;
}
}
_mesa_set_destroy(shader->programs, NULL);