From: Rémi Bernon rbernon@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(