aboutsummaryrefslogtreecommitdiff
path: root/src/yuzu/check_vulkan.cpp
diff options
context:
space:
mode:
authorlat9nq <lat9nq@gmail.com>2022-05-28 02:33:23 -0400
committerlat9nq <lat9nq@gmail.com>2022-05-30 10:57:59 -0400
commitf22867efc5fc3b970a706f7997b997048c969a89 (patch)
tree942633953e2c3d2c379d388e9b1c05b446f0027d /src/yuzu/check_vulkan.cpp
parent67fa7434147618c060b7186a272e8c3e0ab0c560 (diff)
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.
Diffstat (limited to 'src/yuzu/check_vulkan.cpp')
-rw-r--r--src/yuzu/check_vulkan.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/yuzu/check_vulkan.cpp b/src/yuzu/check_vulkan.cpp
new file mode 100644
index 0000000000..1b21efe696
--- /dev/null
+++ b/src/yuzu/check_vulkan.cpp
@@ -0,0 +1,51 @@
+#include "video_core/vulkan_common/vulkan_wrapper.h"
+
+#include <exception>
+#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());
+ UISettings::values.has_broken_vulkan = true;
+ return false;
+ }
+
+ std::filesystem::remove(temp_file_loc);
+ return true;
+}