From: Arkadiusz Hiler ahiler@codeweavers.com
With VK_EXT_device_address_binding_report we can get debug_util callbacks used to track memory bindings. Since it's the host's implementation that starts the callback we have to be sure that we have a way of converting it to the client side's variant before it's added to the handle map - i.e. we don't know the host handle at that time yet. --- dlls/winevulkan/vulkan.c | 33 ++++++++++++++++++++++++++++++--- include/ntuser.h | 1 + 2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index e7d00813a42..4e1086b7cd4 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -159,6 +159,28 @@ static uint64_t client_handle_from_host(struct wine_instance *instance, uint64_t return result; }
+static void set_transient_client_handle(struct wine_instance *instance, struct wine_device_memory *memory) +{ + struct ntuser_thread_info *thread_info; + if (!instance->enable_wrapper_list) return; + thread_info = NtUserGetThreadInfo(); + thread_info->vulkan_data = (uintptr_t)memory; +} + +static uint64_t get_transient_handle(uint64_t host_handle) +{ + struct ntuser_thread_info *thread_info; + struct wine_device_memory *memory; + + thread_info = NtUserGetThreadInfo(); + if (!thread_info->vulkan_data) return 0; + + memory = (struct wine_device_memory *)(uintptr_t)thread_info->vulkan_data; + memory->host_memory = host_handle; + + return (uintptr_t)memory; +} + static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT message_types, const VkDebugUtilsMessengerCallbackDataEXT *callback_data, @@ -200,6 +222,8 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB if (wine_vk_is_type_wrapped(callback_data->pObjects[i].objectType)) { object_name_infos[i].objectHandle = client_handle_from_host(object->instance, callback_data->pObjects[i].objectHandle); + if (!object_name_infos[i].objectHandle && object_name_infos[i].objectType == VK_OBJECT_TYPE_DEVICE_MEMORY) + object_name_infos[i].objectHandle = get_transient_handle(callback_data->pObjects[i].objectHandle); if (!object_name_infos[i].objectHandle) { WARN("handle conversion failed 0x%s\n", wine_dbgstr_longlong(callback_data->pObjects[i].objectHandle)); @@ -1901,16 +1925,19 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo if (!(memory = malloc(sizeof(*memory)))) return VK_ERROR_OUT_OF_HOST_MEMORY;
+ memory->size = info.allocationSize; + memory->vm_map = mapping; + + set_transient_client_handle(device->phys_dev->instance, memory); result = device->funcs.p_vkAllocateMemory(device->host_device, &info, NULL, &memory->host_memory); + set_transient_client_handle(device->phys_dev->instance, NULL); + if (result != VK_SUCCESS) { free(memory); return result; }
- memory->size = info.allocationSize; - memory->vm_map = mapping; - *ret = (VkDeviceMemory)(uintptr_t)memory; add_handle_mapping(device->phys_dev->instance, *ret, memory->host_memory, &memory->wrapper_entry); return VK_SUCCESS; diff --git a/include/ntuser.h b/include/ntuser.h index f947fec7fea..14fc51756f6 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -87,6 +87,7 @@ struct ntuser_thread_info UINT default_imc; /* default input context */ UINT64 client_imm; /* client IMM thread info */ UINT64 wmchar_data; /* client data for WM_CHAR mappings */ + UINT64 vulkan_data; /* used by winevulkan for tls */ };
static inline struct ntuser_thread_info *NtUserGetThreadInfo(void)