diff --git a/src/util/vulkan_device.cpp b/src/util/vulkan_device.cpp index db86e5e70..326846819 100644 --- a/src/util/vulkan_device.cpp +++ b/src/util/vulkan_device.cpp @@ -1272,7 +1272,7 @@ void VulkanDevice::SubmitCommandBuffer(VulkanSwapChain* present_swap_chain /* = { DoSubmitCommandBuffer(m_current_frame, present_swap_chain); if (present_swap_chain) - DoPresent(present_swap_chain, false); + DoPresent(present_swap_chain); return; } @@ -1317,7 +1317,7 @@ void VulkanDevice::DoSubmitCommandBuffer(u32 index, VulkanSwapChain* present_swa } } -void VulkanDevice::DoPresent(VulkanSwapChain* present_swap_chain, bool acquire_next) +void VulkanDevice::DoPresent(VulkanSwapChain* present_swap_chain) { const VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, nullptr, @@ -1344,8 +1344,7 @@ void VulkanDevice::DoPresent(VulkanSwapChain* present_swap_chain, bool acquire_n // Grab the next image as soon as possible, that way we spend less time blocked on the next // submission. Don't care if it fails, we'll deal with that at the presentation call site. // Credit to dxvk for the idea. - if (acquire_next) - present_swap_chain->AcquireNextImage(); + present_swap_chain->AcquireNextImage(); } void VulkanDevice::WaitForPresentComplete() @@ -1379,7 +1378,7 @@ void VulkanDevice::PresentThread() DoSubmitCommandBuffer(m_queued_present.command_buffer_index, m_queued_present.swap_chain); if (m_queued_present.swap_chain) - DoPresent(m_queued_present.swap_chain, true); + DoPresent(m_queued_present.swap_chain); m_present_done.store(true, std::memory_order_release); m_present_done_cv.notify_one(); } diff --git a/src/util/vulkan_device.h b/src/util/vulkan_device.h index cef3c54fb..38517b5e4 100644 --- a/src/util/vulkan_device.h +++ b/src/util/vulkan_device.h @@ -379,7 +379,7 @@ private: void WaitForCommandBufferCompletion(u32 index); void DoSubmitCommandBuffer(u32 index, VulkanSwapChain* present_swap_chain); - void DoPresent(VulkanSwapChain* present_swap_chain, bool acquire_next); + void DoPresent(VulkanSwapChain* present_swap_chain); void WaitForPresentComplete(std::unique_lock& lock); void PresentThread(); void StartPresentThread(); diff --git a/src/util/vulkan_swap_chain.cpp b/src/util/vulkan_swap_chain.cpp index 81c302a07..78af7250e 100644 --- a/src/util/vulkan_swap_chain.cpp +++ b/src/util/vulkan_swap_chain.cpp @@ -534,9 +534,13 @@ bool VulkanSwapChain::CreateSwapChain() m_images.push_back(image); } - m_semaphores.reserve(image_count); - m_current_semaphore = (image_count - 1); - for (u32 i = 0; i < image_count; i++) + // We don't actually need +1 semaphores, or, more than one really. + // But, the validation layer gets cranky if we don't fence wait before the next image acquire. + // So, add an additional semaphore to ensure that we're never acquiring before fence waiting. + const u32 semaphore_count = image_count + 1; + m_semaphores.reserve(semaphore_count); + m_current_semaphore = 0; + for (u32 i = 0; i < semaphore_count; i++) { ImageSemaphores sema;