From f22867efc5fc3b970a706f7997b997048c969a89 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Sat, 28 May 2022 02:33:23 -0400 Subject: 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. --- src/yuzu/configuration/config.cpp | 8 +++ src/yuzu/configuration/configure_graphics.cpp | 39 +++++++++++- src/yuzu/configuration/configure_graphics.h | 2 +- src/yuzu/configuration/configure_graphics.ui | 91 ++++++++++++++------------- 4 files changed, 95 insertions(+), 45 deletions(-) (limited to 'src/yuzu/configuration') 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() { ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); + if (!global && UISettings::values.has_broken_vulkan && + Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::Vulkan && + !Settings::values.renderer_backend.UsingGlobal()) { + Settings::values.renderer_backend.SetGlobal(true); + } + if (global) { ReadBasicSetting(Settings::values.renderer_debug); ReadBasicSetting(Settings::values.renderer_shader_feedback); @@ -798,6 +804,7 @@ void Config::ReadUIValues() { ReadBasicSetting(UISettings::values.pause_when_in_background); ReadBasicSetting(UISettings::values.mute_when_in_background); ReadBasicSetting(UISettings::values.hide_mouse); + ReadBasicSetting(UISettings::values.has_broken_vulkan); ReadBasicSetting(UISettings::values.disable_web_applet); qt_config->endGroup(); @@ -1343,6 +1350,7 @@ void Config::SaveUIValues() { WriteBasicSetting(UISettings::values.pause_when_in_background); WriteBasicSetting(UISettings::values.mute_when_in_background); WriteBasicSetting(UISettings::values.hide_mouse); + WriteBasicSetting(UISettings::values.has_broken_vulkan); WriteBasicSetting(UISettings::values.disable_web_applet); 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 @@ // Include this early to include Vulkan headers how we want to #include "video_core/vulkan_common/vulkan_wrapper.h" +#include #include #include @@ -17,6 +18,7 @@ #include "video_core/vulkan_common/vulkan_library.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_graphics.h" +#include "yuzu/uisettings.h" ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent) : QWidget(parent), ui{std::make_unique()}, system{system_} { @@ -57,6 +59,23 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren UpdateBackgroundColorButton(new_bg_color); }); + connect(ui->button_check_vulkan, &QAbstractButton::clicked, this, [this] { + UISettings::values.has_broken_vulkan = false; + + if (RetrieveVulkanDevices()) { + ui->api->setEnabled(true); + + for (const auto& device : vulkan_devices) { + ui->device->addItem(device); + } + } else { + UISettings::values.has_broken_vulkan = true; + } + }); + + ui->api->setEnabled(!UISettings::values.has_broken_vulkan.GetValue()); + ui->button_check_vulkan->setVisible(UISettings::values.has_broken_vulkan.GetValue()); + ui->bg_label->setVisible(Settings::IsConfiguringGlobal()); ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal()); } @@ -296,7 +315,7 @@ void ConfigureGraphics::UpdateAPILayout() { vulkan_device = Settings::values.vulkan_device.GetValue(true); shader_backend = Settings::values.shader_backend.GetValue(true); ui->device_widget->setEnabled(false); - ui->backend_widget->setEnabled(false); + ui->backend_widget->setEnabled(UISettings::values.has_broken_vulkan.GetValue()); } else { vulkan_device = Settings::values.vulkan_device.GetValue(); shader_backend = Settings::values.shader_backend.GetValue(); @@ -318,7 +337,11 @@ void ConfigureGraphics::UpdateAPILayout() { } } -void ConfigureGraphics::RetrieveVulkanDevices() try { +bool ConfigureGraphics::RetrieveVulkanDevices() try { + if (UISettings::values.has_broken_vulkan) { + return false; + } + using namespace Vulkan; vk::InstanceDispatch dld; @@ -333,8 +356,13 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { vulkan_devices.push_back(QString::fromStdString(name)); } + UISettings::values.has_broken_vulkan = false; + ui->button_check_vulkan->setVisible(false); + + return true; } catch (const Vulkan::vk::Exception& exception) { LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); + return false; } Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { @@ -415,4 +443,11 @@ void ConfigureGraphics::SetupPerGameUI() { ui->api, static_cast(Settings::values.renderer_backend.GetValue(true))); ConfigurationShared::InsertGlobalItem( ui->nvdec_emulation, static_cast(Settings::values.nvdec_emulation.GetValue(true))); + + if (UISettings::values.has_broken_vulkan) { + ui->backend_widget->setEnabled(true); + ConfigurationShared::SetColoredComboBox( + ui->backend, ui->backend_widget, + static_cast(Settings::values.shader_backend.GetValue(true))); + } } 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: void UpdateDeviceSelection(int device); void UpdateShaderBackendSelection(int backend); - void RetrieveVulkanDevices(); + bool RetrieveVulkanDevices(); void SetupPerGameUI(); 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 @@ 0 0 - 437 - 482 + 471 + 759 @@ -171,11 +171,11 @@ - - - Accelerate ASTC texture decoding - - + + + Accelerate ASTC texture decoding + + @@ -438,43 +438,43 @@ - - - - 0 - - - 0 - - - 0 + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Anti-Aliasing Method: + + + + + + + + None - - 0 + + + + FXAA - - - - Anti-Aliasing Method: - - - - - - - - None - - - - - FXAA - - - - - - + + + + + @@ -574,6 +574,13 @@ + + + + Check for Working Vulkan + + + -- cgit v1.2.3 From 500b01076e1a96b9c133ff663daad6f9dd8e4039 Mon Sep 17 00:00:00 2001 From: lat9nq Date: Sun, 29 May 2022 22:26:27 -0400 Subject: yuzu-qt: Make has_broken_vulkan only for crashes Being able to catch and handle a Vulkan exception is not what this is for. --- src/yuzu/check_vulkan.cpp | 8 +++++--- src/yuzu/check_vulkan.h | 5 +++++ src/yuzu/configuration/configure_graphics.cpp | 4 +--- src/yuzu/main.cpp | 10 +++++----- src/yuzu/uisettings.h | 1 + 5 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/check_vulkan.cpp b/src/yuzu/check_vulkan.cpp index 1b21efe69..e6d66ab34 100644 --- a/src/yuzu/check_vulkan.cpp +++ b/src/yuzu/check_vulkan.cpp @@ -1,6 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + #include "video_core/vulkan_common/vulkan_wrapper.h" -#include #include #include #include "common/fs/fs.h" @@ -42,8 +44,8 @@ bool CheckVulkan() { } catch (const Vulkan::vk::Exception& exception) { LOG_ERROR(Frontend, "Failed to initialize Vulkan: {}", exception.what()); - UISettings::values.has_broken_vulkan = true; - return false; + // Don't set has_broken_vulkan to true here: we care when loading Vulkan crashes the + // application, not when we can handle it. } std::filesystem::remove(temp_file_loc); diff --git a/src/yuzu/check_vulkan.h b/src/yuzu/check_vulkan.h index 3b199d3bb..e4ea93582 100644 --- a/src/yuzu/check_vulkan.h +++ b/src/yuzu/check_vulkan.h @@ -1 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + bool CheckVulkan(); diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 482a6a8ab..70015a373 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -64,6 +64,7 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren if (RetrieveVulkanDevices()) { ui->api->setEnabled(true); + ui->button_check_vulkan->hide(); for (const auto& device : vulkan_devices) { ui->device->addItem(device); @@ -356,9 +357,6 @@ bool ConfigureGraphics::RetrieveVulkanDevices() try { vulkan_devices.push_back(QString::fromStdString(name)); } - UISettings::values.has_broken_vulkan = false; - ui->button_check_vulkan->setVisible(false); - return true; } catch (const Vulkan::vk::Exception& exception) { LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 71802cfc2..ff1afa56e 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -299,11 +299,7 @@ GMainWindow::GMainWindow() MigrateConfigFiles(); if (!CheckVulkan()) { - QMessageBox::warning( - this, tr("Broken Vulkan Installation Detected"), - tr("Vulkan initialization failed on the previous boot. Please update your graphics " - "driver, then re-check your Vulkan installation by accessing the Graphics " - "configuration and clicking \"Check for Working Vulkan\".")); + QMessageBox::warning(this, tr("Broken Vulkan Installation Detected"), tr("")); } if (UISettings::values.has_broken_vulkan) { Settings::values.renderer_backend = Settings::RendererBackend::OpenGL; @@ -2788,6 +2784,10 @@ void GMainWindow::OnConfigure() { mouse_hide_timer.start(); } + if (!UISettings::values.has_broken_vulkan) { + renderer_status_button->setEnabled(!emulation_running); + } + UpdateStatusButtons(); controller_dialog->refreshConfiguration(); } diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 653b76883..c64d87ace 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -77,6 +77,7 @@ struct Values { Settings::BasicSetting pause_when_in_background{false, "pauseWhenInBackground"}; Settings::BasicSetting mute_when_in_background{false, "muteWhenInBackground"}; Settings::BasicSetting hide_mouse{true, "hideInactiveMouse"}; + // Set when Vulkan is known to crash the application Settings::BasicSetting has_broken_vulkan{false, "has_broken_vulkan"}; Settings::BasicSetting select_user_on_boot{false, "select_user_on_boot"}; -- cgit v1.2.3 From 4544407af6d541611d17c076bbd1d2d2adecbf7e Mon Sep 17 00:00:00 2001 From: lat9nq Date: Sat, 4 Jun 2022 04:18:21 -0400 Subject: configure_graphics: Remove unused include --- src/yuzu/configuration/configure_graphics.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/yuzu/configuration') diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 70015a373..85f34dc35 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -5,7 +5,6 @@ // Include this early to include Vulkan headers how we want to #include "video_core/vulkan_common/vulkan_wrapper.h" -#include #include #include -- cgit v1.2.3