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

Reply via email to