[PATCH vkd3d 7/8] libs/vkd3d: Load libvulkan dynamically.

Józef Kucia joseph.kucia at gmail.com
Wed Jan 17 05:48:14 CST 2018


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at 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 */
-- 
2.13.6




More information about the wine-devel mailing list