renderer_vulkan: add Extended Dynamic State user setting

Add configurable EDS levels (Disabled/EDS1/EDS2/EDS3) to allow users to
troubleshoot graphics issues by controlling which Vulkan Extended Dynamic
State features are enabled. Defaults to EDS3 for maximum performance.

Implements setting in both desktop and Android frontends with proper
translations and descriptions.

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-10-17 18:52:30 +10:00
parent ac21b19165
commit b85fd5fc73
10 changed files with 79 additions and 7 deletions

View File

@@ -30,7 +30,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SHOW_THERMAL_OVERLAY("show_thermal_overlay"),
SHOW_RAM_METER("show_ram_meter"),
SHOW_SHADER_BUILDING_OVERLAY("show_shader_building_overlay"),
SHOW_PERFORMANCE_GRAPH("show_performance_graph");
SHOW_PERFORMANCE_GRAPH("show_performance_graph"),
USE_CONDITIONAL_RENDERING("use_conditional_rendering");
override fun getBoolean(needsGlobal: Boolean): Boolean =
NativeConfig.getBoolean(key, needsGlobal)

View File

@@ -38,6 +38,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
ASTC_RECOMPRESSION("astc_recompression"),
SHADER_BACKEND("shader_backend"),
VRAM_USAGE_MODE("vram_usage_mode"),
EXTENDED_DYNAMIC_STATE("extended_dynamic_state"),
// Applet Mode settings
CABINET_APPLET_MODE("cabinet_applet_mode"),

View File

@@ -1014,6 +1014,8 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.advanced_graphics_header))
add(IntSetting.SHADER_BACKEND.key)
add(IntSetting.VRAM_USAGE_MODE.key)
add(IntSetting.EXTENDED_DYNAMIC_STATE.key)
add(BooleanSetting.USE_CONDITIONAL_RENDERING.key)
add(HeaderSetting(R.string.frame_skipping_header))
add(IntSetting.FRAME_SKIPPING.key)

View File

@@ -404,6 +404,20 @@
<item>2</item>
</integer-array>
<string-array name="extendedDynamicStateNames">
<item>Disabled</item>
<item>EDS1</item>
<item>EDS2</item>
<item>EDS3</item>
</string-array>
<integer-array name="extendedDynamicStateValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</integer-array>
<string-array name="vramUsageModeNames">
<item>Conservative</item>
<item>Aggressive</item>

View File

@@ -1239,6 +1239,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<string name="shader_backend_description">Controls which shader backend to use for rendering.</string>
<string name="vram_usage_mode">VRAM Usage Mode</string>
<string name="vram_usage_mode_description">Controls how aggressively VRAM is used. Conservative mode limits VRAM usage for better stability.</string>
<string name="extended_dynamic_state">Extended Dynamic State</string>
<string name="extended_dynamic_state_description">Controls which Vulkan Extended Dynamic State features are enabled. EDS3 (default) enables all features for maximum compatibility. EDS2/EDS1 limit features for troubleshooting graphics issues. Disabled turns off all EDS features. Try lower settings if you experience rendering problems in some games.</string>
<string name="use_conditional_rendering">Use Conditional Rendering</string>
<string name="use_conditional_rendering_description">Enables conditional rendering based on query results. Disabling this can fix flickering objects in some games but may impact performance. Try disabling if you see objects appearing and disappearing rapidly.</string>
<string name="frame_skipping">Frame Skipping</string>
<string name="frame_skipping_description">Skips frames to maintain performance when the system cannot keep up with the target frame rate.</string>
<string name="frame_skipping_mode">Frame Skipping Mode</string>

View File

