diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index de9f466110..7ad70d64e0 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2831,7 +2831,7 @@ void VKGSRender::reinitialize_swapchain() //Flush the command buffer close_and_submit_command_buffer({}, resize_fence); - CHECK_RESULT(vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX)); + vk::wait_for_fence(resize_fence); vkDestroyFence((*m_device), resize_fence, nullptr); m_current_command_buffer->reset(); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 82b75f74e5..4635a301a2 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -130,8 +130,7 @@ struct command_buffer_chunk: public vk::command_buffer if (!pending) return; - // NOTE: vkWaitForFences is slower than polling fence status at least on NV - while (vkGetFenceStatus(m_device, submit_fence) == VK_NOT_READY); + vk::wait_for_fence(submit_fence); lock.upgrade(); diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 3b21142766..9c09a47bdb 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -585,6 +585,21 @@ namespace vk { CHECK_RESULT(vkResetFences(*g_current_renderer, 1, pFence)); } + } + + void wait_for_fence(VkFence fence) + { + while (auto status = vkGetFenceStatus(*g_current_renderer, fence)) + { + switch (status) + { + case VK_NOT_READY: + continue; + default: + die_with_error(HERE, status); + return; + } + } } void die_with_error(const char* faulting_addr, VkResult error_code) diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index d01aa621de..0e5a55e91c 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -171,6 +171,7 @@ namespace vk //Fence reset with driver workarounds in place void reset_fence(VkFence *pFence); + void wait_for_fence(VkFence pFence); void die_with_error(const char* faulting_addr, VkResult error_code); @@ -1152,7 +1153,7 @@ namespace vk { if (m_submit_fence && is_pending) { - while (vkGetFenceStatus(pool->get_owner(), m_submit_fence) != VK_SUCCESS); + wait_for_fence(m_submit_fence); is_pending = false; CHECK_RESULT(vkResetFences(pool->get_owner(), 1, &m_submit_fence)); @@ -1196,6 +1197,7 @@ namespace vk if (fence == VK_NULL_HANDLE) { fence = m_submit_fence; + is_pending = (fence != VK_NULL_HANDLE); } VkSubmitInfo infos = {}; @@ -1209,8 +1211,6 @@ namespace vk acquire_global_submit_lock(); CHECK_RESULT(vkQueueSubmit(queue, 1, &infos, fence)); release_global_submit_lock(); - - is_pending = true; } }; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 5a8713b795..0d18dc0470 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -268,9 +268,9 @@ namespace vk cmd.submit(submit_queue, {}, dma_fence, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); //Now we need to restart the command-buffer to restore it to the way it was before... - CHECK_RESULT(vkWaitForFences(*m_device, 1, &dma_fence, VK_TRUE, UINT64_MAX)); - CHECK_RESULT(vkResetCommandBuffer(cmd, 0)); + vk::wait_for_fence(dma_fence); vk::reset_fence(&dma_fence); + CHECK_RESULT(vkResetCommandBuffer(cmd, 0)); if (cmd.access_hint != vk::command_buffer::access_type_hint::all) cmd.begin();