[PATCH v5 4/5] vkd3d: Load Vulkan dynamically in d3d12 test app.

Hans-Kristian Arntzen post at arntzen-software.no
Mon Nov 18 08:38:01 CST 2019


On Windows, it is not ideal to rely on Vulkan being available as a
linkable library as a full install of the Vulkan SDK must be present and
set up, be friendly and load Vulkan dynamically instead.

Signed-off-by: Hans-Kristian Arntzen <post at arntzen-software.no>
---
 libs/vkd3d/device.c     | 22 +++++++++++++
 tests/d3d12_crosstest.h | 70 +++++++++++++++++++++++++++++++++++------
 2 files changed, 83 insertions(+), 9 deletions(-)

diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index cc8e282..f2f1aca 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -40,6 +40,28 @@ static const char *vkd3d_dlerror(void)
 {
     return dlerror();
 }
+#elif defined(_WIN32)
+#include <windows.h>
+static void *vkd3d_dlopen(const char *name)
+{
+    return LoadLibraryA(name);
+}
+
+static void *vkd3d_dlsym(void *handle, const char *symbol)
+{
+    return GetProcAddress(handle, symbol);
+}
+
+static int vkd3d_dlclose(void *handle)
+{
+    FreeLibrary(handle);
+    return 0;
+}
+
+static const char *vkd3d_dlerror(void)
+{
+    return "Not implemented for this platform.\n";
+}
 #else
 static void *vkd3d_dlopen(const char *name)
 {
diff --git a/tests/d3d12_crosstest.h b/tests/d3d12_crosstest.h
index 7592000..1bf8976 100644
--- a/tests/d3d12_crosstest.h
+++ b/tests/d3d12_crosstest.h
@@ -60,6 +60,10 @@ typedef int HRESULT;
 # include "vkd3d_utils.h"
 #endif
 
+#if !defined(_WIN32)
+#include <dlfcn.h>
+#endif
+
 #include "d3d12_test_utils.h"
 
 #if defined(_WIN32) && !defined(VKD3D_FORCE_UTILS_WRAPPER)
@@ -401,7 +405,39 @@ static inline bool is_depth_clip_enable_supported(ID3D12Device *device)
 
 #else
 
-static bool check_device_extension(VkPhysicalDevice vk_physical_device, const char *name)
+static PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
+static bool init_vulkan_loader(void)
+{
+    if (pfn_vkGetInstanceProcAddr)
+        return true;
+
+#ifdef _WIN32
+    HMODULE mod = LoadLibrary(SONAME_LIBVULKAN);
+    if (!mod)
+        return false;
+
+    pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(mod, "vkGetInstanceProcAddr");
+#else
+    void *mod = dlopen(SONAME_LIBVULKAN, RTLD_LAZY);
+    if (!mod)
+        return false;
+
+    pfn_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(mod, "vkGetInstanceProcAddr");
+#endif
+
+    return pfn_vkGetInstanceProcAddr != NULL;
+}
+
+#define get_vk_instance_proc(instance, sym) (PFN_##sym)get_vk_instance_proc_(instance, #sym)
+static PFN_vkVoidFunction get_vk_instance_proc_(VkInstance instance, const char *sym)
+{
+    if (!init_vulkan_loader())
+        return NULL;
+
+    return pfn_vkGetInstanceProcAddr(instance, sym);
+}
+
+static bool check_device_extension(VkInstance instance, VkPhysicalDevice vk_physical_device, const char *name)
 {
     VkExtensionProperties *properties;
     bool ret = false;
@@ -409,7 +445,12 @@ static bool check_device_extension(VkPhysicalDevice vk_physical_device, const ch
     uint32_t count;
     VkResult vr;
 
-    vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, NULL);
+    PFN_vkEnumerateDeviceExtensionProperties pfn_vkEnumerateDeviceExtensionProperties;
+    pfn_vkEnumerateDeviceExtensionProperties = get_vk_instance_proc(instance, vkEnumerateDeviceExtensionProperties);
+    if (!pfn_vkEnumerateDeviceExtensionProperties)
+        return false;
+
+    vr = pfn_vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, NULL);
     ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
     if (!count)
         return false;
@@ -417,7 +458,7 @@ static bool check_device_extension(VkPhysicalDevice vk_physical_device, const ch
     properties = calloc(count, sizeof(*properties));
     ok(properties, "Failed to allocate memory.\n");
 
-    vr = vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, properties);
+    vr = pfn_vkEnumerateDeviceExtensionProperties(vk_physical_device, NULL, &count, properties);
     ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
     for (i = 0; i < count; ++i)
     {
@@ -463,10 +504,14 @@ static VkPhysicalDevice select_physical_device(struct vkd3d_instance *instance)
     VkInstance vk_instance;
     uint32_t count;
     VkResult vr;
-
+    PFN_vkEnumeratePhysicalDevices pfn_vkEnumeratePhysicalDevices;
     vk_instance = vkd3d_instance_get_vk_instance(instance);
 
-    vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
+    pfn_vkEnumeratePhysicalDevices = get_vk_instance_proc(vk_instance, vkEnumeratePhysicalDevices);
+    if (!pfn_vkEnumeratePhysicalDevices)
+        return VK_NULL_HANDLE;
+
+    vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
     ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
 
     if (use_adapter_idx >= count)
@@ -477,7 +522,7 @@ static VkPhysicalDevice select_physical_device(struct vkd3d_instance *instance)
 
     vk_physical_devices = calloc(count, sizeof(*vk_physical_devices));
     ok(vk_physical_devices, "Failed to allocate memory.\n");
-    vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
+    vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
     ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
 
     vk_physical_device = vk_physical_devices[use_adapter_idx];
@@ -537,19 +582,24 @@ static bool get_driver_properties(ID3D12Device *device, VkPhysicalDeviceDriverPr
     PFN_vkGetPhysicalDeviceProperties2KHR pfn_vkGetPhysicalDeviceProperties2KHR;
     VkPhysicalDeviceProperties2 device_properties2;
     VkPhysicalDevice vk_physical_device;
+    VkInstance vk_instance;
 
     memset(driver_properties, 0, sizeof(*driver_properties));
     driver_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
 
     vk_physical_device = vkd3d_get_vk_physical_device(device);
+    vk_instance = vkd3d_instance_get_vk_instance(vkd3d_instance_from_device(device));
+
+    if (!init_vulkan_loader())
+        return false;
 
-    if (check_device_extension(vk_physical_device, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
+    if (check_device_extension(vk_instance, vk_physical_device, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
     {
         struct vkd3d_instance *instance = vkd3d_instance_from_device(device);
         VkInstance vk_instance = vkd3d_instance_get_vk_instance(instance);
 
         pfn_vkGetPhysicalDeviceProperties2KHR
-                = (void *)vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
+                = (void *)pfn_vkGetInstanceProcAddr(vk_instance, "vkGetPhysicalDeviceProperties2KHR");
         ok(pfn_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR is NULL.\n");
 
         memset(&device_properties2, 0, sizeof(device_properties2));
@@ -628,8 +678,10 @@ static inline bool is_radv_device(ID3D12Device *device)
 
 static inline bool is_depth_clip_enable_supported(ID3D12Device *device)
 {
+    struct vkd3d_instance *instance = vkd3d_instance_from_device(device);
+    VkInstance vk_instance = vkd3d_instance_get_vk_instance(instance);
     VkPhysicalDevice vk_physical_device = vkd3d_get_vk_physical_device(device);
-    return check_device_extension(vk_physical_device, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
+    return check_device_extension(vk_instance, vk_physical_device, VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME);
 }
 #endif
 
-- 
2.24.0




More information about the wine-devel mailing list