early-access version 2746

This commit is contained in:
pineappleEA 2022-05-30 20:36:13 +02:00
parent f7ed0b4f77
commit 7efffeb933
13 changed files with 186 additions and 49 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 2745. This is the source code for early-access 2746.
## Legal Notice ## Legal Notice

View file

@ -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"};

View file

@ -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

View file

@ -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 Executable file
View 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 Executable file
View file

@ -0,0 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
bool CheckVulkan();

View file

@ -679,6 +679,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);
@ -798,6 +804,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();
@ -1343,6 +1350,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();

View file

@ -5,6 +5,7 @@
// Include this early to include Vulkan headers how we want to // Include this early to include Vulkan headers how we want to
#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_wrapper.h"
#include <exception>
#include <QColorDialog> #include <QColorDialog>
#include <QVulkanInstance> #include <QVulkanInstance>
@ -17,6 +18,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 +59,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 +316,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 +338,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 +357,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 +441,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)));
}
} }

View file

@ -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();

View file

@ -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/>

View file

@ -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"
@ -297,6 +298,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
@ -1563,7 +1581,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();
@ -2773,6 +2791,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();
} }

View file

@ -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"};

View file

@ -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.