[Mesa-dev] [PATCH 13/25] radeonsi: document some subtle details of fence_finish & fence_server_sync
Nicolai Hähnle
nhaehnle at gmail.com
Sun Oct 22 19:07:56 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at 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
More information about the mesa-dev
mailing list