From fe91ae06d3ecc2080b61a6bc35867653de0da418 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 25 Aug 2016 01:26:54 +0200 Subject: [PATCH] gallium/radeon: unify and simplify checking for an empty gfx IB We can take advantage of the fact that multi_fence does the obvious thing with NULL fences. This fixes unflushed fences that can get stuck due to empty IBs. --- src/gallium/drivers/r600/r600_hw_context.c | 8 +---- src/gallium/drivers/radeon/r600_pipe_common.c | 29 ++++++++++++------- src/gallium/drivers/radeonsi/si_hw_context.c | 13 ++------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 444739315ed..58ba09d1014 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -255,14 +255,8 @@ void r600_context_gfx_flush(void *context, unsigned flags, struct radeon_winsys_cs *cs = ctx->b.gfx.cs; struct radeon_winsys *ws = ctx->b.ws; - if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size) && - (!fence || ctx->b.last_gfx_fence)) { - if (fence) - ws->fence_reference(fence, ctx->b.last_gfx_fence); - if (!(flags & RADEON_FLUSH_ASYNC)) - ws->cs_sync_flush(cs); + if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size)) return; - } r600_preflush_suspend_features(&ctx->b); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index ab620eb779f..b1da22f0fd5 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -265,6 +265,7 @@ 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; @@ -279,26 +280,34 @@ static void r600_flush_from_st(struct pipe_context *ctx, rctx->dma.flush(rctx, rflags, fence ? &sdma_fence : NULL); } - /* 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; + 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)) + ws->cs_sync_flush(rctx->gfx.cs); } else { - rctx->gfx.flush(rctx, rflags, fence ? &gfx_fence : NULL); + /* 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; + } else { + rctx->gfx.flush(rctx, rflags, fence ? &gfx_fence : NULL); + } } /* Both engines can signal out of order, so we need to keep both fences. */ - if (gfx_fence || sdma_fence) { + if (fence) { struct r600_multi_fence *multi_fence = CALLOC_STRUCT(r600_multi_fence); if (!multi_fence) return; multi_fence->reference.count = 1; + /* If both fences are NULL, fence_finish will always return true. */ multi_fence->gfx = gfx_fence; multi_fence->sdma = sdma_fence; diff --git a/src/gallium/drivers/radeonsi/si_hw_context.c b/src/gallium/drivers/radeonsi/si_hw_context.c index 49d1a35a618..aeccb2d85f2 100644 --- a/src/gallium/drivers/radeonsi/si_hw_context.c +++ b/src/gallium/drivers/radeonsi/si_hw_context.c @@ -100,17 +100,10 @@ void si_context_gfx_flush(void *context, unsigned flags, if (ctx->gfx_flush_in_progress) return; - ctx->gfx_flush_in_progress = true; - - if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size) && - (!fence || ctx->b.last_gfx_fence)) { - if (fence) - ws->fence_reference(fence, ctx->b.last_gfx_fence); - if (!(flags & RADEON_FLUSH_ASYNC)) - ws->cs_sync_flush(cs); - ctx->gfx_flush_in_progress = false; + if (!radeon_emitted(cs, ctx->b.initial_gfx_cs_size)) return; - } + + ctx->gfx_flush_in_progress = true; r600_preflush_suspend_features(&ctx->b); -- 2.30.2