diff --git a/core/cc/armlinux/get_vulkan_proc_address.cpp b/core/cc/armlinux/get_vulkan_proc_address.cpp index 14eec9f04a..7399c71ecc 100644 --- a/core/cc/armlinux/get_vulkan_proc_address.cpp +++ b/core/cc/armlinux/get_vulkan_proc_address.cpp @@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress; GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress; bool HasVulkanLoader() { - return DlLoader::can_load("libvulkan.so"); + return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1"); } } // namespace core diff --git a/core/cc/dl_loader.cpp b/core/cc/dl_loader.cpp index da0321048b..101168af78 100644 --- a/core/cc/dl_loader.cpp +++ b/core/cc/dl_loader.cpp @@ -30,9 +30,15 @@ namespace { // load defs -void* load(const char* name) { +void* load() { + return nullptr; +} + +template +void* load(const char* name, ConstCharPtrs... fallback_names) { + void* ret = nullptr; #if TARGET_OS == GAPID_OS_WINDOWS - return reinterpret_cast(LoadLibraryExA(name, NULL, 0)); + ret = reinterpret_cast(LoadLibraryExA(name, NULL, 0)); #elif TARGET_OS == GAPID_OS_OSX if (name == nullptr) { return nullptr; @@ -50,14 +56,19 @@ void* load(const char* name) { remove(tmp); } } - return res; + ret = res; #else - return dlopen(name, RTLD_NOW | RTLD_LOCAL); + ret = dlopen(name, RTLD_NOW | RTLD_LOCAL); #endif // TARGET_OS + if (ret == nullptr) { + return load(fallback_names...); + } + return ret; } -void* must_load(const char* name) { - void* res = load(name); +template +void* must_load(const char* name, ConstCharPtrs... fallback_names) { + void* res = load(name, fallback_names...); if (res == nullptr) { #if TARGET_OS == GAPID_OS_WINDOWS GAPID_FATAL("Can't load library %s: %d", name, GetLastError()); @@ -100,8 +111,8 @@ void close(void* lib) { } // anonymous namespace namespace core { - -DlLoader::DlLoader(const char* name) : mLibrary(must_load(name)) {} +template +DlLoader::DlLoader(const char* name, ConstCharPtrs... fallback_names) : mLibrary(must_load(name, fallback_names...)) {} DlLoader::~DlLoader() { close(mLibrary); @@ -125,4 +136,15 @@ bool DlLoader::can_load(const char* lib_name) { return false; } +#define CC const char* +#define DL(...) \ + template DlLoader::DlLoader(__VA_ARGS__) +DL(CC _1); +DL(CC _1, CC _2); +DL(CC _1, CC _2, CC _3); +DL(CC _1, CC _2, CC _3, CC _4); +DL(CC _1, CC _2, CC _3, CC _4, CC _5); +#undef DL +#undef CC + } // namespace core diff --git a/core/cc/dl_loader.h b/core/cc/dl_loader.h index a62e2a09cb..e0997ba8ee 100644 --- a/core/cc/dl_loader.h +++ b/core/cc/dl_loader.h @@ -22,10 +22,12 @@ namespace core { // Utility class for retrieving function pointers from dynamic libraries. class DlLoader { public: - // Loads the specified dynamic library. - // If the library cannot be loaded then this is a fatal error. - // For *nix systems, a nullptr can be used to search the application's functions. - DlLoader(const char* name); + // Loads the dynamic library specified by the given name and fallback names + // (if any). Names will be used to try to find the library in order. If the + // library cannot be loaded then this is a fatal error. For *nix systems, + // a nullptr can be used to search the application's functions. + template + DlLoader(const char* name, ConstCharPtrs... fallback_names); // Unloads the library loaded in the constructor. ~DlLoader(); diff --git a/core/cc/linux/get_vulkan_proc_address.cpp b/core/cc/linux/get_vulkan_proc_address.cpp index 14eec9f04a..02ea1eda86 100644 --- a/core/cc/linux/get_vulkan_proc_address.cpp +++ b/core/cc/linux/get_vulkan_proc_address.cpp @@ -30,7 +30,7 @@ typedef size_t VkInstance; void* getVulkanInstanceProcAddress(size_t instance, const char *name, bool bypassLocal) { typedef PFN_vkVoidFunction (*VPAPROC)(VkInstance instance, const char *name); - static DlLoader dylib("libvulkan.so"); + static DlLoader dylib("libvulkan.so", "libvulkan.so.1"); if (VPAPROC vpa = reinterpret_cast(dylib.lookup("vkGetInstanceProcAddr"))) { if (void* proc = vpa(instance, name)) { @@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress; GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress; bool HasVulkanLoader() { - return DlLoader::can_load("libvulkan.so"); + return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1"); } } // namespace core