From f6641b7e4fd666a620843f1a3b5d5117a1397f9c Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 9 Mar 2019 23:31:34 +1000 Subject: [PATCH] Vulkan: Use Common::DynamicLibrary --- .../VideoBackends/Vulkan/VulkanLoader.cpp | 150 ++++-------------- 1 file changed, 28 insertions(+), 122 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp index d8d1e99d0c..bfc8b5673e 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp @@ -7,18 +7,13 @@ #include #include "Common/CommonFuncs.h" +#include "Common/DynamicLibrary.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "VideoBackends/Vulkan/VulkanLoader.h" -#if defined(_WIN32) -#include -#else -#include -#endif - #define VULKAN_MODULE_ENTRY_POINT(name, required) PFN_##name name; #define VULKAN_INSTANCE_ENTRY_POINT(name, required) PFN_##name name; #define VULKAN_DEVICE_ENTRY_POINT(name, required) PFN_##name name; @@ -40,145 +35,56 @@ static void ResetVulkanLibraryFunctionPointers() #undef VULKAN_MODULE_ENTRY_POINT } -#if defined(_WIN32) +static Common::DynamicLibrary s_vulkan_module; -static HMODULE vulkan_module; -static std::atomic_int vulkan_module_ref_count = {0}; - -bool LoadVulkanLibrary() +static std::string GetVulkanLibraryFilename() { - // Not thread safe if a second thread calls the loader whilst the first is still in-progress. - if (vulkan_module) - { - vulkan_module_ref_count++; - return true; - } - - vulkan_module = LoadLibraryA("vulkan-1.dll"); - if (!vulkan_module) - { - ERROR_LOG(VIDEO, "Failed to load vulkan-1.dll"); - return false; - } - - bool required_functions_missing = false; - auto LoadFunction = [&](FARPROC* func_ptr, const char* name, bool is_required) { - *func_ptr = GetProcAddress(vulkan_module, name); - if (!(*func_ptr) && is_required) - { - ERROR_LOG(VIDEO, "Vulkan: Failed to load required module function %s", name); - required_functions_missing = true; - } - }; - -#define VULKAN_MODULE_ENTRY_POINT(name, required) \ - LoadFunction(reinterpret_cast(&name), #name, required); -#include "VideoBackends/Vulkan/VulkanEntryPoints.inl" -#undef VULKAN_MODULE_ENTRY_POINT - - if (required_functions_missing) - { - ResetVulkanLibraryFunctionPointers(); - FreeLibrary(vulkan_module); - vulkan_module = nullptr; - return false; - } - - vulkan_module_ref_count++; - return true; -} - -void UnloadVulkanLibrary() -{ - if ((--vulkan_module_ref_count) > 0) - return; - - ResetVulkanLibraryFunctionPointers(); - FreeLibrary(vulkan_module); - vulkan_module = nullptr; -} - -#else - -static void* vulkan_module; -static std::atomic_int vulkan_module_ref_count = {0}; - -bool LoadVulkanLibrary() -{ - // Not thread safe if a second thread calls the loader whilst the first is still in-progress. - if (vulkan_module) - { - vulkan_module_ref_count++; - return true; - } - -#if defined(__APPLE__) +#ifdef __APPLE__ // Check if a path to a specific Vulkan library has been specified. char* libvulkan_env = getenv("LIBVULKAN_PATH"); if (libvulkan_env) - vulkan_module = dlopen(libvulkan_env, RTLD_NOW); - if (!vulkan_module) - { - // Use the libvulkan.dylib from the application bundle. - std::string path = File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib"; - vulkan_module = dlopen(path.c_str(), RTLD_NOW); - } + return std::string(libvulkan_env); + + // Use the libvulkan.dylib from the application bundle. + return File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib"; #else - // Names of libraries to search. Desktop should use libvulkan.so.1 or libvulkan.so. - static const char* search_lib_names[] = {"libvulkan.so.1", "libvulkan.so"}; - for (size_t i = 0; i < ArraySize(search_lib_names); i++) - { - vulkan_module = dlopen(search_lib_names[i], RTLD_NOW); - if (vulkan_module) - break; - } + return Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); #endif +} - if (!vulkan_module) +bool LoadVulkanLibrary() +{ + if (!s_vulkan_module.IsOpen()) { - ERROR_LOG(VIDEO, "Failed to load or locate libvulkan.so"); - return false; - } - - bool required_functions_missing = false; - auto LoadFunction = [&](void** func_ptr, const char* name, bool is_required) { - *func_ptr = dlsym(vulkan_module, name); - if (!(*func_ptr) && is_required) + const std::string filename = GetVulkanLibraryFilename(); + if (!s_vulkan_module.Open(filename.c_str())) { - ERROR_LOG(VIDEO, "Vulkan: Failed to load required module function %s", name); - required_functions_missing = true; + ERROR_LOG(VIDEO, "Failed to load %s", filename.c_str()); + return false; } - }; + } #define VULKAN_MODULE_ENTRY_POINT(name, required) \ - LoadFunction(reinterpret_cast(&name), #name, required); + if (!s_vulkan_module.GetSymbol(#name, &name) && required) \ + { \ + ERROR_LOG(VIDEO, "Vulkan: Failed to load required module function %s", #name); \ + ResetVulkanLibraryFunctionPointers(); \ + s_vulkan_module.Close(); \ + return false; \ + } #include "VideoBackends/Vulkan/VulkanEntryPoints.inl" #undef VULKAN_MODULE_ENTRY_POINT - if (required_functions_missing) - { - ResetVulkanLibraryFunctionPointers(); - dlclose(vulkan_module); - vulkan_module = nullptr; - return false; - } - - vulkan_module_ref_count++; return true; } void UnloadVulkanLibrary() { - if ((--vulkan_module_ref_count) > 0) - return; - - ResetVulkanLibraryFunctionPointers(); - dlclose(vulkan_module); - vulkan_module = nullptr; + s_vulkan_module.Close(); + if (!s_vulkan_module.IsOpen()) + ResetVulkanLibraryFunctionPointers(); } -#endif - bool LoadVulkanInstanceFunctions(VkInstance instance) { bool required_functions_missing = false;