[Mesa-dev] [PATCH] radeonsi: try flushing unflushed fences in si_fence_finish even when timeout == 0

Nicolai Hähnle nhaehnle at gmail.com
Wed Nov 22 16:52:43 UTC 2017


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

Under certain conditions, waiting on a GL sync objects should act like
a flush, regardless of the timeout.

Portal 2, CS:GO, and presumably other Source engine games rely on this
behavior and hang during loading without this fix.

Fixes: bc65dcab3bc4 ("radeonsi: avoid syncing the driver thread in si_fence_finish")
---
 src/gallium/drivers/radeonsi/si_fence.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_fence.c b/src/gallium/drivers/radeonsi/si_fence.c
index 9d6bcfe1027..b835ed649ee 100644
--- a/src/gallium/drivers/radeonsi/si_fence.c
+++ b/src/gallium/drivers/radeonsi/si_fence.c
@@ -184,36 +184,36 @@ static void si_fine_fence_set(struct si_context *ctx,
 static boolean si_fence_finish(struct pipe_screen *screen,
 			       struct pipe_context *ctx,
 			       struct pipe_fence_handle *fence,
 			       uint64_t timeout)
 {
 	struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws;
 	struct si_multi_fence *rfence = (struct si_multi_fence *)fence;
 	int64_t abs_timeout = os_time_get_absolute_timeout(timeout);
 
 	if (!util_queue_fence_is_signalled(&rfence->ready)) {
-		if (!timeout)
-			return false;
-
 		if (rfence->tc_token) {
 			/* Ensure that si_flush_from_st will be called for
 			 * this fence, but only if we're in the API thread
 			 * where the context is current.
 			 *
 			 * Note that the batch containing the flush may already
 			 * be in flight in the driver thread, so the fence
 			 * may not be ready yet when this call returns.
 			 */
 			threaded_context_flush(ctx, rfence->tc_token,
 					       timeout == 0);
 		}
 
+		if (!timeout)
+			return false;
+
 		if (timeout == PIPE_TIMEOUT_INFINITE) {
 			util_queue_fence_wait(&rfence->ready);
 		} else {
 			if (!util_queue_fence_wait_timeout(&rfence->ready, abs_timeout))
 				return false;
 		}
 
 		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