mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-29 19:44:17 +01:00
Fix waitForFences
crash on Mali drivers
Mali GPU drivers utilize the `ppoll()` syscall inside `waitForFences` which isn't correctly restarted after a signal, which we can receive at any time on a guest thread. This commit fixes that by recursively calling the function on failure till it succeeds or returns an unexpected error. Co-authored-by: PixelyIon <pixelyion@protonmail.com> Co-authored-by: Billy Laws <blaws05@gmail.com>
This commit is contained in:
parent
942e22f275
commit
cbc896c8f8
@ -68,7 +68,20 @@ namespace skyline::gpu {
|
||||
void Wait() {
|
||||
if (signalled.test(std::memory_order_consume))
|
||||
return;
|
||||
while (device.waitForFences(fence, false, std::numeric_limits<u64>::max()) != vk::Result::eSuccess);
|
||||
|
||||
vk::Result waitResult;
|
||||
while ((waitResult = (*device).waitForFences(1, &fence, false, std::numeric_limits<u64>::max(), *device.getDispatcher())) != vk::Result::eSuccess) {
|
||||
if (waitResult == vk::Result::eTimeout)
|
||||
// Retry if the waiting time out
|
||||
continue;
|
||||
|
||||
if (waitResult == vk::Result::eErrorInitializationFailed)
|
||||
// eErrorInitializationFailed occurs on Mali GPU drivers due to them using the ppoll() syscall which isn't correctly restarted after a signal, we need to manually retry waiting in that case
|
||||
continue;
|
||||
|
||||
throw exception("An error occurred while waiting for fence 0x{:X}: {}", static_cast<VkFence>(fence), vk::to_string(waitResult));
|
||||
}
|
||||
|
||||
if (!signalled.test_and_set(std::memory_order_release))
|
||||
DestroyDependencies();
|
||||
}
|
||||
@ -80,7 +93,7 @@ namespace skyline::gpu {
|
||||
bool Wait(std::chrono::duration<u64, std::nano> timeout) {
|
||||
if (signalled.test(std::memory_order_consume))
|
||||
return true;
|
||||
if (device.waitForFences(fence, false, timeout.count()) == vk::Result::eSuccess) {
|
||||
if ((*device).waitForFences(1, &fence, false, std::numeric_limits<u64>::max(), *device.getDispatcher()) == vk::Result::eSuccess) {
|
||||
if (!signalled.test_and_set(std::memory_order_release))
|
||||
DestroyDependencies();
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user