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/check_vulkan.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/yuzu/check_vulkan.cpp (limited to 'src/yuzu/check_vulkan.cpp') 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 @@ +#include "video_core/vulkan_common/vulkan_wrapper.h" + +#include +#include +#include +#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()); + UISettings::values.has_broken_vulkan = true; + return false; + } + + std::filesystem::remove(temp_file_loc); + return true; +} -- cgit v1.2.3