summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/r600_pipe_common.c
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2016-08-25 01:26:54 +0200
committerMarek Olšák <marek.olsak@amd.com>2016-08-25 21:19:17 +0200
commitfe91ae06d3ecc2080b61a6bc35867653de0da418 (patch)
tree75c65d7de7807da4a8826193477b1ee8c742cb7b /src/gallium/drivers/radeon/r600_pipe_common.c
parente6673e7ac285e013ba25ce0e8c5bba691b1cdf3e (diff)
downloadexternal_mesa3d-fe91ae06d3ecc2080b61a6bc35867653de0da418.zip
external_mesa3d-fe91ae06d3ecc2080b61a6bc35867653de0da418.tar.gz
external_mesa3d-fe91ae06d3ecc2080b61a6bc35867653de0da418.tar.bz2
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.c29
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 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;