summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar lat9nq2022-05-28 02:33:23 -0400
committerGravatar lat9nq2022-05-30 10:57:59 -0400
commitf22867efc5fc3b970a706f7997b997048c969a89 (patch)
tree942633953e2c3d2c379d388e9b1c05b446f0027d
parentdefault_ini: Reflect new renderer backend default setting (diff)
downloadyuzu-f22867efc5fc3b970a706f7997b997048c969a89.tar.gz
yuzu-f22867efc5fc3b970a706f7997b997048c969a89.tar.xz
yuzu-f22867efc5fc3b970a706f7997b997048c969a89.zip
yuzu-qt: Attempt to workaround broken Vulkan installations
This does a few things in order to make the default setting Vulkan workable. - When yuzu boots, it just opens the Vulkan library. - If it works, all good and we continue with Vulkan as the default. - If something breaks, a new file in the config directory will be left behind (this is deleted normally). - If Vulkan is not working, has_broken_vulkan is set to true. - The first time this happens, a warning is displayed to notify the user. - This forces use of OpenGL, and Vulkan cannot be selected. - The Shader Backend selector is made accessible for use in custom configurations. - To disable has_broken_vulkan, the user needs to press a button in Graphics Configuration to manually run the Vulkan device enumeration.
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/check_vulkan.cpp51
-rw-r--r--src/yuzu/check_vulkan.h1
-rw-r--r--src/yuzu/configuration/config.cpp8
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp39
-rw-r--r--src/yuzu/configuration/configure_graphics.h2
-rw-r--r--src/yuzu/configuration/configure_graphics.ui91
-rw-r--r--src/yuzu/main.cpp17
-rw-r--r--src/yuzu/uisettings.h1
9 files changed, 166 insertions, 46 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 404acdd05..39989885d 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -30,6 +30,8 @@ add_executable(yuzu
30 applets/qt_web_browser_scripts.h 30 applets/qt_web_browser_scripts.h
31 bootmanager.cpp 31 bootmanager.cpp
32 bootmanager.h 32 bootmanager.h
33 check_vulkan.cpp
34 check_vulkan.h
33 compatdb.ui 35 compatdb.ui
34 compatibility_list.cpp 36 compatibility_list.cpp
35 compatibility_list.h 37 compatibility_list.h
diff --git a/src/yuzu/check_vulkan.cpp b/src/yuzu/check_vulkan.cpp
new file mode 100644
index 000000000..1b21efe69
--- /dev/null
+++ b/src/yuzu/check_vulkan.cpp
@@ -0,0 +1,51 @@
1#include "video_core/vulkan_common/vulkan_wrapper.h"
2
3#include <exception>
4#include <filesystem>
5#include <fstream>
6#include "common/fs/fs.h"
7#include "common/fs/path_util.h"
8#include "common/logging/log.h"
9#include "video_core/vulkan_common/vulkan_instance.h"
10#include "video_core/vulkan_common/vulkan_library.h"
11#include "yuzu/check_vulkan.h"
12#include "yuzu/uisettings.h"
13
14constexpr char TEMP_FILE_NAME[] = "vulkan_check";
15
16bool CheckVulkan() {
17 if (UISettings::values.has_broken_vulkan) {
18 return true;
19 }
20
21 LOG_DEBUG(Frontend, "Checking presence of Vulkan");
22
23 const auto fs_config_loc = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir);
24 const auto temp_file_loc = fs_config_loc / TEMP_FILE_NAME;
25
26 if (std::filesystem::exists(temp_file_loc)) {
27 LOG_WARNING(Frontend, "Detected recovery from previous failed Vulkan initialization");
28
29 UISettings::values.has_broken_vulkan = true;
30 std::filesystem::remove(temp_file_loc);
31 return false;
32 }
33
34 std::ofstream temp_file_handle(temp_file_loc);
35 temp_file_handle.close();
36
37 try {
38 Vulkan::vk::InstanceDispatch dld;
39 const Common::DynamicLibrary library = Vulkan::OpenLibrary();
40 const Vulkan::vk::Instance instance =
41 Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_0);
42
43 } catch (const Vulkan::vk::Exception& exception) {
44 LOG_ERROR(Frontend, "Failed to initialize Vulkan: {}", exception.what());
45 UISettings::values.has_broken_vulkan = true;
46 return false;
47 }
48
49 std::filesystem::remove(temp_file_loc);
50 return true;
51}
diff --git a/src/yuzu/check_vulkan.h b/src/yuzu/check_vulkan.h
new file mode 100644
index 000000000..3b199d3bb
--- /dev/null
+++ b/src/yuzu/check_vulkan.h
@@ -0,0 +1 @@
bool CheckVulkan();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index ac26b885b..8b95b677b 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -679,6 +679,12 @@ void Config::ReadRendererValues() {
679 ReadGlobalSetting(Settings::values.bg_green); 679 ReadGlobalSetting(Settings::values.bg_green);
680 ReadGlobalSetting(Settings::values.bg_blue); 680 ReadGlobalSetting(Settings::values.bg_blue);
681 681
682 if (!global && UISettings::values.has_broken_vulkan &&
683 Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::Vulkan &&
684 !Settings::values.renderer_backend.UsingGlobal()) {
685 Settings::values.renderer_backend.SetGlobal(true);
686 }
687
682 if (global) { 688 if (global) {
683 ReadBasicSetting(Settings::values.renderer_debug); 689 ReadBasicSetting(Settings::values.renderer_debug);
684 ReadBasicSetting(Settings::values.renderer_shader_feedback); 690 ReadBasicSetting(Settings::values.renderer_shader_feedback);
@@ -798,6 +804,7 @@ void Config::ReadUIValues() {
798 ReadBasicSetting(UISettings::values.pause_when_in_background); 804 ReadBasicSetting(UISettings::values.pause_when_in_background);
799 ReadBasicSetting(UISettings::values.mute_when_in_background); 805 ReadBasicSetting(UISettings::values.mute_when_in_background);
800 ReadBasicSetting(UISettings::values.hide_mouse); 806 ReadBasicSetting(UISettings::values.hide_mouse);
807 ReadBasicSetting(UISettings::values.has_broken_vulkan);
801 ReadBasicSetting(UISettings::values.disable_web_applet); 808 ReadBasicSetting(UISettings::values.disable_web_applet);
802 809
803 qt_config->endGroup(); 810 qt_config->endGroup();
@@ -1343,6 +1350,7 @@ void Config::SaveUIValues() {
1343 WriteBasicSetting(UISettings::values.pause_when_in_background); 1350 WriteBasicSetting(UISettings::values.pause_when_in_background);
1344 WriteBasicSetting(UISettings::values.mute_when_in_background); 1351 WriteBasicSetting(UISettings::values.mute_when_in_background);
1345 WriteBasicSetting(UISettings::values.hide_mouse); 1352 WriteBasicSetting(UISettings::values.hide_mouse);
1353 WriteBasicSetting(UISettings::values.has_broken_vulkan);
1346 WriteBasicSetting(UISettings::values.disable_web_applet); 1354 WriteBasicSetting(UISettings::values.disable_web_applet);
1347 1355
1348 qt_config->endGroup(); 1356 qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 2f1435b10..482a6a8ab 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -5,6 +5,7 @@
5// Include this early to include Vulkan headers how we want to 5// Include this early to include Vulkan headers how we want to
6#include "video_core/vulkan_common/vulkan_wrapper.h" 6#include "video_core/vulkan_common/vulkan_wrapper.h"
7 7
8#include <exception>
8#include <QColorDialog> 9#include <QColorDialog>
9#include <QVulkanInstance> 10#include <QVulkanInstance>
10 11
@@ -17,6 +18,7 @@
17#include "video_core/vulkan_common/vulkan_library.h" 18#include "video_core/vulkan_common/vulkan_library.h"
18#include "yuzu/configuration/configuration_shared.h" 19#include "yuzu/configuration/configuration_shared.h"
19#include "yuzu/configuration/configure_graphics.h" 20#include "yuzu/configuration/configure_graphics.h"
21#include "yuzu/uisettings.h"
20 22
21ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent) 23ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent)
22 : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} { 24 : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} {
@@ -57,6 +59,23 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren
57 UpdateBackgroundColorButton(new_bg_color); 59 UpdateBackgroundColorButton(new_bg_color);
58 }); 60 });
59 61
62 connect(ui->button_check_vulkan, &QAbstractButton::clicked, this, [this] {
63 UISettings::values.has_broken_vulkan = false;
64
65 if (RetrieveVulkanDevices()) {
66 ui->api->setEnabled(true);
67
68 for (const auto& device : vulkan_devices) {
69 ui->device->addItem(device);
70 }
71 } else {
72 UISettings::values.has_broken_vulkan = true;
73 }
74 });
75
76 ui->api->setEnabled(!UISettings::values.has_broken_vulkan.GetValue());
77 ui->button_check_vulkan->setVisible(UISettings::values.has_broken_vulkan.GetValue());
78
60 ui->bg_label->setVisible(Settings::IsConfiguringGlobal()); 79 ui->bg_label->setVisible(Settings::IsConfiguringGlobal());
61 ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal()); 80 ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
62} 81}
@@ -296,7 +315,7 @@ void ConfigureGraphics::UpdateAPILayout() {
296 vulkan_device = Settings::values.vulkan_device.GetValue(true); 315 vulkan_device = Settings::values.vulkan_device.GetValue(true);
297 shader_backend = Settings::values.shader_backend.GetValue(true); 316 shader_backend = Settings::values.shader_backend.GetValue(true);
298 ui->device_widget->setEnabled(false); 317 ui->device_widget->setEnabled(false);
299 ui->backend_widget->setEnabled(false); 318 ui->backend_widget->setEnabled(UISettings::values.has_broken_vulkan.GetValue());
300 } else { 319 } else {
301 vulkan_device = Settings::values.vulkan_device.GetValue(); 320 vulkan_device = Settings::values.vulkan_device.GetValue();
302 shader_backend = Settings::values.shader_backend.GetValue(); 321 shader_backend = Settings::values.shader_backend.GetValue();
@@ -318,7 +337,11 @@ void ConfigureGraphics::UpdateAPILayout() {
318 } 337 }
319} 338}
320 339
321void ConfigureGraphics::RetrieveVulkanDevices() try { 340bool ConfigureGraphics::RetrieveVulkanDevices() try {
341 if (UISettings::values.has_broken_vulkan) {
342 return false;
343 }
344
322 using namespace Vulkan; 345 using namespace Vulkan;
323 346
324 vk::InstanceDispatch dld; 347 vk::InstanceDispatch dld;
@@ -333,8 +356,13 @@ void ConfigureGraphics::RetrieveVulkanDevices() try {
333 vulkan_devices.push_back(QString::fromStdString(name)); 356 vulkan_devices.push_back(QString::fromStdString(name));
334 } 357 }
335 358
359 UISettings::values.has_broken_vulkan = false;
360 ui->button_check_vulkan->setVisible(false);
361
362 return true;
336} catch (const Vulkan::vk::Exception& exception) { 363} catch (const Vulkan::vk::Exception& exception) {
337 LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); 364 LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what());
365 return false;
338} 366}
339 367
340Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { 368Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
@@ -415,4 +443,11 @@ void ConfigureGraphics::SetupPerGameUI() {
415 ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true))); 443 ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
416 ConfigurationShared::InsertGlobalItem( 444 ConfigurationShared::InsertGlobalItem(
417 ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true))); 445 ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true)));
446
447 if (UISettings::values.has_broken_vulkan) {
448 ui->backend_widget->setEnabled(true);
449 ConfigurationShared::SetColoredComboBox(
450 ui->backend, ui->backend_widget,
451 static_cast<int>(Settings::values.shader_backend.GetValue(true)));
452 }
418} 453}
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index 1b101c940..8438f0187 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -41,7 +41,7 @@ private:
41 void UpdateDeviceSelection(int device); 41 void UpdateDeviceSelection(int device);
42 void UpdateShaderBackendSelection(int backend); 42 void UpdateShaderBackendSelection(int backend);
43 43
44 void RetrieveVulkanDevices(); 44 bool RetrieveVulkanDevices();
45 45
46 void SetupPerGameUI(); 46 void SetupPerGameUI();
47 47
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 74f0e0b79..2f94c94bc 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -6,8 +6,8 @@
6 <rect> 6 <rect>
7 <x>0</x> 7 <x>0</x>
8 <y>0</y> 8 <y>0</y>
9 <width>437</width> 9 <width>471</width>
10 <height>482</height> 10 <height>759</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
@@ -171,11 +171,11 @@
171 </widget> 171 </widget>
172 </item> 172 </item>
173 <item> 173 <item>
174 <widget class="QCheckBox" name="accelerate_astc"> 174 <widget class="QCheckBox" name="accelerate_astc">
175 <property name="text"> 175 <property name="text">
176 <string>Accelerate ASTC texture decoding</string> 176 <string>Accelerate ASTC texture decoding</string>
177 </property> 177 </property>
178 </widget> 178 </widget>
179 </item> 179 </item>
180 <item> 180 <item>
181 <widget class="QWidget" name="nvdec_emulation_widget" native="true"> 181 <widget class="QWidget" name="nvdec_emulation_widget" native="true">
@@ -438,43 +438,43 @@
438 </widget> 438 </widget>
439 </item> 439 </item>
440 <item> 440 <item>
441 <widget class="QWidget" name="anti_aliasing_layout" native="true"> 441 <widget class="QWidget" name="anti_aliasing_layout" native="true">
442 <layout class="QHBoxLayout" name="horizontalLayout_7"> 442 <layout class="QHBoxLayout" name="horizontalLayout_7">
443 <property name="leftMargin"> 443 <property name="leftMargin">
444 <number>0</number> 444 <number>0</number>
445 </property> 445 </property>
446 <property name="topMargin"> 446 <property name="topMargin">
447 <number>0</number> 447 <number>0</number>
448 </property> 448 </property>
449 <property name="rightMargin"> 449 <property name="rightMargin">
450 <number>0</number> 450 <number>0</number>
451 </property>
452 <property name="bottomMargin">
453 <number>0</number>
454 </property>
455 <item>
456 <widget class="QLabel" name="anti_aliasing_label">
457 <property name="text">
458 <string>Anti-Aliasing Method:</string>
459 </property>
460 </widget>
461 </item>
462 <item>
463 <widget class="QComboBox" name="anti_aliasing_combobox">
464 <item>
465 <property name="text">
466 <string>None</string>
451 </property> 467 </property>
452 <property name="bottomMargin"> 468 </item>
453 <number>0</number> 469 <item>
470 <property name="text">
471 <string>FXAA</string>
454 </property> 472 </property>
455 <item> 473 </item>
456 <widget class="QLabel" name="anti_aliasing_label"> 474 </widget>
457 <property name="text"> 475 </item>
458 <string>Anti-Aliasing Method:</string> 476 </layout>
459 </property> 477 </widget>
460 </widget>
461 </item>
462 <item>
463 <widget class="QComboBox" name="anti_aliasing_combobox">
464 <item>
465 <property name="text">
466 <string>None</string>
467 </property>
468 </item>
469 <item>
470 <property name="text">
471 <string>FXAA</string>
472 </property>
473 </item>
474 </widget>
475 </item>
476 </layout>
477 </widget>
478 </item> 478 </item>
479 <item> 479 <item>
480 <widget class="QWidget" name="bg_layout" native="true"> 480 <widget class="QWidget" name="bg_layout" native="true">
@@ -574,6 +574,13 @@
574 </property> 574 </property>
575 </spacer> 575 </spacer>
576 </item> 576 </item>
577 <item>
578 <widget class="QPushButton" name="button_check_vulkan">
579 <property name="text">
580 <string>Check for Working Vulkan</string>
581 </property>
582 </widget>
583 </item>
577 </layout> 584 </layout>
578 </widget> 585 </widget>
579 <resources/> 586 <resources/>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f4a9a7171..71802cfc2 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -115,6 +115,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
115#include "video_core/shader_notify.h" 115#include "video_core/shader_notify.h"
116#include "yuzu/about_dialog.h" 116#include "yuzu/about_dialog.h"
117#include "yuzu/bootmanager.h" 117#include "yuzu/bootmanager.h"
118#include "yuzu/check_vulkan.h"
118#include "yuzu/compatdb.h" 119#include "yuzu/compatdb.h"
119#include "yuzu/compatibility_list.h" 120#include "yuzu/compatibility_list.h"
120#include "yuzu/configuration/config.h" 121#include "yuzu/configuration/config.h"
@@ -297,6 +298,20 @@ GMainWindow::GMainWindow()
297 298
298 MigrateConfigFiles(); 299 MigrateConfigFiles();
299 300
301 if (!CheckVulkan()) {
302 QMessageBox::warning(
303 this, tr("Broken Vulkan Installation Detected"),
304 tr("Vulkan initialization failed on the previous boot. Please update your graphics "
305 "driver, then re-check your Vulkan installation by accessing the Graphics "
306 "configuration and clicking \"Check for Working Vulkan\"."));
307 }
308 if (UISettings::values.has_broken_vulkan) {
309 Settings::values.renderer_backend = Settings::RendererBackend::OpenGL;
310
311 renderer_status_button->setDisabled(true);
312 renderer_status_button->setChecked(false);
313 }
314
300#if defined(HAVE_SDL2) && !defined(_WIN32) 315#if defined(HAVE_SDL2) && !defined(_WIN32)
301 SDL_InitSubSystem(SDL_INIT_VIDEO); 316 SDL_InitSubSystem(SDL_INIT_VIDEO);
302 // SDL disables the screen saver by default, and setting the hint 317 // SDL disables the screen saver by default, and setting the hint
@@ -1563,7 +1578,7 @@ void GMainWindow::ShutdownGame() {
1563 emu_speed_label->setVisible(false); 1578 emu_speed_label->setVisible(false);
1564 game_fps_label->setVisible(false); 1579 game_fps_label->setVisible(false);
1565 emu_frametime_label->setVisible(false); 1580 emu_frametime_label->setVisible(false);
1566 renderer_status_button->setEnabled(true); 1581 renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
1567 1582
1568 game_path.clear(); 1583 game_path.clear();
1569 1584
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 15ba9ea17..653b76883 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -77,6 +77,7 @@ struct Values {
77 Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"}; 77 Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
78 Settings::BasicSetting<bool> mute_when_in_background{false, "muteWhenInBackground"}; 78 Settings::BasicSetting<bool> mute_when_in_background{false, "muteWhenInBackground"};
79 Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"}; 79 Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"};
80 Settings::BasicSetting<bool> has_broken_vulkan{false, "has_broken_vulkan"};
80 81
81 Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"}; 82 Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
82 83