From 95d849e1f658efcae7588549d8d329b786883518 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 22 Oct 2022 13:25:51 +0100 Subject: [PATCH] Check FenceCycle signalled flag immediately before waiting The lock release within the wait for submission means that another thread could end up signalling the cycle and then the VK wait still happen after when the lock has been reacquired. --- app/src/main/cpp/skyline/gpu/fence_cycle.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/fence_cycle.h b/app/src/main/cpp/skyline/gpu/fence_cycle.h index 04762e29..938a5d67 100644 --- a/app/src/main/cpp/skyline/gpu/fence_cycle.h +++ b/app/src/main/cpp/skyline/gpu/fence_cycle.h @@ -132,14 +132,15 @@ namespace skyline::gpu { }); std::unique_lock lock{mutex}; + + submitCondition.wait(lock, [&] { return submitted; }); + if (signalled.test(std::memory_order_relaxed)) { if (shouldDestroy) DestroyDependencies(); return; } - submitCondition.wait(lock, [&] { return submitted; }); - vk::Result waitResult; while ((waitResult = (*device).waitForFences(1, &fence, false, std::numeric_limits::max(), *device.getDispatcher())) != vk::Result::eSuccess) { if (waitResult == vk::Result::eTimeout) @@ -227,7 +228,7 @@ namespace skyline::gpu { * @param cycle The cycle to chain to this one, this is nullable and this function will be a no-op if this is nullptr */ void ChainCycle(const std::shared_ptr &cycle) { - if (cycle && !signalled.test(std::memory_order_consume) && cycle.get() != this) + if (cycle && !signalled.test(std::memory_order_consume) && cycle.get() != this && !cycle->Poll()) chainedCycles.Append(cycle); // If the cycle isn't the current cycle or already signalled, we need to chain it }