[Mesa-dev] [PATCH v2 14/26] radeonsi: document some subtle details of fence_finish & fence_server_sync

Nicolai Hähnle nhaehnle at gmail.com
Mon Nov 6 10:23:45 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

v2: remove the change to si_fence_server_sync, we'll handle that more
    robustly

Reviewed-by: Marek Olšák <marek.olsak at amd.com> (v1)
---
 src/gallium/drivers/radeonsi/si_fence.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/src/gallium/drivers/radeonsi/si_fence.c b/src/gallium/drivers/radeonsi/si_fence.c
index 701e8df9cfc..81007192994 100644
--- a/src/gallium/drivers/radeonsi/si_fence.c
+++ b/src/gallium/drivers/radeonsi/si_fence.c
@@ -168,20 +168,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