diff --git a/include/vkd3d.h b/include/vkd3d.h index 6017e1ac..5ae76030 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 9fe61a1b..2ea0a16b 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 3255dd6e..62271dbb 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 f94dce50..84141aad 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 eca68957..f32b64a5 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 8875cb24..b1ec77df 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)