From 38737f26e51bba30d96772b00df6a34d1a28ab7b Mon Sep 17 00:00:00 2001 From: Pavel Barabanov Date: Sat, 12 Apr 2025 00:26:47 +0300 Subject: [PATCH] Optimize SpiriV output --- .../yuzu_emu/features/settings/model/IntSetting.kt | 1 + .../yuzu/yuzu_emu/features/settings/model/Settings.kt | 11 +++++++++++ .../features/settings/model/view/SettingsItem.kt | 9 +++++++++ .../features/settings/ui/SettingsFragmentPresenter.kt | 1 + src/android/app/src/main/res/values/arrays.xml | 11 +++++++++++ src/android/app/src/main/res/values/strings.xml | 6 ++++++ src/common/settings.cpp | 1 + src/common/settings.h | 7 +++++++ src/common/settings_enums.h | 2 ++ src/video_core/renderer_opengl/gl_shader_cache.h | 1 + src/video_core/renderer_vulkan/vk_pipeline_cache.h | 1 + src/yuzu/configuration/shared_translation.cpp | 11 ++++++++++- src/yuzu/uisettings.h | 1 + 13 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index 0165cb2d1d..c6d83c346f 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -18,6 +18,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { RENDERER_ANTI_ALIASING("anti_aliasing"), RENDERER_SCREEN_LAYOUT("screen_layout"), RENDERER_ASPECT_RATIO("aspect_ratio"), + RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"), AUDIO_OUTPUT_ENGINE("output_engine"), MAX_ANISOTROPY("max_anisotropy"), THEME("theme"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt index e189c21560..eeeff1043e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt @@ -120,4 +120,15 @@ object Settings { entries.firstOrNull { it.int == int } ?: Center } } + + enum class OptimizeSpirvOutput(val int: Int) { + Never(0), + OnLoad(1), + Always(2); + + companion object { + fun from(int: Int): OptimizeSpirvOutput = + entries.firstOrNull { it.int == int } ?: OnLoad + } + } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 6bc6be0031..4041998d74 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -368,6 +368,15 @@ abstract class SettingsItem( descriptionId = R.string.renderer_force_max_clock_description ) ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT, + titleId = R.string.renderer_optimize_spirv_output, + descriptionId = 0, + choicesId = R.array.optimizeSpirvOutputEntries, + valuesId = R.array.optimizeSpirvOutputValues + ) + ) put( SwitchSetting( BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 33a1c4f5d2..ee359d21f1 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -182,6 +182,7 @@ class SettingsFragmentPresenter( add(IntSetting.RENDERER_SCREEN_LAYOUT.key) add(IntSetting.RENDERER_ASPECT_RATIO.key) add(IntSetting.VERTICAL_ALIGNMENT.key) + add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key) add(BooleanSetting.PICTURE_IN_PICTURE.key) add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key) add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key) diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 99013e0485..056b74be7c 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -326,4 +326,15 @@ 2 + + @string/never + @string/on_load + @string/always + + + 0 + 1 + 2 + + diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 20eed3cb34..477c766200 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -249,6 +249,7 @@ Anti-aliasing method Force maximum clocks (Adreno only) Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). + Optimize SPIRV output Use asynchronous shaders Compiles shaders asynchronously, reducing stutter but may introduce glitches. Use reactive flushing @@ -680,6 +681,11 @@ Center Bottom + + Never + On Load + Always + Licenses FidelityFX-FSR diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 80d388fe88..245c432939 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -52,6 +52,7 @@ SWITCHABLE(NvdecEmulation, false); SWITCHABLE(Region, true); SWITCHABLE(RendererBackend, true); SWITCHABLE(ScalingFilter, false); +SWITCHABLE(SpirvOptimizeMode, true); SWITCHABLE(ShaderBackend, true); SWITCHABLE(TimeZone, true); SETTING(VSyncMode, true); diff --git a/src/common/settings.h b/src/common/settings.h index 0aba539e45..7b475e3fbb 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -73,6 +73,7 @@ SWITCHABLE(NvdecEmulation, false); SWITCHABLE(Region, true); SWITCHABLE(RendererBackend, true); SWITCHABLE(ScalingFilter, false); +SWITCHABLE(SpirvOptimizeMode, true); SWITCHABLE(ShaderBackend, true); SWITCHABLE(TimeZone, true); SETTING(VSyncMode, true); @@ -281,6 +282,12 @@ struct Values { #endif SwitchableSetting use_disk_shader_cache{linkage, true, "use_disk_shader_cache", Category::Renderer}; + SwitchableSetting optimize_spirv_output{linkage, + SpirvOptimizeMode::OnLoad, + SpirvOptimizeMode::Never, + SpirvOptimizeMode::Always, + "optimize_spirv_output", + Category::Renderer}; SwitchableSetting use_asynchronous_gpu_emulation{ linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer}; SwitchableSetting accelerate_astc{linkage, diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index 6e247e9306..75189e60d7 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -155,6 +155,8 @@ ENUM(ConsoleMode, Handheld, Docked); ENUM(AppletMode, HLE, LLE); +ENUM(SpirvOptimizeMode, Never, OnLoad, Always); + template inline std::string CanonicalizeEnum(Type id) { const auto group = EnumMetadata::Canonicalizations(); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 5ac4135295..2b46c22c70 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -73,6 +73,7 @@ private: VideoCore::ShaderNotify& shader_notify; const bool use_asynchronous_shaders; const bool strict_context_required; + bool optimize_spirv_output{}; GraphicsPipelineKey graphics_key{}; GraphicsPipeline* current_pipeline{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 7977001280..7909bd8cf0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -150,6 +150,7 @@ private: VideoCore::ShaderNotify& shader_notify; bool use_asynchronous_shaders{}; bool use_vulkan_pipeline_cache{}; + bool optimize_spirv_output{}; GraphicsPipelineCacheKey graphics_key{}; GraphicsPipeline* current_pipeline{}; diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index e80319cddf..440467010b 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -147,6 +147,10 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { tr("Allows saving shaders to storage for faster loading on following game " "boots.\nDisabling " "it is only intended for debugging.")); + INSERT(Settings, optimize_spirv_output, tr("Optimize SPIRV output shader"), + tr("Runs an additional optimization pass over generated SPIRV shaders.\n" + "Will increase time required for shader compilation.\nMay slightly improve " + "performance.\nThis feature is experimental.")); INSERT( Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); @@ -310,7 +314,12 @@ std::unique_ptr ComboboxEnumeration(QWidget* parent) { PAIR(AppletMode, HLE, tr("Custom frontend")), PAIR(AppletMode, LLE, tr("Real applet")), }}); - + translations->insert({Settings::EnumMetadata::Index(), + { + PAIR(SpirvOptimizeMode, Never, tr("Never")), + PAIR(SpirvOptimizeMode, OnLoad, tr("On Load")), + PAIR(SpirvOptimizeMode, Always, tr("Always")), + }}); translations->insert({Settings::EnumMetadata::Index(), { PAIR(AstcDecodeMode, Cpu, tr("CPU")), diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 61704c6fa6..4bbdb1e11c 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -277,3 +277,4 @@ Q_DECLARE_METATYPE(Settings::RendererBackend); Q_DECLARE_METATYPE(Settings::ShaderBackend); Q_DECLARE_METATYPE(Settings::AstcRecompression); Q_DECLARE_METATYPE(Settings::AstcDecodeMode); +Q_DECLARE_METATYPE(Settings::SpirvOptimizeMode); \ No newline at end of file