summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp29
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.h11
3 files changed, 38 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 9ff0a28cd..adb6b7a3b 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -149,7 +149,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
149 const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); 149 const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
150 swapchain.Create(layout.width, layout.height, is_srgb); 150 swapchain.Create(layout.width, layout.height, is_srgb);
151 }; 151 };
152 if (swapchain.IsSubOptimal() || swapchain.HasColorSpaceChanged(is_srgb)) { 152 if (swapchain.NeedsRecreation(is_srgb)) {
153 recreate_swapchain(); 153 recreate_swapchain();
154 } 154 }
155 bool is_outdated; 155 bool is_outdated;
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index aadf03cb0..8972a6921 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -9,6 +9,7 @@
9 9
10#include "common/assert.h" 10#include "common/assert.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "common/settings.h"
12#include "core/core.h" 13#include "core/core.h"
13#include "core/frontend/framebuffer_layout.h" 14#include "core/frontend/framebuffer_layout.h"
14#include "video_core/renderer_vulkan/vk_scheduler.h" 15#include "video_core/renderer_vulkan/vk_scheduler.h"
@@ -36,8 +37,19 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats)
36 37
37VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) { 38VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) {
38 // Mailbox doesn't lock the application like fifo (vsync), prefer it 39 // Mailbox doesn't lock the application like fifo (vsync), prefer it
39 const auto found = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR); 40 const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
40 return found != modes.end() ? *found : VK_PRESENT_MODE_FIFO_KHR; 41 if (found_mailbox != modes.end()) {
42 return VK_PRESENT_MODE_MAILBOX_KHR;
43 }
44 if (Settings::values.disable_fps_limit.GetValue()) {
45 // FIFO present mode locks the framerate to the monitor's refresh rate,
46 // Find an alternative to surpass this limitation if FPS is unlocked.
47 const auto found_imm = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
48 if (found_imm != modes.end()) {
49 return VK_PRESENT_MODE_IMMEDIATE_KHR;
50 }
51 }
52 return VK_PRESENT_MODE_FIFO_KHR;
41} 53}
42 54
43VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) { 55VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) {
@@ -143,7 +155,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
143 const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; 155 const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)};
144 156
145 const VkSurfaceFormatKHR surface_format{ChooseSwapSurfaceFormat(formats)}; 157 const VkSurfaceFormatKHR surface_format{ChooseSwapSurfaceFormat(formats)};
146 const VkPresentModeKHR present_mode{ChooseSwapPresentMode(present_modes)}; 158 present_mode = ChooseSwapPresentMode(present_modes);
147 159
148 u32 requested_image_count{capabilities.minImageCount + 1}; 160 u32 requested_image_count{capabilities.minImageCount + 1};
149 if (capabilities.maxImageCount > 0 && requested_image_count > capabilities.maxImageCount) { 161 if (capabilities.maxImageCount > 0 && requested_image_count > capabilities.maxImageCount) {
@@ -196,6 +208,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
196 208
197 extent = swapchain_ci.imageExtent; 209 extent = swapchain_ci.imageExtent;
198 current_srgb = srgb; 210 current_srgb = srgb;
211 current_fps_unlocked = Settings::values.disable_fps_limit.GetValue();
199 212
200 images = swapchain.GetImages(); 213 images = swapchain.GetImages();
201 image_count = static_cast<u32>(images.size()); 214 image_count = static_cast<u32>(images.size());
@@ -248,4 +261,14 @@ void VKSwapchain::Destroy() {
248 swapchain.reset(); 261 swapchain.reset();
249} 262}
250 263
264bool VKSwapchain::HasFpsUnlockChanged() const {
265 return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue();
266}
267
268bool VKSwapchain::NeedsPresentModeUpdate() const {
269 // Mailbox present mode is the ideal for all scenarios. If it is not available,
270 // A different present mode is needed to support unlocked FPS above the monitor's refresh rate.
271 return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged();
272}
273
251} // namespace Vulkan 274} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h
index 5bce41e21..61a6d959e 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.h
+++ b/src/video_core/renderer_vulkan/vk_swapchain.h
@@ -33,6 +33,11 @@ public:
33 /// Presents the rendered image to the swapchain. 33 /// Presents the rendered image to the swapchain.
34 void Present(VkSemaphore render_semaphore); 34 void Present(VkSemaphore render_semaphore);
35 35
36 /// Returns true when the swapchain needs to be recreated.
37 bool NeedsRecreation(bool is_srgb) const {
38 return HasColorSpaceChanged(is_srgb) || IsSubOptimal() || NeedsPresentModeUpdate();
39 }
40
36 /// Returns true when the color space has changed. 41 /// Returns true when the color space has changed.
37 bool HasColorSpaceChanged(bool is_srgb) const { 42 bool HasColorSpaceChanged(bool is_srgb) const {
38 return current_srgb != is_srgb; 43 return current_srgb != is_srgb;
@@ -84,6 +89,10 @@ private:
84 89
85 void Destroy(); 90 void Destroy();
86 91
92 bool HasFpsUnlockChanged() const;
93
94 bool NeedsPresentModeUpdate() const;
95
87 const VkSurfaceKHR surface; 96 const VkSurfaceKHR surface;
88 const Device& device; 97 const Device& device;
89 VKScheduler& scheduler; 98 VKScheduler& scheduler;
@@ -102,8 +111,10 @@ private:
102 111
103 VkFormat image_view_format{}; 112 VkFormat image_view_format{};
104 VkExtent2D extent{}; 113 VkExtent2D extent{};
114 VkPresentModeKHR present_mode{};
105 115
106 bool current_srgb{}; 116 bool current_srgb{};
117 bool current_fps_unlocked{};
107 bool is_outdated{}; 118 bool is_outdated{};
108 bool is_suboptimal{}; 119 bool is_suboptimal{};
109}; 120};