@@ -230,6 +230,12 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
"unlocked."));
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
tr("Improves rendering of transparency effects in specific games."));
INSERT(Settings, extended_dynamic_state, tr("Extended Dynamic State:"),
tr("Selects the level of Vulkan Extended Dynamic State support.\n"
"EDS3: Enables all Extended Dynamic State features (recommended).\n"
"EDS2: Enables EDS1 and EDS2 features only.\n"
"EDS1: Enables basic Extended Dynamic State features only.\n"
"Disabled: Disables all Extended Dynamic State features (may reduce compatibility)."));
INSERT(Settings, use_conditional_rendering, tr("Use conditional rendering"),
tr("Enables conditional rendering based on query results.\n"
"Disabling this can fix flickering objects in some games but may impact performance.\n"
@@ -340,6 +346,13 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
PAIR(VramUsageMode, HighEnd, tr("High-End GPU (4090/4080+)")),
PAIR(VramUsageMode, Insane, tr("Insane (RTX 4090 24GB)")),
}});
translations->insert({Settings::EnumMetadata<Settings::ExtendedDynamicState>::Index(),
{
PAIR(ExtendedDynamicState, Disabled, tr("Disabled")),
PAIR(ExtendedDynamicState, EDS1, tr("EDS1")),
PAIR(ExtendedDynamicState, EDS2, tr("EDS2")),
PAIR(ExtendedDynamicState, EDS3, tr("EDS3")),
}});
translations->insert({Settings::EnumMetadata<Settings::RendererBackend>::Index(),
{
#ifdef HAS_OPENGL

View File

@@ -42,6 +42,7 @@ SWITCHABLE(AspectRatio, true);
SWITCHABLE(AstcDecodeMode, true);
SWITCHABLE(AstcRecompression, true);
SWITCHABLE(AudioMode, true);
SWITCHABLE(ExtendedDynamicState, true);
SWITCHABLE(CpuBackend, true);
SWITCHABLE(CpuAccuracy, true);
SWITCHABLE(FullscreenMode, true);

View File

@@ -64,6 +64,7 @@ SWITCHABLE(AspectRatio, true);
SWITCHABLE(AstcDecodeMode, true);
SWITCHABLE(AstcRecompression, true);
SWITCHABLE(AudioMode, true);
SWITCHABLE(ExtendedDynamicState, true);
SWITCHABLE(CpuBackend, true);
SWITCHABLE(CpuAccuracy, true);
SWITCHABLE(FullscreenMode, true);
@@ -469,6 +470,12 @@ struct Values {
Category::RendererAdvanced};
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
Category::RendererAdvanced};
SwitchableSetting<ExtendedDynamicState, true> extended_dynamic_state{linkage,
ExtendedDynamicState::EDS3,
ExtendedDynamicState::Disabled,
ExtendedDynamicState::EDS3,
"extended_dynamic_state",
Category::RendererAdvanced};
SwitchableSetting<bool> use_conditional_rendering{linkage, true, "use_conditional_rendering",
Category::RendererAdvanced};

View File

@@ -853,6 +853,29 @@ inline u32 EnumMetadata<AppletMode>::Index() {
return 25;
}
enum class ExtendedDynamicState : u32 {
Disabled = 0,
EDS1 = 1,
EDS2 = 2,
EDS3 = 3,
};
template <>
inline std::vector<std::pair<std::string, ExtendedDynamicState>>
EnumMetadata<ExtendedDynamicState>::Canonicalizations() {
return {
{"Disabled", ExtendedDynamicState::Disabled},
{"EDS1", ExtendedDynamicState::EDS1},
{"EDS2", ExtendedDynamicState::EDS2},
{"EDS3", ExtendedDynamicState::EDS3},
};
}
template <>
inline u32 EnumMetadata<ExtendedDynamicState>::Index() {
return 26;
}
template <typename Type>
inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations();

View File

@@ -403,13 +403,19 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays);
}
// Apply user's Extended Dynamic State setting
const auto eds_setting = Settings::values.extended_dynamic_state.GetValue();
const bool allow_eds1 = eds_setting >= Settings::ExtendedDynamicState::EDS1;
const bool allow_eds2 = eds_setting >= Settings::ExtendedDynamicState::EDS2;
const bool allow_eds3 = eds_setting >= Settings::ExtendedDynamicState::EDS3;
dynamic_features = DynamicFeatures{
.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(),
.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(),
.has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported(),
.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported(),
.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported(),
.has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(),
.has_extended_dynamic_state = allow_eds1 && device.IsExtExtendedDynamicStateSupported(),
.has_extended_dynamic_state_2 = allow_eds2 && device.IsExtExtendedDynamicState2Supported(),
.has_extended_dynamic_state_2_extra = allow_eds2 && device.IsExtExtendedDynamicState2ExtrasSupported(),
.has_extended_dynamic_state_3_blend = allow_eds3 && device.IsExtExtendedDynamicState3BlendingSupported(),
.has_extended_dynamic_state_3_enables = allow_eds3 && device.IsExtExtendedDynamicState3EnablesSupported(),
.has_dynamic_vertex_input = allow_eds3 && device.IsExtVertexInputDynamicStateSupported(),
};
}