Vulkan/Context: Acquire swap chain image after presenting

This commit is contained in:
Stenzek 2023-01-06 21:58:26 +10:00 committed by refractionpcsx2
parent 93bd95f4bd
commit 3fa3bc1719
4 changed files with 23 additions and 0 deletions

View File

@ -1268,6 +1268,8 @@ namespace Vulkan
1, present_swap_chain->GetSwapChainPtr(), present_swap_chain->GetCurrentImageIndexPtr(), 1, present_swap_chain->GetSwapChainPtr(), present_swap_chain->GetCurrentImageIndexPtr(),
nullptr}; nullptr};
present_swap_chain->ReleaseCurrentImage();
VkResult res = vkQueuePresentKHR(m_present_queue, &present_info); VkResult res = vkQueuePresentKHR(m_present_queue, &present_info);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
{ {
@ -1276,7 +1278,13 @@ namespace Vulkan
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: "); LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
m_last_present_failed.store(true); m_last_present_failed.store(true);
return;
} }
// 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.
present_swap_chain->AcquireNextImage();
} }
void Context::WaitForPresentComplete() void Context::WaitForPresentComplete()

View File

@ -690,6 +690,7 @@ namespace Vulkan
vkDestroyFramebuffer(g_vulkan_context->GetDevice(), it.framebuffer, nullptr); vkDestroyFramebuffer(g_vulkan_context->GetDevice(), it.framebuffer, nullptr);
} }
m_images.clear(); m_images.clear();
m_image_acquire_result.reset();
} }
void SwapChain::DestroySwapChain() void SwapChain::DestroySwapChain()
@ -705,6 +706,9 @@ namespace Vulkan
VkResult SwapChain::AcquireNextImage() VkResult SwapChain::AcquireNextImage()
{ {
if (m_image_acquire_result.has_value())
return m_image_acquire_result.value();
if (!m_swap_chain) if (!m_swap_chain)
return VK_ERROR_SURFACE_LOST_KHR; return VK_ERROR_SURFACE_LOST_KHR;
@ -723,9 +727,15 @@ namespace Vulkan
} }
} }
m_image_acquire_result = res;
return res; return res;
} }
void SwapChain::ReleaseCurrentImage()
{
m_image_acquire_result.reset();
}
bool SwapChain::ResizeSwapChain(u32 new_width, u32 new_height, float new_scale) bool SwapChain::ResizeSwapChain(u32 new_width, u32 new_height, float new_scale)
{ {
DestroySwapChainImages(); DestroySwapChainImages();

View File

@ -20,6 +20,7 @@
#include "common/Vulkan/Texture.h" #include "common/Vulkan/Texture.h"
#include "common/Vulkan/Loader.h" #include "common/Vulkan/Loader.h"
#include <memory> #include <memory>
#include <optional>
#include <vector> #include <vector>
namespace Vulkan namespace Vulkan
@ -74,6 +75,7 @@ namespace Vulkan
__fi VkSemaphore GetRenderingFinishedSemaphore() const { return m_images[m_current_image].rendering_finished_semaphore; } __fi VkSemaphore GetRenderingFinishedSemaphore() const { return m_images[m_current_image].rendering_finished_semaphore; }
__fi const VkSemaphore* GetRenderingFinishedSemaphorePtr() const { return &m_images[m_current_image].rendering_finished_semaphore; } __fi const VkSemaphore* GetRenderingFinishedSemaphorePtr() const { return &m_images[m_current_image].rendering_finished_semaphore; }
VkResult AcquireNextImage(); VkResult AcquireNextImage();
void ReleaseCurrentImage();
bool RecreateSurface(const WindowInfo& new_wi); bool RecreateSurface(const WindowInfo& new_wi);
bool ResizeSwapChain(u32 new_width = 0, u32 new_height = 0, float new_scale = 1.0f); bool ResizeSwapChain(u32 new_width = 0, u32 new_height = 0, float new_scale = 1.0f);
@ -122,5 +124,6 @@ namespace Vulkan
VkSwapchainKHR m_swap_chain = VK_NULL_HANDLE; VkSwapchainKHR m_swap_chain = VK_NULL_HANDLE;
std::vector<SwapChainImage> m_images; std::vector<SwapChainImage> m_images;
u32 m_current_image = 0; u32 m_current_image = 0;
std::optional<VkResult> m_image_acquire_result;
}; };
} // namespace Vulkan } // namespace Vulkan

View File

@ -353,6 +353,8 @@ bool VulkanHostDisplay::BeginPresent(bool frame_skip)
VkResult res = m_swap_chain->AcquireNextImage(); VkResult res = m_swap_chain->AcquireNextImage();
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
{ {
m_swap_chain->ReleaseCurrentImage();
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR) if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR)
{ {
ResizeWindow(0, 0, m_window_info.surface_scale); ResizeWindow(0, 0, m_window_info.surface_scale);