From fd2ce82b6e147c523a56f0643eff5471b489df63 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Wed, 28 May 2025 22:22:59 +0200 Subject: [PATCH] Add toggle to disable SPIRV optimization pass (#1080) * Add toggle to disable SPIRV optimization pass * vk_shader_util.cpp: Nitpicky comment tweak * Consistently refer to "optimizer" instead of "optimization" --------- Co-authored-by: OpenSauce04 --- .../features/settings/model/BooleanSetting.kt | 1 + .../features/settings/ui/SettingsFragmentPresenter.kt | 9 +++++++++ src/android/app/src/main/jni/config.cpp | 1 + src/android/app/src/main/jni/default_ini.h | 4 ++++ src/android/app/src/main/res/values/strings.xml | 2 ++ src/citra_qt/configuration/configure_graphics.cpp | 10 +++++++++- src/citra_qt/configuration/configure_graphics.h | 3 ++- src/citra_qt/configuration/configure_graphics.ui | 10 ++++++++++ src/common/settings.h | 1 + src/video_core/renderer_vulkan/vk_shader_util.cpp | 7 ++++--- 10 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt index ef62087e1..997e30a30 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt @@ -12,6 +12,7 @@ enum class BooleanSetting( EXPAND_TO_CUTOUT_AREA("expand_to_cutout_area", Settings.SECTION_LAYOUT, false), SPIRV_SHADER_GEN("spirv_shader_gen", Settings.SECTION_RENDERER, true), ASYNC_SHADERS("async_shader_compilation", Settings.SECTION_RENDERER, false), + DISABLE_SPIRV_OPTIMIZER("disable_spirv_optimizer", Settings.SECTION_RENDERER, true), PLUGIN_LOADER("plugin_loader", Settings.SECTION_SYSTEM, false), ALLOW_PLUGIN_LOADER("allow_plugin_loader", Settings.SECTION_SYSTEM, true), SWAP_SCREEN("swap_screen", Settings.SECTION_LAYOUT, false), diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt index fc0b40d67..70b896e92 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -839,6 +839,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) BooleanSetting.SPIRV_SHADER_GEN.defaultValue, ) ) + add( + SwitchSetting( + BooleanSetting.DISABLE_SPIRV_OPTIMIZER, + R.string.disable_spirv_optimizer, + R.string.disable_spirv_optimizer_description, + BooleanSetting.DISABLE_SPIRV_OPTIMIZER.key, + BooleanSetting.DISABLE_SPIRV_OPTIMIZER.defaultValue, + ) + ) add( SwitchSetting( BooleanSetting.ASYNC_SHADERS, diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 9df017a6f..b46333ada 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -142,6 +142,7 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.async_presentation); ReadSetting("Renderer", Settings::values.async_shader_compilation); ReadSetting("Renderer", Settings::values.spirv_shader_gen); + ReadSetting("Renderer", Settings::values.disable_spirv_optimizer); ReadSetting("Renderer", Settings::values.use_hw_shader); ReadSetting("Renderer", Settings::values.use_shader_jit); ReadSetting("Renderer", Settings::values.resolution_factor); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index f3a6a169a..83fa897fa 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -113,6 +113,10 @@ async_shader_compilation = # 0: GLSL, 1: SPIR-V (default) spirv_shader_gen = +# Whether to disable the SPIRV optimizer. Disabling it reduces stutter, but may slightly worsen performance +# 0: Enabled, 1: Disabled (default) +disable_spirv_optimizer = + # Whether to use hardware shaders to emulate 3DS shaders # 0: Software, 1 (default): Hardware use_hw_shader = diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 19e570f21..922c25476 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -870,5 +870,7 @@ Quickload Quicksave - %1$tF %1$tR No Quicksave available. + Disable SPIR-V Optimizer + Disables the SPIR-V optimization pass, reducing stuttering considerably while barely affecting performance. diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index d06f5a97d..eb706fb56 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -1,4 +1,4 @@ -// Copyright 2016 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -59,6 +59,7 @@ ConfigureGraphics::ConfigureGraphics(QString gl_renderer, std::spanphysical_device_combo->setVisible(false); ui->spirv_shader_gen->setVisible(false); + ui->disable_spirv_optimizer->setVisible(false); } else { for (const QString& name : physical_devices) { ui->physical_device_combo->addItem(name); @@ -143,6 +144,7 @@ void ConfigureGraphics::SetConfiguration() { ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue()); ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new.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()); ui->toggle_async_present->setChecked(Settings::values.async_presentation.GetValue()); @@ -162,6 +164,8 @@ void ConfigureGraphics::ApplyConfiguration() { ui->toggle_async_present, async_presentation); ConfigurationShared::ApplyPerGameSetting(&Settings::values.spirv_shader_gen, ui->spirv_shader_gen, spirv_shader_gen); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.disable_spirv_optimizer, + ui->disable_spirv_optimizer, disable_spirv_optimizer); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader, use_hw_shader); ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul, @@ -241,6 +245,9 @@ void ConfigureGraphics::SetupPerGameUI() { ui->toggle_async_present, Settings::values.async_presentation, async_presentation); ConfigurationShared::SetColoredTristate(ui->spirv_shader_gen, Settings::values.spirv_shader_gen, spirv_shader_gen); + ConfigurationShared::SetColoredTristate(ui->disable_spirv_optimizer, + Settings::values.disable_spirv_optimizer, + disable_spirv_optimizer); } void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { @@ -263,5 +270,6 @@ void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { ui->physical_device_group->setVisible(effective_api == Settings::GraphicsAPI::Vulkan); ui->spirv_shader_gen->setVisible(effective_api == Settings::GraphicsAPI::Vulkan); + ui->disable_spirv_optimizer->setVisible(effective_api == Settings::GraphicsAPI::Vulkan); ui->opengl_renderer_group->setVisible(effective_api == Settings::GraphicsAPI::OpenGL); } diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 129c4a9d5..1031b964a 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -1,4 +1,4 @@ -// Copyright 2016 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -42,6 +42,7 @@ private: ConfigurationShared::CheckState async_shader_compilation; ConfigurationShared::CheckState async_presentation; ConfigurationShared::CheckState spirv_shader_gen; + ConfigurationShared::CheckState disable_spirv_optimizer; std::unique_ptr ui; QColor bg_color; }; diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index b2ee3c279..fea3c523d 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -136,6 +136,16 @@ + + + + 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> + + + diff --git a/src/common/settings.h b/src/common/settings.h index 19b3dfa48..c8e76179c 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -498,6 +498,7 @@ struct Values { Setting renderer_debug{false, "renderer_debug"}; Setting dump_command_buffers{false, "dump_command_buffers"}; SwitchableSetting spirv_shader_gen{true, "spirv_shader_gen"}; + SwitchableSetting disable_spirv_optimizer{true, "disable_spirv_optimizer"}; SwitchableSetting async_shader_compilation{false, "async_shader_compilation"}; SwitchableSetting async_presentation{true, "async_presentation"}; SwitchableSetting use_hw_shader{true, "use_hw_shader"}; diff --git a/src/video_core/renderer_vulkan/vk_shader_util.cpp b/src/video_core/renderer_vulkan/vk_shader_util.cpp index 3d2f2f1d1..ee3db73de 100644 --- a/src/video_core/renderer_vulkan/vk_shader_util.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_util.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Citra Emulator Project +// Copyright Citra Emulator Project / Azahar Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -9,6 +9,7 @@ #include "common/assert.h" #include "common/literals.h" #include "common/logging/log.h" +#include "common/settings.h" #include "video_core/renderer_vulkan/vk_shader_util.h" namespace Vulkan { @@ -203,8 +204,8 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v spv::SpvBuildLogger logger; glslang::SpvOptions options; - // Enable optimizations on the generated SPIR-V code. - options.disableOptimizer = false; + // Controls optimizations on the generated SPIR-V code. + options.disableOptimizer = Settings::values.disable_spirv_optimizer.GetValue(); options.validate = false; options.optimizeSize = true;