config, nvflinger: Add FPS cap setting

Allows finer tuning of the FPS limit.
master
ameerj 2021-07-22 21:03:50 +07:00
parent db46f8a70c
commit 2c6e274b39
8 changed files with 49 additions and 6 deletions

@ -330,6 +330,7 @@ struct Values {
Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"};
Setting<bool> accelerate_astc{true, "accelerate_astc"}; Setting<bool> accelerate_astc{true, "accelerate_astc"};
Setting<bool> use_vsync{true, "use_vsync"}; Setting<bool> use_vsync{true, "use_vsync"};
BasicSetting<u16> fps_cap{1000, "fps_cap"};
BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"}; BasicSetting<bool> disable_fps_limit{false, "disable_fps_limit"};
Setting<bool> use_assembly_shaders{false, "use_assembly_shaders"}; Setting<bool> use_assembly_shaders{false, "use_assembly_shaders"};
Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; Setting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"};

@ -307,11 +307,12 @@ void NVFlinger::Compose() {
} }
s64 NVFlinger::GetNextTicks() const { s64 NVFlinger::GetNextTicks() const {
if (Settings::values.disable_fps_limit.GetValue()) { static constexpr s64 max_hertz = 120LL;
return 0;
} const auto& settings = Settings::values;
constexpr s64 max_hertz = 120LL; const bool unlocked_fps = settings.disable_fps_limit.GetValue();
return (1000000000 * (1LL << swap_interval)) / max_hertz; const s64 fps_cap = unlocked_fps ? static_cast<s64>(settings.fps_cap.GetValue()) : 1;
return (1000000000 * (1LL << swap_interval)) / (max_hertz * fps_cap);
} }
} // namespace Service::NVFlinger } // namespace Service::NVFlinger

@ -823,6 +823,7 @@ void Config::ReadRendererValues() {
ReadGlobalSetting(Settings::values.bg_blue); ReadGlobalSetting(Settings::values.bg_blue);
if (global) { if (global) {
ReadBasicSetting(Settings::values.fps_cap);
ReadBasicSetting(Settings::values.renderer_debug); ReadBasicSetting(Settings::values.renderer_debug);
} }
@ -1352,6 +1353,7 @@ void Config::SaveRendererValues() {
WriteGlobalSetting(Settings::values.bg_blue); WriteGlobalSetting(Settings::values.bg_blue);
if (global) { if (global) {
WriteBasicSetting(Settings::values.fps_cap);
WriteBasicSetting(Settings::values.renderer_debug); WriteBasicSetting(Settings::values.renderer_debug);
} }

@ -48,6 +48,8 @@ void ConfigureGeneral::SetConfiguration() {
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue()); ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue());
ui->frame_limit->setValue(Settings::values.frame_limit.GetValue()); ui->frame_limit->setValue(Settings::values.frame_limit.GetValue());
ui->fps_cap->setValue(Settings::values.fps_cap.GetValue());
ui->button_reset_defaults->setEnabled(runtime_lock); ui->button_reset_defaults->setEnabled(runtime_lock);
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
@ -87,6 +89,8 @@ void ConfigureGeneral::ApplyConfiguration() {
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked(); UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked(); UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
Settings::values.fps_cap.SetValue(ui->fps_cap->value());
// Guard if during game and set to game-specific value // Guard if during game and set to game-specific value
if (Settings::values.use_frame_limit.UsingGlobal()) { if (Settings::values.use_frame_limit.UsingGlobal()) {
Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() == Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==

@ -51,6 +51,36 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="fps_cap_label">
<property name="text">
<string>Framerate Cap</string>
</property>
<property name="toolTip">
<string>Requires the use of the FPS Limiter Toggle hotkey to take effect.</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="fps_cap">
<property name="suffix">
<string>x</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QCheckBox" name="use_multi_core"> <widget class="QCheckBox" name="use_multi_core">
<property name="text"> <property name="text">

@ -2921,7 +2921,7 @@ void GMainWindow::UpdateStatusBar() {
} }
if (Settings::values.disable_fps_limit) { if (Settings::values.disable_fps_limit) {
game_fps_label->setText( game_fps_label->setText(
tr("Game: %1 FPS (Limit off)").arg(results.average_game_fps, 0, 'f', 0)); tr("Game: %1 FPS (Unlocked)").arg(results.average_game_fps, 0, 'f', 0));
} else { } else {
game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0)); game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0));
} }

@ -455,6 +455,7 @@ void Config::ReadValues() {
ReadSetting("Renderer", Settings::values.gpu_accuracy); ReadSetting("Renderer", Settings::values.gpu_accuracy);
ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation); ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
ReadSetting("Renderer", Settings::values.use_vsync); ReadSetting("Renderer", Settings::values.use_vsync);
ReadSetting("Renderer", Settings::values.fps_cap);
ReadSetting("Renderer", Settings::values.disable_fps_limit); ReadSetting("Renderer", Settings::values.disable_fps_limit);
ReadSetting("Renderer", Settings::values.use_assembly_shaders); ReadSetting("Renderer", Settings::values.use_assembly_shaders);
ReadSetting("Renderer", Settings::values.use_asynchronous_shaders); ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);

@ -290,6 +290,10 @@ bg_red =
bg_blue = bg_blue =
bg_green = bg_green =
# Caps the unlocked framerate to a multiple of the title's target FPS.
# 1 - 1000: Target FPS multiple cap. 1000 (default)
fps_cap =
[Audio] [Audio]
# Which audio output engine to use. # Which audio output engine to use.
# auto (default): Auto-select # auto (default): Auto-select