From 49adcd7b819ff269f7fb84e46ca5581cc5563242 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Wed, 16 Aug 2023 18:12:26 +0200 Subject: [PATCH] VulkanRenderer/Loader: Try to load other vulkan libs --- src/Nazara/VulkanRenderer/Wrapper/Loader.cpp | 95 ++++++++++++-------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/src/Nazara/VulkanRenderer/Wrapper/Loader.cpp b/src/Nazara/VulkanRenderer/Wrapper/Loader.cpp index 6989e9cf6..400138d2b 100644 --- a/src/Nazara/VulkanRenderer/Wrapper/Loader.cpp +++ b/src/Nazara/VulkanRenderer/Wrapper/Loader.cpp @@ -64,54 +64,73 @@ namespace Nz bool Loader::Initialize() { - #ifdef NAZARA_PLATFORM_WINDOWS - s_vulkanLib.Load("vulkan-1.dll"); - #elif defined(NAZARA_PLATFORM_LINUX) - s_vulkanLib.Load("libvulkan.so"); - #elif defined(NAZARA_PLATFORM_MACOS) - s_vulkanLib.Load("libMoltenVK.dylib"); - #else - #error Unhandled platform - #endif - - if (!s_vulkanLib.IsLoaded()) - { - NazaraError("failed to open vulkan library: {0}", s_vulkanLib.GetLastError()); - return false; - } - - // vkGetInstanceProcAddr is the only function that's guarantee to be exported - vkGetInstanceProcAddr = reinterpret_cast(s_vulkanLib.GetSymbol("vkGetInstanceProcAddr")); - if (!vkGetInstanceProcAddr) - { - NazaraError("Failed to get symbol \"vkGetInstanceProcAddr\": {0}", s_vulkanLib.GetLastError()); - return false; - } - - auto GetProcAddr = [&](const char* name, bool opt) - { - PFN_vkVoidFunction func = vkGetInstanceProcAddr(nullptr, name); - if (!func && !opt) - NazaraError("Failed to get {0} address", name); - - return func; +#if defined(NAZARA_PLATFORM_WINDOWS) + std::array libs{ + "vulkan-1.dll" }; +#elif defined(NAZARA_PLATFORM_LINUX) || defined(NAZARA_PLATFORM_ANDROID) + std::array libs{ + "libvulkan.so.1", + "libvulkan.so" + }; +#elif defined(NAZARA_PLATFORM_MACOS) || defined(NAZARA_PLATFORM_IOS) + std::array libs{ + "libvulkan.dylib", + "libvulkan.1.dylib", + "libMoltenVK.dylib", + }; +#else + NazaraError("unhandled OS"); + return false; +#endif - // all other functions should be loaded using vkGetInstanceProcAddr - #define NAZARA_VULKANRENDERER_LOAD_GLOBAL(func) func = reinterpret_cast(GetProcAddr(#func)) - try + for (const char* libname : libs) { - ErrorFlags flags(ErrorMode::ThrowException); + ErrorFlags errorFlags(ErrorMode::Silent, ~ErrorMode::ThrowException); + + if (!s_vulkanLib.Load(libname)) + continue; + + Error::ApplyFlags({}, ~ErrorMode::Silent); + + // vkGetInstanceProcAddr is the only function that's guarantee to be exported + vkGetInstanceProcAddr = reinterpret_cast(s_vulkanLib.GetSymbol("vkGetInstanceProcAddr")); + if (!vkGetInstanceProcAddr) + { + NazaraError("Failed to get symbol \"vkGetInstanceProcAddr\": {0}", s_vulkanLib.GetLastError()); + continue; + } + + auto GetProcAddr = [&](const char* name, bool opt) + { + PFN_vkVoidFunction func = vkGetInstanceProcAddr(nullptr, name); + if (!func && !opt) + NazaraError("Failed to get {0} address", name); + + return func; + }; + + // all other functions should be loaded using vkGetInstanceProcAddr +#define NAZARA_VULKANRENDERER_LOAD_GLOBAL(func) func = reinterpret_cast(GetProcAddr(#func)) + try + { + ErrorFlags flags(ErrorMode::ThrowException); #define NAZARA_VULKANRENDERER_GLOBAL_FUNCTION(func) func = reinterpret_cast(GetProcAddr(#func, false)); #define NAZARA_VULKANRENDERER_GLOBAL_FUNCTION_OPT(func) func = reinterpret_cast(GetProcAddr(#func, true)); #include - + } + catch (const std::exception& e) + { + NazaraError("Failed to query device function: {0}", e.what()); + return false; + } } - catch (const std::exception& e) + + if (!s_vulkanLib.IsLoaded()) { - NazaraError("Failed to query device function: {0}", e.what()); + NazaraError("failed to open vulkan library"); return false; }