summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/settings.h53
-rw-r--r--src/core/telemetry_session.cpp2
-rw-r--r--src/video_core/textures/texture.cpp4
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp153
-rw-r--r--src/yuzu/configuration/configuration_shared.h6
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp8
-rw-r--r--src/yuzu/configuration/configure_dialog.h1
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp172
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h20
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui234
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp9
-rw-r--r--src/yuzu/configuration/configure_per_game.h1
-rw-r--r--src/yuzu/configuration/shared_translation.cpp170
-rw-r--r--src/yuzu/configuration/shared_translation.h18
15 files changed, 451 insertions, 402 deletions
diff --git a/src/common/settings.h b/src/common/settings.h
index df4bcb053..48f86d0aa 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -20,6 +20,15 @@
20 20
21namespace Settings { 21namespace Settings {
22 22
23enum class AnisotropyMode : u32 {
24 Automatic = 0,
25 Default = 1,
26 X2 = 2,
27 X4 = 3,
28 X8 = 4,
29 X16 = 5,
30};
31
23enum class AstcDecodeMode : u32 { 32enum class AstcDecodeMode : u32 {
24 CPU = 0, 33 CPU = 0,
25 GPU = 1, 34 GPU = 1,
@@ -49,6 +58,7 @@ enum class GPUAccuracy : u32 {
49 Normal = 0, 58 Normal = 0,
50 High = 1, 59 High = 1,
51 Extreme = 2, 60 Extreme = 2,
61 MaxEnum = 3,
52}; 62};
53 63
54enum class CPUAccuracy : u32 { 64enum class CPUAccuracy : u32 {
@@ -166,11 +176,16 @@ public:
166 virtual Category Category() const = 0; 176 virtual Category Category() const = 0;
167 virtual constexpr bool Switchable() const = 0; 177 virtual constexpr bool Switchable() const = 0;
168 virtual std::string ToString() const = 0; 178 virtual std::string ToString() const = 0;
179 virtual std::string ToStringGlobal() const {
180 return {};
181 }
169 virtual void LoadString(const std::string& load) = 0; 182 virtual void LoadString(const std::string& load) = 0;
170 virtual const std::string& GetLabel() const = 0; 183 virtual const std::string& GetLabel() const = 0;
171 virtual std::string DefaultToString() const = 0; 184 virtual std::string DefaultToString() const = 0;
172 virtual bool Save() const = 0; 185 virtual bool Save() const = 0;
173 virtual std::type_index TypeId() const = 0; 186 virtual std::type_index TypeId() const = 0;
187 virtual bool IsEnum() const = 0;
188 virtual bool RuntimeModfiable() const = 0;
174 virtual void SetGlobal(bool global) {} 189 virtual void SetGlobal(bool global) {}
175 virtual bool UsingGlobal() const { 190 virtual bool UsingGlobal() const {
176 return false; 191 return false;
@@ -188,7 +203,7 @@ public:
188 * configurations. Specifying a default value and label is required. A minimum and maximum range 203 * configurations. Specifying a default value and label is required. A minimum and maximum range
189 * can be specified for sanitization. 204 * can be specified for sanitization.
190 */ 205 */
191template <typename Type, bool ranged = false, bool save = true> 206template <typename Type, bool ranged = false, bool save = true, bool runtime_modifiable = false>
192class Setting : public BasicSetting { 207class Setting : public BasicSetting {
193protected: 208protected:
194 Setting() = default; 209 Setting() = default;
@@ -282,6 +297,14 @@ public:
282 return category; 297 return category;
283 } 298 }
284 299
300 [[nodiscard]] bool RuntimeModfiable() const override {
301 return runtime_modifiable;
302 }
303
304 [[nodiscard]] bool IsEnum() const override {
305 return std::is_enum<Type>::value;
306 }
307
285 /** 308 /**
286 * Returns whether the current setting is Switchable. 309 * Returns whether the current setting is Switchable.
287 * 310 *
@@ -291,7 +314,7 @@ public:
291 return false; 314 return false;
292 } 315 }
293 316
294private: 317protected:
295 std::string ToString(const Type& value_) const { 318 std::string ToString(const Type& value_) const {
296 if constexpr (std::is_same<Type, std::string>()) { 319 if constexpr (std::is_same<Type, std::string>()) {
297 return value_; 320 return value_;
@@ -408,8 +431,8 @@ protected:
408 * 431 *
409 * By default, the global setting is used. 432 * By default, the global setting is used.
410 */ 433 */
411template <typename Type, bool ranged = false, bool save = true> 434template <typename Type, bool ranged = false, bool save = true, bool runtime_modifiable = false>
412class SwitchableSetting : virtual public Setting<Type, ranged, save> { 435class SwitchableSetting : virtual public Setting<Type, ranged, save, runtime_modifiable> {
413public: 436public:
414 /** 437 /**
415 * Sets a default value, label, and setting value. 438 * Sets a default value, label, and setting value.
@@ -422,7 +445,7 @@ public:
422 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, 445 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name,
423 Category category) 446 Category category)
424 requires(!ranged) 447 requires(!ranged)
425 : Setting<Type, false, save>{linkage, default_val, name, category} { 448 : Setting<Type, false, save, runtime_modifiable>{linkage, default_val, name, category} {
426 linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); 449 linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
427 } 450 }
428 virtual ~SwitchableSetting() = default; 451 virtual ~SwitchableSetting() = default;
@@ -440,7 +463,8 @@ public:
440 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, 463 explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val,
441 const Type& max_val, const std::string& name, Category category) 464 const Type& max_val, const std::string& name, Category category)
442 requires(ranged) 465 requires(ranged)
443 : Setting<Type, true, save>{linkage, default_val, min_val, max_val, name, category} { 466 : Setting<Type, true, save, runtime_modifiable>{linkage, default_val, min_val,
467 max_val, name, category} {
444 linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); }); 468 linkage.restore_functions.emplace_back([this]() { this->SetGlobal(true); });
445 } 469 }
446 470
@@ -502,6 +526,10 @@ public:
502 return true; 526 return true;
503 } 527 }
504 528
529 [[nodiscard]] virtual std::string ToStringGlobal() const override {
530 return this->ToString(this->value);
531 }
532
505 /** 533 /**
506 * Assigns the current setting value depending on the global state. 534 * Assigns the current setting value depending on the global state.
507 * 535 *
@@ -667,15 +695,16 @@ struct Values {
667 "fullscreen_mode", 695 "fullscreen_mode",
668 Category::Renderer}; 696 Category::Renderer};
669 SwitchableSetting<int, true> aspect_ratio{linkage, 0, 0, 4, "aspect_ratio", Category::Renderer}; 697 SwitchableSetting<int, true> aspect_ratio{linkage, 0, 0, 4, "aspect_ratio", Category::Renderer};
670 SwitchableSetting<int, true> max_anisotropy{ 698 SwitchableSetting<AnisotropyMode, true> max_anisotropy{
671 linkage, 0, 0, 5, "max_anisotropy", Category::AdvancedGraphics}; 699 linkage, AnisotropyMode::Automatic, AnisotropyMode::Automatic, AnisotropyMode::X16,
700 "max_anisotropy", Category::AdvancedGraphics};
672 SwitchableSetting<bool, false, false> use_speed_limit{linkage, true, "use_speed_limit", 701 SwitchableSetting<bool, false, false> use_speed_limit{linkage, true, "use_speed_limit",
673 Category::Renderer}; 702 Category::Renderer};
674 SwitchableSetting<u16, true> speed_limit{linkage, 100, 0, 703 SwitchableSetting<u16, true> speed_limit{linkage, 100, 0,
675 9999, "speed_limit", Category::Renderer}; 704 9999, "speed_limit", Category::Renderer};
676 SwitchableSetting<bool> use_disk_shader_cache{linkage, true, "use_disk_shader_cache", 705 SwitchableSetting<bool> use_disk_shader_cache{linkage, true, "use_disk_shader_cache",
677 Category::Renderer}; 706 Category::Renderer};
678 SwitchableSetting<GPUAccuracy, true> gpu_accuracy{ 707 SwitchableSetting<GPUAccuracy, true, true, true> gpu_accuracy{
679 linkage, GPUAccuracy::High, GPUAccuracy::Normal, GPUAccuracy::Extreme, 708 linkage, GPUAccuracy::High, GPUAccuracy::Normal, GPUAccuracy::Extreme,
680 "gpu_accuracy", Category::AdvancedGraphics}; 709 "gpu_accuracy", Category::AdvancedGraphics};
681 SwitchableSetting<bool> use_asynchronous_gpu_emulation{ 710 SwitchableSetting<bool> use_asynchronous_gpu_emulation{
@@ -698,9 +727,9 @@ struct Values {
698 "shader_backend", Category::Renderer}; 727 "shader_backend", Category::Renderer};
699 SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", 728 SwitchableSetting<bool> use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders",
700 Category::Renderer}; 729 Category::Renderer};
701 SwitchableSetting<bool> use_fast_gpu_time{linkage, true, "use_fast_gpu_time", 730 SwitchableSetting<bool, false, true, true> use_fast_gpu_time{linkage, true, "use_fast_gpu_time",
702 Category::AdvancedGraphics}; 731 Category::AdvancedGraphics};
703 SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{ 732 SwitchableSetting<bool, false, true, true> use_vulkan_driver_pipeline_cache{
704 linkage, true, "use_vulkan_driver_pipeline_cache", Category::AdvancedGraphics}; 733 linkage, true, "use_vulkan_driver_pipeline_cache", Category::AdvancedGraphics};
705 SwitchableSetting<bool> enable_compute_pipelines{linkage, false, "enable_compute_pipelines", 734 SwitchableSetting<bool> enable_compute_pipelines{linkage, false, "enable_compute_pipelines",
706 Category::AdvancedGraphics}; 735 Category::AdvancedGraphics};
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 665ffe3a2..a3505a505 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -69,6 +69,8 @@ static const char* TranslateGPUAccuracyLevel(Settings::GPUAccuracy backend) {
69 return "High"; 69 return "High";
70 case Settings::GPUAccuracy::Extreme: 70 case Settings::GPUAccuracy::Extreme:
71 return "Extreme"; 71 return "Extreme";
72 case Settings::GPUAccuracy::MaxEnum:
73 break;
72 } 74 }
73 return "Unknown"; 75 return "Unknown";
74} 76}
diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp
index d8b88d9bc..39c08b5ae 100644
--- a/src/video_core/textures/texture.cpp
+++ b/src/video_core/textures/texture.cpp
@@ -72,12 +72,12 @@ float TSCEntry::MaxAnisotropy() const noexcept {
72 } 72 }
73 const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue(); 73 const auto anisotropic_settings = Settings::values.max_anisotropy.GetValue();
74 s32 added_anisotropic{}; 74 s32 added_anisotropic{};
75 if (anisotropic_settings == 0) { 75 if (anisotropic_settings == Settings::AnisotropyMode::Automatic) {
76 added_anisotropic = Settings::values.resolution_info.up_scale >> 76 added_anisotropic = Settings::values.resolution_info.up_scale >>
77 Settings::values.resolution_info.down_shift; 77 Settings::values.resolution_info.down_shift;
78 added_anisotropic = std::max(added_anisotropic - 1, 0); 78 added_anisotropic = std::max(added_anisotropic - 1, 0);
79 } else { 79 } else {
80 added_anisotropic = Settings::values.max_anisotropy.GetValue() - 1U; 80 added_anisotropic = static_cast<u32>(Settings::values.max_anisotropy.GetValue()) - 1U;
81 } 81 }
82 return static_cast<float>(1U << (max_anisotropy + added_anisotropic)); 82 return static_cast<float>(1U << (max_anisotropy + added_anisotropic));
83} 83}
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index fe98e3605..8b54e1268 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -143,6 +143,8 @@ add_executable(yuzu
143 configuration/configure_web.ui 143 configuration/configure_web.ui
144 configuration/input_profiles.cpp 144 configuration/input_profiles.cpp
145 configuration/input_profiles.h 145 configuration/input_profiles.h
146 configuration/shared_translation.cpp
147 configuration/shared_translation.h
146 debugger/console.cpp 148 debugger/console.cpp
147 debugger/console.h 149 debugger/console.h
148 debugger/controller.cpp 150 debugger/controller.cpp
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 72b7957e0..44222718c 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -3,14 +3,167 @@
3 3
4#include <memory> 4#include <memory>
5#include <QCheckBox> 5#include <QCheckBox>
6#include <QHBoxLayout>
7#include <QLabel>
6#include <QObject> 8#include <QObject>
7#include <QString> 9#include <QString>
8#include <QWidget> 10#include <QWidget>
11#include <qnamespace.h>
9#include "common/settings.h" 12#include "common/settings.h"
10#include "yuzu/configuration/configuration_shared.h" 13#include "yuzu/configuration/configuration_shared.h"
11#include "yuzu/configuration/configure_per_game.h" 14#include "yuzu/configuration/configure_per_game.h"
15#include "yuzu/configuration/shared_translation.h"
12 16
13namespace ConfigurationShared { 17namespace ConfigurationShared {
18static std::pair<QWidget*, std::function<void()>> CreateCheckBox(Settings::BasicSetting* setting,
19 const QString& label,
20 QWidget* parent,
21 std::list<CheckState>& trackers) {
22 QCheckBox* checkbox = new QCheckBox(label, parent);
23 checkbox->setObjectName(QString::fromStdString(setting->GetLabel()));
24 checkbox->setCheckState(setting->ToString() == "true" ? Qt::CheckState::Checked
25 : Qt::CheckState::Unchecked);
26
27 CheckState* tracker{};
28
29 // Per-game config highlight
30 if (setting->Switchable() && !Settings::IsConfiguringGlobal()) {
31 bool global_state = setting->ToStringGlobal() == "true";
32 bool state = setting->ToString() == "true";
33 bool global = setting->UsingGlobal();
34 tracker = &trackers.emplace_front(CheckState{});
35 SetColoredTristate(checkbox, global, state, global_state, *tracker);
36 }
37
38 auto load_func = [checkbox, setting, tracker]() {
39 if (Settings::IsConfiguringGlobal()) {
40 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
41 }
42
43 if (Settings::IsConfiguringGlobal() || !setting->Switchable()) {
44 return;
45 }
46
47 if (*tracker != CheckState::Global) {
48 setting->SetGlobal(false);
49 setting->LoadString(checkbox->checkState() == Qt::Checked ? "true" : "false");
50 } else {
51 setting->SetGlobal(true);
52 }
53 };
54
55 return {checkbox, load_func};
56}
57
58static std::pair<QWidget*, std::function<void()>> CreateCombobox(Settings::BasicSetting* setting,
59 const QString& label,
60 QWidget* parent) {
61 const auto type = setting->TypeId();
62
63 QWidget* group = new QWidget(parent);
64 group->setObjectName(QString::fromStdString(setting->GetLabel()));
65 QLayout* combobox_layout = new QHBoxLayout(group);
66
67 QLabel* qt_label = new QLabel(label, parent);
68 QComboBox* combobox = new QComboBox(parent);
69
70 std::forward_list<QString> combobox_enumerations = ComboboxEnumeration(type, parent);
71 for (const auto& item : combobox_enumerations) {
72 combobox->addItem(item);
73 }
74
75 combobox_layout->addWidget(qt_label);
76 combobox_layout->addWidget(combobox);
77
78 combobox_layout->setSpacing(6);
79 combobox_layout->setContentsMargins(0, 0, 0, 0);
80
81 if (setting->Switchable() && !Settings::IsConfiguringGlobal()) {
82 int current = std::stoi(setting->ToString());
83 int global_value = std::stoi(setting->ToStringGlobal());
84 SetColoredComboBox(combobox, group, global_value);
85 if (setting->UsingGlobal()) {
86 combobox->setCurrentIndex(USE_GLOBAL_INDEX);
87 } else {
88 SetHighlight(group, true);
89 combobox->setCurrentIndex(current + USE_GLOBAL_OFFSET);
90 }
91 } else {
92 combobox->setCurrentIndex(std::stoi(setting->ToString()));
93 }
94
95 const auto load_func = [combobox, setting]() {
96 if (Settings::IsConfiguringGlobal()) {
97 setting->LoadString(std::to_string(combobox->currentIndex()));
98 }
99
100 if (Settings::IsConfiguringGlobal() || !setting->Switchable()) {
101 return;
102 }
103
104 bool using_global = combobox->currentIndex() == USE_GLOBAL_INDEX;
105 int index = combobox->currentIndex() - USE_GLOBAL_OFFSET;
106
107 setting->SetGlobal(using_global);
108 if (!using_global) {
109 setting->LoadString(std::to_string(index));
110 }
111 };
112
113 return {group, load_func};
114}
115
116QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& translations,
117 QWidget* parent, bool runtime_lock,
118 std::forward_list<std::function<void(bool)>>& apply_funcs,
119 std::list<CheckState>& trackers) {
120 const auto type = setting->TypeId();
121 QWidget* widget{nullptr};
122
123 std::function<void()> load_func;
124
125 const auto [label, tooltip] = [&]() {
126 const auto& setting_label = setting->GetLabel();
127 if (translations.contains(setting_label)) {
128 return std::pair{translations.at(setting_label).first,
129 translations.at(setting_label).second};
130 }
131 LOG_ERROR(Frontend, "Translation map lacks entry for \"{}\"", setting_label);
132 return std::pair{QString::fromStdString(setting_label), QStringLiteral("")};
133 }();
134
135 if (type == typeid(bool)) {
136 auto pair = CreateCheckBox(setting, label, parent, trackers);
137 widget = pair.first;
138 load_func = pair.second;
139 } else if (setting->IsEnum()) {
140 auto pair = CreateCombobox(setting, label, parent);
141 widget = pair.first;
142 load_func = pair.second;
143 }
144
145 if (widget == nullptr) {
146 LOG_ERROR(Frontend, "No widget was created for \"{}\"", setting->GetLabel());
147 return widget;
148 }
149
150 apply_funcs.push_front([load_func, setting](bool powered_on) {
151 if (setting->RuntimeModfiable() || !powered_on) {
152 load_func();
153 }
154 });
155
156 bool enable = runtime_lock || setting->RuntimeModfiable();
157 enable &=
158 setting->Switchable() && !(Settings::IsConfiguringGlobal() && !setting->UsingGlobal());
159
160 widget->setEnabled(enable);
161 widget->setVisible(Settings::IsConfiguringGlobal() || setting->Switchable());
162
163 widget->setToolTip(tooltip);
164
165 return widget;
166}
14 167
15Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent) 168Tab::Tab(std::shared_ptr<std::forward_list<Tab*>> group_, QWidget* parent)
16 : QWidget(parent), group{group_} { 169 : QWidget(parent), group{group_} {
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index 1a3a2a985..7040673ea 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -11,6 +11,7 @@
11#include <QWidget> 11#include <QWidget>
12#include <qobjectdefs.h> 12#include <qobjectdefs.h>
13#include "common/settings.h" 13#include "common/settings.h"
14#include "yuzu/configuration/shared_translation.h"
14 15
15namespace ConfigurationShared { 16namespace ConfigurationShared {
16 17
@@ -40,6 +41,11 @@ enum class CheckState {
40 Count, // Simply the number of states, not a valid checkbox state 41 Count, // Simply the number of states, not a valid checkbox state
41}; 42};
42 43
44QWidget* CreateWidget(Settings::BasicSetting* setting, const TranslationMap& translations,
45 QWidget* parent, bool runtime_lock,
46 std::forward_list<std::function<void(bool)>>& apply_funcs,
47 std::list<CheckState>& trackers);
48
43// Global-aware apply and set functions 49// Global-aware apply and set functions
44 50
45// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting 51// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 2cc9f3621..b3f4764c7 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -32,13 +32,15 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_,
32 std::vector<VkDeviceInfo::Record>& vk_device_records, 32 std::vector<VkDeviceInfo::Record>& vk_device_records,
33 Core::System& system_, bool enable_web_config) 33 Core::System& system_, bool enable_web_config)
34 : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, 34 : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()},
35 registry(registry_), system{system_}, audio_tab{std::make_unique<ConfigureAudio>( 35 registry(registry_), system{system_},
36 system_, nullptr, this)}, 36 translations{ConfigurationShared::InitializeTranslations(this)},
37 audio_tab{std::make_unique<ConfigureAudio>(system_, nullptr, this)},
37 cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, this)}, 38 cpu_tab{std::make_unique<ConfigureCpu>(system_, nullptr, this)},
38 debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, 39 debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)},
39 filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, 40 filesystem_tab{std::make_unique<ConfigureFilesystem>(this)},
40 general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, this)}, 41 general_tab{std::make_unique<ConfigureGeneral>(system_, nullptr, this)},
41 graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, this)}, 42 graphics_advanced_tab{
43 std::make_unique<ConfigureGraphicsAdvanced>(system_, nullptr, *translations, this)},
42 graphics_tab{std::make_unique<ConfigureGraphics>( 44 graphics_tab{std::make_unique<ConfigureGraphics>(
43 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, 45 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
44 nullptr, this)}, 46 nullptr, this)},
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h
index 8ee89a192..0416b01d9 100644
--- a/src/yuzu/configuration/configure_dialog.h
+++ b/src/yuzu/configuration/configure_dialog.h
@@ -71,6 +71,7 @@ private:
71 HotkeyRegistry& registry; 71 HotkeyRegistry& registry;
72 72
73 Core::System& system; 73 Core::System& system;
74 std::unique_ptr<ConfigurationShared::TranslationMap> translations;
74 std::forward_list<ConfigurationShared::Tab*> tab_group; 75 std::forward_list<ConfigurationShared::Tab*> tab_group;
75 76
76 std::unique_ptr<ConfigureAudio> audio_tab; 77 std::unique_ptr<ConfigureAudio> audio_tab;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index d332c9b7b..6d387b5c3 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <QLabel>
5#include <qnamespace.h>
4#include "common/settings.h" 6#include "common/settings.h"
5#include "core/core.h" 7#include "core/core.h"
6#include "ui_configure_graphics_advanced.h" 8#include "ui_configure_graphics_advanced.h"
@@ -9,94 +11,54 @@
9 11
10ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced( 12ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(
11 const Core::System& system_, 13 const Core::System& system_,
12 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, QWidget* parent) 14 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
13 : Tab(group, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_} { 15 const ConfigurationShared::TranslationMap& translations_, QWidget* parent)
16 : Tab(group, parent), ui{std::make_unique<Ui::ConfigureGraphicsAdvanced>()}, system{system_},
17 translations{translations_} {
14 18
15 ui->setupUi(this); 19 ui->setupUi(this);
16 20
17 SetupPerGameUI();
18
19 SetConfiguration(); 21 SetConfiguration();
20 22
21 ui->enable_compute_pipelines_checkbox->setVisible(false); 23 checkbox_enable_compute_pipelines->setVisible(false);
22} 24}
23 25
24ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; 26ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
25 27
26void ConfigureGraphicsAdvanced::SetConfiguration() { 28void ConfigureGraphicsAdvanced::SetConfiguration() {
27 const bool runtime_lock = !system.IsPoweredOn(); 29 const bool runtime_lock = !system.IsPoweredOn();
28 ui->use_reactive_flushing->setEnabled(runtime_lock); 30 auto& layout = *ui->populate_target->layout();
29 ui->async_present->setEnabled(runtime_lock); 31 std::map<std::string, QWidget*> hold{}; // A map will sort the data for us
30 ui->renderer_force_max_clock->setEnabled(runtime_lock); 32
31 ui->astc_recompression_combobox->setEnabled(runtime_lock); 33 for (auto setting :
32 ui->use_asynchronous_shaders->setEnabled(runtime_lock); 34 Settings::values.linkage.by_category[Settings::Category::AdvancedGraphics]) {
33 ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); 35 QWidget* widget = ConfigurationShared::CreateWidget(setting, translations, this,
34 ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock); 36 runtime_lock, apply_funcs, trackers);
35 37
36 ui->async_present->setChecked(Settings::values.async_presentation.GetValue()); 38 if (widget == nullptr) {
37 ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); 39 continue;
38 ui->use_reactive_flushing->setChecked(Settings::values.use_reactive_flushing.GetValue()); 40 }
39 ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); 41
40 ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); 42 if (!setting->IsEnum()) {
41 ui->use_vulkan_driver_pipeline_cache->setChecked( 43 hold.emplace(setting->GetLabel(), widget);
42 Settings::values.use_vulkan_driver_pipeline_cache.GetValue()); 44 } else {
43 ui->enable_compute_pipelines_checkbox->setChecked( 45 layout.addWidget(widget);
44 Settings::values.enable_compute_pipelines.GetValue()); 46 }
45 ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue()); 47
46 ui->barrier_feedback_loops_checkbox->setChecked( 48 if (setting->GetLabel() == "enable_compute_pipelines") {
47 Settings::values.barrier_feedback_loops.GetValue()); 49 checkbox_enable_compute_pipelines = widget;
48 50 }
49 if (Settings::IsConfiguringGlobal()) { 51 }
50 ui->gpu_accuracy->setCurrentIndex( 52 for (const auto& [label, widget] : hold) {
51 static_cast<int>(Settings::values.gpu_accuracy.GetValue())); 53 layout.addWidget(widget);
52 ui->anisotropic_filtering_combobox->setCurrentIndex(
53 Settings::values.max_anisotropy.GetValue());
54 ui->astc_recompression_combobox->setCurrentIndex(
55 static_cast<int>(Settings::values.astc_recompression.GetValue()));
56 } else {
57 ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy);
58 ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox,
59 &Settings::values.max_anisotropy);
60 ConfigurationShared::SetPerGameSetting(ui->astc_recompression_combobox,
61 &Settings::values.astc_recompression);
62 ConfigurationShared::SetHighlight(ui->label_gpu_accuracy,
63 !Settings::values.gpu_accuracy.UsingGlobal());
64 ConfigurationShared::SetHighlight(ui->af_label,
65 !Settings::values.max_anisotropy.UsingGlobal());
66 ConfigurationShared::SetHighlight(ui->label_astc_recompression,
67 !Settings::values.astc_recompression.UsingGlobal());
68 } 54 }
69} 55}
70 56
71void ConfigureGraphicsAdvanced::ApplyConfiguration() { 57void ConfigureGraphicsAdvanced::ApplyConfiguration() {
72 ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy); 58 const bool is_powered_on = system.IsPoweredOn();
73 ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_presentation, 59 for (const auto& func : apply_funcs) {
74 ui->async_present, async_present); 60 func(is_powered_on);
75 ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock, 61 }
76 ui->renderer_force_max_clock,
77 renderer_force_max_clock);
78 ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
79 ui->anisotropic_filtering_combobox);
80 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_reactive_flushing,
81 ui->use_reactive_flushing, use_reactive_flushing);
82 ConfigurationShared::ApplyPerGameSetting(&Settings::values.astc_recompression,
83 ui->astc_recompression_combobox);
84 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
85 ui->use_asynchronous_shaders,
86 use_asynchronous_shaders);
87 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
88 ui->use_fast_gpu_time, use_fast_gpu_time);
89 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache,
90 ui->use_vulkan_driver_pipeline_cache,
91 use_vulkan_driver_pipeline_cache);
92 ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines,
93 ui->enable_compute_pipelines_checkbox,
94 enable_compute_pipelines);
95 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate,
96 ui->use_video_framerate_checkbox, use_video_framerate);
97 ConfigurationShared::ApplyPerGameSetting(&Settings::values.barrier_feedback_loops,
98 ui->barrier_feedback_loops_checkbox,
99 barrier_feedback_loops);
100} 62}
101 63
102void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { 64void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@@ -111,68 +73,6 @@ void ConfigureGraphicsAdvanced::RetranslateUI() {
111 ui->retranslateUi(this); 73 ui->retranslateUi(this);
112} 74}
113 75
114void ConfigureGraphicsAdvanced::SetupPerGameUI() {
115 // Disable if not global (only happens during game)
116 if (Settings::IsConfiguringGlobal()) {
117 ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
118 ui->async_present->setEnabled(Settings::values.async_presentation.UsingGlobal());
119 ui->renderer_force_max_clock->setEnabled(
120 Settings::values.renderer_force_max_clock.UsingGlobal());
121 ui->use_reactive_flushing->setEnabled(Settings::values.use_reactive_flushing.UsingGlobal());
122 ui->astc_recompression_combobox->setEnabled(
123 Settings::values.astc_recompression.UsingGlobal());
124 ui->use_asynchronous_shaders->setEnabled(
125 Settings::values.use_asynchronous_shaders.UsingGlobal());
126 ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
127 ui->use_vulkan_driver_pipeline_cache->setEnabled(
128 Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal());
129 ui->anisotropic_filtering_combobox->setEnabled(
130 Settings::values.max_anisotropy.UsingGlobal());
131 ui->enable_compute_pipelines_checkbox->setEnabled(
132 Settings::values.enable_compute_pipelines.UsingGlobal());
133 ui->use_video_framerate_checkbox->setEnabled(
134 Settings::values.use_video_framerate.UsingGlobal());
135 ui->barrier_feedback_loops_checkbox->setEnabled(
136 Settings::values.barrier_feedback_loops.UsingGlobal());
137
138 return;
139 }
140
141 ConfigurationShared::SetColoredTristate(ui->async_present, Settings::values.async_presentation,
142 async_present);
143 ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock,
144 Settings::values.renderer_force_max_clock,
145 renderer_force_max_clock);
146 ConfigurationShared::SetColoredTristate(
147 ui->use_reactive_flushing, Settings::values.use_reactive_flushing, use_reactive_flushing);
148 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
149 Settings::values.use_asynchronous_shaders,
150 use_asynchronous_shaders);
151 ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
152 Settings::values.use_fast_gpu_time, use_fast_gpu_time);
153 ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache,
154 Settings::values.use_vulkan_driver_pipeline_cache,
155 use_vulkan_driver_pipeline_cache);
156 ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox,
157 Settings::values.enable_compute_pipelines,
158 enable_compute_pipelines);
159 ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox,
160 Settings::values.use_video_framerate,
161 use_video_framerate);
162 ConfigurationShared::SetColoredTristate(ui->barrier_feedback_loops_checkbox,
163 Settings::values.barrier_feedback_loops,
164 barrier_feedback_loops);
165 ConfigurationShared::SetColoredComboBox(
166 ui->gpu_accuracy, ui->label_gpu_accuracy,
167 static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
168 ConfigurationShared::SetColoredComboBox(
169 ui->anisotropic_filtering_combobox, ui->af_label,
170 static_cast<int>(Settings::values.max_anisotropy.GetValue(true)));
171 ConfigurationShared::SetColoredComboBox(
172 ui->astc_recompression_combobox, ui->label_astc_recompression,
173 static_cast<int>(Settings::values.astc_recompression.GetValue(true)));
174}
175
176void ConfigureGraphicsAdvanced::ExposeComputeOption() { 76void ConfigureGraphicsAdvanced::ExposeComputeOption() {
177 ui->enable_compute_pipelines_checkbox->setVisible(true); 77 checkbox_enable_compute_pipelines->setVisible(true);
178} 78}
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index 585b9cb50..3ac6b4bce 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -20,7 +20,7 @@ public:
20 explicit ConfigureGraphicsAdvanced( 20 explicit ConfigureGraphicsAdvanced(
21 const Core::System& system_, 21 const Core::System& system_,
22 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group, 22 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> group,
23 QWidget* parent = nullptr); 23 const ConfigurationShared::TranslationMap& translations_, QWidget* parent = nullptr);
24 ~ConfigureGraphicsAdvanced() override; 24 ~ConfigureGraphicsAdvanced() override;
25 25
26 void ApplyConfiguration() override; 26 void ApplyConfiguration() override;
@@ -32,21 +32,13 @@ private:
32 void changeEvent(QEvent* event) override; 32 void changeEvent(QEvent* event) override;
33 void RetranslateUI(); 33 void RetranslateUI();
34 34
35 void SetupPerGameUI();
36
37 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; 35 std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
38 36
39 ConfigurationShared::CheckState async_present; 37 std::list<ConfigurationShared::CheckState> trackers{};
40 ConfigurationShared::CheckState renderer_force_max_clock;
41 ConfigurationShared::CheckState use_vsync;
42 ConfigurationShared::CheckState async_astc;
43 ConfigurationShared::CheckState use_reactive_flushing;
44 ConfigurationShared::CheckState use_asynchronous_shaders;
45 ConfigurationShared::CheckState use_fast_gpu_time;
46 ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
47 ConfigurationShared::CheckState enable_compute_pipelines;
48 ConfigurationShared::CheckState use_video_framerate;
49 ConfigurationShared::CheckState barrier_feedback_loops;
50 38
51 const Core::System& system; 39 const Core::System& system;
40 const ConfigurationShared::TranslationMap& translations;
41 std::forward_list<std::function<void(bool)>> apply_funcs;
42
43 QWidget* checkbox_enable_compute_pipelines{};
52}; 44};
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 859ab9366..113fbc010 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -26,238 +26,8 @@
26 </property> 26 </property>
27 <layout class="QVBoxLayout" name="verticalLayout_3"> 27 <layout class="QVBoxLayout" name="verticalLayout_3">
28 <item> 28 <item>
29 <widget class="QWidget" name="gpu_accuracy_layout" native="true"> 29 <widget class="QWidget" name="populate_target" native="true">
30 <layout class="QHBoxLayout" name="horizontalLayout_2"> 30 <layout class="QVBoxLayout" name="verticalLayout"/>
31 <property name="leftMargin">
32 <number>0</number>
33 </property>
34 <property name="topMargin">
35 <number>0</number>
36 </property>
37 <property name="rightMargin">
38 <number>0</number>
39 </property>
40 <property name="bottomMargin">
41 <number>0</number>
42 </property>
43 <item>
44 <widget class="QLabel" name="label_gpu_accuracy">
45 <property name="text">
46 <string>Accuracy Level:</string>
47 </property>
48 </widget>
49 </item>
50 <item>
51 <widget class="QComboBox" name="gpu_accuracy">
52 <item>
53 <property name="text">
54 <string notr="true">Normal</string>
55 </property>
56 </item>
57 <item>
58 <property name="text">
59 <string notr="true">High</string>
60 </property>
61 </item>
62 <item>
63 <property name="text">
64 <string notr="true">Extreme(very slow)</string>
65 </property>
66 </item>
67 </widget>
68 </item>
69 </layout>
70 </widget>
71 </item>
72 <item>
73 <widget class="QWidget" name="astc_recompression_layout" native="true">
74 <layout class="QHBoxLayout" name="horizontalLayout_3">
75 <property name="leftMargin">
76 <number>0</number>
77 </property>
78 <property name="topMargin">
79 <number>0</number>
80 </property>
81 <property name="rightMargin">
82 <number>0</number>
83 </property>
84 <property name="bottomMargin">
85 <number>0</number>
86 </property>
87 <item>
88 <widget class="QLabel" name="label_astc_recompression">
89 <property name="text">
90 <string>ASTC recompression:</string>
91 </property>
92 </widget>
93 </item>
94 <item>
95 <widget class="QComboBox" name="astc_recompression_combobox">
96 <item>
97 <property name="text">
98 <string>Uncompressed (Best quality)</string>
99 </property>
100 </item>
101 <item>
102 <property name="text">
103 <string>BC1 (Low quality)</string>
104 </property>
105 </item>
106 <item>
107 <property name="text">
108 <string>BC3 (Medium quality)</string>
109 </property>
110 </item>
111 </widget>
112 </item>
113 </layout>
114 </widget>
115 </item>
116 <item>
117 <widget class="QCheckBox" name="async_present">
118 <property name="text">
119 <string>Enable asynchronous presentation (Vulkan only)</string>
120 </property>
121 </widget>
122 </item>
123 <item>
124 <widget class="QCheckBox" name="renderer_force_max_clock">
125 <property name="toolTip">
126 <string>Runs work in the background while waiting for graphics commands to keep the GPU from lowering its clock speed.</string>
127 </property>
128 <property name="text">
129 <string>Force maximum clocks (Vulkan only)</string>
130 </property>
131 </widget>
132 </item>
133 <item>
134 <widget class="QCheckBox" name="use_reactive_flushing">
135 <property name="toolTip">
136 <string>Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.</string>
137 </property>
138 <property name="text">
139 <string>Enable Reactive Flushing</string>
140 </property>
141 </widget>
142 </item>
143 <item>
144 <widget class="QCheckBox" name="use_asynchronous_shaders">
145 <property name="toolTip">
146 <string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string>
147 </property>
148 <property name="text">
149 <string>Use asynchronous shader building (Hack)</string>
150 </property>
151 </widget>
152 </item>
153 <item>
154 <widget class="QCheckBox" name="use_fast_gpu_time">
155 <property name="toolTip">
156 <string>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</string>
157 </property>
158 <property name="text">
159 <string>Use Fast GPU Time (Hack)</string>
160 </property>
161 </widget>
162 </item>
163 <item>
164 <widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache">
165 <property name="toolTip">
166 <string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string>
167 </property>
168 <property name="text">
169 <string>Use Vulkan pipeline cache</string>
170 </property>
171 </widget>
172 </item>
173 <item>
174 <widget class="QCheckBox" name="enable_compute_pipelines_checkbox">
175 <property name="toolTip">
176 <string>Enable compute pipelines, required by some games. This setting only exists for Intel proprietary drivers, and may crash if enabled.
177Compute pipelines are always enabled on all other drivers.</string>
178 </property>
179 <property name="text">
180 <string>Enable Compute Pipelines (Intel Vulkan only)</string>
181 </property>
182 </widget>
183 </item>
184 <item>
185 <widget class="QCheckBox" name="use_video_framerate_checkbox">
186 <property name="toolTip">
187 <string>Run the game at normal speed during video playback, even when the framerate is unlocked.</string>
188 </property>
189 <property name="text">
190 <string>Sync to framerate of video playback</string>
191 </property>
192 </widget>
193 </item>
194 <item>
195 <widget class="QCheckBox" name="barrier_feedback_loops_checkbox">
196 <property name="toolTip">
197 <string>Improves rendering of transparency effects in specific games.</string>
198 </property>
199 <property name="text">
200 <string>Barrier feedback loops</string>
201 </property>
202 </widget>
203 </item>
204 <item>
205 <widget class="QWidget" name="af_layout" native="true">
206 <layout class="QHBoxLayout" name="horizontalLayout_1">
207 <property name="leftMargin">
208 <number>0</number>
209 </property>
210 <property name="topMargin">
211 <number>0</number>
212 </property>
213 <property name="rightMargin">
214 <number>0</number>
215 </property>
216 <property name="bottomMargin">
217 <number>0</number>
218 </property>
219 <item>
220 <widget class="QLabel" name="af_label">
221 <property name="text">
222 <string>Anisotropic Filtering:</string>
223 </property>
224 </widget>
225 </item>
226 <item>
227 <widget class="QComboBox" name="anisotropic_filtering_combobox">
228 <item>
229 <property name="text">
230 <string>Automatic</string>
231 </property>
232 </item>
233 <item>
234 <property name="text">
235 <string>Default</string>
236 </property>
237 </item>
238 <item>
239 <property name="text">
240 <string>2x</string>
241 </property>
242 </item>
243 <item>
244 <property name="text">
245 <string>4x</string>
246 </property>
247 </item>
248 <item>
249 <property name="text">
250 <string>8x</string>
251 </property>
252 </item>
253 <item>
254 <property name="text">
255 <string>16x</string>
256 </property>
257 </item>
258 </widget>
259 </item>
260 </layout>
261 </widget> 31 </widget>
262 </item> 32 </item>
263 </layout> 33 </layout>
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 7ec0bf9d3..339768017 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -41,8 +41,10 @@
41ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, 41ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name,
42 std::vector<VkDeviceInfo::Record>& vk_device_records, 42 std::vector<VkDeviceInfo::Record>& vk_device_records,
43 Core::System& system_) 43 Core::System& system_)
44 : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, 44 : QDialog(parent),
45 system{system_}, tab_group{std::make_shared<std::forward_list<ConfigurationShared::Tab*>>()} { 45 ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_},
46 translations{ConfigurationShared::InitializeTranslations(this)},
47 tab_group{std::make_shared<std::forward_list<ConfigurationShared::Tab*>>()} {
46 const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); 48 const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
47 const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) 49 const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
48 : fmt::format("{:016X}", title_id); 50 : fmt::format("{:016X}", title_id);
@@ -52,7 +54,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
52 audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, this); 54 audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, this);
53 cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, this); 55 cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, this);
54 general_tab = std::make_unique<ConfigureGeneral>(system_, tab_group, this); 56 general_tab = std::make_unique<ConfigureGeneral>(system_, tab_group, this);
55 graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, this); 57 graphics_advanced_tab =
58 std::make_unique<ConfigureGraphicsAdvanced>(system_, tab_group, *translations, this);
56 graphics_tab = std::make_unique<ConfigureGraphics>( 59 graphics_tab = std::make_unique<ConfigureGraphics>(
57 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, 60 system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); },
58 tab_group, this); 61 tab_group, this);
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h
index 9fceff414..1e222c2f9 100644
--- a/src/yuzu/configuration/configure_per_game.h
+++ b/src/yuzu/configuration/configure_per_game.h
@@ -75,6 +75,7 @@ private:
75 std::unique_ptr<Config> game_config; 75 std::unique_ptr<Config> game_config;
76 76
77 Core::System& system; 77 Core::System& system;
78 std::unique_ptr<ConfigurationShared::TranslationMap> translations;
78 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> tab_group; 79 std::shared_ptr<std::forward_list<ConfigurationShared::Tab*>> tab_group;
79 80
80 std::unique_ptr<ConfigurePerGameAddons> addons_tab; 81 std::unique_ptr<ConfigurePerGameAddons> addons_tab;
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
new file mode 100644
index 000000000..974203f75
--- /dev/null
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -0,0 +1,170 @@
1#include <forward_list>
2#include <map>
3#include <memory>
4#include <string>
5#include <typeindex>
6#include <utility>
7#include <QString>
8#include <QWidget>
9#include "common/settings.h"
10#include "yuzu/configuration/shared_translation.h"
11
12namespace ConfigurationShared {
13
14std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
15 std::unique_ptr<TranslationMap> translations = std::make_unique<TranslationMap>();
16 const auto& tr = [parent](const char* text) -> QString { return parent->tr(text); };
17
18#define INSERT(LABEL, NAME, TOOLTIP) \
19 translations->insert(std::pair{(LABEL), std::pair{tr((NAME)), tr((TOOLTIP))}})
20
21 // Audio
22 INSERT("output_engine", "Output Engine:", "");
23 INSERT("output_device", "Output Device:", "");
24 INSERT("input_device", "Input Device:", "");
25 INSERT("audio_muted", "Mute audio when in background", "");
26 INSERT("volume", "Volume:", "");
27
28 // Core
29 INSERT("use_multi_core", "Multicore CPU Emulation", "");
30 INSERT("use_unsafe_extended_memory_layout", "Unsafe extended memory layout (8GB DRAM)", "");
31
32 // Cpu
33 INSERT("cpu_accuracy", "Accuracy:", "");
34 INSERT("cpu_debug_mode", "Enable CPU Debugging", "");
35 INSERT("cpuopt_page_tables", "Enable inline page tables", "");
36 INSERT("cpuopt_block_linking", "Enable block linking", "");
37 INSERT("cpuopt_return_stack_buffer", "Enable return stack buffer", "");
38 INSERT("cpuopt_fast_dispatcher", "Enable fast dispatcher", "");
39 INSERT("cpuopt_context_elimination", "Enable context elimination", "");
40 INSERT("cpuopt_const_prop", "Enable constant propagation", "");
41 INSERT("cpuopt_misc_ir", "Enable miscellaneous optimizations", "");
42 INSERT("cpuopt_reduce_misalign_checks", "Enable misalignment check reduction", "");
43 INSERT("cpuopt_fastmem", "Enable Host MMU Emulation (general memory instructions)", "");
44 INSERT("cpuopt_fastmem_exclusives", "Enable Host MMU Emulation (exclusive memory instructions)",
45 "");
46 INSERT("cpuopt_recompile_exclusives", "Enable recompilation of exlucsive memory instructions",
47 "");
48 INSERT("cpuopt_ignore_memory_aborts", "Enable fallbacks for invalid memory accesses", "");
49
50 INSERT("cpuopt_unsafe_unfuse_fma", "Unfuse FMA (improve performance on CPUs without FMA)", "");
51 INSERT("cpuopt_unsafe_reduce_fp_error", "Faster FRSQRTE and FRECPE", "");
52 INSERT("cpuopt_unsafe_ignore_standard_fpcr", "Faster ASIMD instructions (32 bits only)", "");
53 INSERT("cpuopt_unsafe_inaccurate_nan", "Inaccurate NaN handling", "");
54 INSERT("cpuopt_unsafe_fastmem_check", "Disable address space checks", "");
55 INSERT("cpuopt_unsafe_ignore_global_monitor", "Ignore global monitor", "");
56
57 // Renderer
58 INSERT("backend", "API:", "");
59 INSERT("vulkan_device", "Device:", "");
60 INSERT("shader_backend", "Shader Backend:", "");
61 INSERT("resolution_setup", "Resolution:", "");
62 INSERT("scaling_filter", "Window Adapting Filter:", "");
63 INSERT("fsr_sharpening_slider", "AMD FidelityFX™ Super Resolution Sharpness:", "");
64 INSERT("anti_aliasing", "Anti-Aliasing Method:", "");
65 INSERT("fullscreen_mode", "Fullscreen Mode:", "");
66 INSERT("aspect_ratio", "Aspect Ratio:", "");
67 INSERT("use_disk_shader_cache", "Use disk pipeline cache", "");
68 INSERT("use_asynchronous_gpu_emulation", "Use asynchronous GPU emulation", "");
69 INSERT("nvdec_emulation", "NVDEC emulation:", "");
70 INSERT("acclerate_astc", "ASTC Decoding Method:", "");
71 INSERT(
72 "use_vsync", "VSync Mode:",
73 "FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh "
74 "rate. FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down. "
75 "Mailbox can have lower latency than FIFO and does not tear but may drop frames. Immediate "
76 "(no synchronization) just presents whatever is available and can exhibit tearing.");
77
78 // Renderer (Advanced Graphics)
79 INSERT("async_presentation", "Enable asynchronous presentation (Vulkan only)", "");
80 INSERT("force_max_clock", "Force maximum clocks (Vulkan only)",
81 "Runs work in the background while waiting for graphics commands to keep the GPU from "
82 "lowering its clock speed.");
83 INSERT("max_anisotropy", "Anisotropic Filtering:", "");
84 INSERT("gpu_accuracy", "Accuracy Level:", "");
85 INSERT("use_asynchronous_shaders", "Use asynchronous shader building (Hack)",
86 "Enables asynchronous shader compilation, which may reduce shader stutter. This feature "
87 "is experimental.");
88 INSERT("use_fast_gpu_time", "Use Fast GPU Time (Hack)",
89 "Enables Fast GPU Time. This option will force most games to run at their highest "
90 "native resolution.");
91 INSERT("use_vulkan_driver_pipeline_cache", "Use Vulkan pipeline cache",
92 "Enables GPU vendor-specific pipeline cache. This option can improve shader loading "
93 "time significantly in cases where the Vulkan driver does not store pipeline cache "
94 "files internally.");
95 INSERT("enable_compute_pipelines", "Enable Compute Pipelines (Intel Vulkan Only)",
96 "Enable compute pipelines, required by some games.\nThis setting only exists for Intel "
97 "proprietary drivers, and may crash if enabled.\nCompute pipelines are always enabled "
98 "on all other drivers.");
99 INSERT("bg_red", "Background Color:", "");
100 INSERT("bg_green", "Background Color:", "");
101 INSERT("bg_blue", "Background Color:", "");
102
103 // Renderer (Debug)
104 INSERT("debug", "Enable Graphics Debugging",
105 "When checked, the graphics API enters a slower debugging mode");
106 INSERT("shader_feedback", "Enable Shader Feedback",
107 "When checked, yuzu will log statistics about the compiled pipeline cache");
108 INSERT("nsight_aftermath", "Enable Nsight Aftermath",
109 "When checked, it enables Nsight Aftermath crash dumps");
110 INSERT("disable_shader_loop_safety_checks", "Disable Loop safety checks",
111 "When checked, it executes shaders without loop logic changes");
112
113 // Renderer (General)
114 INSERT("use_speed_limit", "Limit Speed Percent", "");
115 INSERT("speed_limit", "Limit Speed Percent", "");
116
117 // System
118 INSERT("rng_seed_enabled", "RNG Seed", "");
119 INSERT("rng_seed", "RNG Seed", "");
120 INSERT("device_name", "Device Name", "");
121 INSERT("custom_rtc_enabled", "Custom RTC", "");
122 INSERT("custom_rtc", "Custom RTC", "");
123 INSERT("language_index", "Language:", "");
124 INSERT("region_index", "Region:", "");
125 INSERT("time_zone_index", "Time Zone:", "");
126 INSERT("sound_index", "Sound Output Mode:", "");
127 INSERT("use_docked_mode", "Docked", "");
128
129#undef INSERT
130
131 return translations;
132}
133
134std::forward_list<QString> ComboboxEnumeration(std::type_index type, QWidget* parent) {
135 const auto& tr = [&](const char* text) { return parent->tr(text); };
136
137 if (type == typeid(Settings::AstcDecodeMode)) {
138 return {
139 tr("CPU"),
140 tr("GPU"),
141 tr("CPU Asynchronous"),
142 };
143 } else if (type == typeid(Settings::RendererBackend)) {
144 return {
145 tr("OpenGL"),
146 tr("Vulkan"),
147 tr("Null"),
148 };
149 } else if (type == typeid(Settings::ShaderBackend)) {
150 return {
151 tr("GLSL"),
152 tr("GLASM (Assembly Shaders, NVIDIA Only)"),
153 tr("SPIR-V (Experimental, Mesa Only)"),
154 };
155 } else if (type == typeid(Settings::GPUAccuracy)) {
156 return {
157 tr("Normal"),
158 tr("High"),
159 tr("Extreme"),
160 };
161 } else if (type == typeid(Settings::AnisotropyMode)) {
162 return {
163 tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"),
164 };
165 }
166
167 return {};
168}
169
170} // namespace ConfigurationShared
diff --git a/src/yuzu/configuration/shared_translation.h b/src/yuzu/configuration/shared_translation.h
new file mode 100644
index 000000000..a81ae9c87
--- /dev/null
+++ b/src/yuzu/configuration/shared_translation.h
@@ -0,0 +1,18 @@
1#include <forward_list>
2#include <map>
3#include <memory>
4#include <string>
5#include <typeindex>
6#include <utility>
7#include <QString>
8
9class QWidget;
10
11namespace ConfigurationShared {
12using TranslationMap = std::map<std::string, std::pair<QString, QString>>;
13
14std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
15
16std::forward_list<QString> ComboboxEnumeration(std::type_index type, QWidget* parent);
17
18} // namespace ConfigurationShared