summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp11
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp26
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.h14
3 files changed, 34 insertions, 17 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 54c41bcaf..6fda06a7e 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -143,18 +143,17 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
143 const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); 143 const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
144 swapchain.Create(layout.width, layout.height, is_srgb); 144 swapchain.Create(layout.width, layout.height, is_srgb);
145 }; 145 };
146 if (swapchain.NeedsRecreate() || swapchain.HasColorSpaceChanged(is_srgb)) { 146 if (swapchain.IsSubOptimal() || swapchain.HasColorSpaceChanged(is_srgb)) {
147 recreate_swapchain(); 147 recreate_swapchain();
148 } 148 }
149 bool needs_recreate; 149 bool is_outdated;
150 do { 150 do {
151 needs_recreate = false;
152 swapchain.AcquireNextImage(); 151 swapchain.AcquireNextImage();
153 if (swapchain.NeedsRecreate()) { 152 is_outdated = swapchain.IsOutDated();
153 if (is_outdated) {
154 recreate_swapchain(); 154 recreate_swapchain();
155 needs_recreate = true;
156 } 155 }
157 } while (needs_recreate); 156 } while (is_outdated);
158 if (has_been_recreated) { 157 if (has_been_recreated) {
159 blit_screen.Recreate(); 158 blit_screen.Recreate();
160 } 159 }
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index a71b0b01e..d990eefba 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -65,7 +65,8 @@ VKSwapchain::VKSwapchain(VkSurfaceKHR surface_, const Device& device_, VKSchedul
65VKSwapchain::~VKSwapchain() = default; 65VKSwapchain::~VKSwapchain() = default;
66 66
67void VKSwapchain::Create(u32 width, u32 height, bool srgb) { 67void VKSwapchain::Create(u32 width, u32 height, bool srgb) {
68 needs_recreate = false; 68 is_outdated = false;
69 is_suboptimal = false;
69 70
70 const auto physical_device = device.GetPhysical(); 71 const auto physical_device = device.GetPhysical();
71 const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; 72 const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)};
@@ -85,11 +86,22 @@ void VKSwapchain::Create(u32 width, u32 height, bool srgb) {
85} 86}
86 87
87void VKSwapchain::AcquireNextImage() { 88void VKSwapchain::AcquireNextImage() {
88 const VkResult result = 89 const VkResult result = device.GetLogical().AcquireNextImageKHR(
89 device.GetLogical().AcquireNextImageKHR(*swapchain, std::numeric_limits<u64>::max(), 90 *swapchain, std::numeric_limits<u64>::max(), *present_semaphores[frame_index],
90 *present_semaphores[frame_index], {}, &image_index); 91 VK_NULL_HANDLE, &image_index);
91 needs_recreate |= result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR; 92 switch (result) {
92 93 case VK_SUCCESS:
94 break;
95 case VK_SUBOPTIMAL_KHR:
96 is_suboptimal = true;
97 break;
98 case VK_ERROR_OUT_OF_DATE_KHR:
99 is_outdated = true;
100 break;
101 default:
102 LOG_ERROR(Render_Vulkan, "vkAcquireNextImageKHR returned {}", vk::ToString(result));
103 break;
104 }
93 scheduler.Wait(resource_ticks[image_index]); 105 scheduler.Wait(resource_ticks[image_index]);
94 resource_ticks[image_index] = scheduler.CurrentTick(); 106 resource_ticks[image_index] = scheduler.CurrentTick();
95} 107}
@@ -115,7 +127,7 @@ void VKSwapchain::Present(VkSemaphore render_semaphore) {
115 LOG_DEBUG(Render_Vulkan, "Suboptimal swapchain"); 127 LOG_DEBUG(Render_Vulkan, "Suboptimal swapchain");
116 break; 128 break;
117 case VK_ERROR_OUT_OF_DATE_KHR: 129 case VK_ERROR_OUT_OF_DATE_KHR:
118 needs_recreate = true; 130 is_outdated = true;
119 break; 131 break;
120 default: 132 default:
121 LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result)); 133 LOG_CRITICAL(Render_Vulkan, "Failed to present with error {}", vk::ToString(result));
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h
index df6da3d93..35c2cdc14 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.h
+++ b/src/video_core/renderer_vulkan/vk_swapchain.h
@@ -38,9 +38,14 @@ public:
38 return current_srgb != is_srgb; 38 return current_srgb != is_srgb;
39 } 39 }
40 40
41 /// Returns true when the image has to be recreated. 41 /// Returns true when the swapchain is outdated.
42 bool NeedsRecreate() const { 42 bool IsOutDated() const {
43 return needs_recreate; 43 return is_outdated;
44 }
45
46 /// Returns true when the swapchain is suboptimal.
47 bool IsSubOptimal() const {
48 return is_suboptimal;
44 } 49 }
45 50
46 VkExtent2D GetSize() const { 51 VkExtent2D GetSize() const {
@@ -95,7 +100,8 @@ private:
95 VkExtent2D extent{}; 100 VkExtent2D extent{};
96 101
97 bool current_srgb{}; 102 bool current_srgb{};
98 bool needs_recreate{}; 103 bool is_outdated{};
104 bool is_suboptimal{};
99}; 105};
100 106
101} // namespace Vulkan 107} // namespace Vulkan