[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