From: Marek Olšák <marek.ol...@amd.com> This hides the overhead of everything in the driver after the CS flush and before returning from pipe_context::flush. Only microbenchmarks will benefit.
+2% FPS for glxgears. --- src/gallium/drivers/radeon/r600_pipe_common.c | 12 ++++++++---- src/gallium/drivers/radeonsi/si_hw_context.c | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 47d4058..ce84139 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -359,38 +359,36 @@ void r600_postflush_resume_features(struct r600_common_context *ctx) r600_resume_queries(ctx); } static void r600_flush_from_st(struct pipe_context *ctx, struct pipe_fence_handle **fence, unsigned flags) { struct pipe_screen *screen = ctx->screen; struct r600_common_context *rctx = (struct r600_common_context *)ctx; struct radeon_winsys *ws = rctx->ws; - unsigned rflags = 0; struct pipe_fence_handle *gfx_fence = NULL; struct pipe_fence_handle *sdma_fence = NULL; bool deferred_fence = false; + unsigned rflags = RADEON_FLUSH_ASYNC; if (flags & PIPE_FLUSH_END_OF_FRAME) rflags |= RADEON_FLUSH_END_OF_FRAME; - if (flags & PIPE_FLUSH_DEFERRED) - rflags |= RADEON_FLUSH_ASYNC; /* 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) ws->fence_reference(&gfx_fence, rctx->last_gfx_fence); - if (!(rflags & RADEON_FLUSH_ASYNC)) + if (!(flags & PIPE_FLUSH_DEFERRED)) ws->cs_sync_flush(rctx->gfx.cs); } else { /* Instead of flushing, create a deferred fence. Constraints: * - The state tracker must allow a deferred flush. * - The state tracker must request a fence. * Thread safety in fence_finish must be ensured by the state tracker. */ if (flags & PIPE_FLUSH_DEFERRED && fence) { gfx_fence = rctx->ws->cs_get_next_fence(rctx->gfx.cs); deferred_fence = true; @@ -412,20 +410,26 @@ static void r600_flush_from_st(struct pipe_context *ctx, multi_fence->sdma = sdma_fence; if (deferred_fence) { multi_fence->gfx_unflushed.ctx = rctx; multi_fence->gfx_unflushed.ib_index = rctx->num_gfx_cs_flushes; } screen->fence_reference(screen, fence, NULL); *fence = (struct pipe_fence_handle*)multi_fence; } + + if (!(flags & PIPE_FLUSH_DEFERRED)) { + if (rctx->dma.cs) + ws->cs_sync_flush(rctx->dma.cs); + ws->cs_sync_flush(rctx->gfx.cs); + } } static void r600_flush_dma_ring(void *ctx, unsigned flags, struct pipe_fence_handle **fence) { struct r600_common_context *rctx = (struct r600_common_context *)ctx; struct radeon_winsys_cs *cs = rctx->dma.cs; struct radeon_saved_cs saved; bool check_vm = (rctx->screen->debug_flags & DBG_CHECK_VM) && diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index e51abfc..e15f6a9 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -101,20 +101,23 @@ void si_context_gfx_flush(void *context, unsigned flags, if (ctx->gfx_flush_in_progress) return; if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size)) return; if (r600_check_device_reset(&ctx->b)) return; + if (ctx->screen->b.debug_flags & DBG_CHECK_VM) + flags &= ~RADEON_FLUSH_ASYNC; + /* 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); } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev