mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-22 23:24:34 +00:00
Cleanup internal class VulkanFunctions
Removes the subclassing of VulkanLibrary, bringing its logic into the VulkanFunctions class. This resolves a weird linking issue which was causing hot-reloading of shared libraries that statically linked vk-bootstrap to fail to unload correctly, preventing reloading. The commit also consolidates the logic in load_vulkan_funcs() into a single function rather than having it be split in three, which only made the code harder to reason about. Also made vk-bootstrap look for `libMoltenVK.dylib` on apple platforms, in case the application only has the MoltenVK shared library but not the loader (and the user didn't manually load GetInstanceProcAddr from MoltenVK then give it to vk-bootstrap).
This commit is contained in:
parent
49491c28c7
commit
9864d2b838
@ -50,28 +50,33 @@ bool GenericFeaturesPNextNode::match(GenericFeaturesPNextNode const& requested,
|
|||||||
class VulkanFunctions {
|
class VulkanFunctions {
|
||||||
private:
|
private:
|
||||||
std::mutex init_mutex;
|
std::mutex init_mutex;
|
||||||
struct VulkanLibrary {
|
|
||||||
#if defined(__linux__) || defined(__APPLE__)
|
|
||||||
void* library;
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
HMODULE library;
|
|
||||||
#endif
|
|
||||||
PFN_vkGetInstanceProcAddr ptr_vkGetInstanceProcAddr = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
VulkanLibrary() {
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
void* library = nullptr;
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
HMODULE library = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool load_vulkan_library() {
|
||||||
|
// Can immediately return if it has already been loaded
|
||||||
|
if (library) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
library = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
|
library = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
|
||||||
if (!library) library = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
|
if (!library) library = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
library = dlopen("libvulkan.dylib", RTLD_NOW | RTLD_LOCAL);
|
library = dlopen("libvulkan.dylib", RTLD_NOW | RTLD_LOCAL);
|
||||||
if (!library) library = dlopen("libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL);
|
if (!library) library = dlopen("libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL);
|
||||||
|
if (!library) library = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL);
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
library = LoadLibrary(TEXT("vulkan-1.dll"));
|
library = LoadLibrary(TEXT("vulkan-1.dll"));
|
||||||
#else
|
#else
|
||||||
assert(false && "Unsupported platform");
|
assert(false && "Unsupported platform");
|
||||||
#endif
|
#endif
|
||||||
if (!library) return;
|
if (!library) return false;
|
||||||
load_func(ptr_vkGetInstanceProcAddr, "vkGetInstanceProcAddr");
|
load_func(ptr_vkGetInstanceProcAddr, "vkGetInstanceProcAddr");
|
||||||
|
return ptr_vkGetInstanceProcAddr != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void load_func(T& func_dest, const char* func_name) {
|
template <typename T> void load_func(T& func_dest, const char* func_name) {
|
||||||
@ -89,24 +94,17 @@ class VulkanFunctions {
|
|||||||
#endif
|
#endif
|
||||||
library = 0;
|
library = 0;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
VulkanLibrary& get_vulkan_library() {
|
|
||||||
static VulkanLibrary lib;
|
|
||||||
return lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool load_vulkan(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr = nullptr) {
|
public:
|
||||||
|
bool init_vulkan_funcs(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr = nullptr) {
|
||||||
|
std::lock_guard<std::mutex> lg(init_mutex);
|
||||||
if (fp_vkGetInstanceProcAddr != nullptr) {
|
if (fp_vkGetInstanceProcAddr != nullptr) {
|
||||||
ptr_vkGetInstanceProcAddr = fp_vkGetInstanceProcAddr;
|
ptr_vkGetInstanceProcAddr = fp_vkGetInstanceProcAddr;
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
auto& lib = get_vulkan_library();
|
bool ret = load_vulkan_library();
|
||||||
ptr_vkGetInstanceProcAddr = lib.ptr_vkGetInstanceProcAddr;
|
if (!ret) return false;
|
||||||
return lib.library != nullptr && lib.ptr_vkGetInstanceProcAddr != VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_pre_instance_funcs() {
|
|
||||||
fp_vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
|
fp_vkEnumerateInstanceExtensionProperties = reinterpret_cast<PFN_vkEnumerateInstanceExtensionProperties>(
|
||||||
ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"));
|
ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"));
|
||||||
fp_vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
|
fp_vkEnumerateInstanceLayerProperties = reinterpret_cast<PFN_vkEnumerateInstanceLayerProperties>(
|
||||||
@ -115,6 +113,7 @@ class VulkanFunctions {
|
|||||||
ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion"));
|
ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion"));
|
||||||
fp_vkCreateInstance =
|
fp_vkCreateInstance =
|
||||||
reinterpret_cast<PFN_vkCreateInstance>(ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance"));
|
reinterpret_cast<PFN_vkCreateInstance>(ptr_vkGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance"));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -155,13 +154,6 @@ class VulkanFunctions {
|
|||||||
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fp_vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fp_vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
|
||||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fp_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
|
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fp_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = nullptr;
|
||||||
|
|
||||||
bool init_vulkan_funcs(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) {
|
|
||||||
std::lock_guard<std::mutex> lg(init_mutex);
|
|
||||||
if (!load_vulkan(fp_vkGetInstanceProcAddr)) return false;
|
|
||||||
init_pre_instance_funcs();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_instance_funcs(VkInstance inst) {
|
void init_instance_funcs(VkInstance inst) {
|
||||||
instance = inst;
|
instance = inst;
|
||||||
get_inst_proc_addr(fp_vkDestroyInstance, "vkDestroyInstance");
|
get_inst_proc_addr(fp_vkDestroyInstance, "vkDestroyInstance");
|
||||||
@ -188,7 +180,7 @@ class VulkanFunctions {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
VulkanFunctions& vulkan_functions() {
|
static VulkanFunctions& vulkan_functions() {
|
||||||
static VulkanFunctions v;
|
static VulkanFunctions v;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user