mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-25 19:47:06 +02:00
[vk] Fix lost wakeup in fence mode using atomic wait (#3598)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3598 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com> Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
This commit is contained in:
parent
83cdeed3c4
commit
40251c2115
2 changed files with 15 additions and 25 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
|
@ -78,11 +78,16 @@ void MasterSemaphore::Refresh() {
|
||||||
|
|
||||||
void MasterSemaphore::Wait(u64 tick) {
|
void MasterSemaphore::Wait(u64 tick) {
|
||||||
if (!semaphore) {
|
if (!semaphore) {
|
||||||
// If we don't support timeline semaphores, wait for the value normally
|
// Fast check: already reached the requested tick?
|
||||||
std::unique_lock lk{free_mutex};
|
if (gpu_tick.load(std::memory_order_acquire) >= tick) {
|
||||||
free_cv.wait(lk, [&] {
|
return;
|
||||||
return gpu_tick.load(std::memory_order_acquire) >= tick;
|
}
|
||||||
});
|
|
||||||
|
u64 last_tick = gpu_tick.load(std::memory_order_relaxed);
|
||||||
|
while (gpu_tick.load(std::memory_order_acquire) < tick) {
|
||||||
|
gpu_tick.wait(last_tick, std::memory_order_acquire);
|
||||||
|
last_tick = gpu_tick.load(std::memory_order_relaxed);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,32 +223,15 @@ void MasterSemaphore::WaitThread(std::stop_token token) {
|
||||||
wait_queue.pop();
|
wait_queue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
VkResult status;
|
|
||||||
do {
|
|
||||||
status = fence.GetStatus();
|
|
||||||
if (status == VK_NOT_READY) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
|
||||||
}
|
|
||||||
} while (status == VK_NOT_READY);
|
|
||||||
|
|
||||||
if (status == VK_SUCCESS) {
|
|
||||||
fence.Reset();
|
|
||||||
} else {
|
|
||||||
vk::Check(status);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
fence.Wait();
|
fence.Wait();
|
||||||
fence.Reset();
|
fence.Reset();
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{free_mutex};
|
std::scoped_lock lock{free_mutex};
|
||||||
free_queue.push_front(std::move(fence));
|
free_queue.push_front(std::move(fence));
|
||||||
gpu_tick.store(host_tick, std::memory_order_release);
|
gpu_tick.store(host_tick, std::memory_order_release);
|
||||||
}
|
}
|
||||||
free_cv.notify_all();
|
gpu_tick.notify_one();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
|
@ -74,7 +77,6 @@ private:
|
||||||
std::atomic<u64> current_tick{1}; ///< Current logical tick.
|
std::atomic<u64> current_tick{1}; ///< Current logical tick.
|
||||||
std::mutex wait_mutex;
|
std::mutex wait_mutex;
|
||||||
std::mutex free_mutex;
|
std::mutex free_mutex;
|
||||||
std::condition_variable free_cv;
|
|
||||||
std::condition_variable_any wait_cv;
|
std::condition_variable_any wait_cv;
|
||||||
std::queue<Waitable> wait_queue; ///< Queue for the fences to be waited on by the wait thread.
|
std::queue<Waitable> wait_queue; ///< Queue for the fences to be waited on by the wait thread.
|
||||||
std::deque<vk::Fence> free_queue; ///< Holds available fences for submission.
|
std::deque<vk::Fence> free_queue; ///< Holds available fences for submission.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue