From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
It doesn't make much sense to link directly to libvulkan after the previous patch.
--- Makefile.am | 2 +- configure.ac | 5 +++++ libs/vkd3d/device.c | 34 ++++++++++++++++++++++++++++++---- libs/vkd3d/vkd3d_private.h | 10 +--------- 4 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/Makefile.am b/Makefile.am index f796befb3672..d8212b7ca80d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -89,7 +89,7 @@ libvkd3d_la_SOURCES = \ libs/vkd3d/vkd3d_main.c \ libs/vkd3d/vkd3d_private.h \ libs/vkd3d/vulkan_procs.h -libvkd3d_la_LIBADD = libvkd3d-common.la libvkd3d-shader.la @PTHREAD_LIBS@ @VULKAN_LIBS@ +libvkd3d_la_LIBADD = libvkd3d-common.la libvkd3d-shader.la @DL_LIBS@ @PTHREAD_LIBS@ if HAVE_LD_VERSION_SCRIPT libvkd3d_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libs/vkd3d/vkd3d.map endif diff --git a/configure.ac b/configure.ac index b886058fef51..8a39fef7d2b9 100644 --- a/configure.ac +++ b/configure.ac @@ -62,6 +62,11 @@ m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG], [m4_fatal([pkg-config aut
AC_CHECK_LIB([m], [ceilf])
+AC_ARG_VAR([DL_LIBS], [linker flags for dl]) +AC_CHECK_LIB([dl], [dlopen], + [AC_SUBST([DL_LIBS], ["-ldl"])], + [AC_MSG_ERROR([libdl not found.])]) + AC_ARG_VAR([PTHREAD_LIBS], [linker flags for pthreads]) AC_CHECK_LIB([pthread], [pthread_create], [AC_SUBST([PTHREAD_LIBS], ["-lpthread"])], diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 62271dbb11a9..72253207cfd7 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -18,6 +18,8 @@
#include "vkd3d_private.h"
+#include <dlfcn.h> + struct vkd3d_optional_extension_info { const char *extension_name; @@ -176,16 +178,34 @@ static bool vkd3d_init_vk_global_procs(struct vkd3d_instance *instance, { struct vkd3d_vulkan_procs_info *procs = &instance->vk_global_procs;
+ instance->libvulkan = NULL; + if (vulkan_procs_info) { *procs = *vulkan_procs_info; return true; }
- procs->vkCreateInstance = vkCreateInstance; - procs->vkDestroyInstance = vkDestroyInstance; - procs->vkGetInstanceProcAddr = vkGetInstanceProcAddr; - procs->vkEnumerateInstanceExtensionProperties = vkEnumerateInstanceExtensionProperties; + if (!(instance->libvulkan = dlopen("libvulkan.so.1", RTLD_NOW))) + { + ERR("Failed to load libvulkan.\n"); + return false; + } + +#define LOAD_PROC(name) \ + if (!(procs->name = dlsym(instance->libvulkan, #name))) \ + { \ + ERR("Could not get proc addr for '" #name "'.\n"); \ + dlclose(instance->libvulkan); \ + instance->libvulkan = NULL; \ + return false; \ + } + LOAD_PROC(vkCreateInstance) + LOAD_PROC(vkDestroyInstance) + LOAD_PROC(vkGetInstanceProcAddr) + LOAD_PROC(vkEnumerateInstanceExtensionProperties) +#undef LOAD_PROC + return true; }
@@ -248,6 +268,8 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, if ((vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance))) { ERR("Failed to create Vulkan instance, vr %d.\n", vr); + if (instance->libvulkan) + dlclose(instance->libvulkan); return hresult_from_vk_result(vr); }
@@ -255,6 +277,8 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, { ERR("Failed to load instance procs, hr %#x.\n", hr); vk_global_procs->vkDestroyInstance(vk_instance, NULL); + if (instance->libvulkan) + dlclose(instance->libvulkan); return hr; }
@@ -310,6 +334,8 @@ ULONG vkd3d_instance_decref(struct vkd3d_instance *instance) { const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs; VK_CALL(vkDestroyInstance(instance->vk_instance, NULL)); + if (instance->libvulkan) + dlclose(instance->libvulkan); vkd3d_free(instance); }
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index f32b64a58cef..44d90b9c907b 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -88,6 +88,7 @@ struct vkd3d_instance
struct vkd3d_vulkan_info vk_info; struct vkd3d_vulkan_procs_info vk_global_procs; + void *libvulkan;
LONG refcount; }; @@ -752,13 +753,4 @@ HRESULT vkd3d_load_vk_instance_procs(struct vkd3d_vk_instance_procs *procs, HRESULT vkd3d_load_vk_device_procs(struct vkd3d_vk_device_procs *procs, const struct vkd3d_vk_instance_procs *parent_procs, VkDevice device) DECLSPEC_HIDDEN;
-/* We link directly to the loader library and use the following exported functions. */ -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, - const char *name); -VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *create_info, - const VkAllocationCallbacks *allocator, VkInstance *instance); -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *layer_name, - uint32_t *property_count, VkExtensionProperties *properties); -VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *allocator); - #endif /* __VKD3D_PRIVATE_H */