summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorameerj <52414509+ameerj@users.noreply.github.com>2021-09-13 02:32:23 +0200
committerameerj <52414509+ameerj@users.noreply.github.com>2021-09-13 02:32:23 +0200
commit35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7 (patch)
tree97277e9d79845b83fdde1f938b68932e69067f6b
parentMerge pull request #7002 from ameerj/vk-state-unused (diff)
downloadyuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar.gz
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar.bz2
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar.lz
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar.xz
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.tar.zst
yuzu-35e5a67a839c5b1b5f12d21b2d4e3911e1af33b7.zip
-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) {
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
swapchain.Create(layout.width, layout.height, is_srgb);
};
- if (swapchain.IsSubOptimal() || swapchain.HasColorSpaceChanged(is_srgb)) {
+ if (swapchain.NeedsRecreation(is_srgb)) {
recreate_swapchain();
}
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 @@
#include "common/assert.h"
#include "common/logging/log.h"
+#include "common/settings.h"
#include "core/core.h"
#include "core/frontend/framebuffer_layout.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
@@ -36,8 +37,19 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats)
VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) {
// Mailbox doesn't lock the application like fifo (vsync), prefer it
- const auto found = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
- return found != modes.end() ? *found : VK_PRESENT_MODE_FIFO_KHR;
+ const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
+ if (found_mailbox != modes.end()) {
+ return VK_PRESENT_MODE_MAILBOX_KHR;
+ }
+ if (Settings::values.disable_fps_limit.GetValue()) {
+ // FIFO present mode locks the framerate to the monitor's refresh rate,
+ // Find an alternative to surpass this limitation if FPS is unlocked.
+ const auto found_imm = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR);
+ if (found_imm != modes.end()) {
+ return VK_PRESENT_MODE_IMMEDIATE_KHR;
+ }
+ }
+ return VK_PRESENT_MODE_FIFO_KHR;
}
VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) {
@@ -143,7 +155,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)};
const VkSurfaceFormatKHR surface_format{ChooseSwapSurfaceFormat(formats)};
- const VkPresentModeKHR present_mode{ChooseSwapPresentMode(present_modes)};
+ present_mode = ChooseSwapPresentMode(present_modes);
u32 requested_image_count{capabilities.minImageCount + 1};
if (capabilities.maxImageCount > 0 && requested_image_count > capabilities.maxImageCount) {
@@ -196,6 +208,7 @@ void VKSwapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities,
extent = swapchain_ci.imageExtent;
current_srgb = srgb;
+ current_fps_unlocked = Settings::values.disable_fps_limit.GetValue();
images = swapchain.GetImages();
image_count = static_cast<u32>(images.size());
@@ -248,4 +261,14 @@ void VKSwapchain::Destroy() {
swapchain.reset();
}
+bool VKSwapchain::HasFpsUnlockChanged() const {
+ return current_fps_unlocked != Settings::values.disable_fps_limit.GetValue();
+}
+
+bool VKSwapchain::NeedsPresentModeUpdate() const {
+ // Mailbox present mode is the ideal for all scenarios. If it is not available,
+ // A different present mode is needed to support unlocked FPS above the monitor's refresh rate.
+ return present_mode != VK_PRESENT_MODE_MAILBOX_KHR && HasFpsUnlockChanged();
+}
+
} // 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:
/// Presents the rendered image to the swapchain.
void Present(VkSemaphore render_semaphore);
+ /// Returns true when the swapchain needs to be recreated.
+ bool NeedsRecreation(bool is_srgb) const {
+ return HasColorSpaceChanged(is_srgb) || IsSubOptimal() || NeedsPresentModeUpdate();
+ }
+
/// Returns true when the color space has changed.
bool HasColorSpaceChanged(bool is_srgb) const {
return current_srgb != is_srgb;
@@ -84,6 +89,10 @@ private:
void Destroy();
+ bool HasFpsUnlockChanged() const;
+
+ bool NeedsPresentModeUpdate() const;
+
const VkSurfaceKHR surface;
const Device& device;
VKScheduler& scheduler;
@@ -102,8 +111,10 @@ private:
VkFormat image_view_format{};
VkExtent2D extent{};
+ VkPresentModeKHR present_mode{};
bool current_srgb{};
+ bool current_fps_unlocked{};
bool is_outdated{};
bool is_suboptimal{};
};