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); |     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) { | ||||||
|   | |||||||
| @@ -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)}; | ||||||
|   | |||||||
| @@ -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{}; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user