[Mesa-dev] [PATCH 02/11] radeonsi: drop unfinished shader compilations when destroying shaders
Marek Olšák
maraeo at gmail.com
Thu Jun 1 18:18:20 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
If we enqueue too many jobs and destroy the GL context, it may take
several seconds before the jobs finish. Just drop them instead.
---
src/gallium/drivers/radeonsi/si_compute.c | 3 ++-
src/gallium/drivers/radeonsi/si_state_shaders.c | 5 +++--
src/util/u_queue.c | 5 ++++-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
index 4c98066..0338b8a 100644
--- a/src/gallium/drivers/radeonsi/si_compute.c
+++ b/src/gallium/drivers/radeonsi/si_compute.c
@@ -853,21 +853,22 @@ static void si_launch_grid(
static void si_delete_compute_state(struct pipe_context *ctx, void* state){
struct si_compute *program = (struct si_compute *)state;
struct si_context *sctx = (struct si_context*)ctx;
if (!state) {
return;
}
if (program->ir_type == PIPE_SHADER_IR_TGSI) {
- util_queue_fence_wait(&program->ready);
+ util_queue_drop_job(&sctx->screen->shader_compiler_queue,
+ &program->ready);
util_queue_fence_destroy(&program->ready);
}
if (program == sctx->cs_shader_state.program)
sctx->cs_shader_state.program = NULL;
if (program == sctx->cs_shader_state.emitted_program)
sctx->cs_shader_state.emitted_program = NULL;
si_shader_destroy(&program->shader);
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 8ac4309..62bb221 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -2251,21 +2251,22 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
sctx->do_update_shaders = true;
if (sel && sctx->ia_multi_vgt_param_key.u.uses_tess)
si_update_tess_uses_prim_id(sctx);
si_mark_atom_dirty(sctx, &sctx->cb_render_state);
si_set_active_descriptors_for_shader(sctx, sel);
}
static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
{
if (shader->is_optimized) {
- util_queue_fence_wait(&shader->optimized_ready);
+ util_queue_drop_job(&sctx->screen->shader_compiler_queue,
+ &shader->optimized_ready);
util_queue_fence_destroy(&shader->optimized_ready);
}
if (shader->pm4) {
switch (shader->selector->type) {
case PIPE_SHADER_VERTEX:
if (shader->key.as_ls) {
assert(sctx->b.chip_class <= VI);
si_pm4_delete_state(sctx, ls, shader->pm4);
} else if (shader->key.as_es) {
@@ -2308,21 +2309,21 @@ static void si_destroy_shader_selector(struct si_context *sctx,
{
struct si_shader *p = sel->first_variant, *c;
struct si_shader_ctx_state *current_shader[SI_NUM_SHADERS] = {
[PIPE_SHADER_VERTEX] = &sctx->vs_shader,
[PIPE_SHADER_TESS_CTRL] = &sctx->tcs_shader,
[PIPE_SHADER_TESS_EVAL] = &sctx->tes_shader,
[PIPE_SHADER_GEOMETRY] = &sctx->gs_shader,
[PIPE_SHADER_FRAGMENT] = &sctx->ps_shader,
};
- util_queue_fence_wait(&sel->ready);
+ util_queue_drop_job(&sctx->screen->shader_compiler_queue, &sel->ready);
if (current_shader[sel->type]->cso == sel) {
current_shader[sel->type]->cso = NULL;
current_shader[sel->type]->current = NULL;
}
while (p) {
c = p->next_variant;
si_delete_shader(sctx, p);
p = c;
diff --git a/src/util/u_queue.c b/src/util/u_queue.c
index 3834b6f..99de34c 100644
--- a/src/util/u_queue.c
+++ b/src/util/u_queue.c
@@ -346,21 +346,24 @@ util_queue_drop_job(struct util_queue *queue, struct util_queue_fence *fence)
{
bool removed = false;
if (util_queue_fence_is_signalled(fence))
return;
mtx_lock(&queue->lock);
for (unsigned i = queue->read_idx; i != queue->write_idx;
i = (i + 1) % queue->max_jobs) {
if (queue->jobs[i].fence == fence) {
- /* Just clear it. The threads will drop it. */
+ if (queue->jobs[i].cleanup)
+ queue->jobs[i].cleanup(queue->jobs[i].job, -1);
+
+ /* Just clear it. The threads will treat as a no-op job. */
memset(&queue->jobs[i], 0, sizeof(queue->jobs[i]));
removed = true;
break;
}
}
mtx_unlock(&queue->lock);
if (removed)
util_queue_fence_signal(fence);
else
--
2.7.4
More information about the mesa-dev
mailing list