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