summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
diff options
context:
space:
mode:
authorConnor McLaughlin <stenzek@gmail.com>2019-03-29 20:40:06 +1000
committerGitHub <noreply@github.com>2019-03-29 20:40:06 +1000
commitf3fadd730218429a5f6472283d16d30d7e276f8d (patch)
treed1d6577cd52b2d3b3d7872aef4fac80dbd0ce563 /Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
parentfbe57e8dbef17e583f0ba0208af7bf414a3716bf (diff)
parentd0d010f8549cc902829f567b3b5127d9a0556ca5 (diff)
Merge pull request #7869 from stenzek/d3dcommon
D3D: Move sharable D3D11/D3D12 code to common library
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp150
1 files 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 <cstdlib>
#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 <Windows.h>
-#else
-#include <dlfcn.h>
-#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 HMODULE 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;
- }
-
- 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<FARPROC*>(&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};
+static Common::DynamicLibrary s_vulkan_module;
-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;
- }
-
-#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<void**>(&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;