Merge pull request #8393 from lat9nq/default-vulkan
general: Set renderer_backend's default to Vulkan
This commit is contained in:
commit
ae83d5c6d3
12 changed files with 184 additions and 48 deletions
|
@ -496,7 +496,7 @@ struct Values {
|
||||||
|
|
||||||
// Renderer
|
// Renderer
|
||||||
RangedSetting<RendererBackend> renderer_backend{
|
RangedSetting<RendererBackend> renderer_backend{
|
||||||
RendererBackend::OpenGL, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"};
|
RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Vulkan, "backend"};
|
||||||
BasicSetting<bool> renderer_debug{false, "debug"};
|
BasicSetting<bool> renderer_debug{false, "debug"};
|
||||||
BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"};
|
BasicSetting<bool> renderer_shader_feedback{false, "shader_feedback"};
|
||||||
BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
|
BasicSetting<bool> enable_nsight_aftermath{false, "nsight_aftermath"};
|
||||||
|
|
|
@ -5,11 +5,13 @@
|
||||||
|
|
||||||
#include "common/dynamic_library.h"
|
#include "common/dynamic_library.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "video_core/vulkan_common/vulkan_library.h"
|
#include "video_core/vulkan_common/vulkan_library.h"
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
Common::DynamicLibrary OpenLibrary() {
|
Common::DynamicLibrary OpenLibrary() {
|
||||||
|
LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library");
|
||||||
Common::DynamicLibrary library;
|
Common::DynamicLibrary library;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Check if a path to a specific Vulkan library has been specified.
|
// Check if a path to a specific Vulkan library has been specified.
|
||||||
|
@ -22,9 +24,11 @@ Common::DynamicLibrary OpenLibrary() {
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
|
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
|
||||||
|
LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename);
|
||||||
if (!library.Open(filename.c_str())) {
|
if (!library.Open(filename.c_str())) {
|
||||||
// Android devices may not have libvulkan.so.1, only libvulkan.so.
|
// Android devices may not have libvulkan.so.1, only libvulkan.so.
|
||||||
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
|
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
|
||||||
|
LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename);
|
||||||
void(library.Open(filename.c_str()));
|
void(library.Open(filename.c_str()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,8 @@ add_executable(yuzu
|
||||||
applets/qt_web_browser_scripts.h
|
applets/qt_web_browser_scripts.h
|
||||||
bootmanager.cpp
|
bootmanager.cpp
|
||||||
bootmanager.h
|
bootmanager.h
|
||||||
|
check_vulkan.cpp
|
||||||
|
check_vulkan.h
|
||||||
compatdb.ui
|
compatdb.ui
|
||||||
compatibility_list.cpp
|
compatibility_list.cpp
|
||||||
compatibility_list.h
|
compatibility_list.h
|
||||||
|
|
53
src/yuzu/check_vulkan.cpp
Normal file
53
src/yuzu/check_vulkan.cpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include "common/fs/fs.h"
|
||||||
|
#include "common/fs/path_util.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_library.h"
|
||||||
|
#include "yuzu/check_vulkan.h"
|
||||||
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
|
constexpr char TEMP_FILE_NAME[] = "vulkan_check";
|
||||||
|
|
||||||
|
bool CheckVulkan() {
|
||||||
|
if (UISettings::values.has_broken_vulkan) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Frontend, "Checking presence of Vulkan");
|
||||||
|
|
||||||
|
const auto fs_config_loc = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ConfigDir);
|
||||||
|
const auto temp_file_loc = fs_config_loc / TEMP_FILE_NAME;
|
||||||
|
|
||||||
|
if (std::filesystem::exists(temp_file_loc)) {
|
||||||
|
LOG_WARNING(Frontend, "Detected recovery from previous failed Vulkan initialization");
|
||||||
|
|
||||||
|
UISettings::values.has_broken_vulkan = true;
|
||||||
|
std::filesystem::remove(temp_file_loc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream temp_file_handle(temp_file_loc);
|
||||||
|
temp_file_handle.close();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Vulkan::vk::InstanceDispatch dld;
|
||||||
|
const Common::DynamicLibrary library = Vulkan::OpenLibrary();
|
||||||
|
const Vulkan::vk::Instance instance =
|
||||||
|
Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_0);
|
||||||
|
|
||||||
|
} catch (const Vulkan::vk::Exception& exception) {
|
||||||
|
LOG_ERROR(Frontend, "Failed to initialize Vulkan: {}", exception.what());
|
||||||
|
// 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);
|
||||||
|
return true;
|
||||||
|
}
|
6
src/yuzu/check_vulkan.h
Normal file
6
src/yuzu/check_vulkan.h
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool CheckVulkan();
|
|
@ -682,6 +682,12 @@ void Config::ReadRendererValues() {
|
||||||
ReadGlobalSetting(Settings::values.bg_green);
|
ReadGlobalSetting(Settings::values.bg_green);
|
||||||
ReadGlobalSetting(Settings::values.bg_blue);
|
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) {
|
if (global) {
|
||||||
ReadBasicSetting(Settings::values.renderer_debug);
|
ReadBasicSetting(Settings::values.renderer_debug);
|
||||||
ReadBasicSetting(Settings::values.renderer_shader_feedback);
|
ReadBasicSetting(Settings::values.renderer_shader_feedback);
|
||||||
|
@ -801,6 +807,7 @@ void Config::ReadUIValues() {
|
||||||
ReadBasicSetting(UISettings::values.pause_when_in_background);
|
ReadBasicSetting(UISettings::values.pause_when_in_background);
|
||||||
ReadBasicSetting(UISettings::values.mute_when_in_background);
|
ReadBasicSetting(UISettings::values.mute_when_in_background);
|
||||||
ReadBasicSetting(UISettings::values.hide_mouse);
|
ReadBasicSetting(UISettings::values.hide_mouse);
|
||||||
|
ReadBasicSetting(UISettings::values.has_broken_vulkan);
|
||||||
ReadBasicSetting(UISettings::values.disable_web_applet);
|
ReadBasicSetting(UISettings::values.disable_web_applet);
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
@ -1348,6 +1355,7 @@ void Config::SaveUIValues() {
|
||||||
WriteBasicSetting(UISettings::values.pause_when_in_background);
|
WriteBasicSetting(UISettings::values.pause_when_in_background);
|
||||||
WriteBasicSetting(UISettings::values.mute_when_in_background);
|
WriteBasicSetting(UISettings::values.mute_when_in_background);
|
||||||
WriteBasicSetting(UISettings::values.hide_mouse);
|
WriteBasicSetting(UISettings::values.hide_mouse);
|
||||||
|
WriteBasicSetting(UISettings::values.has_broken_vulkan);
|
||||||
WriteBasicSetting(UISettings::values.disable_web_applet);
|
WriteBasicSetting(UISettings::values.disable_web_applet);
|
||||||
|
|
||||||
qt_config->endGroup();
|
qt_config->endGroup();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "video_core/vulkan_common/vulkan_library.h"
|
#include "video_core/vulkan_common/vulkan_library.h"
|
||||||
#include "yuzu/configuration/configuration_shared.h"
|
#include "yuzu/configuration/configuration_shared.h"
|
||||||
#include "yuzu/configuration/configure_graphics.h"
|
#include "yuzu/configuration/configure_graphics.h"
|
||||||
|
#include "yuzu/uisettings.h"
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent)
|
ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent)
|
||||||
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} {
|
: QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} {
|
||||||
|
@ -57,6 +58,24 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren
|
||||||
UpdateBackgroundColorButton(new_bg_color);
|
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);
|
||||||
|
ui->button_check_vulkan->hide();
|
||||||
|
|
||||||
|
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_label->setVisible(Settings::IsConfiguringGlobal());
|
||||||
ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
|
||||||
}
|
}
|
||||||
|
@ -296,7 +315,7 @@ void ConfigureGraphics::UpdateAPILayout() {
|
||||||
vulkan_device = Settings::values.vulkan_device.GetValue(true);
|
vulkan_device = Settings::values.vulkan_device.GetValue(true);
|
||||||
shader_backend = Settings::values.shader_backend.GetValue(true);
|
shader_backend = Settings::values.shader_backend.GetValue(true);
|
||||||
ui->device_widget->setEnabled(false);
|
ui->device_widget->setEnabled(false);
|
||||||
ui->backend_widget->setEnabled(false);
|
ui->backend_widget->setEnabled(UISettings::values.has_broken_vulkan.GetValue());
|
||||||
} else {
|
} else {
|
||||||
vulkan_device = Settings::values.vulkan_device.GetValue();
|
vulkan_device = Settings::values.vulkan_device.GetValue();
|
||||||
shader_backend = Settings::values.shader_backend.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;
|
using namespace Vulkan;
|
||||||
|
|
||||||
vk::InstanceDispatch dld;
|
vk::InstanceDispatch dld;
|
||||||
|
@ -333,8 +356,10 @@ void ConfigureGraphics::RetrieveVulkanDevices() try {
|
||||||
vulkan_devices.push_back(QString::fromStdString(name));
|
vulkan_devices.push_back(QString::fromStdString(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
} catch (const Vulkan::vk::Exception& exception) {
|
} catch (const Vulkan::vk::Exception& exception) {
|
||||||
LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what());
|
LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const {
|
||||||
|
@ -415,4 +440,11 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||||
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
|
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
|
||||||
ConfigurationShared::InsertGlobalItem(
|
ConfigurationShared::InsertGlobalItem(
|
||||||
ui->nvdec_emulation, static_cast<int>(Settings::values.nvdec_emulation.GetValue(true)));
|
ui->nvdec_emulation, static_cast<int>(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<int>(Settings::values.shader_backend.GetValue(true)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ private:
|
||||||
void UpdateDeviceSelection(int device);
|
void UpdateDeviceSelection(int device);
|
||||||
void UpdateShaderBackendSelection(int backend);
|
void UpdateShaderBackendSelection(int backend);
|
||||||
|
|
||||||
void RetrieveVulkanDevices();
|
bool RetrieveVulkanDevices();
|
||||||
|
|
||||||
void SetupPerGameUI();
|
void SetupPerGameUI();
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>437</width>
|
<width>471</width>
|
||||||
<height>482</height>
|
<height>759</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -574,6 +574,13 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="button_check_vulkan">
|
||||||
|
<property name="text">
|
||||||
|
<string>Check for Working Vulkan</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
|
@ -115,6 +115,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
||||||
#include "video_core/shader_notify.h"
|
#include "video_core/shader_notify.h"
|
||||||
#include "yuzu/about_dialog.h"
|
#include "yuzu/about_dialog.h"
|
||||||
#include "yuzu/bootmanager.h"
|
#include "yuzu/bootmanager.h"
|
||||||
|
#include "yuzu/check_vulkan.h"
|
||||||
#include "yuzu/compatdb.h"
|
#include "yuzu/compatdb.h"
|
||||||
#include "yuzu/compatibility_list.h"
|
#include "yuzu/compatibility_list.h"
|
||||||
#include "yuzu/configuration/config.h"
|
#include "yuzu/configuration/config.h"
|
||||||
|
@ -322,6 +323,23 @@ GMainWindow::GMainWindow()
|
||||||
|
|
||||||
MigrateConfigFiles();
|
MigrateConfigFiles();
|
||||||
|
|
||||||
|
if (!CheckVulkan()) {
|
||||||
|
config->Save();
|
||||||
|
|
||||||
|
QMessageBox::warning(
|
||||||
|
this, tr("Broken Vulkan Installation Detected"),
|
||||||
|
tr("Vulkan initialization failed on the previous boot.<br><br>Click <a "
|
||||||
|
"href='https://yuzu-emu.org/wiki/faq/"
|
||||||
|
"#yuzu-starts-with-the-error-broken-vulkan-installation-detected'>here for "
|
||||||
|
"instructions to fix the issue</a>."));
|
||||||
|
}
|
||||||
|
if (UISettings::values.has_broken_vulkan) {
|
||||||
|
Settings::values.renderer_backend = Settings::RendererBackend::OpenGL;
|
||||||
|
|
||||||
|
renderer_status_button->setDisabled(true);
|
||||||
|
renderer_status_button->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SDL2) && !defined(_WIN32)
|
#if defined(HAVE_SDL2) && !defined(_WIN32)
|
||||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||||
// SDL disables the screen saver by default, and setting the hint
|
// SDL disables the screen saver by default, and setting the hint
|
||||||
|
@ -1591,7 +1609,7 @@ void GMainWindow::ShutdownGame() {
|
||||||
emu_speed_label->setVisible(false);
|
emu_speed_label->setVisible(false);
|
||||||
game_fps_label->setVisible(false);
|
game_fps_label->setVisible(false);
|
||||||
emu_frametime_label->setVisible(false);
|
emu_frametime_label->setVisible(false);
|
||||||
renderer_status_button->setEnabled(true);
|
renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan);
|
||||||
|
|
||||||
game_path.clear();
|
game_path.clear();
|
||||||
|
|
||||||
|
@ -2801,6 +2819,10 @@ void GMainWindow::OnConfigure() {
|
||||||
mouse_hide_timer.start();
|
mouse_hide_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!UISettings::values.has_broken_vulkan) {
|
||||||
|
renderer_status_button->setEnabled(!emulation_running);
|
||||||
|
}
|
||||||
|
|
||||||
UpdateStatusButtons();
|
UpdateStatusButtons();
|
||||||
controller_dialog->refreshConfiguration();
|
controller_dialog->refreshConfiguration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ struct Values {
|
||||||
Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
||||||
Settings::BasicSetting<bool> mute_when_in_background{false, "muteWhenInBackground"};
|
Settings::BasicSetting<bool> mute_when_in_background{false, "muteWhenInBackground"};
|
||||||
Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"};
|
Settings::BasicSetting<bool> hide_mouse{true, "hideInactiveMouse"};
|
||||||
|
// Set when Vulkan is known to crash the application
|
||||||
|
Settings::BasicSetting<bool> has_broken_vulkan{false, "has_broken_vulkan"};
|
||||||
|
|
||||||
Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
|
Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ cpuopt_unsafe_ignore_global_monitor =
|
||||||
|
|
||||||
[Renderer]
|
[Renderer]
|
||||||
# Which backend API to use.
|
# Which backend API to use.
|
||||||
# 0 (default): OpenGL, 1: Vulkan
|
# 0: OpenGL, 1 (default): Vulkan
|
||||||
backend =
|
backend =
|
||||||
|
|
||||||
# Enable graphics API debugging mode.
|
# Enable graphics API debugging mode.
|
||||||
|
|
Loading…
Reference in a new issue