From 50283109aa2b1a3fd92e92eb1c85426444ef508e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Fri, 25 Aug 2017 09:04:40 +0200 Subject: [PATCH] radeonsi: ensure cache flushes happen before SET_PREDICATION packets MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The data is read when the render_cond_atom is emitted, so we must delay emitting the atom until after the flush. Fixes: 0fe0320dc074 ("radeonsi: use optimal packet order when doing a pipeline sync") Reviewed-by: Marek Olšák --- src/gallium/drivers/radeon/r600_pipe_common.h | 3 ++- src/gallium/drivers/radeon/r600_query.c | 9 ++++++--- src/gallium/drivers/radeonsi/si_state_draw.c | 15 ++++++++++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 9805088bd8f..8c70e91ae03 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -61,7 +61,8 @@ struct u_log_context; /* Pipeline & streamout query controls. */ #define R600_CONTEXT_START_PIPELINE_STATS (1u << 1) #define R600_CONTEXT_STOP_PIPELINE_STATS (1u << 2) -#define R600_CONTEXT_PRIVATE_FLAG (1u << 3) +#define R600_CONTEXT_FLUSH_FOR_RENDER_COND (1u << 3) +#define R600_CONTEXT_PRIVATE_FLAG (1u << 4) /* special primitive types */ #define R600_PRIM_RECTANGLE_LIST PIPE_PRIM_MAX diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c index f937612bc1f..03ff1018a71 100644 --- a/src/gallium/drivers/radeon/r600_query.c +++ b/src/gallium/drivers/radeon/r600_query.c @@ -1835,11 +1835,14 @@ static void r600_render_condition(struct pipe_context *ctx, /* Settings this in the render cond atom is too late, * so set it here. */ - rctx->flags |= rctx->screen->barrier_flags.L2_to_cp; - - atom->num_dw = 5; + rctx->flags |= rctx->screen->barrier_flags.L2_to_cp | + R600_CONTEXT_FLUSH_FOR_RENDER_COND; rctx->render_cond_force_off = old_force_off; + } + + if (needs_workaround) { + atom->num_dw = 5; } else { for (qbuf = &rquery->buffer; qbuf; qbuf = qbuf->previous) atom->num_dw += (qbuf->results_end / rquery->result_size) * 5; diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 1d8be49a480..81751d2186e 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -1392,9 +1392,13 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) * the wait and the draw) */ struct r600_atom *shader_pointers = &sctx->shader_pointers.atom; + unsigned masked_atoms = 1u << shader_pointers->id; - /* Emit all states except shader pointers. */ - si_emit_all_states(sctx, info, 1 << shader_pointers->id); + if (unlikely(sctx->b.flags & R600_CONTEXT_FLUSH_FOR_RENDER_COND)) + masked_atoms |= 1u << sctx->b.render_cond_atom.id; + + /* Emit all states except shader pointers and render condition. */ + si_emit_all_states(sctx, info, masked_atoms); si_emit_cache_flush(sctx); /* <-- CUs are idle here. */ @@ -1402,10 +1406,11 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; /* Set shader pointers after descriptors are uploaded. */ - if (si_is_atom_dirty(sctx, shader_pointers)) { + if (si_is_atom_dirty(sctx, shader_pointers)) shader_pointers->emit(&sctx->b, NULL); - sctx->dirty_atoms = 0; - } + if (si_is_atom_dirty(sctx, &sctx->b.render_cond_atom)) + sctx->b.render_cond_atom.emit(&sctx->b, NULL); + sctx->dirty_atoms = 0; si_emit_draw_packets(sctx, info, indexbuf, index_size, index_offset); /* <-- CUs are busy here. */ -- 2.30.2