summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar bunnei2023-05-06 21:55:39 -0700
committerGravatar GitHub2023-05-06 21:55:39 -0700
commit3547248ec2f303ba1ce5cf41548631ad00e7f739 (patch)
treea7e99fa79998384d4f20361234bf77de57671571 /src/video_core/renderer_vulkan
parentMerge pull request #10174 from german77/motriod (diff)
parentqt_common: Remove yuzu prefix (diff)
downloadyuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.gz
yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.xz
yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.zip
Merge pull request #10125 from lat9nq/vsync-select
configuration: Expose separate swap present modes
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp75
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.h6
3 files changed, 54 insertions, 29 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 908625c66..8e31eba34 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -88,7 +88,7 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
88 instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, 88 instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
89 Settings::values.renderer_debug.GetValue())), 89 Settings::values.renderer_debug.GetValue())),
90 debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), 90 debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
91 surface(CreateSurface(instance, render_window)), 91 surface(CreateSurface(instance, render_window.GetWindowInfo())),
92 device(CreateDevice(instance, dld, *surface)), memory_allocator(device, false), 92 device(CreateDevice(instance, dld, *surface)), memory_allocator(device, false),
93 state_tracker(), scheduler(device, state_tracker), 93 state_tracker(), scheduler(device, state_tracker),
94 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, 94 swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index 23bbea7f1..1e80ce463 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -14,6 +14,7 @@
14#include "video_core/renderer_vulkan/vk_swapchain.h" 14#include "video_core/renderer_vulkan/vk_swapchain.h"
15#include "video_core/vulkan_common/vulkan_device.h" 15#include "video_core/vulkan_common/vulkan_device.h"
16#include "video_core/vulkan_common/vulkan_wrapper.h" 16#include "video_core/vulkan_common/vulkan_wrapper.h"
17#include "vulkan/vulkan_core.h"
17 18
18namespace Vulkan { 19namespace Vulkan {
19 20
@@ -33,23 +34,47 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats)
33 return found != formats.end() ? *found : formats[0]; 34 return found != formats.end() ? *found : formats[0];
34} 35}
35 36
36VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) { 37static constexpr VkPresentModeKHR ChooseSwapPresentMode(bool has_imm, bool has_mailbox,
37 // Mailbox (triple buffering) doesn't lock the application like fifo (vsync), 38 bool has_fifo_relaxed) {
38 // prefer it if vsync option is not selected 39 // Mailbox doesn't lock the application like FIFO (vsync)
39 const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR); 40 // FIFO present mode locks the framerate to the monitor's refresh rate
40 if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Borderless && 41 Settings::VSyncMode setting = [has_imm, has_mailbox]() {
41 found_mailbox != modes.end() && !Settings::values.use_vsync.GetValue()) { 42 // Choose Mailbox or Immediate if unlocked and those modes are supported
42 return VK_PRESENT_MODE_MAILBOX_KHR; 43 const auto mode = Settings::values.vsync_mode.GetValue();
43 } 44 if (Settings::values.use_speed_limit.GetValue()) {
44 if (!Settings::values.use_speed_limit.GetValue()) { 45 return mode;
45 // FIFO present mode locks the framerate to the monitor's refresh rate, 46 }
46 // Find an alternative to surpass this limitation if FPS is unlocked. 47 switch (mode) {
47 const auto found_imm = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR); 48 case Settings::VSyncMode::FIFO:
48 if (found_imm != modes.end()) { 49 case Settings::VSyncMode::FIFORelaxed:
49 return VK_PRESENT_MODE_IMMEDIATE_KHR; 50 if (has_mailbox) {
51 return Settings::VSyncMode::Mailbox;
52 } else if (has_imm) {
53 return Settings::VSyncMode::Immediate;
54 }
55 [[fallthrough]];
56 default:
57 return mode;
50 } 58 }
59 }();
60 if ((setting == Settings::VSyncMode::Mailbox && !has_mailbox) ||
61 (setting == Settings::VSyncMode::Immediate && !has_imm) ||
62 (setting == Settings::VSyncMode::FIFORelaxed && !has_fifo_relaxed)) {
63 setting = Settings::VSyncMode::FIFO;
64 }
65
66 switch (setting) {
67 case Settings::VSyncMode::Immediate:
68 return VK_PRESENT_MODE_IMMEDIATE_KHR;
69 case Settings::VSyncMode::Mailbox:
70 return VK_PRESENT_MODE_MAILBOX_KHR;
71 case Settings::VSyncMode::FIFO:
72 return VK_PRESENT_MODE_FIFO_KHR;
73 case Settings::VSyncMode::FIFORelaxed:
74 return VK_PRESENT_MODE_FIFO_RELAXED_KHR;
75 default:
76 return VK_PRESENT_MODE_FIFO_KHR;
51 } 77 }
52 return VK_PRESENT_MODE_FIFO_KHR;
53} 78}
54 79
55VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) { 80VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) {
@@ -167,11 +192,17 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
167void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) { 192void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) {
168 const auto physical_device{device.GetPhysical()}; 193 const auto physical_device{device.GetPhysical()};
169 const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; 194 const auto formats{physical_device.GetSurfaceFormatsKHR(surface)};
170 const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; 195 const auto present_modes = physical_device.GetSurfacePresentModesKHR(surface);
196 has_mailbox = std::find(present_modes.begin(), present_modes.end(),
197 VK_PRESENT_MODE_MAILBOX_KHR) != present_modes.end();
198 has_imm = std::find(present_modes.begin(), present_modes.end(),
199 VK_PRESENT_MODE_IMMEDIATE_KHR) != present_modes.end();
200 has_fifo_relaxed = std::find(present_modes.begin(), present_modes.end(),
201 VK_PRESENT_MODE_FIFO_RELAXED_KHR) != present_modes.end();
171 202
172 const VkCompositeAlphaFlagBitsKHR alpha_flags{ChooseAlphaFlags(capabilities)}; 203 const VkCompositeAlphaFlagBitsKHR alpha_flags{ChooseAlphaFlags(capabilities)};
173 surface_format = ChooseSwapSurfaceFormat(formats); 204 surface_format = ChooseSwapSurfaceFormat(formats);
174 present_mode = ChooseSwapPresentMode(present_modes); 205 present_mode = ChooseSwapPresentMode(has_imm, has_mailbox, has_fifo_relaxed);
175 206
176 u32 requested_image_count{capabilities.minImageCount + 1}; 207 u32 requested_image_count{capabilities.minImageCount + 1};
177 // Ensure Triple buffering if possible. 208 // Ensure Triple buffering if possible.
@@ -232,7 +263,6 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bo
232 263
233 extent = swapchain_ci.imageExtent; 264 extent = swapchain_ci.imageExtent;
234 current_srgb = srgb; 265 current_srgb = srgb;
235 current_fps_unlocked = !Settings::values.use_speed_limit.GetValue();
236 266
237 images = swapchain.GetImages(); 267 images = swapchain.GetImages();
238 image_count = static_cast<u32>(images.size()); 268 image_count = static_cast<u32>(images.size());
@@ -254,14 +284,9 @@ void Swapchain::Destroy() {
254 swapchain.reset(); 284 swapchain.reset();
255} 285}
256 286
257bool Swapchain::HasFpsUnlockChanged() const {
258 return current_fps_unlocked != !Settings::values.use_speed_limit.GetValue();
259}
260
261bool Swapchain::NeedsPresentModeUpdate() const { 287bool Swapchain::NeedsPresentModeUpdate() const {
262 // Mailbox present mode is the ideal for all scenarios. If it is not available, 288 const auto requested_mode = ChooseSwapPresentMode(has_imm, has_mailbox, has_fifo_relaxed);
263 // A different present mode is needed to support unlocked FPS above the monitor's refresh rate. 289 return present_mode != requested_mode;
264 return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged();
265} 290}
266 291
267} // namespace Vulkan 292} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h
index 419742586..bf1ea7254 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.h
+++ b/src/video_core/renderer_vulkan/vk_swapchain.h
@@ -116,8 +116,6 @@ private:
116 116
117 void Destroy(); 117 void Destroy();
118 118
119 bool HasFpsUnlockChanged() const;
120
121 bool NeedsPresentModeUpdate() const; 119 bool NeedsPresentModeUpdate() const;
122 120
123 const VkSurfaceKHR surface; 121 const VkSurfaceKHR surface;
@@ -142,9 +140,11 @@ private:
142 VkExtent2D extent{}; 140 VkExtent2D extent{};
143 VkPresentModeKHR present_mode{}; 141 VkPresentModeKHR present_mode{};
144 VkSurfaceFormatKHR surface_format{}; 142 VkSurfaceFormatKHR surface_format{};
143 bool has_imm{false};
144 bool has_mailbox{false};
145 bool has_fifo_relaxed{false};
145 146
146 bool current_srgb{}; 147 bool current_srgb{};
147 bool current_fps_unlocked{};
148 bool is_outdated{}; 148 bool is_outdated{};
149 bool is_suboptimal{}; 149 bool is_suboptimal{};
150}; 150};