1 // Copyright 2016 Citra Emulator Project
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4
5 #include <QColorDialog>
6 #include <QComboBox>
7 #ifdef HAS_VULKAN
8 #include <QVulkanInstance>
9 #endif
10
11 #include "common/common_types.h"
12 #include "common/logging/log.h"
13 #include "core/core.h"
14 #include "core/settings.h"
15 #include "ui_configure_graphics.h"
16 #include "yuzu/configuration/configuration_shared.h"
17 #include "yuzu/configuration/configure_graphics.h"
18
19 #ifdef HAS_VULKAN
20 #include "video_core/renderer_vulkan/renderer_vulkan.h"
21 #endif
22
ConfigureGraphics(QWidget * parent)23 ConfigureGraphics::ConfigureGraphics(QWidget* parent)
24 : QWidget(parent), ui(new Ui::ConfigureGraphics) {
25 vulkan_device = Settings::values.vulkan_device.GetValue();
26 RetrieveVulkanDevices();
27
28 ui->setupUi(this);
29
30 SetupPerGameUI();
31
32 SetConfiguration();
33
34 connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
35 UpdateDeviceComboBox();
36 if (!Settings::IsConfiguringGlobal()) {
37 ConfigurationShared::SetHighlight(
38 ui->api_layout, ui->api->currentIndex() != ConfigurationShared::USE_GLOBAL_INDEX);
39 }
40 });
41 connect(ui->device, qOverload<int>(&QComboBox::activated), this,
42 [this](int device) { UpdateDeviceSelection(device); });
43
44 connect(ui->bg_button, &QPushButton::clicked, this, [this] {
45 const QColor new_bg_color = QColorDialog::getColor(bg_color);
46 if (!new_bg_color.isValid()) {
47 return;
48 }
49 UpdateBackgroundColorButton(new_bg_color);
50 });
51
52 ui->bg_label->setVisible(Settings::IsConfiguringGlobal());
53 ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
54 }
55
UpdateDeviceSelection(int device)56 void ConfigureGraphics::UpdateDeviceSelection(int device) {
57 if (device == -1) {
58 return;
59 }
60 if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) {
61 vulkan_device = device;
62 }
63 }
64
65 ConfigureGraphics::~ConfigureGraphics() = default;
66
SetConfiguration()67 void ConfigureGraphics::SetConfiguration() {
68 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
69
70 ui->api->setEnabled(runtime_lock);
71 ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
72 ui->use_disk_shader_cache->setEnabled(runtime_lock);
73 ui->use_nvdec_emulation->setEnabled(runtime_lock);
74 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
75 ui->use_asynchronous_gpu_emulation->setChecked(
76 Settings::values.use_asynchronous_gpu_emulation.GetValue());
77 ui->use_nvdec_emulation->setChecked(Settings::values.use_nvdec_emulation.GetValue());
78
79 if (Settings::IsConfiguringGlobal()) {
80 ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
81 ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
82 } else {
83 ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
84 ConfigurationShared::SetHighlight(ui->api_layout,
85 !Settings::values.renderer_backend.UsingGlobal());
86 ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox,
87 &Settings::values.aspect_ratio);
88
89 ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1);
90 ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
91 ConfigurationShared::SetHighlight(ui->ar_label,
92 !Settings::values.aspect_ratio.UsingGlobal());
93 ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal());
94 }
95
96 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(),
97 Settings::values.bg_green.GetValue(),
98 Settings::values.bg_blue.GetValue()));
99 UpdateDeviceComboBox();
100 }
101
ApplyConfiguration()102 void ConfigureGraphics::ApplyConfiguration() {
103 if (Settings::IsConfiguringGlobal()) {
104 // Guard if during game and set to game-specific value
105 if (Settings::values.renderer_backend.UsingGlobal()) {
106 Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
107 }
108 if (Settings::values.vulkan_device.UsingGlobal()) {
109 Settings::values.vulkan_device.SetValue(vulkan_device);
110 }
111 if (Settings::values.aspect_ratio.UsingGlobal()) {
112 Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex());
113 }
114 if (Settings::values.use_disk_shader_cache.UsingGlobal()) {
115 Settings::values.use_disk_shader_cache.SetValue(ui->use_disk_shader_cache->isChecked());
116 }
117 if (Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()) {
118 Settings::values.use_asynchronous_gpu_emulation.SetValue(
119 ui->use_asynchronous_gpu_emulation->isChecked());
120 }
121 if (Settings::values.use_nvdec_emulation.UsingGlobal()) {
122 Settings::values.use_nvdec_emulation.SetValue(ui->use_nvdec_emulation->isChecked());
123 }
124 if (Settings::values.bg_red.UsingGlobal()) {
125 Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
126 Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
127 Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
128 }
129 } else {
130 if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
131 Settings::values.renderer_backend.SetGlobal(true);
132 Settings::values.vulkan_device.SetGlobal(true);
133 } else {
134 Settings::values.renderer_backend.SetGlobal(false);
135 Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
136 if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) {
137 Settings::values.vulkan_device.SetGlobal(false);
138 Settings::values.vulkan_device.SetValue(vulkan_device);
139 } else {
140 Settings::values.vulkan_device.SetGlobal(true);
141 }
142 }
143
144 ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio,
145 ui->aspect_ratio_combobox);
146
147 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
148 ui->use_disk_shader_cache, use_disk_shader_cache);
149 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation,
150 ui->use_asynchronous_gpu_emulation,
151 use_asynchronous_gpu_emulation);
152 ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_nvdec_emulation,
153 ui->use_nvdec_emulation, use_nvdec_emulation);
154
155 if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
156 Settings::values.bg_red.SetGlobal(true);
157 Settings::values.bg_green.SetGlobal(true);
158 Settings::values.bg_blue.SetGlobal(true);
159 } else {
160 Settings::values.bg_red.SetGlobal(false);
161 Settings::values.bg_green.SetGlobal(false);
162 Settings::values.bg_blue.SetGlobal(false);
163 Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
164 Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
165 Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
166 }
167 }
168 }
169
changeEvent(QEvent * event)170 void ConfigureGraphics::changeEvent(QEvent* event) {
171 if (event->type() == QEvent::LanguageChange) {
172 RetranslateUI();
173 }
174
175 QWidget::changeEvent(event);
176 }
177
RetranslateUI()178 void ConfigureGraphics::RetranslateUI() {
179 ui->retranslateUi(this);
180 }
181
UpdateBackgroundColorButton(QColor color)182 void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
183 bg_color = color;
184
185 QPixmap pixmap(ui->bg_button->size());
186 pixmap.fill(bg_color);
187
188 const QIcon color_icon(pixmap);
189 ui->bg_button->setIcon(color_icon);
190 }
191
UpdateDeviceComboBox()192 void ConfigureGraphics::UpdateDeviceComboBox() {
193 ui->device->clear();
194
195 bool enabled = false;
196
197 if (!Settings::IsConfiguringGlobal() &&
198 ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
199 vulkan_device = Settings::values.vulkan_device.GetValue();
200 }
201 switch (GetCurrentGraphicsBackend()) {
202 case Settings::RendererBackend::OpenGL:
203 ui->device->addItem(tr("OpenGL Graphics Device"));
204 enabled = false;
205 break;
206 case Settings::RendererBackend::Vulkan:
207 for (const auto& device : vulkan_devices) {
208 ui->device->addItem(device);
209 }
210 ui->device->setCurrentIndex(vulkan_device);
211 enabled = !vulkan_devices.empty();
212 break;
213 }
214 // If in per-game config and use global is selected, don't enable.
215 enabled &= !(!Settings::IsConfiguringGlobal() &&
216 ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX);
217 ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn());
218 }
219
RetrieveVulkanDevices()220 void ConfigureGraphics::RetrieveVulkanDevices() {
221 #ifdef HAS_VULKAN
222 vulkan_devices.clear();
223 for (auto& name : Vulkan::RendererVulkan::EnumerateDevices()) {
224 vulkan_devices.push_back(QString::fromStdString(name));
225 }
226 #endif
227 }
228
GetCurrentGraphicsBackend() const229 Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
230 if (Settings::IsConfiguringGlobal()) {
231 return static_cast<Settings::RendererBackend>(ui->api->currentIndex());
232 }
233
234 if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
235 Settings::values.renderer_backend.SetGlobal(true);
236 return Settings::values.renderer_backend.GetValue();
237 }
238 Settings::values.renderer_backend.SetGlobal(false);
239 return static_cast<Settings::RendererBackend>(ui->api->currentIndex() -
240 ConfigurationShared::USE_GLOBAL_OFFSET);
241 }
242
SetupPerGameUI()243 void ConfigureGraphics::SetupPerGameUI() {
244 if (Settings::IsConfiguringGlobal()) {
245 ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal());
246 ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal());
247 ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal());
248 ui->use_asynchronous_gpu_emulation->setEnabled(
249 Settings::values.use_asynchronous_gpu_emulation.UsingGlobal());
250 ui->use_nvdec_emulation->setEnabled(Settings::values.use_nvdec_emulation.UsingGlobal());
251 ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal());
252 ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal());
253
254 return;
255 }
256
257 connect(ui->bg_combobox, qOverload<int>(&QComboBox::activated), this, [this](int index) {
258 ui->bg_button->setEnabled(index == 1);
259 ConfigurationShared::SetHighlight(ui->bg_layout, index == 1);
260 });
261
262 ConfigurationShared::SetColoredTristate(
263 ui->use_disk_shader_cache, Settings::values.use_disk_shader_cache, use_disk_shader_cache);
264 ConfigurationShared::SetColoredTristate(
265 ui->use_nvdec_emulation, Settings::values.use_nvdec_emulation, use_nvdec_emulation);
266 ConfigurationShared::SetColoredTristate(ui->use_asynchronous_gpu_emulation,
267 Settings::values.use_asynchronous_gpu_emulation,
268 use_asynchronous_gpu_emulation);
269
270 ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label,
271 Settings::values.aspect_ratio.GetValue(true));
272 ConfigurationShared::InsertGlobalItem(
273 ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
274 }
275