From e6a89e1b2c0f32eee77219801d05e3e2dc4fdcb9 Mon Sep 17 00:00:00 2001 From: KojoZero Date: Wed, 11 Mar 2026 22:06:12 -0700 Subject: [PATCH] initial changes --- CMakeModules/GenerateSettingKeys.cmake | 1 + .../features/settings/SettingKeys.kt | 1 + src/android/app/src/main/jni/config.cpp | 1 + src/android/app/src/main/jni/default_ini.h | 4 + src/citra_qt/configuration/config.cpp | 2 + .../configuration/configure_graphics.cpp | 8 + .../configuration/configure_graphics.h | 1 + .../configuration/configure_graphics.ui | 166 ++++++++++-------- src/common/settings.cpp | 2 + src/common/settings.h | 1 + .../renderer_vulkan/renderer_vulkan.cpp | 1 - .../renderer_vulkan/renderer_vulkan.h | 2 +- 12 files changed, 110 insertions(+), 80 deletions(-) diff --git a/CMakeModules/GenerateSettingKeys.cmake b/CMakeModules/GenerateSettingKeys.cmake index 15a28a5de..8d9b3326b 100644 --- a/CMakeModules/GenerateSettingKeys.cmake +++ b/CMakeModules/GenerateSettingKeys.cmake @@ -40,6 +40,7 @@ foreach(KEY IN ITEMS "use_disk_shader_cache" "shaders_accurate_mul" "use_vsync" + "use_skip_duplicate_frames" "use_display_refresh_rate_detection" "use_shader_jit" "resolution_factor" diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt index 1d6e0dcee..b4acd2cbe 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt @@ -38,6 +38,7 @@ object SettingKeys { external fun use_disk_shader_cache(): String external fun shaders_accurate_mul(): String external fun use_vsync(): String + external fun use_skip_duplicate_frames(): String external fun use_shader_jit(): String external fun resolution_factor(): String external fun frame_limit(): String diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index e0fa260c5..b88f0d29c 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -152,6 +152,7 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.resolution_factor); ReadSetting("Renderer", Settings::values.use_disk_shader_cache); ReadSetting("Renderer", Settings::values.use_vsync); + ReadSetting("Renderer", Settings::values.use_skip_duplicate_frames); ReadSetting("Renderer", Settings::values.texture_filter); ReadSetting("Renderer", Settings::values.texture_sampling); ReadSetting("Renderer", Settings::values.turbo_limit); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index 5e2eab1d1..677ca7ac9 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -127,6 +127,10 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"( # 0 (default): Off, 1: On )") DECLARE_KEY(use_vsync) BOOST_HANA_STRING(R"( +# Skips display of duplicated frames in 30 fps games +# 0 (default): Off, 1: On +)") DECLARE_KEY(use_skip_duplicate_frames) BOOST_HANA_STRING(R"( + # Reduce stuttering by storing and loading generated shaders to disk # 0: Off, 1 (default. On) )") DECLARE_KEY(use_disk_shader_cache) BOOST_HANA_STRING(R"( diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index fa6ff311d..9413b2b15 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -701,6 +701,7 @@ void QtConfig::ReadRendererValues() { ReadGlobalSetting(Settings::values.shaders_accurate_mul); ReadGlobalSetting(Settings::values.use_disk_shader_cache); ReadGlobalSetting(Settings::values.use_vsync); + ReadGlobalSetting(Settings::values.use_skip_duplicate_frames); ReadGlobalSetting(Settings::values.use_display_refresh_rate_detection); ReadGlobalSetting(Settings::values.resolution_factor); ReadGlobalSetting(Settings::values.use_integer_scaling); @@ -1242,6 +1243,7 @@ void QtConfig::SaveRendererValues() { WriteGlobalSetting(Settings::values.shaders_accurate_mul); WriteGlobalSetting(Settings::values.use_disk_shader_cache); WriteGlobalSetting(Settings::values.use_vsync); + WriteGlobalSetting(Settings::values.use_skip_duplicate_frames); WriteGlobalSetting(Settings::values.use_display_refresh_rate_detection); WriteGlobalSetting(Settings::values.resolution_factor); WriteGlobalSetting(Settings::values.use_integer_scaling); diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index aac27ab16..bbf529757 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -7,6 +7,7 @@ #include "citra_qt/configuration/configuration_shared.h" #include "citra_qt/configuration/configure_graphics.h" #include "common/settings.h" +#include "configuration/ui_configure_graphics.h" #include "ui_configure_graphics.h" #ifdef ENABLE_VULKAN #include "video_core/renderer_vulkan/vk_instance.h" @@ -144,6 +145,7 @@ void ConfigureGraphics::SetConfiguration() { ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue()); ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue()); ui->toggle_vsync->setChecked(Settings::values.use_vsync.GetValue()); + ui->toggle_skip_duplicate_frames->setChecked(Settings::values.use_skip_duplicate_frames.GetValue()); ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue()); ui->disable_spirv_optimizer->setChecked(Settings::values.disable_spirv_optimizer.GetValue()); ui->toggle_async_shaders->setChecked(Settings::values.async_shader_compilation.GetValue()); @@ -179,6 +181,8 @@ void ConfigureGraphics::ApplyConfiguration() { ui->toggle_disk_shader_cache, use_disk_shader_cache); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->toggle_vsync, use_vsync); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_skip_duplicate_frames, ui->toggle_skip_duplicate_frames, + use_skip_duplicate_frames); ConfigurationShared::ApplyPerGameSetting( &Settings::values.delay_game_render_thread_us, ui->delay_render_combo, [this](s32) { return ui->delay_render_slider->value(); }); @@ -204,6 +208,8 @@ void ConfigureGraphics::SetupPerGameUI() { Settings::values.use_disk_shader_cache.UsingGlobal()); ui->toggle_vsync->setEnabled(ui->toggle_vsync->isEnabled() && Settings::values.use_vsync.UsingGlobal()); + ui->toggle_skip_duplicate_frames->setEnabled(ui->toggle_skip_duplicate_frames->isEnabled() && + Settings::values.use_skip_duplicate_frames.UsingGlobal()); ui->toggle_async_shaders->setEnabled( Settings::values.async_shader_compilation.UsingGlobal()); ui->widget_texture_sampling->setEnabled(Settings::values.texture_sampling.UsingGlobal()); @@ -244,6 +250,8 @@ void ConfigureGraphics::SetupPerGameUI() { use_disk_shader_cache); ConfigurationShared::SetColoredTristate(ui->toggle_vsync, Settings::values.use_vsync, use_vsync); + ConfigurationShared::SetColoredTristate(ui->toggle_skip_duplicate_frames, Settings::values.use_skip_duplicate_frames, + use_skip_duplicate_frames); ConfigurationShared::SetColoredTristate(ui->toggle_async_shaders, Settings::values.async_shader_compilation, async_shader_compilation); diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 61a462a67..8b387254a 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -39,6 +39,7 @@ private: ConfigurationShared::CheckState shaders_accurate_mul; ConfigurationShared::CheckState use_disk_shader_cache; ConfigurationShared::CheckState use_vsync; + ConfigurationShared::CheckState use_skip_duplicate_frames; ConfigurationShared::CheckState use_display_refresh_rate_detection; ConfigurationShared::CheckState async_shader_compilation; ConfigurationShared::CheckState async_presentation; diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index ff5ec613f..a73ec4468 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -7,7 +7,7 @@ 0 0 400 - 509 + 559 @@ -138,12 +138,12 @@ - - Disable GLSL -> SPIR-V optimizer - <html><head/><body><p>Disables the SPIR-V optimization pass, reducing stuttering considerably while barely affecting performance.</p></body></html> + + Disable GLSL -> SPIR-V optimizer + @@ -317,6 +317,16 @@ + + + + <html><head/><body><p>Skips presenting duplicated frames in 30fps games. This allows external frame generation tools to work correctly in 30fps games. This does not boost performance.</p></body></html> + + + Skip Duplicate Frame Display + + + @@ -328,81 +338,81 @@ - - - - 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + Use global - - 0 + + + + Use per-application - - 0 - - - 0 - - - - - - Use global - - - - - Use per-application - - - - - - - - Delay Application Render Thread - - - <html><head/><body><p>Delays the emulated application render thread the specified amount of milliseconds every time it submits render commands to the GPU.</p><p>Adjust this feature in the (very few) dynamic framerate applications to fix performance issues.</p></body></html> - - - - - - - 0 - - - 16000 - - - 100 - - - 250 - - - 0 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - + + + + + + + <html><head/><body><p>Delays the emulated application render thread the specified amount of milliseconds every time it submits render commands to the GPU.</p><p>Adjust this feature in the (very few) dynamic framerate applications to fix performance issues.</p></body></html> + + + Delay Application Render Thread + + + + + + + 0 + + + 16000 + + + 100 + + + 250 + + + 0 + + + Qt::Orientation::Horizontal + + + QSlider::TickPosition::TicksBelow + + + + + + + + + + Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter + + + + + @@ -410,7 +420,7 @@ - Qt::Vertical + Qt::Orientation::Vertical diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 2ac231f50..f0906711b 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -100,6 +100,7 @@ void LogSettings() { log_setting("Renderer_UseIntegerScaling", values.use_integer_scaling.GetValue()); log_setting("Renderer_FrameLimit", values.frame_limit.GetValue()); log_setting("Renderer_VSyncNew", values.use_vsync.GetValue()); + log_setting("Renderer_SkipDuplicateFrames", values.use_skip_duplicate_frames.GetValue()); log_setting("Renderer_PostProcessingShader", values.pp_shader_name.GetValue()); log_setting("Renderer_FilterMode", values.filter_mode.GetValue()); log_setting("Renderer_TextureFilter", GetTextureFilterName(values.texture_filter.GetValue())); @@ -209,6 +210,7 @@ void RestoreGlobalState(bool is_powered_on) { values.use_disk_shader_cache.SetGlobal(true); values.shaders_accurate_mul.SetGlobal(true); values.use_vsync.SetGlobal(true); + values.use_skip_duplicate_frames.SetGlobal(true); values.resolution_factor.SetGlobal(true); values.use_integer_scaling.SetGlobal(true); values.frame_limit.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index e03c46961..36c739e90 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -518,6 +518,7 @@ struct Values { SwitchableSetting async_presentation{true, Keys::async_presentation}; SwitchableSetting use_hw_shader{true, Keys::use_hw_shader}; SwitchableSetting use_disk_shader_cache{true, Keys::use_disk_shader_cache}; + SwitchableSetting use_skip_duplicate_frames{true, Keys::use_skip_duplicate_frames}; SwitchableSetting shaders_accurate_mul{true, Keys::shaders_accurate_mul}; #ifdef ANDROID // TODO: Fuck this -OS SwitchableSetting use_vsync{false, Keys::use_vsync}; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 0a25c2036..760e1eaa6 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -24,7 +24,6 @@ #include "video_core/host_shaders/vulkan_cursor_vert.h" #include - #if defined(__APPLE__) && !defined(HAVE_LIBRETRO) #include "common/apple_utils.h" #endif diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 14c9bd34f..c236adc7e 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -134,7 +134,7 @@ private: DescriptorUpdateQueue update_queue; RasterizerVulkan rasterizer; std::unique_ptr secondary_present_window_ptr; - + bool skip_frame_display; DescriptorHeap present_heap; vk::UniquePipelineLayout present_pipeline_layout; std::array present_pipelines;