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:
		| @@ -139,23 +139,25 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | ||||
|     RenderScreenshot(*framebuffer, use_accelerated); | ||||
|  | ||||
|     bool has_been_recreated = false; | ||||
|     const auto recreate_swapchain = [&] { | ||||
|     const auto recreate_swapchain = [&](u32 width, u32 height) { | ||||
|         if (!has_been_recreated) { | ||||
|             has_been_recreated = true; | ||||
|             scheduler.Finish(); | ||||
|         } | ||||
|         const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); | ||||
|         swapchain.Create(layout.width, layout.height, is_srgb); | ||||
|         swapchain.Create(width, 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; | ||||
|     do { | ||||
|         swapchain.AcquireNextImage(); | ||||
|         is_outdated = swapchain.IsOutDated(); | ||||
|         if (is_outdated) { | ||||
|             recreate_swapchain(); | ||||
|             recreate_swapchain(layout.width, layout.height); | ||||
|         } | ||||
|     } while (is_outdated); | ||||
|     if (has_been_recreated) { | ||||
|   | ||||
| @@ -67,17 +67,19 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width, | ||||
|                      u32 height, bool srgb) | ||||
| Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, | ||||
|                      u32 width_, u32 height_, bool srgb) | ||||
|     : surface{surface_}, device{device_}, scheduler{scheduler_} { | ||||
|     Create(width, height, srgb); | ||||
|     Create(width_, height_, srgb); | ||||
| } | ||||
|  | ||||
| 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_suboptimal = false; | ||||
|     width = width_; | ||||
|     height = height_; | ||||
|  | ||||
|     const auto physical_device = device.GetPhysical(); | ||||
|     const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; | ||||
| @@ -88,7 +90,7 @@ void Swapchain::Create(u32 width, u32 height, bool srgb) { | ||||
|     device.GetLogical().WaitIdle(); | ||||
|     Destroy(); | ||||
|  | ||||
|     CreateSwapchain(capabilities, width, height, srgb); | ||||
|     CreateSwapchain(capabilities, srgb); | ||||
|     CreateSemaphores(); | ||||
|     CreateImageViews(); | ||||
|  | ||||
| @@ -148,8 +150,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, | ||||
|                                 bool srgb) { | ||||
| void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) { | ||||
|     const auto physical_device{device.GetPhysical()}; | ||||
|     const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; | ||||
|     const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; | ||||
|   | ||||
| @@ -80,9 +80,16 @@ public: | ||||
|         return *present_semaphores[frame_index]; | ||||
|     } | ||||
|  | ||||
|     u32 GetWidth() const { | ||||
|         return width; | ||||
|     } | ||||
|  | ||||
|     u32 GetHeight() const { | ||||
|         return height; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height, | ||||
|                          bool srgb); | ||||
|     void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb); | ||||
|     void CreateSemaphores(); | ||||
|     void CreateImageViews(); | ||||
|  | ||||
| @@ -105,6 +112,9 @@ private: | ||||
|     std::vector<u64> resource_ticks; | ||||
|     std::vector<vk::Semaphore> present_semaphores; | ||||
|  | ||||
|     u32 width; | ||||
|     u32 height; | ||||
|  | ||||
|     u32 image_index{}; | ||||
|     u32 frame_index{}; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user