configuration: Expose separate swap present modes
Previously, yuzu would try and guess which vsync mode to use given different scenarios, but apparently we didn't always get it right. This exposes the separate modes in a drop-down the user can select. If a mode isn't available in Vulkan, it defaults to FIFO.
This commit is contained in:
parent
8f43b05d6b
commit
6f0929df82
11 changed files with 115 additions and 37 deletions
|
@ -60,7 +60,7 @@ void LogSettings() {
|
|||
log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
|
||||
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
|
||||
log_setting("Renderer_AsyncASTC", values.async_astc.GetValue());
|
||||
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
|
||||
log_setting("Renderer_UseVsync", values.vsync_mode.GetValue());
|
||||
log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
|
||||
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
|
||||
log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
|
||||
|
@ -222,7 +222,6 @@ void RestoreGlobalState(bool is_powered_on) {
|
|||
values.nvdec_emulation.SetGlobal(true);
|
||||
values.accelerate_astc.SetGlobal(true);
|
||||
values.async_astc.SetGlobal(true);
|
||||
values.use_vsync.SetGlobal(true);
|
||||
values.shader_backend.SetGlobal(true);
|
||||
values.use_asynchronous_shaders.SetGlobal(true);
|
||||
values.use_fast_gpu_time.SetGlobal(true);
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
|
||||
namespace Settings {
|
||||
|
||||
enum class VSyncMode : u32 {
|
||||
Immediate,
|
||||
FIFO,
|
||||
Mailbox,
|
||||
};
|
||||
|
||||
enum class RendererBackend : u32 {
|
||||
OpenGL = 0,
|
||||
Vulkan = 1,
|
||||
|
@ -455,7 +461,8 @@ struct Values {
|
|||
SwitchableSetting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
|
||||
SwitchableSetting<bool> accelerate_astc{true, "accelerate_astc"};
|
||||
SwitchableSetting<bool> async_astc{false, "async_astc"};
|
||||
SwitchableSetting<bool> use_vsync{true, "use_vsync"};
|
||||
Setting<VSyncMode, true> vsync_mode{VSyncMode::FIFO, VSyncMode::Immediate, VSyncMode::Mailbox,
|
||||
"use_vsync"};
|
||||
SwitchableSetting<ShaderBackend, true> shader_backend{ShaderBackend::GLSL, ShaderBackend::GLSL,
|
||||
ShaderBackend::SPIRV, "shader_backend"};
|
||||
SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};
|
||||
|
|
|
@ -85,6 +85,18 @@ static const char* TranslateNvdecEmulation(Settings::NvdecEmulation backend) {
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
constexpr const char* TranslateVSyncMode(Settings::VSyncMode mode) {
|
||||
switch (mode) {
|
||||
case Settings::VSyncMode::Immediate:
|
||||
return "Immediate";
|
||||
case Settings::VSyncMode::FIFO:
|
||||
return "FIFO";
|
||||
case Settings::VSyncMode::Mailbox:
|
||||
return "Mailbox";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
u64 GetTelemetryId() {
|
||||
u64 telemetry_id{};
|
||||
const auto filename = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir) / "telemetry_id";
|
||||
|
@ -241,7 +253,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
|
|||
AddField(field_type, "Renderer_NvdecEmulation",
|
||||
TranslateNvdecEmulation(Settings::values.nvdec_emulation.GetValue()));
|
||||
AddField(field_type, "Renderer_AccelerateASTC", Settings::values.accelerate_astc.GetValue());
|
||||
AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync.GetValue());
|
||||
AddField(field_type, "Renderer_UseVsync",
|
||||
TranslateVSyncMode(Settings::values.vsync_mode.GetValue()));
|
||||
AddField(field_type, "Renderer_ShaderBackend",
|
||||
static_cast<u32>(Settings::values.shader_backend.GetValue()));
|
||||
AddField(field_type, "Renderer_UseAsynchronousShaders",
|
||||
|
|
|
@ -34,21 +34,22 @@ VkSurfaceFormatKHR ChooseSwapSurfaceFormat(vk::Span<VkSurfaceFormatKHR> formats)
|
|||
}
|
||||
|
||||
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()) {
|
||||
// Mailbox (triple buffering) doesn't lock the application like FIFO (vsync)
|
||||
// FIFO present mode locks the framerate to the monitor's refresh rate
|
||||
const bool has_mailbox =
|
||||
std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR) != modes.end();
|
||||
const bool has_imm =
|
||||
std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR) != modes.end();
|
||||
const Settings::VSyncMode mode = Settings::values.vsync_mode.GetValue();
|
||||
|
||||
if (mode == Settings::VSyncMode::Immediate && has_imm) {
|
||||
LOG_INFO(Render_Vulkan, "Using swap present mode Immediate");
|
||||
return VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||
} else if (mode == Settings::VSyncMode::Mailbox && has_mailbox) {
|
||||
LOG_INFO(Render_Vulkan, "Using swap present mode Mailbox");
|
||||
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;
|
||||
}
|
||||
}
|
||||
LOG_INFO(Render_Vulkan, "Using swap present mode FIFO");
|
||||
return VK_PRESENT_MODE_FIFO_KHR;
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,18 @@ public:
|
|||
|
||||
// disable vsync for any shared contexts
|
||||
auto format = share_context->format();
|
||||
format.setSwapInterval(main_surface ? Settings::values.use_vsync.GetValue() : 0);
|
||||
const int swap_interval = [&]() {
|
||||
switch (Settings::values.vsync_mode.GetValue()) {
|
||||
case Settings::VSyncMode::Immediate:
|
||||
return 0;
|
||||
case Settings::VSyncMode::FIFO:
|
||||
return 1;
|
||||
case Settings::VSyncMode::Mailbox:
|
||||
return 2;
|
||||
}
|
||||
}();
|
||||
|
||||
format.setSwapInterval(main_surface ? swap_interval : 0);
|
||||
|
||||
context = std::make_unique<QOpenGLContext>();
|
||||
context->setShareContext(share_context);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QSettings>
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
|
@ -709,7 +710,6 @@ void Config::ReadRendererValues() {
|
|||
ReadGlobalSetting(Settings::values.nvdec_emulation);
|
||||
ReadGlobalSetting(Settings::values.accelerate_astc);
|
||||
ReadGlobalSetting(Settings::values.async_astc);
|
||||
ReadGlobalSetting(Settings::values.use_vsync);
|
||||
ReadGlobalSetting(Settings::values.shader_backend);
|
||||
ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
|
||||
ReadGlobalSetting(Settings::values.use_fast_gpu_time);
|
||||
|
@ -720,6 +720,10 @@ void Config::ReadRendererValues() {
|
|||
ReadGlobalSetting(Settings::values.bg_blue);
|
||||
|
||||
if (global) {
|
||||
Settings::values.vsync_mode.SetValue(static_cast<Settings::VSyncMode>(
|
||||
ReadSetting(QString::fromStdString(Settings::values.vsync_mode.GetLabel()),
|
||||
static_cast<u32>(Settings::values.vsync_mode.GetDefault()))
|
||||
.value<u32>()));
|
||||
ReadBasicSetting(Settings::values.renderer_debug);
|
||||
ReadBasicSetting(Settings::values.renderer_shader_feedback);
|
||||
ReadBasicSetting(Settings::values.enable_nsight_aftermath);
|
||||
|
@ -1352,7 +1356,6 @@ void Config::SaveRendererValues() {
|
|||
Settings::values.nvdec_emulation.UsingGlobal());
|
||||
WriteGlobalSetting(Settings::values.accelerate_astc);
|
||||
WriteGlobalSetting(Settings::values.async_astc);
|
||||
WriteGlobalSetting(Settings::values.use_vsync);
|
||||
WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()),
|
||||
static_cast<u32>(Settings::values.shader_backend.GetValue(global)),
|
||||
static_cast<u32>(Settings::values.shader_backend.GetDefault()),
|
||||
|
@ -1366,6 +1369,9 @@ void Config::SaveRendererValues() {
|
|||
WriteGlobalSetting(Settings::values.bg_blue);
|
||||
|
||||
if (global) {
|
||||
WriteSetting(QString::fromStdString(Settings::values.vsync_mode.GetLabel()),
|
||||
static_cast<u32>(Settings::values.vsync_mode.GetValue()),
|
||||
static_cast<u32>(Settings::values.vsync_mode.GetDefault()));
|
||||
WriteBasicSetting(Settings::values.renderer_debug);
|
||||
WriteBasicSetting(Settings::values.renderer_shader_feedback);
|
||||
WriteBasicSetting(Settings::values.enable_nsight_aftermath);
|
||||
|
|
|
@ -99,6 +99,7 @@ void ConfigureGraphics::SetConfiguration() {
|
|||
ui->nvdec_emulation_widget->setEnabled(runtime_lock);
|
||||
ui->resolution_combobox->setEnabled(runtime_lock);
|
||||
ui->accelerate_astc->setEnabled(runtime_lock);
|
||||
ui->vsync_mode_combobox->setEnabled(runtime_lock);
|
||||
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||
ui->use_asynchronous_gpu_emulation->setChecked(
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
|
@ -118,6 +119,9 @@ void ConfigureGraphics::SetConfiguration() {
|
|||
ui->fsr_sharpening_slider->setValue(Settings::values.fsr_sharpening_slider.GetValue());
|
||||
ui->anti_aliasing_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.anti_aliasing.GetValue()));
|
||||
|
||||
ui->vsync_mode_combobox->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.vsync_mode.GetValue()));
|
||||
} else {
|
||||
ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
|
||||
ConfigurationShared::SetHighlight(ui->api_widget,
|
||||
|
@ -232,6 +236,9 @@ void ConfigureGraphics::ApplyConfiguration() {
|
|||
Settings::values.anti_aliasing.SetValue(anti_aliasing);
|
||||
}
|
||||
Settings::values.fsr_sharpening_slider.SetValue(ui->fsr_sharpening_slider->value());
|
||||
|
||||
Settings::values.vsync_mode.SetValue(
|
||||
static_cast<Settings::VSyncMode>(ui->vsync_mode_combobox->currentIndex()));
|
||||
} else {
|
||||
if (ui->resolution_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||
Settings::values.resolution_setup.SetGlobal(true);
|
||||
|
@ -465,4 +472,6 @@ void ConfigureGraphics::SetupPerGameUI() {
|
|||
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
|
||||
ConfigurationShared::InsertGlobalItem(
|
||||
ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true)));
|
||||
|
||||
ui->vsync_mode_layout->setVisible(false);
|
||||
}
|
||||
|
|
|
@ -188,6 +188,53 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="vsync_mode_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="vsync_mode_label">
|
||||
<property name="text">
|
||||
<string>VSync Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="vsync_mode_combobox">
|
||||
<property name="currentText">
|
||||
<string>Off (Immediate)</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off (Immediate)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Double Buffering (FIFO)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Triple Buffering (Mailbox)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="nvdec_emulation_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="nvdec_emulation_layout">
|
||||
|
@ -366,7 +413,7 @@
|
|||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1.5X (1080p/1620p) [EXPERIMENTAL]</string>
|
||||
<string>1.5X (1080p/1620p) [EXPERIMENTAL]</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -21,7 +21,6 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
|
|||
|
||||
void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||
const bool runtime_lock = !system.IsPoweredOn();
|
||||
ui->use_vsync->setEnabled(runtime_lock);
|
||||
ui->async_present->setEnabled(runtime_lock);
|
||||
ui->renderer_force_max_clock->setEnabled(runtime_lock);
|
||||
ui->async_astc->setEnabled(runtime_lock);
|
||||
|
@ -30,7 +29,6 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
|||
|
||||
ui->async_present->setChecked(Settings::values.async_presentation.GetValue());
|
||||
ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue());
|
||||
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||
ui->async_astc->setChecked(Settings::values.async_astc.GetValue());
|
||||
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
||||
|
@ -63,7 +61,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
|||
renderer_force_max_clock);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
||||
ui->anisotropic_filtering_combobox);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_astc, ui->async_astc,
|
||||
async_astc);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
||||
|
@ -97,7 +94,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
|||
ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
|
||||
ui->renderer_force_max_clock->setEnabled(
|
||||
Settings::values.renderer_force_max_clock.UsingGlobal());
|
||||
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
|
||||
ui->async_astc->setEnabled(Settings::values.async_astc.UsingGlobal());
|
||||
ui->use_asynchronous_shaders->setEnabled(
|
||||
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
||||
|
@ -117,7 +113,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
|||
ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
|
||||
Settings::values.renderer_force_max_clock,
|
||||
renderer_force_max_clock);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
|
||||
ConfigurationShared::SetColoredTristate(ui->async_astc, Settings::values.async_astc,
|
||||
async_astc);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
|
||||
|
|
|
@ -86,16 +86,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_vsync">
|
||||
<property name="toolTip">
|
||||
<string>VSync prevents the screen from tearing, but some graphics cards have lower performance with VSync enabled. Keep it enabled if you don't notice a performance difference.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use VSync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="async_astc">
|
||||
<property name="toolTip">
|
||||
|
|
|
@ -320,7 +320,7 @@ void Config::ReadValues() {
|
|||
ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
|
||||
ReadSetting("Renderer", Settings::values.gpu_accuracy);
|
||||
ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
|
||||
ReadSetting("Renderer", Settings::values.use_vsync);
|
||||
ReadSetting("Renderer", Settings::values.vsync_mode);
|
||||
ReadSetting("Renderer", Settings::values.shader_backend);
|
||||
ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
|
||||
ReadSetting("Renderer", Settings::values.nvdec_emulation);
|
||||
|
|
Loading…
Reference in a new issue