From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winevulkan/vulkan.c | 62 ++++++++++++++++---------------- dlls/winevulkan/vulkan_private.h | 7 ++-- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 308d3a546ca..d690bb6a322 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -44,21 +44,6 @@ static BOOL use_external_memory(void) static ULONG_PTR zero_bits = 0; -#define wine_vk_count_struct(s, t) wine_vk_count_struct_((void *)s, VK_STRUCTURE_TYPE_##t) -static uint32_t wine_vk_count_struct_(void *s, VkStructureType t) -{ - const VkBaseInStructure *header; - uint32_t result = 0; - - for (header = s; header; header = header->pNext) - { - if (header->sType == t) - result++; - } - - return result; -} - static const struct vulkan_funcs *vk_funcs; #define WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, client_handle, native_handle, object) \ @@ -487,29 +472,28 @@ NTSTATUS init_vulkan(void *args) static VkResult wine_vk_instance_convert_create_info(struct conversion_context *ctx, const VkInstanceCreateInfo *src, VkInstanceCreateInfo *dst, struct wine_instance *object) { - VkDebugUtilsMessengerCreateInfoEXT *debug_utils_messenger; + VkDebugUtilsMessengerCreateInfoEXT *messenger_info; VkDebugReportCallbackCreateInfoEXT *callback_info; - VkBaseInStructure *header; unsigned int i; *dst = *src; - object->utils_messenger_count = wine_vk_count_struct(dst, DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT); - object->utils_messengers = calloc(object->utils_messenger_count, sizeof(*object->utils_messengers)); - header = (VkBaseInStructure *) dst; - for (i = 0; i < object->utils_messenger_count; i++) + messenger_info = (VkDebugUtilsMessengerCreateInfoEXT *)dst; + while ((messenger_info = find_next_struct(messenger_info->pNext, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT))) { - header = find_next_struct(header->pNext, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT); - debug_utils_messenger = (VkDebugUtilsMessengerCreateInfoEXT *) header; + struct wine_debug_utils_messenger *messenger; - object->utils_messengers[i].instance = object; - object->utils_messengers[i].debug_messenger = VK_NULL_HANDLE; - object->utils_messengers[i].user_callback = debug_utils_messenger->pfnUserCallback; - object->utils_messengers[i].user_data = debug_utils_messenger->pUserData; + if (!(messenger = calloc(1, sizeof(*messenger)))) return VK_ERROR_OUT_OF_HOST_MEMORY; + messenger->instance = object; + messenger->debug_messenger = VK_NULL_HANDLE; + messenger->user_callback = messenger_info->pfnUserCallback; + messenger->user_data = messenger_info->pUserData; /* convert_VkInstanceCreateInfo_* already copied the chain, so we can modify it in-place. */ - debug_utils_messenger->pfnUserCallback = (void *) &debug_utils_callback_conversion; - debug_utils_messenger->pUserData = &object->utils_messengers[i]; + messenger_info->pfnUserCallback = debug_utils_callback_conversion; + messenger_info->pUserData = messenger; + + list_add_tail(&object->debug_utils_messengers, &messenger->entry); } callback_info = (VkDebugReportCallbackCreateInfoEXT *)dst; @@ -576,8 +560,19 @@ static VkResult wine_vk_instance_convert_create_info(struct conversion_context * static void cleanup_instance_create_info(struct conversion_context *ctx, VkInstanceCreateInfo *info) { + VkDebugUtilsMessengerCreateInfoEXT *messenger_info = (VkDebugUtilsMessengerCreateInfoEXT *)info; VkDebugReportCallbackCreateInfoEXT *callback_info = (VkDebugReportCallbackCreateInfoEXT *)info; + while ((messenger_info = find_next_struct(messenger_info->pNext, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT))) + { + struct wine_debug_utils_messenger *messenger = (struct wine_debug_utils_messenger *)messenger_info->pUserData; + + if (messenger_info->pfnUserCallback != debug_utils_callback_conversion) break; + /* restore previous create info values, if VkCreateInstance needs to be called again */ + messenger_info->pfnUserCallback = messenger->user_callback; + messenger_info->pUserData = messenger->user_data; + } + while ((callback_info = find_next_struct(callback_info->pNext, VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT))) { struct wine_debug_report_callback *callback = (struct wine_debug_report_callback *)callback_info->pUserData; @@ -674,6 +669,7 @@ static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_i */ static void wine_vk_instance_free(struct wine_instance *instance) { + struct wine_debug_utils_messenger *messenger; struct wine_debug_report_callback *callback; void *next; @@ -698,7 +694,12 @@ static void wine_vk_instance_free(struct wine_instance *instance) } pthread_rwlock_destroy(&instance->wrapper_lock); - free(instance->utils_messengers); + + LIST_FOR_EACH_ENTRY_SAFE(messenger, next, &instance->debug_utils_messengers, struct wine_debug_utils_messenger, entry) + { + list_remove(&messenger->entry); + free(messenger); + } LIST_FOR_EACH_ENTRY_SAFE(callback, next, &instance->debug_report_callbacks, struct wine_debug_report_callback, entry) { @@ -877,6 +878,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, return VK_ERROR_OUT_OF_HOST_MEMORY; } list_init(&object->wrappers); + list_init(&object->debug_utils_messengers); list_init(&object->debug_report_callbacks); pthread_rwlock_init(&object->wrapper_lock, NULL); diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index d2280f0e734..0c9fef43551 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -72,8 +72,6 @@ static inline struct wine_device *wine_device_from_handle(VkDevice handle) return (struct wine_device *)(uintptr_t)handle->base.unix_handle; } -struct wine_debug_utils_messenger; - struct wine_instance { struct vulkan_instance_funcs funcs; @@ -91,9 +89,7 @@ struct wine_instance struct list wrappers; pthread_rwlock_t wrapper_lock; - struct wine_debug_utils_messenger *utils_messengers; - uint32_t utils_messenger_count; - + struct list debug_utils_messengers; struct list debug_report_callbacks; unsigned int quirks; @@ -181,6 +177,7 @@ struct wine_debug_utils_messenger void *user_data; struct wine_vk_mapping mapping; + struct list entry; /* entry in wine_instance debug_utils_messengers */ }; static inline struct wine_debug_utils_messenger *wine_debug_utils_messenger_from_handle( -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4488