Przeglądaj źródła

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.
Alexander Orzechowski 3 lat temu
rodzic
commit
3cc3176ad6

+ 8 - 6
src/video_core/renderer_vulkan/renderer_vulkan.cpp

@@ -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(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;
     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) {

+ 8 - 7
src/video_core/renderer_vulkan/vk_swapchain.cpp

@@ -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,
-                     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_} {
     : 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,
-                                bool srgb) {
+void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, 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)};

+ 12 - 2
src/video_core/renderer_vulkan/vk_swapchain.h

@@ -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,
-                         bool srgb);
+    void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, 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{};