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)
{
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
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);