diff options
author | Marek Olšák <[email protected]> | 2016-08-25 01:26:54 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-08-25 21:19:17 +0200 |
commit | fe91ae06d3ecc2080b61a6bc35867653de0da418 (patch) | |
tree | 75c65d7de7807da4a8826193477b1ee8c742cb7b /src/gallium/drivers/radeon/r600_pipe_common.c | |
parent | e6673e7ac285e013ba25ce0e8c5bba691b1cdf3e (diff) |
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.
Diffstat (limited to 'src/gallium/drivers/radeon/r600_pipe_common.c')
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.c | 29 |
1 files changed, 19 insertions, 10 deletions
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; |