summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_hw_context.c20
2 files changed, 18 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 35d3e7b16bd..f6e49f2e663 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -355,9 +355,9 @@ static void r600_flush_from_st(struct pipe_context *ctx,
if (flags & PIPE_FLUSH_DEFERRED)
rflags |= RADEON_FLUSH_ASYNC;
- if (rctx->dma.cs) {
+ /* DMA IBs are preambles to gfx IBs, therefore must be flushed first. */
+ if (rctx->dma.cs)
rctx->dma.flush(rctx, rflags, fence ? &sdma_fence : NULL);
- }
if (!radeon_emitted(rctx->gfx.cs, rctx->initial_gfx_cs_size)) {
if (fence)
diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c
index 87ba31659b0..57eaac9dadc 100644
--- a/src/gallium/drivers/radeonsi/si_hw_context.c
+++ b/src/gallium/drivers/radeonsi/si_hw_context.c
@@ -62,11 +62,13 @@ void si_need_cs_space(struct si_context *ctx)
{
struct radeon_winsys_cs *cs = ctx->b.gfx.cs;
struct radeon_winsys_cs *ce_ib = ctx->ce_ib;
- struct radeon_winsys_cs *dma = ctx->b.dma.cs;
- /* Flush the DMA IB if it's not empty. */
- if (radeon_emitted(dma, 0))
- ctx->b.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+ /* There is no need to flush the DMA IB here, because
+ * r600_need_dma_space always flushes the GFX IB if there is
+ * a conflict, which means any unflushed DMA commands automatically
+ * precede the GFX IB (= they had no dependency on the GFX IB when
+ * they were submitted).
+ */
/* There are two memory usage counters in the winsys for all buffers
* that have been added (cs_add_buffer) and two counters in the pipe
@@ -106,6 +108,16 @@ void si_context_gfx_flush(void *context, unsigned flags,
if (r600_check_device_reset(&ctx->b))
return;
+ /* If the state tracker is flushing the GFX IB, r600_flush_from_st is
+ * responsible for flushing the DMA IB and merging the fences from both.
+ * This code is only needed when the driver flushes the GFX IB
+ * internally, and it never asks for a fence handle.
+ */
+ if (radeon_emitted(ctx->b.dma.cs, 0)) {
+ assert(fence == NULL); /* internal flushes only */
+ ctx->b.dma.flush(ctx, flags, NULL);
+ }
+
ctx->gfx_flush_in_progress = true;
r600_preflush_suspend_features(&ctx->b);