video_core/vulkan: Explicity check swapchain size when deciding to recreate

Vulkan for whatever reason does not return VK_ERROR_OUT_OF_DATE_KHR when
the swapchain is the wrong size. Explicity make sure the size is indeed
up to date to workaround this.
This commit is contained in:
Alexander Orzechowski 2022-12-13 13:08:02 -05:00
parent d5f53da79d
commit 3cc3176ad6
3 changed files with 28 additions and 15 deletions

View file

@ -139,23 +139,25 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
RenderScreenshot(*framebuffer, use_accelerated); RenderScreenshot(*framebuffer, use_accelerated);
bool has_been_recreated = false; bool has_been_recreated = false;
const auto recreate_swapchain = [&] { const auto recreate_swapchain = [&](u32 width, u32 height) {
if (!has_been_recreated) { if (!has_been_recreated) {
has_been_recreated = true; has_been_recreated = true;
scheduler.Finish(); scheduler.Finish();
} }
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); swapchain.Create(width, height, is_srgb);
swapchain.Create(layout.width, layout.height, is_srgb);
}; };
if (swapchain.NeedsRecreation(is_srgb)) {
recreate_swapchain(); const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
if (swapchain.NeedsRecreation(is_srgb) || swapchain.GetWidth() != layout.width ||
swapchain.GetHeight() != layout.height) {
recreate_swapchain(layout.width, layout.height);
} }
bool is_outdated; bool is_outdated;
do { do {
swapchain.AcquireNextImage(); swapchain.AcquireNextImage();
is_outdated = swapchain.IsOutDated(); is_outdated = swapchain.IsOutDated();
if (is_outdated) { if (is_outdated) {
recreate_swapchain(); recreate_swapchain(layout.width, layout.height);
} }
} while (is_outdated); } while (is_outdated);
if (has_been_recreated) { if (has_been_recreated) {

View file

@ -67,17 +67,19 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi
} // Anonymous namespace } // Anonymous namespace
Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width, Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_,
u32 height, bool srgb) u32 width_, u32 height_, bool srgb)
: surface{surface_}, device{device_}, scheduler{scheduler_} { : surface{surface_}, device{device_}, scheduler{scheduler_} {
Create(width, height, srgb); Create(width_, height_, srgb);
} }
Swapchain::~Swapchain() = default; Swapchain::~Swapchain() = default;
void Swapchain::Create(u32 width, u32 height, bool srgb) { void Swapchain::Create(u32 width_, u32 height_, bool srgb) {
is_outdated = false; is_outdated = false;
is_suboptimal = false; is_suboptimal = false;
width = width_;
height = height_;
const auto physical_device = device.GetPhysical(); const auto physical_device = device.GetPhysical();
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)};
@ -88,7 +90,7 @@ void Swapchain::Create(u32 width, u32 height, bool srgb) {
device.GetLogical().WaitIdle(); device.GetLogical().WaitIdle();
Destroy(); Destroy();
CreateSwapchain(capabilities, width, height, srgb); CreateSwapchain(capabilities, srgb);
CreateSemaphores(); CreateSemaphores();
CreateImageViews(); CreateImageViews();
@ -148,8 +150,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
} }
} }
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) {
bool srgb) {
const auto physical_device{device.GetPhysical()}; const auto physical_device{device.GetPhysical()};
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; const auto formats{physical_device.GetSurfaceFormatsKHR(surface)};
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)};

View file

@ -80,9 +80,16 @@ public:
return *present_semaphores[frame_index]; return *present_semaphores[frame_index];
} }
u32 GetWidth() const {
return width;
}
u32 GetHeight() const {
return height;
}
private: private:
void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb);
bool srgb);
void CreateSemaphores(); void CreateSemaphores();
void CreateImageViews(); void CreateImageViews();
@ -105,6 +112,9 @@ private:
std::vector<u64> resource_ticks; std::vector<u64> resource_ticks;
std::vector<vk::Semaphore> present_semaphores; std::vector<vk::Semaphore> present_semaphores;
u32 width;
u32 height;
u32 image_index{}; u32 image_index{};
u32 frame_index{}; u32 frame_index{};