From: Nicolai Hähnle <nicolai.haeh...@amd.com> --- src/gallium/drivers/radeonsi/si_fence.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/src/gallium/drivers/radeonsi/si_fence.c b/src/gallium/drivers/radeonsi/si_fence.c index c51efad7106..b7b02b55831 100644 --- a/src/gallium/drivers/radeonsi/si_fence.c +++ b/src/gallium/drivers/radeonsi/si_fence.c @@ -111,22 +111,29 @@ static void si_fence_server_sync(struct pipe_context *ctx, util_queue_fence_wait(&rfence->ready); /* Only imported fences need to be handled by fence_server_sync, * because the winsys handles synchronizations automatically for BOs * within the process. * * Simply skip unflushed fences here, and the winsys will drop no-op * dependencies (i.e. dependencies within the same ring). */ - if (rfence->gfx_unflushed.ctx) + if (rfence->gfx_unflushed.ctx) { + /* It is an application error to call glWaitSync for an + * unflushed fence from a different context, since it could + * cause a deadlock. Conceptually, it would be more correct to + * just hang here in that case. + */ + assert(rfence->gfx_unflushed.ctx == rctx); return; + } /* All unflushed commands will not start execution before * this fence dependency is signalled. * * Should we flush the context to allow more GPU parallelism? */ if (rfence->sdma) si_add_fence_dependency(rctx, rfence->sdma); if (rfence->gfx) si_add_fence_dependency(rctx, rfence->gfx); @@ -182,20 +189,42 @@ static boolean si_fence_finish(struct pipe_screen *screen, } } if (!rfence->gfx) return true; /* Flush the gfx IB if it hasn't been flushed yet. */ if (rctx && rfence->gfx_unflushed.ctx == rctx && rfence->gfx_unflushed.ib_index == rctx->num_gfx_cs_flushes) { + /* Section 4.1.2 (Signaling) of the OpenGL 4.6 (Core profile) + * spec says: + * + * "If the sync object being blocked upon will not be + * signaled in finite time (for example, by an associated + * fence command issued previously, but not yet flushed to + * the graphics pipeline), then ClientWaitSync may hang + * forever. To help prevent this behavior, if + * ClientWaitSync is called and all of the following are + * true: + * + * * the SYNC_FLUSH_COMMANDS_BIT bit is set in flags, + * * sync is unsignaled when ClientWaitSync is called, + * * and the calls to ClientWaitSync and FenceSync were + * issued from the same context, + * + * then the GL will behave as if the equivalent of Flush + * were inserted immediately after the creation of sync." + * + * This means we need to flush for such fences even when we're + * not going to wait. + */ rctx->gfx.flush(rctx, timeout ? 0 : RADEON_FLUSH_ASYNC, NULL); rfence->gfx_unflushed.ctx = NULL; if (!timeout) return false; /* Recompute the timeout after all that. */ if (timeout && timeout != PIPE_TIMEOUT_INFINITE) { int64_t time = os_time_get_nano(); timeout = abs_timeout > time ? abs_timeout - time : 0; -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev