From 5080513a5e9d040da687435f7c0b7af175065963 Mon Sep 17 00:00:00 2001 From: edendev Date: Tue, 22 Apr 2025 18:22:25 -0700 Subject: [PATCH 01/13] Enable ExtendedDynamicState 1 across platforms --- .../vulkan_common/vulkan_device.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index f2d554a65a..14b6b72fcd 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -483,16 +483,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_qualcomm || is_turnip) { LOG_WARNING(Render_Vulkan, "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); - RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, - VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, + //VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); } if (is_qualcomm) { - must_emulate_scaled_formats = true; + must_emulate_scaled_formats = false; LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_extended_dynamic_state"); - RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, + //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); LOG_WARNING(Render_Vulkan, "Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); @@ -522,11 +522,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_arm) { - must_emulate_scaled_formats = true; + must_emulate_scaled_formats = false; LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state"); - RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, + //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } if (is_nvidia) { @@ -552,9 +552,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state"); - RemoveExtensionFeature(extensions.extended_dynamic_state, - features.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.extended_dynamic_state, + //features.extended_dynamic_state, + //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_radv) { From 8823f12f186d8b6b442f485a7eb6ec26d142848f Mon Sep 17 00:00:00 2001 From: edendev Date: Tue, 22 Apr 2025 20:59:02 -0700 Subject: [PATCH 02/13] Enable ExtendedDynamicState 2 and other features --- .../vulkan_common/vulkan_device.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 14b6b72fcd..9bbd81739a 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -563,9 +563,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING( Render_Vulkan, "RADV versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2"); - RemoveExtensionFeature(extensions.extended_dynamic_state2, - features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.extended_dynamic_state2, + // features.extended_dynamic_state2, + // VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_qualcomm) { @@ -575,9 +575,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2. LOG_WARNING(Render_Vulkan, "Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2"); - RemoveExtensionFeature(extensions.extended_dynamic_state2, - features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.extended_dynamic_state2, + //features.extended_dynamic_state2, + //VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state3 && is_radv) { @@ -610,18 +610,18 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_rdna2) { LOG_WARNING(Render_Vulkan, "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware"); - RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - features.vertex_input_dynamic_state, - VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + // RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + // features.vertex_input_dynamic_state, + // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.vertex_input_dynamic_state && is_qualcomm) { // Qualcomm drivers do not properly support vertex_input_dynamic_state. LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state"); - RemoveExtensionFeature(extensions.vertex_input_dynamic_state, - features.vertex_input_dynamic_state, - VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + //RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + // features.vertex_input_dynamic_state, + // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } sets_per_pool = 64; @@ -1159,7 +1159,7 @@ void Device::RemoveUnsuitableExtensions() { RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); - // VK_EXT_extended_dynamic_state + /* */ // VK_EXT_extended_dynamic_state extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState; RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state, features.extended_dynamic_state, @@ -1169,7 +1169,7 @@ void Device::RemoveUnsuitableExtensions() { extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); **/ // VK_EXT_extended_dynamic_state3 dynamic_state3_blending = From e96383615b931e690c29a9064243965baa41f6b0 Mon Sep 17 00:00:00 2001 From: edendev Date: Tue, 22 Apr 2025 21:02:48 -0700 Subject: [PATCH 03/13] Fixed typo --- src/video_core/vulkan_common/vulkan_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9bbd81739a..4c1a350e76 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1169,7 +1169,7 @@ void Device::RemoveUnsuitableExtensions() { extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, features.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); **/ + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); // VK_EXT_extended_dynamic_state3 dynamic_state3_blending = From c64c404a2f60fee2126f671ab38940bf6c19089a Mon Sep 17 00:00:00 2001 From: JPikachu Date: Wed, 23 Apr 2025 19:01:56 +0100 Subject: [PATCH 04/13] Enable ExtendedDynamicState 3 --- .../vulkan_common/vulkan_device.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 4c1a350e76..9426d31faf 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -582,25 +582,25 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (extensions.extended_dynamic_state3 && is_radv) { LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; - dynamic_state3_blending = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true; + dynamic_state3_blending = true; const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 23.1.0 have broken depth clamp dynamic state"); - features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false; - dynamic_state3_enables = false; + features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = true; + dynamic_state3_enables = true; } } if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { // AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation LOG_WARNING(Render_Vulkan, "AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation"); - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; - features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; - dynamic_state3_blending = false; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true; + features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true; + dynamic_state3_blending = true; } if (extensions.vertex_input_dynamic_state && is_radv) { // TODO(ameerj): Blacklist only offending driver versions @@ -721,8 +721,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR "Removing extendedDynamicState3 due to missing extendedDynamicState2"); RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); - dynamic_state3_blending = false; - dynamic_state3_enables = false; + dynamic_state3_blending = true; + dynamic_state3_enables = true; } logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), From 1949e7c438bd0d8a19c8fa2861a3ef3461837fc7 Mon Sep 17 00:00:00 2001 From: swurl Date: Wed, 23 Apr 2025 20:57:53 -0400 Subject: [PATCH 05/13] Add dynamic state extension configs Signed-off-by: swurl --- src/common/settings.cpp | 1 + src/common/settings.h | 11 +++ src/common/settings_common.h | 1 + src/frontend_common/config.cpp | 2 + .../renderer_vulkan/vk_pipeline_cache.cpp | 11 +-- src/yuzu/CMakeLists.txt | 1 + src/yuzu/configuration/configure_dialog.cpp | 29 ++++---- src/yuzu/configuration/configure_dialog.h | 2 + .../configure_graphics_extensions.cpp | 71 +++++++++++++++++++ .../configure_graphics_extensions.h | 45 ++++++++++++ .../configure_graphics_extensions.ui | 68 ++++++++++++++++++ src/yuzu/configuration/configure_per_game.cpp | 4 ++ src/yuzu/configuration/configure_per_game.h | 2 + src/yuzu/configuration/shared_translation.cpp | 20 ++++++ 14 files changed, 251 insertions(+), 17 deletions(-) create mode 100644 src/yuzu/configuration/configure_graphics_extensions.cpp create mode 100644 src/yuzu/configuration/configure_graphics_extensions.h create mode 100644 src/yuzu/configuration/configure_graphics_extensions.ui diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 245c432939..ee7074b128 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -206,6 +206,7 @@ const char* TranslateCategory(Category category) { case Category::Renderer: case Category::RendererAdvanced: case Category::RendererDebug: + case Category::RendererExtensions: return "Renderer"; case Category::System: case Category::SystemAudio: diff --git a/src/common/settings.h b/src/common/settings.h index c2cdeb4994..ca1de28d0a 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -445,6 +445,17 @@ struct Values { SwitchableSetting barrier_feedback_loops{linkage, true, "barrier_feedback_loops", Category::RendererAdvanced}; + SwitchableSetting use_dyna_state_1{linkage, true, "use_dyna_state_1", + Category::RendererExtensions}; + SwitchableSetting use_dyna_state_2{linkage, true, "use_dyna_state_2", + Category::RendererExtensions}; + SwitchableSetting use_dyna_state_2_extras{linkage, true, "use_dyna_state_2_extras", + Category::RendererExtensions}; + SwitchableSetting use_dyna_state_3{linkage, false, "use_dyna_state_3", + Category::RendererExtensions}; + SwitchableSetting use_dyna_state_3_blend{linkage, false, "use_dyna_state_3_blend", + Category::RendererExtensions}; + Setting renderer_debug{linkage, false, "debug", Category::RendererDebug}; Setting renderer_shader_feedback{linkage, false, "shader_feedback", Category::RendererDebug}; diff --git a/src/common/settings_common.h b/src/common/settings_common.h index 2df3f08099..af16ec692b 100644 --- a/src/common/settings_common.h +++ b/src/common/settings_common.h @@ -21,6 +21,7 @@ enum class Category : u32 { Overlay, Renderer, RendererAdvanced, + RendererExtensions, RendererDebug, System, SystemAudio, diff --git a/src/frontend_common/config.cpp b/src/frontend_common/config.cpp index 95f8c8c369..326267e774 100644 --- a/src/frontend_common/config.cpp +++ b/src/frontend_common/config.cpp @@ -362,6 +362,7 @@ void Config::ReadRendererValues() { ReadCategory(Settings::Category::Renderer); ReadCategory(Settings::Category::RendererAdvanced); + ReadCategory(Settings::Category::RendererExtensions); ReadCategory(Settings::Category::RendererDebug); EndGroup(); @@ -670,6 +671,7 @@ void Config::SaveRendererValues() { WriteCategory(Settings::Category::Renderer); WriteCategory(Settings::Category::RendererAdvanced); + WriteCategory(Settings::Category::RendererExtensions); WriteCategory(Settings::Category::RendererDebug); EndGroup(); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a8883bc89f..a0312df65a 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -427,11 +428,11 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, } 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_extended_dynamic_state = Settings::values.use_dyna_state_1.GetValue(), + .has_extended_dynamic_state_2 = Settings::values.use_dyna_state_2.GetValue(), + .has_extended_dynamic_state_2_extra = Settings::values.use_dyna_state_2_extras.GetValue(), + .has_extended_dynamic_state_3_blend = Settings::values.use_dyna_state_3_blend.GetValue(), + .has_extended_dynamic_state_3_enables = Settings::values.use_dyna_state_3.GetValue(), .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), }; } diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 7b94b8054b..e8d2a9ad2a 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -231,6 +231,7 @@ add_executable(yuzu compatdb.h yuzu.qrc yuzu.rc + configuration/configure_graphics_extensions.h configuration/configure_graphics_extensions.cpp configuration/configure_graphics_extensions.ui ) set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden") diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 37f23388e6..987b1462db 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -17,6 +17,7 @@ #include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics_advanced.h" +#include "yuzu/configuration/configure_graphics_extensions.h" #include "yuzu/configuration/configure_hotkeys.h" #include "yuzu/configuration/configure_input.h" #include "yuzu/configuration/configure_input_player.h" @@ -42,7 +43,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, filesystem_tab{std::make_unique(this)}, general_tab{std::make_unique(system_, nullptr, *builder, this)}, graphics_advanced_tab{ - std::make_unique(system_, nullptr, *builder, this)}, + std::make_unique(system_, nullptr, *builder, this)}, + graphics_extensions_tab{ + std::make_unique(system_, nullptr, *builder, this)}, ui_tab{std::make_unique(system_, this)}, graphics_tab{std::make_unique( system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, @@ -68,6 +71,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, ui->tabWidget->addTab(general_tab.get(), tr("General")); ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("GraphicsAdvanced")); + ui->tabWidget->addTab(graphics_extensions_tab.get(), tr("GraphicsExtensions")); ui->tabWidget->addTab(hotkeys_tab.get(), tr("Hotkeys")); ui->tabWidget->addTab(input_tab.get(), tr("Controls")); ui->tabWidget->addTab(profile_tab.get(), tr("Profiles")); @@ -104,7 +108,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, adjustSize(); ui->selectorList->setCurrentRow(0); - // Selects the leftmost button on the bottom bar (Cancel as of writing) + // Selects the leftmost button on the bottom bar (Cancel as of writing) ui->buttonBox->setFocus(); } @@ -123,6 +127,7 @@ void ConfigureDialog::ApplyConfiguration() { cpu_tab->ApplyConfiguration(); graphics_tab->ApplyConfiguration(); graphics_advanced_tab->ApplyConfiguration(); + graphics_extensions_tab->ApplyConfiguration(); audio_tab->ApplyConfiguration(); debug_tab_tab->ApplyConfiguration(); web_tab->ApplyConfiguration(); @@ -162,16 +167,16 @@ Q_DECLARE_METATYPE(QList); void ConfigureDialog::PopulateSelectionList() { const std::array>, 6> items{ - {{tr("General"), - {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, - {tr("System"), - {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), - applets_tab.get()}}, - {tr("CPU"), {cpu_tab.get()}}, - {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get()}}, - {tr("Audio"), {audio_tab.get()}}, - {tr("Controls"), input_tab->GetSubTabs()}}, - }; + {{tr("General"), + {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, + {tr("System"), + {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), + applets_tab.get()}}, + {tr("CPU"), {cpu_tab.get()}}, + {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get(), graphics_extensions_tab.get()}}, + {tr("Audio"), {audio_tab.get()}}, + {tr("Controls"), input_tab->GetSubTabs()}}, + }; [[maybe_unused]] const QSignalBlocker blocker(ui->selectorList); diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index d0a24a07b3..0b6b285678 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -23,6 +23,7 @@ class ConfigureFilesystem; class ConfigureGeneral; class ConfigureGraphics; class ConfigureGraphicsAdvanced; +class ConfigureGraphicsExtensions; class ConfigureHotkeys; class ConfigureInput; class ConfigureProfileManager; @@ -83,6 +84,7 @@ private: std::unique_ptr filesystem_tab; std::unique_ptr general_tab; std::unique_ptr graphics_advanced_tab; + std::unique_ptr graphics_extensions_tab; std::unique_ptr ui_tab; std::unique_ptr graphics_tab; std::unique_ptr hotkeys_tab; diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp new file mode 100644 index 0000000000..28e11b78b7 --- /dev/null +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include "common/settings.h" +#include "core/core.h" +#include "ui_configure_graphics_extensions.h" +#include "yuzu/configuration/configuration_shared.h" +#include "yuzu/configuration/configure_graphics_extensions.h" +#include "yuzu/configuration/shared_translation.h" +#include "yuzu/configuration/shared_widget.h" + +ConfigureGraphicsExtensions::ConfigureGraphicsExtensions( + const Core::System& system_, std::shared_ptr> group_, + const ConfigurationShared::Builder& builder, QWidget* parent) + : Tab(group_, parent), ui{std::make_unique()}, system{system_} { + + ui->setupUi(this); + + Setup(builder); + + SetConfiguration(); +} + +ConfigureGraphicsExtensions::~ConfigureGraphicsExtensions() = default; + +void ConfigureGraphicsExtensions::SetConfiguration() {} + +void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& builder) { + auto& layout = *ui->populate_target->layout(); + std::map hold{}; // A map will sort the data for us + + for (auto setting : + Settings::values.linkage.by_category[Settings::Category::RendererExtensions]) { + ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); + + if (widget == nullptr) { + continue; + } + if (!widget->Valid()) { + widget->deleteLater(); + continue; + } + + hold.emplace(setting->Id(), widget); + } + for (const auto& [id, widget] : hold) { + layout.addWidget(widget); + } +} + +void ConfigureGraphicsExtensions::ApplyConfiguration() { + const bool is_powered_on = system.IsPoweredOn(); + for (const auto& func : apply_funcs) { + func(is_powered_on); + } +} + +void ConfigureGraphicsExtensions::changeEvent(QEvent* event) { + if (event->type() == QEvent::LanguageChange) { + RetranslateUI(); + } + + QWidget::changeEvent(event); +} + +void ConfigureGraphicsExtensions::RetranslateUI() { + ui->retranslateUi(this); +} diff --git a/src/yuzu/configuration/configure_graphics_extensions.h b/src/yuzu/configuration/configure_graphics_extensions.h new file mode 100644 index 0000000000..aea51f5fbe --- /dev/null +++ b/src/yuzu/configuration/configure_graphics_extensions.h @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include "yuzu/configuration/configuration_shared.h" + +namespace Core { +class System; +} + +namespace Ui { +class ConfigureGraphicsExtensions; +} + +namespace ConfigurationShared { +class Builder; +} + +class ConfigureGraphicsExtensions : public ConfigurationShared::Tab { + Q_OBJECT + +public: + explicit ConfigureGraphicsExtensions( + const Core::System& system_, std::shared_ptr> group, + const ConfigurationShared::Builder& builder, QWidget* parent = nullptr); + ~ConfigureGraphicsExtensions() override; + + void ApplyConfiguration() override; + void SetConfiguration() override; + +private: + void Setup(const ConfigurationShared::Builder& builder); + void changeEvent(QEvent* event) override; + void RetranslateUI(); + + std::unique_ptr ui; + + const Core::System& system; + + std::vector> apply_funcs; +}; diff --git a/src/yuzu/configuration/configure_graphics_extensions.ui b/src/yuzu/configuration/configure_graphics_extensions.ui new file mode 100644 index 0000000000..871c794a7c --- /dev/null +++ b/src/yuzu/configuration/configure_graphics_extensions.ui @@ -0,0 +1,68 @@ + + + ConfigureGraphicsExtensions + + + + 0 + 0 + 404 + 376 + + + + Form + + + Extensions + + + + + + + + Vulkan Extension Settings + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index df3251b9bf..031a8d4c2d 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -32,6 +32,7 @@ #include "yuzu/configuration/configure_cpu.h" #include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics_advanced.h" +#include "yuzu/configuration/configure_graphics_extensions.h" #include "yuzu/configuration/configure_input_per_game.h" #include "yuzu/configuration/configure_linux_tab.h" #include "yuzu/configuration/configure_per_game.h" @@ -57,6 +58,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st cpu_tab = std::make_unique(system_, tab_group, *builder, this); graphics_advanced_tab = std::make_unique(system_, tab_group, *builder, this); + graphics_extensions_tab = + std::make_unique(system_, tab_group, *builder, this); graphics_tab = std::make_unique( system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, [](Settings::AspectRatio, Settings::ResolutionSetup) {}, tab_group, *builder, this); @@ -71,6 +74,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st ui->tabWidget->addTab(cpu_tab.get(), tr("CPU")); ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); + ui->tabWidget->addTab(graphics_extensions_tab.get(), tr("GPU Extensions")); ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 196cb32e6f..e0f4e5cd67 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -31,6 +31,7 @@ class ConfigureAudio; class ConfigureCpu; class ConfigureGraphics; class ConfigureGraphicsAdvanced; +class ConfigureGraphicsExtensions; class ConfigureInputPerGame; class ConfigureLinuxTab; class ConfigureSystem; @@ -84,6 +85,7 @@ private: std::unique_ptr audio_tab; std::unique_ptr cpu_tab; std::unique_ptr graphics_advanced_tab; + std::unique_ptr graphics_extensions_tab; std::unique_ptr graphics_tab; std::unique_ptr input_tab; std::unique_ptr linux_tab; diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 440467010b..63ebba2dc1 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -230,6 +230,26 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"), tr("Improves rendering of transparency effects in specific games.")); + INSERT(Settings, use_dyna_state_1, tr("Enable Extended Dynamic State 1"), + tr("Enables the VkExtendedDynamicState1 extension.\nThis setting may improve performance, " + "but may also cause games to break on some systems.")); + + INSERT(Settings, use_dyna_state_2, tr("Enable Extended Dynamic State 2"), + tr("Enables the VkExtendedDynamicState2 extension.\nThis setting may improve performance, " + "but may also cause games to break on some systems.")); + + INSERT(Settings, use_dyna_state_2_extras, tr("Enable Extended Dynamic State 2 Extras"), + tr("Enables the VkExtendedDynamicState2Extras extension.\nThis setting may improve performance, " + "but may also cause games to break on some systems.")); + + INSERT(Settings, use_dyna_state_3, tr("Enable Extended Dynamic State 3"), + tr("Enables the VkExtendedDynamicState3 extension.\nThis setting may improve performance, " + "but may also cause games to break on some systems.")); + + INSERT(Settings, use_dyna_state_3_blend, tr("Enable Extended Dynamic State 3 Blending"), + tr("Enables the VkExtendedDynamicState3Blending extension.\nThis setting may improve performance, " + "but may also cause games to break on some systems.")); + // Renderer (Debug) // System From a137760b48cb0d989ab6a3d7ec2530971b810a0f Mon Sep 17 00:00:00 2001 From: swurl Date: Wed, 23 Apr 2025 21:09:45 -0400 Subject: [PATCH 06/13] add dynamic state settings to android settings Signed-off-by: swurl --- .../yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 6abdc1e1bd..74003e3743 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -18,6 +18,11 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"), RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"), RENDERER_DEBUG("debug"), + DYNA_STATE_1("dyna_state_1"), + DYNA_STATE_2("dyna_state_2"), + DYNA_STATE_2_EXTRAS("dyna_state_2_extras"), + DYNA_STATE_3("dyna_state_3"), + DYNA_STATE_3_blend("dyna_state_3_blend"), RENDERER_ENHANCED_SHADER_BUILDING("use_enhanced_shader_building"), PICTURE_IN_PICTURE("picture_in_picture"), USE_CUSTOM_RTC("custom_rtc_enabled"), From b47c0e07a3f6a2a670651aa19fc20f784d409e6a Mon Sep 17 00:00:00 2001 From: swurl Date: Wed, 23 Apr 2025 21:58:06 -0400 Subject: [PATCH 07/13] Proper linking between states Signed-off-by: swurl --- .../configure_graphics_extensions.cpp | 116 ++++++++++++++++++ src/yuzu/configuration/shared_translation.cpp | 1 + 2 files changed, 117 insertions(+) diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 28e11b78b7..b460dd0887 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "common/settings.h" #include "core/core.h" #include "ui_configure_graphics_extensions.h" @@ -32,6 +33,12 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil auto& layout = *ui->populate_target->layout(); std::map hold{}; // A map will sort the data for us + QCheckBox *dyna_state_1_box = nullptr; + QCheckBox *dyna_state_2_box = nullptr; + QCheckBox *dyna_state_2_extras_box = nullptr; + QCheckBox *dyna_state_3_box = nullptr; + QCheckBox *dyna_state_3_blend_box = nullptr; + for (auto setting : Settings::values.linkage.by_category[Settings::Category::RendererExtensions]) { ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); @@ -45,10 +52,119 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil } hold.emplace(setting->Id(), widget); + + if (setting->Id() == Settings::values.use_dyna_state_1.Id()) { + dyna_state_1_box = widget->checkbox; + } else if (setting->Id() == Settings::values.use_dyna_state_2.Id()) { + dyna_state_2_box = widget->checkbox; + } else if (setting->Id() == Settings::values.use_dyna_state_2_extras.Id()) { + dyna_state_2_extras_box = widget->checkbox; + } else if (setting->Id() == Settings::values.use_dyna_state_3.Id()) { + dyna_state_3_box = widget->checkbox; + } else if (setting->Id() == Settings::values.use_dyna_state_3_blend.Id()) { + dyna_state_3_blend_box = widget->checkbox; + } } + for (const auto& [id, widget] : hold) { layout.addWidget(widget); } + + // I hate everything about this + auto state_1_check = [=](int state) { + bool checked = state == (int) Qt::CheckState::Checked; + + if (!checked) dyna_state_2_box->setChecked(false); + dyna_state_2_box->setEnabled(checked); + }; + + connect(dyna_state_1_box, &QCheckBox::stateChanged, this, state_1_check); + + auto state_2_check = [=](int state) { + bool checked = state == (int) Qt::CheckState::Checked; + bool valid = dyna_state_1_box->isChecked(); + + if (!valid) { + // THIS IS SO BAD + if (!checked) { + emit dyna_state_2_box->clicked(); + } else { + checked = false; + dyna_state_2_box->setChecked(false); + return; + } + } + + if (!checked) { + dyna_state_2_extras_box->setChecked(false); + dyna_state_3_box->setChecked(false); + } + + dyna_state_2_extras_box->setEnabled(checked); + dyna_state_3_box->setEnabled(checked); + }; + + connect(dyna_state_2_box, &QCheckBox::stateChanged, this, state_2_check); + + auto state_3_check = [=](int state) { + bool checked = state == (int) Qt::CheckState::Checked; + bool valid = dyna_state_2_box->isChecked(); + + if (!valid) { + if (!checked) { + emit dyna_state_3_box->clicked(); + } else { + checked = false; + dyna_state_3_box->setChecked(false); + return; + } + } + + if (!checked) dyna_state_3_blend_box->setChecked(false); + dyna_state_3_blend_box->setEnabled(checked); + }; + + connect(dyna_state_3_box, &QCheckBox::stateChanged, this, state_3_check); + + auto state_2_extras_check = [=](int state) { + bool checked = state == (int) Qt::CheckState::Checked; + bool valid = dyna_state_2_box->isChecked(); + + if (!valid) { + if (!checked) { + emit dyna_state_2_extras_box->clicked(); + } else { + checked = false; + dyna_state_2_extras_box->setChecked(false); + return; + } + } + }; + + connect(dyna_state_2_extras_box, &QCheckBox::stateChanged, this, state_2_extras_check); + + auto state_3_blend_check = [=](int state) { + bool checked = state == (int) Qt::CheckState::Checked; + bool valid = dyna_state_3_box->isChecked(); + + if (!valid) { + if (!checked) { + emit dyna_state_3_blend_box->clicked(); + } else { + checked = false; + dyna_state_3_blend_box->setChecked(false); + return; + } + } + }; + + connect(dyna_state_3_blend_box, &QCheckBox::stateChanged, this, state_3_blend_check); + + state_1_check((int) dyna_state_1_box->checkState()); + state_2_check((int) dyna_state_2_box->checkState()); + state_2_extras_check((int) dyna_state_2_extras_box->checkState()); + state_3_check((int) dyna_state_3_box->checkState()); + state_3_blend_check((int) dyna_state_3_blend_box->checkState()); } void ConfigureGraphicsExtensions::ApplyConfiguration() { diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index 63ebba2dc1..c14b35f58f 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -230,6 +230,7 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"), tr("Improves rendering of transparency effects in specific games.")); + // Renderer (Extensions) INSERT(Settings, use_dyna_state_1, tr("Enable Extended Dynamic State 1"), tr("Enables the VkExtendedDynamicState1 extension.\nThis setting may improve performance, " "but may also cause games to break on some systems.")); From eb90246803136124db097b36156c1aa2984e270c Mon Sep 17 00:00:00 2001 From: swurl Date: Wed, 23 Apr 2025 22:14:57 -0400 Subject: [PATCH 08/13] use macro to remove eye destruction Signed-off-by: swurl --- .../configure_graphics_extensions.cpp | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index b460dd0887..a6f50f3ddd 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -53,17 +53,16 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil hold.emplace(setting->Id(), widget); - if (setting->Id() == Settings::values.use_dyna_state_1.Id()) { - dyna_state_1_box = widget->checkbox; - } else if (setting->Id() == Settings::values.use_dyna_state_2.Id()) { - dyna_state_2_box = widget->checkbox; - } else if (setting->Id() == Settings::values.use_dyna_state_2_extras.Id()) { - dyna_state_2_extras_box = widget->checkbox; - } else if (setting->Id() == Settings::values.use_dyna_state_3.Id()) { - dyna_state_3_box = widget->checkbox; - } else if (setting->Id() == Settings::values.use_dyna_state_3_blend.Id()) { - dyna_state_3_blend_box = widget->checkbox; - } +#define CHECKBOX(state) if (setting->Id() == Settings::values.use_dyna_state_##state.Id()) { \ + dyna_state_##state##_box = widget->checkbox; \ + } else + + CHECKBOX(1) + CHECKBOX(2) + CHECKBOX(2_extras) + CHECKBOX(3) + CHECKBOX(3_blend) + {} // else } for (const auto& [id, widget] : hold) { From c140529a7574a43fdadd08912880692204aa64e5 Mon Sep 17 00:00:00 2001 From: swurl Date: Thu, 24 Apr 2025 11:07:17 -0400 Subject: [PATCH 09/13] add notice for extensions Signed-off-by: swurl --- .../configuration/configure_graphics_extensions.ui | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/yuzu/configuration/configure_graphics_extensions.ui b/src/yuzu/configuration/configure_graphics_extensions.ui index 871c794a7c..88dceb3bfa 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.ui +++ b/src/yuzu/configuration/configure_graphics_extensions.ui @@ -25,6 +25,16 @@ Vulkan Extension Settings + + + + While all dynamic state extensions are recommended, some games or systems may not function with Dynamic State 3, or will perform far better with only State 1 or State 2 enabled. + + + true + + + From 83cf9774e19ffa9cf766faaafcd70d7446573035 Mon Sep 17 00:00:00 2001 From: swurl Date: Thu, 24 Apr 2025 12:08:01 -0400 Subject: [PATCH 10/13] switch dynamic state to a slider Signed-off-by: swurl --- src/common/settings.h | 17 ++- .../renderer_vulkan/vk_pipeline_cache.cpp | 11 +- .../configure_graphics_extensions.cpp | 114 ------------------ .../configure_graphics_extensions.ui | 2 +- src/yuzu/configuration/shared_translation.cpp | 22 +--- 5 files changed, 17 insertions(+), 149 deletions(-) diff --git a/src/common/settings.h b/src/common/settings.h index ca1de28d0a..f7cee32ef2 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -445,16 +445,13 @@ struct Values { SwitchableSetting barrier_feedback_loops{linkage, true, "barrier_feedback_loops", Category::RendererAdvanced}; - SwitchableSetting use_dyna_state_1{linkage, true, "use_dyna_state_1", - Category::RendererExtensions}; - SwitchableSetting use_dyna_state_2{linkage, true, "use_dyna_state_2", - Category::RendererExtensions}; - SwitchableSetting use_dyna_state_2_extras{linkage, true, "use_dyna_state_2_extras", - Category::RendererExtensions}; - SwitchableSetting use_dyna_state_3{linkage, false, "use_dyna_state_3", - Category::RendererExtensions}; - SwitchableSetting use_dyna_state_3_blend{linkage, false, "use_dyna_state_3_blend", - Category::RendererExtensions}; + SwitchableSetting dyna_state{linkage, + 0, + 0, + 3, + "dyna_state", + Category::RendererExtensions, + Specialization::Scalar}; Setting renderer_debug{linkage, false, "debug", Category::RendererDebug}; Setting renderer_shader_feedback{linkage, false, "shader_feedback", diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a0312df65a..3a27ed895b 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -427,12 +427,13 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays); } + const u8 dynamic_state = Settings::values.dyna_state.GetValue(); dynamic_features = DynamicFeatures{ - .has_extended_dynamic_state = Settings::values.use_dyna_state_1.GetValue(), - .has_extended_dynamic_state_2 = Settings::values.use_dyna_state_2.GetValue(), - .has_extended_dynamic_state_2_extra = Settings::values.use_dyna_state_2_extras.GetValue(), - .has_extended_dynamic_state_3_blend = Settings::values.use_dyna_state_3_blend.GetValue(), - .has_extended_dynamic_state_3_enables = Settings::values.use_dyna_state_3.GetValue(), + .has_extended_dynamic_state = dynamic_state > 0, + .has_extended_dynamic_state_2 = dynamic_state > 1, + .has_extended_dynamic_state_2_extra = dynamic_state > 1, + .has_extended_dynamic_state_3_blend = dynamic_state > 2, + .has_extended_dynamic_state_3_enables = dynamic_state > 2, .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), }; } diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index a6f50f3ddd..96151c5e09 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -32,13 +32,6 @@ void ConfigureGraphicsExtensions::SetConfiguration() {} void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& builder) { auto& layout = *ui->populate_target->layout(); std::map hold{}; // A map will sort the data for us - - QCheckBox *dyna_state_1_box = nullptr; - QCheckBox *dyna_state_2_box = nullptr; - QCheckBox *dyna_state_2_extras_box = nullptr; - QCheckBox *dyna_state_3_box = nullptr; - QCheckBox *dyna_state_3_blend_box = nullptr; - for (auto setting : Settings::values.linkage.by_category[Settings::Category::RendererExtensions]) { ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); @@ -52,118 +45,11 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil } hold.emplace(setting->Id(), widget); - -#define CHECKBOX(state) if (setting->Id() == Settings::values.use_dyna_state_##state.Id()) { \ - dyna_state_##state##_box = widget->checkbox; \ - } else - - CHECKBOX(1) - CHECKBOX(2) - CHECKBOX(2_extras) - CHECKBOX(3) - CHECKBOX(3_blend) - {} // else } for (const auto& [id, widget] : hold) { layout.addWidget(widget); } - - // I hate everything about this - auto state_1_check = [=](int state) { - bool checked = state == (int) Qt::CheckState::Checked; - - if (!checked) dyna_state_2_box->setChecked(false); - dyna_state_2_box->setEnabled(checked); - }; - - connect(dyna_state_1_box, &QCheckBox::stateChanged, this, state_1_check); - - auto state_2_check = [=](int state) { - bool checked = state == (int) Qt::CheckState::Checked; - bool valid = dyna_state_1_box->isChecked(); - - if (!valid) { - // THIS IS SO BAD - if (!checked) { - emit dyna_state_2_box->clicked(); - } else { - checked = false; - dyna_state_2_box->setChecked(false); - return; - } - } - - if (!checked) { - dyna_state_2_extras_box->setChecked(false); - dyna_state_3_box->setChecked(false); - } - - dyna_state_2_extras_box->setEnabled(checked); - dyna_state_3_box->setEnabled(checked); - }; - - connect(dyna_state_2_box, &QCheckBox::stateChanged, this, state_2_check); - - auto state_3_check = [=](int state) { - bool checked = state == (int) Qt::CheckState::Checked; - bool valid = dyna_state_2_box->isChecked(); - - if (!valid) { - if (!checked) { - emit dyna_state_3_box->clicked(); - } else { - checked = false; - dyna_state_3_box->setChecked(false); - return; - } - } - - if (!checked) dyna_state_3_blend_box->setChecked(false); - dyna_state_3_blend_box->setEnabled(checked); - }; - - connect(dyna_state_3_box, &QCheckBox::stateChanged, this, state_3_check); - - auto state_2_extras_check = [=](int state) { - bool checked = state == (int) Qt::CheckState::Checked; - bool valid = dyna_state_2_box->isChecked(); - - if (!valid) { - if (!checked) { - emit dyna_state_2_extras_box->clicked(); - } else { - checked = false; - dyna_state_2_extras_box->setChecked(false); - return; - } - } - }; - - connect(dyna_state_2_extras_box, &QCheckBox::stateChanged, this, state_2_extras_check); - - auto state_3_blend_check = [=](int state) { - bool checked = state == (int) Qt::CheckState::Checked; - bool valid = dyna_state_3_box->isChecked(); - - if (!valid) { - if (!checked) { - emit dyna_state_3_blend_box->clicked(); - } else { - checked = false; - dyna_state_3_blend_box->setChecked(false); - return; - } - } - }; - - connect(dyna_state_3_blend_box, &QCheckBox::stateChanged, this, state_3_blend_check); - - state_1_check((int) dyna_state_1_box->checkState()); - state_2_check((int) dyna_state_2_box->checkState()); - state_2_extras_check((int) dyna_state_2_extras_box->checkState()); - state_3_check((int) dyna_state_3_box->checkState()); - state_3_blend_check((int) dyna_state_3_blend_box->checkState()); } void ConfigureGraphicsExtensions::ApplyConfiguration() { diff --git a/src/yuzu/configuration/configure_graphics_extensions.ui b/src/yuzu/configuration/configure_graphics_extensions.ui index 88dceb3bfa..3033bd090c 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.ui +++ b/src/yuzu/configuration/configure_graphics_extensions.ui @@ -28,7 +28,7 @@ - While all dynamic state extensions are recommended, some games or systems may not function with Dynamic State 3, or will perform far better with only State 1 or State 2 enabled. + While it's recommended to use state 3, some games may perform better on lower states. Additionally, some older devices and drivers will not work properly with state 3. true diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index c14b35f58f..59f00f384e 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -231,25 +231,9 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { tr("Improves rendering of transparency effects in specific games.")); // Renderer (Extensions) - INSERT(Settings, use_dyna_state_1, tr("Enable Extended Dynamic State 1"), - tr("Enables the VkExtendedDynamicState1 extension.\nThis setting may improve performance, " - "but may also cause games to break on some systems.")); - - INSERT(Settings, use_dyna_state_2, tr("Enable Extended Dynamic State 2"), - tr("Enables the VkExtendedDynamicState2 extension.\nThis setting may improve performance, " - "but may also cause games to break on some systems.")); - - INSERT(Settings, use_dyna_state_2_extras, tr("Enable Extended Dynamic State 2 Extras"), - tr("Enables the VkExtendedDynamicState2Extras extension.\nThis setting may improve performance, " - "but may also cause games to break on some systems.")); - - INSERT(Settings, use_dyna_state_3, tr("Enable Extended Dynamic State 3"), - tr("Enables the VkExtendedDynamicState3 extension.\nThis setting may improve performance, " - "but may also cause games to break on some systems.")); - - INSERT(Settings, use_dyna_state_3_blend, tr("Enable Extended Dynamic State 3 Blending"), - tr("Enables the VkExtendedDynamicState3Blending extension.\nThis setting may improve performance, " - "but may also cause games to break on some systems.")); + INSERT(Settings, dyna_state, tr("Extended Dynamic State"), + tr("Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will generally improve " + "performance, but may cause issues on certain games or devices.")); // Renderer (Debug) From 01065a89a5633fe1670e106afc8d535531ee938c Mon Sep 17 00:00:00 2001 From: swurl Date: Thu, 24 Apr 2025 12:09:59 -0400 Subject: [PATCH 11/13] fix android setting Signed-off-by: swurl --- .../yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt | 5 ----- .../org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 74003e3743..6abdc1e1bd 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -18,11 +18,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"), RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"), RENDERER_DEBUG("debug"), - DYNA_STATE_1("dyna_state_1"), - DYNA_STATE_2("dyna_state_2"), - DYNA_STATE_2_EXTRAS("dyna_state_2_extras"), - DYNA_STATE_3("dyna_state_3"), - DYNA_STATE_3_blend("dyna_state_3_blend"), RENDERER_ENHANCED_SHADER_BUILDING("use_enhanced_shader_building"), PICTURE_IN_PICTURE("picture_in_picture"), USE_CUSTOM_RTC("custom_rtc_enabled"), 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 035a33a762..111a1b0a00 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 @@ -24,6 +24,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { RENDERER_SCREEN_LAYOUT("screen_layout"), RENDERER_ASPECT_RATIO("aspect_ratio"), RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"), + RENDERER_DYNA_STATE("dyna_state"), AUDIO_OUTPUT_ENGINE("output_engine"), MAX_ANISOTROPY("max_anisotropy"), THEME("theme"), From 13eb5e1be40ce705dcf0af336a34be8925545774 Mon Sep 17 00:00:00 2001 From: Briar <205427297+icy-briar@users.noreply.github.com> Date: Thu, 24 Apr 2025 21:20:49 +0200 Subject: [PATCH 12/13] android: Add `dyna_state` setting to UI --- .../features/settings/model/ByteSetting.kt | 3 ++- .../features/settings/model/IntSetting.kt | 1 - .../settings/model/view/SettingsItem.kt | 18 ++++++++++++++++++ .../settings/ui/SettingsFragmentPresenter.kt | 1 + .../app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/ByteSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/ByteSetting.kt index 7b7fac2112..0d84c16c65 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/ByteSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/ByteSetting.kt @@ -6,7 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.model import org.yuzu.yuzu_emu.utils.NativeConfig enum class ByteSetting(override val key: String) : AbstractByteSetting { - AUDIO_VOLUME("volume"); + AUDIO_VOLUME("volume"), + RENDERER_DYNA_STATE("dyna_state"); override fun getByte(needsGlobal: Boolean): Byte = NativeConfig.getByte(key, needsGlobal) 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 111a1b0a00..035a33a762 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 @@ -24,7 +24,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { RENDERER_SCREEN_LAYOUT("screen_layout"), RENDERER_ASPECT_RATIO("aspect_ratio"), RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"), - RENDERER_DYNA_STATE("dyna_state"), 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/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 8fa90bf05f..a0ace00c0b 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 @@ -17,6 +17,7 @@ import org.yuzu.yuzu_emu.features.settings.model.IntSetting import org.yuzu.yuzu_emu.features.settings.model.LongSetting import org.yuzu.yuzu_emu.features.settings.model.ShortSetting import org.yuzu.yuzu_emu.features.settings.model.StringSetting +import org.yuzu.yuzu_emu.utils.GpuDriverHelper import org.yuzu.yuzu_emu.utils.NativeConfig /** @@ -56,6 +57,13 @@ abstract class SettingsItem( return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld } + if (setting.key == ByteSetting.RENDERER_DYNA_STATE.key) { + // Can't change on Mali GPU's otherwise no game loading for you + if (!GpuDriverHelper.supportsCustomDriverLoading()) { + return false + } + } + // Can't edit settings that aren't saveable in per-game config even if they are switchable if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) { return false @@ -118,6 +126,16 @@ abstract class SettingsItem( descriptionId = R.string.frame_limit_enable_description ) ) + put( + SliderSetting( + ByteSetting.RENDERER_DYNA_STATE, + titleId = R.string.dyna_state, + descriptionId = R.string.dyna_state_description, + min = 0, + max = 3, + ) + ) + put( SliderSetting( ShortSetting.RENDERER_SPEED_LIMIT, 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 971324683c..cfdfce7276 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 @@ -471,6 +471,7 @@ class SettingsFragmentPresenter( descriptionId = R.string.frame_skipping_description ) ) + add(ByteSetting.RENDERER_DYNA_STATE.key) add( SwitchSetting( syncCoreSpeedSetting, diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 3d1927af99..293f4beea5 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -292,6 +292,8 @@ NVDEC Emulation Specifies how videos should be decoded. It can either use the CPU or the GPU for decoding, or perform no decoding at all (black screen on videos). In most cases, GPU decoding provides the best performance. Shader Backend + Extended Dynamic State + Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will generally improve performance, but may cause issues on certain games or devices\nDefault value is 0 for Disabled, The third value might not work properly on some devices CPU From 7a9011b82d0988492f358b961606c5b12c69889d Mon Sep 17 00:00:00 2001 From: swurl Date: Thu, 24 Apr 2025 15:32:42 -0400 Subject: [PATCH 13/13] add tick marks to desktop slider Signed-off-by: swurl --- src/yuzu/configuration/configure_graphics_extensions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/yuzu/configuration/configure_graphics_extensions.cpp b/src/yuzu/configuration/configure_graphics_extensions.cpp index 96151c5e09..88bea9786e 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.cpp +++ b/src/yuzu/configuration/configure_graphics_extensions.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "common/settings.h" #include "core/core.h" #include "ui_configure_graphics_extensions.h" @@ -45,6 +46,11 @@ void ConfigureGraphicsExtensions::Setup(const ConfigurationShared::Builder& buil } hold.emplace(setting->Id(), widget); + + if (setting->Id() == Settings::values.dyna_state.Id()) { + widget->slider->setTickInterval(1); + widget->slider->setTickPosition(QSlider::TicksAbove); + } } for (const auto& [id, widget] : hold) {