diff options
author | bunnei <bunneidev@gmail.com> | 2023-05-07 06:55:39 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-07 06:55:39 +0200 |
commit | 3547248ec2f303ba1ce5cf41548631ad00e7f739 (patch) | |
tree | a7e99fa79998384d4f20361234bf77de57671571 /src/video_core | |
parent | Merge pull request #10174 from german77/motriod (diff) | |
parent | qt_common: Remove yuzu prefix (diff) | |
download | yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.gz yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.bz2 yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.lz yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.xz yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.tar.zst yuzu-3547248ec2f303ba1ce5cf41548631ad00e7f739.zip |
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 2 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.cpp | 75 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.h | 6 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_surface.cpp | 6 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_surface.h | 9 |
5 files changed, 60 insertions, 38 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_, instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, Settings::values.renderer_debug.GetValue())), debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), - surface(CreateSurface(instance, render_window)), + surface(CreateSurface(instance, render_window.GetWindowInfo())), device(CreateDevice(instance, dld, *surface)), memory_allocator(device, false), state_tracker(), scheduler(device, state_tracker), 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 @@ #include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +#include "vulkan/vulkan_core.h" namespace Vulkan { @@ -33,23 +34,47 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats) return found != formats.end() ? *found : formats[0]; } -VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) { - // Mailbox (triple buffering) doesn't lock the application like fifo (vsync), - // prefer it if vsync option is not selected - const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR); - if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Borderless && - found_mailbox != modes.end() && !Settings::values.use_vsync.GetValue()) { - return VK_PRESENT_MODE_MAILBOX_KHR; - } - if (!Settings::values.use_speed_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; +static constexpr VkPresentModeKHR ChooseSwapPresentMode(bool has_imm, bool has_mailbox, + bool has_fifo_relaxed) { + // Mailbox doesn't lock the application like FIFO (vsync) + // FIFO present mode locks the framerate to the monitor's refresh rate + Settings::VSyncMode setting = [has_imm, has_mailbox]() { + // Choose Mailbox or Immediate if unlocked and those modes are supported + const auto mode = Settings::values.vsync_mode.GetValue(); + if (Settings::values.use_speed_limit.GetValue()) { + return mode; + } + switch (mode) { + case Settings::VSyncMode::FIFO: + case Settings::VSyncMode::FIFORelaxed: + if (has_mailbox) { + return Settings::VSyncMode::Mailbox; + } else if (has_imm) { + return Settings::VSyncMode::Immediate; + } + [[fallthrough]]; + default: + return mode; } + }(); + if ((setting == Settings::VSyncMode::Mailbox && !has_mailbox) || + (setting == Settings::VSyncMode::Immediate && !has_imm) || + (setting == Settings::VSyncMode::FIFORelaxed && !has_fifo_relaxed)) { + setting = Settings::VSyncMode::FIFO; + } + + switch (setting) { + case Settings::VSyncMode::Immediate: + return VK_PRESENT_MODE_IMMEDIATE_KHR; + case Settings::VSyncMode::Mailbox: + return VK_PRESENT_MODE_MAILBOX_KHR; + case Settings::VSyncMode::FIFO: + return VK_PRESENT_MODE_FIFO_KHR; + case Settings::VSyncMode::FIFORelaxed: + return VK_PRESENT_MODE_FIFO_RELAXED_KHR; + default: + return VK_PRESENT_MODE_FIFO_KHR; } - return VK_PRESENT_MODE_FIFO_KHR; } VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height) { @@ -167,11 +192,17 @@ void Swapchain::Present(VkSemaphore render_semaphore) { void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) { const auto physical_device{device.GetPhysical()}; const auto formats{physical_device.GetSurfaceFormatsKHR(surface)}; - const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)}; + const auto present_modes = physical_device.GetSurfacePresentModesKHR(surface); + has_mailbox = std::find(present_modes.begin(), present_modes.end(), + VK_PRESENT_MODE_MAILBOX_KHR) != present_modes.end(); + has_imm = std::find(present_modes.begin(), present_modes.end(), + VK_PRESENT_MODE_IMMEDIATE_KHR) != present_modes.end(); + has_fifo_relaxed = std::find(present_modes.begin(), present_modes.end(), + VK_PRESENT_MODE_FIFO_RELAXED_KHR) != present_modes.end(); const VkCompositeAlphaFlagBitsKHR alpha_flags{ChooseAlphaFlags(capabilities)}; surface_format = ChooseSwapSurfaceFormat(formats); - present_mode = ChooseSwapPresentMode(present_modes); + present_mode = ChooseSwapPresentMode(has_imm, has_mailbox, has_fifo_relaxed); u32 requested_image_count{capabilities.minImageCount + 1}; // Ensure Triple buffering if possible. @@ -232,7 +263,6 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bo extent = swapchain_ci.imageExtent; current_srgb = srgb; - current_fps_unlocked = !Settings::values.use_speed_limit.GetValue(); images = swapchain.GetImages(); image_count = static_cast<u32>(images.size()); @@ -254,14 +284,9 @@ void Swapchain::Destroy() { swapchain.reset(); } -bool Swapchain::HasFpsUnlockChanged() const { - return current_fps_unlocked != !Settings::values.use_speed_limit.GetValue(); -} - bool Swapchain::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(); + const auto requested_mode = ChooseSwapPresentMode(has_imm, has_mailbox, has_fifo_relaxed); + return present_mode != requested_mode; } } // 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: void Destroy(); - bool HasFpsUnlockChanged() const; - bool NeedsPresentModeUpdate() const; const VkSurfaceKHR surface; @@ -142,9 +140,11 @@ private: VkExtent2D extent{}; VkPresentModeKHR present_mode{}; VkSurfaceFormatKHR surface_format{}; + bool has_imm{false}; + bool has_mailbox{false}; + bool has_fifo_relaxed{false}; bool current_srgb{}; - bool current_fps_unlocked{}; bool is_outdated{}; bool is_suboptimal{}; }; diff --git a/src/video_core/vulkan_common/vulkan_surface.cpp b/src/video_core/vulkan_common/vulkan_surface.cpp index fa9bafa20..c34599365 100644 --- a/src/video_core/vulkan_common/vulkan_surface.cpp +++ b/src/video_core/vulkan_common/vulkan_surface.cpp @@ -23,10 +23,10 @@ namespace Vulkan { -vk::SurfaceKHR CreateSurface(const vk::Instance& instance, - const Core::Frontend::EmuWindow& emu_window) { +vk::SurfaceKHR CreateSurface( + const vk::Instance& instance, + [[maybe_unused]] const Core::Frontend::EmuWindow::WindowSystemInfo& window_info) { [[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch(); - [[maybe_unused]] const auto& window_info = emu_window.GetWindowInfo(); VkSurfaceKHR unsafe_surface = nullptr; #ifdef _WIN32 diff --git a/src/video_core/vulkan_common/vulkan_surface.h b/src/video_core/vulkan_common/vulkan_surface.h index 5725143e6..5e18c06c4 100644 --- a/src/video_core/vulkan_common/vulkan_surface.h +++ b/src/video_core/vulkan_common/vulkan_surface.h @@ -3,15 +3,12 @@ #pragma once +#include "core/frontend/emu_window.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -namespace Core::Frontend { -class EmuWindow; -} - namespace Vulkan { -[[nodiscard]] vk::SurfaceKHR CreateSurface(const vk::Instance& instance, - const Core::Frontend::EmuWindow& emu_window); +[[nodiscard]] vk::SurfaceKHR CreateSurface( + const vk::Instance& instance, const Core::Frontend::EmuWindow::WindowSystemInfo& window_info); } // namespace Vulkan |