Mesa (master): gallium/radeon: unify and simplify checking for an empty gfx IB

Marek Olšák mareko at kemper.freedesktop.org
Thu Aug 25 19:20:00 UTC 2016


Module: Mesa
Branch: master
Commit: fe91ae06d3ecc2080b61a6bc35867653de0da418
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fe91ae06d3ecc2080b61a6bc35867653de0da418

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Thu Aug 25 01:26:54 2016 +0200

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 4447393..58ba09d 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 ab620eb..b1da22f 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 49d1a35..aeccb2d 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);
 




More information about the mesa-commit mailing list