From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
In Wine, we want Wine Vulkan driver to load libvulkan for us, mainly so we can use VK_KHR_win32_surface.
VK_KHR_win32_surface has the following advantages: * child windows rendering has to be handled only in Wine Vulkan driver, * platform specific Vulkan WSI extensions are handled only in Wine Vulkan drivers.
--- include/vkd3d.h | 9 ++++++++ libs/vkd3d-utils/vkd3d_utils_main.c | 1 + libs/vkd3d/device.c | 46 +++++++++++++++++++++++++++++-------- libs/vkd3d/utils.c | 4 ++-- libs/vkd3d/vkd3d_private.h | 4 ++-- libs/vkd3d/vulkan_procs.h | 2 +- 6 files changed, 52 insertions(+), 14 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h index 6017e1accac6..5ae7603013e0 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -43,12 +43,21 @@ typedef bool (*vkd3d_join_thread_pfn)(void *thread);
struct vkd3d_instance;
+struct vkd3d_vulkan_procs_info +{ + PFN_vkCreateInstance vkCreateInstance; + PFN_vkDestroyInstance vkDestroyInstance; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; +}; + struct vkd3d_instance_create_info { vkd3d_signal_event_pfn signal_event_pfn; vkd3d_create_thread_pfn create_thread_pfn; vkd3d_join_thread_pfn join_thread_pfn; size_t wchar_size; + const struct vkd3d_vulkan_procs_info *vulkan_procs_info; };
struct vkd3d_device_create_info diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c index 9fe61a1bb4da..2ea0a16beefa 100644 --- a/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d-utils/vkd3d_utils_main.c @@ -41,6 +41,7 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, instance_create_info.create_thread_pfn = NULL; instance_create_info.join_thread_pfn = NULL; instance_create_info.wchar_size = sizeof(WCHAR); + instance_create_info.vulkan_procs_info = NULL;
device_create_info.minimum_feature_level = minimum_feature_level; device_create_info.instance = NULL; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 3255dd6ec09e..62271dbb11a9 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -136,13 +136,15 @@ static unsigned int vkd3d_enable_extensions(const char *extensions[], return i; }
-static void vkd3d_init_instance_caps(struct vkd3d_vulkan_info *vulkan_info) +static void vkd3d_init_instance_caps(struct vkd3d_instance *instance) { + const struct vkd3d_vulkan_procs_info *vk_procs = &instance->vk_global_procs; + struct vkd3d_vulkan_info *vulkan_info = &instance->vk_info; VkExtensionProperties *vk_extensions; uint32_t count; VkResult vr;
- if ((vr = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL)) < 0) + if ((vr = vk_procs->vkEnumerateInstanceExtensionProperties(NULL, &count, NULL)) < 0) { ERR("Failed to enumerate instance extensions, vr %d.\n", vr); return; @@ -154,7 +156,7 @@ static void vkd3d_init_instance_caps(struct vkd3d_vulkan_info *vulkan_info) return;
TRACE("Enumerating %u instance extensions.\n", count); - if ((vr = vkEnumerateInstanceExtensionProperties(NULL, &count, vk_extensions)) < 0) + if ((vr = vk_procs->vkEnumerateInstanceExtensionProperties(NULL, &count, vk_extensions)) < 0) { ERR("Failed to enumerate instance extensions, vr %d.\n", vr); vkd3d_free(vk_extensions); @@ -169,9 +171,28 @@ static void vkd3d_init_instance_caps(struct vkd3d_vulkan_info *vulkan_info) vkd3d_free(vk_extensions); }
+static bool vkd3d_init_vk_global_procs(struct vkd3d_instance *instance, + const struct vkd3d_vulkan_procs_info *vulkan_procs_info) +{ + struct vkd3d_vulkan_procs_info *procs = &instance->vk_global_procs; + + if (vulkan_procs_info) + { + *procs = *vulkan_procs_info; + return true; + } + + procs->vkCreateInstance = vkCreateInstance; + procs->vkDestroyInstance = vkDestroyInstance; + procs->vkGetInstanceProcAddr = vkGetInstanceProcAddr; + procs->vkEnumerateInstanceExtensionProperties = vkEnumerateInstanceExtensionProperties; + return true; +} + static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, const struct vkd3d_instance_create_info *create_info) { + const struct vkd3d_vulkan_procs_info *vk_global_procs = &instance->vk_global_procs; const char *extensions[MAX_INSTANCE_EXTENSION_COUNT]; VkApplicationInfo application_info; VkInstanceCreateInfo instance_info; @@ -195,8 +216,14 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, instance->join_thread = create_info->join_thread_pfn; instance->wchar_size = create_info->wchar_size;
+ if (!vkd3d_init_vk_global_procs(instance, create_info->vulkan_procs_info)) + { + ERR("Failed to initialize Vulkan global procs.\n"); + return E_FAIL; + } + memset(&instance->vk_info, 0, sizeof(instance->vk_info)); - vkd3d_init_instance_caps(&instance->vk_info); + vkd3d_init_instance_caps(instance);
application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; application_info.pNext = NULL; @@ -218,16 +245,16 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance, &instance->vk_info); instance_info.ppEnabledExtensionNames = extensions;
- if ((vr = vkCreateInstance(&instance_info, NULL, &vk_instance))) + if ((vr = vk_global_procs->vkCreateInstance(&instance_info, NULL, &vk_instance))) { ERR("Failed to create Vulkan instance, vr %d.\n", vr); return hresult_from_vk_result(vr); }
- if (FAILED(hr = vkd3d_load_vk_instance_procs(&instance->vk_procs, vk_instance))) + if (FAILED(hr = vkd3d_load_vk_instance_procs(&instance->vk_procs, vk_global_procs, vk_instance))) { ERR("Failed to load instance procs, hr %#x.\n", hr); - vkDestroyInstance(vk_instance, NULL); + vk_global_procs->vkDestroyInstance(vk_instance, NULL); return hr; }
@@ -872,7 +899,8 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, VkPhysicalDev if (FAILED(hr = vkd3d_load_vk_device_procs(&device->vk_procs, vk_procs, vk_device))) { ERR("Failed to load device procs, hr %#x.\n", hr); - vkDestroyDevice(vk_device, NULL); + if (device->vk_procs.vkDestroyDevice) + device->vk_procs.vkDestroyDevice(vk_device, NULL); return hr; }
@@ -884,7 +912,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, VkPhysicalDev copy_queue_family_index, copy_queue_timestamp_bits))) { ERR("Failed to create queues, hr %#x.\n", hr); - vkDestroyDevice(vk_device, NULL); + device->vk_procs.vkDestroyDevice(vk_device, NULL); return hr; }
diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c index f94dce50daa3..84141aadb9fb 100644 --- a/libs/vkd3d/utils.c +++ b/libs/vkd3d/utils.c @@ -351,14 +351,14 @@ HRESULT hresult_from_vk_result(VkResult vr) }
#define LOAD_INSTANCE_PFN(name) \ - if (!(procs->name = (void *)vkGetInstanceProcAddr(instance, #name))) \ + if (!(procs->name = (void *)global_procs->vkGetInstanceProcAddr(instance, #name))) \ { \ ERR("Could not get instance proc addr for '" #name "'.\n"); \ return E_FAIL; \ }
HRESULT vkd3d_load_vk_instance_procs(struct vkd3d_vk_instance_procs *procs, - VkInstance instance) + const struct vkd3d_vulkan_procs_info *global_procs, VkInstance instance) { memset(procs, 0, sizeof(*procs));
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index eca6895784b8..f32b64a58cef 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -87,6 +87,7 @@ struct vkd3d_instance size_t wchar_size;
struct vkd3d_vulkan_info vk_info; + struct vkd3d_vulkan_procs_info vk_global_procs;
LONG refcount; }; @@ -747,7 +748,7 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) DECLSPEC_HIDDEN; HRESULT hresult_from_vk_result(VkResult vr) DECLSPEC_HIDDEN;
HRESULT vkd3d_load_vk_instance_procs(struct vkd3d_vk_instance_procs *procs, - VkInstance instance) DECLSPEC_HIDDEN; + const struct vkd3d_vulkan_procs_info *global_procs, VkInstance instance) DECLSPEC_HIDDEN; HRESULT vkd3d_load_vk_device_procs(struct vkd3d_vk_device_procs *procs, const struct vkd3d_vk_instance_procs *parent_procs, VkDevice device) DECLSPEC_HIDDEN;
@@ -759,6 +760,5 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *crea 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); -VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *allocator);
#endif /* __VKD3D_PRIVATE_H */ diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h index 8875cb24b490..b1ec77df7358 100644 --- a/libs/vkd3d/vulkan_procs.h +++ b/libs/vkd3d/vulkan_procs.h @@ -44,6 +44,7 @@ VK_INSTANCE_PFN(vkGetPhysicalDeviceQueueFamilyProperties) VK_INSTANCE_PFN(vkGetPhysicalDeviceSparseImageFormatProperties)
/* Device functions (obtained by vkGetDeviceProcAddr). */ +VK_DEVICE_PFN(vkDestroyDevice) /* Load vkDestroyDevice() first. */ VK_DEVICE_PFN(vkAllocateCommandBuffers) VK_DEVICE_PFN(vkAllocateDescriptorSets) VK_DEVICE_PFN(vkAllocateMemory) @@ -118,7 +119,6 @@ VK_DEVICE_PFN(vkDestroyBufferView) VK_DEVICE_PFN(vkDestroyCommandPool) VK_DEVICE_PFN(vkDestroyDescriptorPool) VK_DEVICE_PFN(vkDestroyDescriptorSetLayout) -VK_DEVICE_PFN(vkDestroyDevice) VK_DEVICE_PFN(vkDestroyEvent) VK_DEVICE_PFN(vkDestroyFence) VK_DEVICE_PFN(vkDestroyFramebuffer)