Merge pull request 'Add configurations for VkExtendedDynamicState extensions' (#53) from crueter/eden:dynamic-state-config into master

Reviewed-on: #53
This commit is contained in:
CamilleLaVey 2025-04-24 19:55:58 +00:00
commit 30670bd92a
19 changed files with 309 additions and 53 deletions

View file

@ -6,7 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class ByteSetting(override val key: String) : AbstractByteSetting { 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) override fun getByte(needsGlobal: Boolean): Byte = NativeConfig.getByte(key, needsGlobal)

View file

@ -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.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
/** /**
@ -56,6 +57,13 @@ abstract class SettingsItem(
return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld 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 // Can't edit settings that aren't saveable in per-game config even if they are switchable
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) { if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
return false return false
@ -118,6 +126,16 @@ abstract class SettingsItem(
descriptionId = R.string.frame_limit_enable_description 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( put(
SliderSetting( SliderSetting(
ShortSetting.RENDERER_SPEED_LIMIT, ShortSetting.RENDERER_SPEED_LIMIT,

View file

@ -471,6 +471,7 @@ class SettingsFragmentPresenter(
descriptionId = R.string.frame_skipping_description descriptionId = R.string.frame_skipping_description
) )
) )
add(ByteSetting.RENDERER_DYNA_STATE.key)
add( add(
SwitchSetting( SwitchSetting(
syncCoreSpeedSetting, syncCoreSpeedSetting,

View file

@ -292,6 +292,8 @@
<string name="nvdec_emulation">NVDEC Emulation</string> <string name="nvdec_emulation">NVDEC Emulation</string>
<string name="nvdec_emulation_description">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.</string> <string name="nvdec_emulation_description">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.</string>
<string name="shader_backend">Shader Backend</string> <string name="shader_backend">Shader Backend</string>
<string name="dyna_state">Extended Dynamic State</string>
<string name="dyna_state_description">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</string>
<!-- Debug settings strings --> <!-- Debug settings strings -->
<string name="cpu">CPU</string> <string name="cpu">CPU</string>

View file

@ -206,6 +206,7 @@ const char* TranslateCategory(Category category) {
case Category::Renderer: case Category::Renderer:
case Category::RendererAdvanced: case Category::RendererAdvanced:
case Category::RendererDebug: case Category::RendererDebug:
case Category::RendererExtensions:
return "Renderer"; return "Renderer";
case Category::System: case Category::System:
case Category::SystemAudio: case Category::SystemAudio:

View file

@ -445,6 +445,14 @@ struct Values {
SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops", SwitchableSetting<bool> barrier_feedback_loops{linkage, true, "barrier_feedback_loops",
Category::RendererAdvanced}; Category::RendererAdvanced};
SwitchableSetting<u8, true> dyna_state{linkage,
0,
0,
3,
"dyna_state",
Category::RendererExtensions,
Specialization::Scalar};
Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug}; Setting<bool> renderer_debug{linkage, false, "debug", Category::RendererDebug};
Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback", Setting<bool> renderer_shader_feedback{linkage, false, "shader_feedback",
Category::RendererDebug}; Category::RendererDebug};

View file

@ -21,6 +21,7 @@ enum class Category : u32 {
Overlay, Overlay,
Renderer, Renderer,
RendererAdvanced, RendererAdvanced,
RendererExtensions,
RendererDebug, RendererDebug,
System, System,
SystemAudio, SystemAudio,

View file

@ -362,6 +362,7 @@ void Config::ReadRendererValues() {
ReadCategory(Settings::Category::Renderer); ReadCategory(Settings::Category::Renderer);
ReadCategory(Settings::Category::RendererAdvanced); ReadCategory(Settings::Category::RendererAdvanced);
ReadCategory(Settings::Category::RendererExtensions);
ReadCategory(Settings::Category::RendererDebug); ReadCategory(Settings::Category::RendererDebug);
EndGroup(); EndGroup();
@ -670,6 +671,7 @@ void Config::SaveRendererValues() {
WriteCategory(Settings::Category::Renderer); WriteCategory(Settings::Category::Renderer);
WriteCategory(Settings::Category::RendererAdvanced); WriteCategory(Settings::Category::RendererAdvanced);
WriteCategory(Settings::Category::RendererExtensions);
WriteCategory(Settings::Category::RendererDebug); WriteCategory(Settings::Category::RendererDebug);
EndGroup(); EndGroup();

View file

@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <fstream> #include <fstream>
#include <iostream>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <vector> #include <vector>
@ -426,12 +427,13 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays); device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays);
} }
const u8 dynamic_state = Settings::values.dyna_state.GetValue();
dynamic_features = DynamicFeatures{ dynamic_features = DynamicFeatures{
.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(), .has_extended_dynamic_state = dynamic_state > 0,
.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(), .has_extended_dynamic_state_2 = dynamic_state > 1,
.has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported(), .has_extended_dynamic_state_2_extra = dynamic_state > 1,
.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported(), .has_extended_dynamic_state_3_blend = dynamic_state > 2,
.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported(), .has_extended_dynamic_state_3_enables = dynamic_state > 2,
.has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(), .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(),
}; };
} }

View file

@ -483,16 +483,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_qualcomm || is_turnip) { if (is_qualcomm || is_turnip) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color");
RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, //RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color,
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); //VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
} }
if (is_qualcomm) { 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"); LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_extended_dynamic_state");
RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, //RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); "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) { 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"); LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state");
RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, //RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
} }
if (is_nvidia) { 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)) { if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state"); "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state");
RemoveExtensionFeature(extensions.extended_dynamic_state, //RemoveExtensionFeature(extensions.extended_dynamic_state,
features.extended_dynamic_state, //features.extended_dynamic_state,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); //VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
} }
} }
if (extensions.extended_dynamic_state2 && is_radv) { if (extensions.extended_dynamic_state2 && is_radv) {
@ -563,9 +563,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
LOG_WARNING( LOG_WARNING(
Render_Vulkan, Render_Vulkan,
"RADV versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2"); "RADV versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2");
RemoveExtensionFeature(extensions.extended_dynamic_state2, // RemoveExtensionFeature(extensions.extended_dynamic_state2,
features.extended_dynamic_state2, // features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); // VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
} }
} }
if (extensions.extended_dynamic_state2 && is_qualcomm) { if (extensions.extended_dynamic_state2 && is_qualcomm) {
@ -575,32 +575,32 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
// Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2. // Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2.
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2"); "Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2");
RemoveExtensionFeature(extensions.extended_dynamic_state2, //RemoveExtensionFeature(extensions.extended_dynamic_state2,
features.extended_dynamic_state2, //features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); //VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
} }
} }
if (extensions.extended_dynamic_state3 && is_radv) { if (extensions.extended_dynamic_state3 && is_radv) {
LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation"); LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation");
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true;
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true;
dynamic_state3_blending = false; dynamic_state3_blending = true;
const u32 version = (properties.properties.driverVersion << 3) >> 3; const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) { if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"RADV versions older than 23.1.0 have broken depth clamp dynamic state"); "RADV versions older than 23.1.0 have broken depth clamp dynamic state");
features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false; features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = true;
dynamic_state3_enables = false; dynamic_state3_enables = true;
} }
} }
if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) { if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
// AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation // AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation"); "AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation");
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false; features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true;
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false; features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true;
dynamic_state3_blending = false; dynamic_state3_blending = true;
} }
if (extensions.vertex_input_dynamic_state && is_radv) { if (extensions.vertex_input_dynamic_state && is_radv) {
// TODO(ameerj): Blacklist only offending driver versions // TODO(ameerj): Blacklist only offending driver versions
@ -610,18 +610,18 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_rdna2) { if (is_rdna2) {
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware"); "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware");
RemoveExtensionFeature(extensions.vertex_input_dynamic_state, // RemoveExtensionFeature(extensions.vertex_input_dynamic_state,
features.vertex_input_dynamic_state, // features.vertex_input_dynamic_state,
VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
} }
} }
if (extensions.vertex_input_dynamic_state && is_qualcomm) { if (extensions.vertex_input_dynamic_state && is_qualcomm) {
// Qualcomm drivers do not properly support vertex_input_dynamic_state. // Qualcomm drivers do not properly support vertex_input_dynamic_state.
LOG_WARNING(Render_Vulkan, LOG_WARNING(Render_Vulkan,
"Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state"); "Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state");
RemoveExtensionFeature(extensions.vertex_input_dynamic_state, //RemoveExtensionFeature(extensions.vertex_input_dynamic_state,
features.vertex_input_dynamic_state, // features.vertex_input_dynamic_state,
VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); // VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
} }
sets_per_pool = 64; sets_per_pool = 64;
@ -721,8 +721,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
"Removing extendedDynamicState3 due to missing extendedDynamicState2"); "Removing extendedDynamicState3 due to missing extendedDynamicState2");
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
dynamic_state3_blending = false; dynamic_state3_blending = true;
dynamic_state3_enables = false; dynamic_state3_enables = true;
} }
logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions),
@ -1159,7 +1159,7 @@ void Device::RemoveUnsuitableExtensions() {
RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control,
VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); 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; extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState;
RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state, RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state,
features.extended_dynamic_state, features.extended_dynamic_state,
@ -1169,7 +1169,7 @@ void Device::RemoveUnsuitableExtensions() {
extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2;
RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2,
features.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 // VK_EXT_extended_dynamic_state3
dynamic_state3_blending = dynamic_state3_blending =

View file

@ -231,6 +231,7 @@ add_executable(yuzu
compatdb.h compatdb.h
yuzu.qrc yuzu.qrc
yuzu.rc 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") set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")

View file

@ -17,6 +17,7 @@
#include "yuzu/configuration/configure_general.h" #include "yuzu/configuration/configure_general.h"
#include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics.h"
#include "yuzu/configuration/configure_graphics_advanced.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_hotkeys.h"
#include "yuzu/configuration/configure_input.h" #include "yuzu/configuration/configure_input.h"
#include "yuzu/configuration/configure_input_player.h" #include "yuzu/configuration/configure_input_player.h"
@ -42,7 +43,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *builder, this)}, general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, *builder, this)},
graphics_advanced_tab{ graphics_advanced_tab{
std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, *builder, this)}, std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, *builder, this)},
graphics_extensions_tab{
std::make_unique<ConfigureGraphicsExtensions>(system_, nullptr, *builder, this)},
ui_tab{std::make_unique<ConfigureUi>(system_, this)}, ui_tab{std::make_unique<ConfigureUi>(system_, this)},
graphics_tab{std::make_unique<ConfigureGraphics>( graphics_tab{std::make_unique<ConfigureGraphics>(
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, 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(general_tab.get(), tr("General"));
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("GraphicsAdvanced")); 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(hotkeys_tab.get(), tr("Hotkeys"));
ui->tabWidget->addTab(input_tab.get(), tr("Controls")); ui->tabWidget->addTab(input_tab.get(), tr("Controls"));
ui->tabWidget->addTab(profile_tab.get(), tr("Profiles")); ui->tabWidget->addTab(profile_tab.get(), tr("Profiles"));
@ -104,7 +108,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
adjustSize(); adjustSize();
ui->selectorList->setCurrentRow(0); 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(); ui->buttonBox->setFocus();
} }
@ -123,6 +127,7 @@ void ConfigureDialog::ApplyConfiguration() {
cpu_tab->ApplyConfiguration(); cpu_tab->ApplyConfiguration();
graphics_tab->ApplyConfiguration(); graphics_tab->ApplyConfiguration();
graphics_advanced_tab->ApplyConfiguration(); graphics_advanced_tab->ApplyConfiguration();
graphics_extensions_tab->ApplyConfiguration();
audio_tab->ApplyConfiguration(); audio_tab->ApplyConfiguration();
debug_tab_tab->ApplyConfiguration(); debug_tab_tab->ApplyConfiguration();
web_tab->ApplyConfiguration(); web_tab->ApplyConfiguration();
@ -162,16 +167,16 @@ Q_DECLARE_METATYPE(QList<QWidget*>);
void ConfigureDialog::PopulateSelectionList() { void ConfigureDialog::PopulateSelectionList() {
const std::array<std::pair<QString, QList<QWidget*>>, 6> items{ const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
{{tr("General"), {{tr("General"),
{general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}}, {general_tab.get(), hotkeys_tab.get(), ui_tab.get(), web_tab.get(), debug_tab_tab.get()}},
{tr("System"), {tr("System"),
{system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(), {system_tab.get(), profile_tab.get(), network_tab.get(), filesystem_tab.get(),
applets_tab.get()}}, applets_tab.get()}},
{tr("CPU"), {cpu_tab.get()}}, {tr("CPU"), {cpu_tab.get()}},
{tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get()}}, {tr("Graphics"), {graphics_tab.get(), graphics_advanced_tab.get(), graphics_extensions_tab.get()}},
{tr("Audio"), {audio_tab.get()}}, {tr("Audio"), {audio_tab.get()}},
{tr("Controls"), input_tab->GetSubTabs()}}, {tr("Controls"), input_tab->GetSubTabs()}},
}; };
[[maybe_unused]] const QSignalBlocker blocker(ui->selectorList); [[maybe_unused]] const QSignalBlocker blocker(ui->selectorList);

View file

@ -23,6 +23,7 @@ class ConfigureFilesystem;
class ConfigureGeneral; class ConfigureGeneral;
class ConfigureGraphics; class ConfigureGraphics;
class ConfigureGraphicsAdvanced; class ConfigureGraphicsAdvanced;
class ConfigureGraphicsExtensions;
class ConfigureHotkeys; class ConfigureHotkeys;
class ConfigureInput; class ConfigureInput;
class ConfigureProfileManager; class ConfigureProfileManager;
@ -83,6 +84,7 @@ private:
std::unique_ptr<ConfigureFilesystem> filesystem_tab; std::unique_ptr<ConfigureFilesystem> filesystem_tab;
std::unique_ptr<ConfigureGeneral> general_tab; std::unique_ptr<ConfigureGeneral> general_tab;
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
std::unique_ptr<ConfigureGraphicsExtensions> graphics_extensions_tab;
std::unique_ptr<ConfigureUi> ui_tab; std::unique_ptr<ConfigureUi> ui_tab;
std::unique_ptr<ConfigureGraphics> graphics_tab; std::unique_ptr<ConfigureGraphics> graphics_tab;
std::unique_ptr<ConfigureHotkeys> hotkeys_tab; std::unique_ptr<ConfigureHotkeys> hotkeys_tab;

View file

@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <vector>
#include <QLabel>
#include <qnamespace.h>
#include <QCheckBox>
#include <QSlider>
#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<std::vector<ConfigurationShared::Tab*>> group_,
const ConfigurationShared::Builder& builder, QWidget* parent)
: Tab(group_, parent), ui{std::make_unique<Ui::ConfigureGraphicsExtensions>()}, 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<u32, QWidget*> 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);
if (setting->Id() == Settings::values.dyna_state.Id()) {
widget->slider->setTickInterval(1);
widget->slider->setTickPosition(QSlider::TicksAbove);
}
}
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);
}

View file

@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <vector>
#include <QWidget>
#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<std::vector<ConfigurationShared::Tab*>> 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::ConfigureGraphicsExtensions> ui;
const Core::System& system;
std::vector<std::function<void(bool)>> apply_funcs;
};

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConfigureGraphicsExtensions</class>
<widget class="QWidget" name="ConfigureGraphicsExtensions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>404</width>
<height>376</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="accessibleName">
<string>Extensions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_1">
<property name="title">
<string>Vulkan Extension Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>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.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="populate_target" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -32,6 +32,7 @@
#include "yuzu/configuration/configure_cpu.h" #include "yuzu/configuration/configure_cpu.h"
#include "yuzu/configuration/configure_graphics.h" #include "yuzu/configuration/configure_graphics.h"
#include "yuzu/configuration/configure_graphics_advanced.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_input_per_game.h"
#include "yuzu/configuration/configure_linux_tab.h" #include "yuzu/configuration/configure_linux_tab.h"
#include "yuzu/configuration/configure_per_game.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<ConfigureCpu>(system_, tab_group, *builder, this); cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *builder, this);
graphics_advanced_tab = graphics_advanced_tab =
std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *builder, this); std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *builder, this);
graphics_extensions_tab =
std::make_unique<ConfigureGraphicsExtensions>(system_, tab_group, *builder, this);
graphics_tab = std::make_unique<ConfigureGraphics>( graphics_tab = std::make_unique<ConfigureGraphics>(
system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
[](Settings::AspectRatio, Settings::ResolutionSetup) {}, tab_group, *builder, this); [](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(cpu_tab.get(), tr("CPU"));
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. 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(audio_tab.get(), tr("Audio"));
ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles")); ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles"));

View file

@ -31,6 +31,7 @@ class ConfigureAudio;
class ConfigureCpu; class ConfigureCpu;
class ConfigureGraphics; class ConfigureGraphics;
class ConfigureGraphicsAdvanced; class ConfigureGraphicsAdvanced;
class ConfigureGraphicsExtensions;
class ConfigureInputPerGame; class ConfigureInputPerGame;
class ConfigureLinuxTab; class ConfigureLinuxTab;
class ConfigureSystem; class ConfigureSystem;
@ -84,6 +85,7 @@ private:
std::unique_ptr<ConfigureAudio> audio_tab; std::unique_ptr<ConfigureAudio> audio_tab;
std::unique_ptr<ConfigureCpu> cpu_tab; std::unique_ptr<ConfigureCpu> cpu_tab;
std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
std::unique_ptr<ConfigureGraphicsExtensions> graphics_extensions_tab;
std::unique_ptr<ConfigureGraphics> graphics_tab; std::unique_ptr<ConfigureGraphics> graphics_tab;
std::unique_ptr<ConfigureInputPerGame> input_tab; std::unique_ptr<ConfigureInputPerGame> input_tab;
std::unique_ptr<ConfigureLinuxTab> linux_tab; std::unique_ptr<ConfigureLinuxTab> linux_tab;

View file

@ -230,6 +230,11 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"), INSERT(Settings, barrier_feedback_loops, tr("Barrier feedback loops"),
tr("Improves rendering of transparency effects in specific games.")); tr("Improves rendering of transparency effects in specific games."));
// Renderer (Extensions)
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) // Renderer (Debug)
// System // System