gallium/radeon: always flush asynchronously and wait after begin_new_cs
authorMarek Olšák <marek.olsak@amd.com>
Thu, 13 Apr 2017 21:46:59 +0000 (23:46 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 16 Apr 2017 23:22:11 +0000 (01:22 +0200)
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.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeonsi/si_hw_context.c

index 47d4058e60a1888bee0f5647c178a27a17e1807b..ce84139a2f6b5791331cd5ca291c9e167e62de75 100644 (file)
@@ -366,15 +366,13 @@ static void r600_flush_from_st(struct pipe_context *ctx,
        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)
@@ -383,7 +381,7 @@ static void r600_flush_from_st(struct pipe_context *ctx,
        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:
@@ -419,6 +417,12 @@ static void r600_flush_from_st(struct pipe_context *ctx,
                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,
index e51abfc5c53989a81e1fb96bf6250477d42b023b..e15f6a9cc69bcb663219515cd5ff96f343cf9877 100644 (file)
@@ -108,6 +108,9 @@ void si_context_gfx_flush(void *context, unsigned flags,
        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