From: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winevulkan/vulkan.c | 112 ++++++++++++++----------------- dlls/winevulkan/vulkan_private.h | 34 +--------- include/wine/vulkan_driver.h | 2 + 3 files changed, 53 insertions(+), 95 deletions(-) diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 8b3d5bccc53..c1ed44fbdda 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -123,46 +123,34 @@ static uint32_t wine_vk_count_struct_(void *s, VkStructureType t) static const struct vulkan_funcs *vk_funcs; -static int wrapper_entry_compare(const void *key, const struct rb_entry *entry) +static int vulkan_object_compare(const void *key, const struct rb_entry *entry) { - struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); + struct vulkan_object *object = RB_ENTRY_VALUE(entry, struct vulkan_object, entry); const uint64_t *host_handle = key; - if (*host_handle < wrapper->host_handle) return -1; - if (*host_handle > wrapper->host_handle) return 1; + if (*host_handle < object->host_handle) return -1; + if (*host_handle > object->host_handle) return 1; return 0; } -static void add_handle_mapping(struct vulkan_instance *obj, uint64_t client_handle, - uint64_t host_handle, struct wrapper_entry *entry) +static void vulkan_instance_insert_object( struct vulkan_instance *instance, struct vulkan_object *obj ) { - struct wine_instance *instance = CONTAINING_RECORD(obj, struct wine_instance, obj); - - if (instance->enable_wrapper_list) + struct wine_instance *impl = CONTAINING_RECORD(instance, struct wine_instance, obj); + if (impl->objects.compare) { - entry->host_handle = host_handle; - entry->client_handle = client_handle; - - pthread_rwlock_wrlock(&instance->wrapper_lock); - rb_put(&instance->wrappers, &host_handle, &entry->entry); - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_wrlock( &impl->objects_lock ); + rb_put( &impl->objects, &obj->host_handle, &obj->entry ); + pthread_rwlock_unlock( &impl->objects_lock ); } } -static void add_handle_mapping_ptr(struct vulkan_instance *obj, void *client_handle, - void *host_handle, struct wrapper_entry *entry) +static void vulkan_instance_remove_object( struct vulkan_instance *instance, struct vulkan_object *obj ) { - add_handle_mapping(obj, (uintptr_t)client_handle, (uintptr_t)host_handle, entry); -} - -static void remove_handle_mapping(struct vulkan_instance *obj, struct wrapper_entry *entry) -{ - struct wine_instance *instance = CONTAINING_RECORD(obj, struct wine_instance, obj); - - if (instance->enable_wrapper_list) + struct wine_instance *impl = CONTAINING_RECORD(instance, struct wine_instance, obj); + if (impl->objects.compare) { - pthread_rwlock_wrlock(&instance->wrapper_lock); - rb_remove(&instance->wrappers, &entry->entry); - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_wrlock( &impl->objects_lock ); + rb_remove( &impl->objects, &obj->entry ); + pthread_rwlock_unlock( &impl->objects_lock ); } } @@ -172,13 +160,13 @@ static uint64_t client_handle_from_host(struct vulkan_instance *obj, uint64_t ho struct rb_entry *entry; uint64_t result = 0; - pthread_rwlock_rdlock(&instance->wrapper_lock); - if ((entry = rb_get(&instance->wrappers, &host_handle))) + pthread_rwlock_rdlock(&instance->objects_lock); + if ((entry = rb_get(&instance->objects, &host_handle))) { - struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); - result = wrapper->client_handle; + struct vulkan_object *object = RB_ENTRY_VALUE(entry, struct vulkan_object, entry); + result = object->client_handle; } - pthread_rwlock_unlock(&instance->wrapper_lock); + pthread_rwlock_unlock(&instance->objects_lock); return result; } @@ -524,7 +512,7 @@ static void wine_vk_free_command_buffers(struct vulkan_device *device, device->p_vkFreeCommandBuffers(device->host.device, pool->host.command_pool, 1, &buffer->host.command_buffer); - remove_handle_mapping(instance, &buffer->wrapper_entry); + vulkan_instance_remove_object(instance, &buffer->obj); buffer->client.command_buffer->obj.unix_handle = 0; free(buffer); } @@ -752,7 +740,8 @@ static VkResult wine_vk_instance_convert_create_info(struct conversion_context * const char *extension_name = dst->ppEnabledExtensionNames[i]; if (!strcmp(extension_name, "VK_EXT_debug_utils") || !strcmp(extension_name, "VK_EXT_debug_report")) { - instance->enable_wrapper_list = VK_TRUE; + rb_init(&instance->objects, vulkan_object_compare); + pthread_rwlock_init(&instance->objects_lock, NULL); } if (!strcmp(extension_name, "VK_KHR_win32_surface")) { @@ -889,7 +878,7 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice client_device, const VkCommandBu vulkan_object_init_ptr(&buffer->obj, host_command_buffer, &client_command_buffer->obj); buffer->device = device; - add_handle_mapping_ptr(instance, buffer->client.command_buffer, buffer->host.command_buffer, &buffer->wrapper_entry); + vulkan_instance_insert_object(instance, &buffer->obj); } if (res != VK_SUCCESS) @@ -966,9 +955,9 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice client_physical_device, const VkDe for (i = 0; i < device->queue_count; i++) { struct wine_queue *queue = device->queues + i; - add_handle_mapping_ptr(instance, queue->obj.client.queue, queue->obj.host.queue, &queue->wrapper_entry); + vulkan_instance_insert_object(instance, &queue->obj.obj); } - add_handle_mapping_ptr(instance, client_device, device->obj.host.device, &device->wrapper_entry); + vulkan_instance_insert_object(instance, &device->obj.obj); *ret = client_device; return VK_SUCCESS; @@ -1048,17 +1037,14 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, TRACE("Created instance %p, host_instance %p.\n", instance, instance->obj.host.instance); - rb_init(&instance->wrappers, wrapper_entry_compare); - pthread_rwlock_init(&instance->wrapper_lock, NULL); - for (i = 0; i < instance->phys_dev_count; i++) { struct wine_phys_dev *phys_dev = &instance->phys_devs[i]; - add_handle_mapping_ptr(&instance->obj, phys_dev->obj.client.physical_device, phys_dev->obj.host.physical_device, &phys_dev->wrapper_entry); + vulkan_instance_insert_object(&instance->obj, &phys_dev->obj.obj); } + vulkan_instance_insert_object(&instance->obj, &instance->obj.obj); *ret = client_instance; - add_handle_mapping_ptr(&instance->obj, *ret, instance->obj.host.instance, &instance->wrapper_entry); return VK_SUCCESS; } @@ -1075,8 +1061,8 @@ void wine_vkDestroyDevice(VkDevice client_device, const VkAllocationCallbacks *a device->obj.p_vkDestroyDevice(device->obj.host.device, NULL /* pAllocator */); for (i = 0; i < device->queue_count; i++) - remove_handle_mapping(instance, &device->queues[i].wrapper_entry); - remove_handle_mapping(instance, &device->wrapper_entry); + vulkan_instance_remove_object(instance, &device->queues[i].obj.obj); + vulkan_instance_remove_object(instance, &device->obj.obj); free(device); } @@ -1094,12 +1080,12 @@ void wine_vkDestroyInstance(VkInstance client_instance, const VkAllocationCallba instance->obj.p_vkDestroyInstance(instance->obj.host.instance, NULL /* allocator */); for (i = 0; i < instance->phys_dev_count; i++) { - remove_handle_mapping(&instance->obj, &instance->phys_devs[i].wrapper_entry); + vulkan_instance_remove_object(&instance->obj, &instance->phys_devs[i].obj.obj); wine_phys_dev_cleanup(&instance->phys_devs[i]); } - remove_handle_mapping(&instance->obj, &instance->wrapper_entry); + vulkan_instance_remove_object(&instance->obj, &instance->obj.obj); - pthread_rwlock_destroy(&instance->wrapper_lock); + if (instance->objects.compare) pthread_rwlock_destroy(&instance->objects_lock); free(instance->utils_messengers); free(instance); } @@ -1318,9 +1304,9 @@ VkResult wine_vkCreateCommandPool(VkDevice client_device, const VkCommandPoolCre } vulkan_object_init(&object->obj, host_command_pool, &client_command_pool->obj); + vulkan_instance_insert_object(instance, &object->obj); *command_pool = object->client.command_pool; - add_handle_mapping(instance, *command_pool, object->host.command_pool, &object->wrapper_entry); return VK_SUCCESS; } @@ -1335,7 +1321,7 @@ void wine_vkDestroyCommandPool(VkDevice client_device, VkCommandPool handle, FIXME("Support for allocation callbacks not implemented yet\n"); device->p_vkDestroyCommandPool(device->host.device, pool->host.command_pool, NULL); - remove_handle_mapping(instance, &pool->wrapper_entry); + vulkan_instance_remove_object(instance, &pool->obj); free(pool); } @@ -1721,12 +1707,12 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance client_instance, const VkWin32S host_surface = vk_funcs->p_wine_get_host_surface(surface->driver_surface); vulkan_object_init(&surface->obj.obj, host_surface, NULL); surface->obj.instance = instance; + vulkan_instance_insert_object(instance, &surface->obj.obj); if (dummy) NtUserDestroyWindow(dummy); window_surfaces_insert(surface); *ret = surface->obj.client.surface; - add_handle_mapping(instance, *ret, surface->obj.host.surface, &surface->wrapper_entry); return VK_SUCCESS; } @@ -1740,7 +1726,7 @@ void wine_vkDestroySurfaceKHR(VkInstance client_instance, VkSurfaceKHR client_su return; instance->p_vkDestroySurfaceKHR(instance->host.instance, surface->driver_surface, NULL); - remove_handle_mapping(instance, &surface->wrapper_entry); + vulkan_instance_remove_object(instance, &surface->obj.obj); window_surfaces_remove(surface); free(surface); @@ -1843,9 +1829,9 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice client_device, const VkSwapchainCrea vulkan_object_init(&object->obj.obj, host_swapchain, NULL); object->surface = surface; object->extents = create_info->imageExtent; + vulkan_instance_insert_object(instance, &object->obj.obj); *ret = object->obj.client.swapchain; - add_handle_mapping(instance, *ret, object->obj.host.swapchain, &object->wrapper_entry); return VK_SUCCESS; } @@ -1860,7 +1846,7 @@ void wine_vkDestroySwapchainKHR(VkDevice client_device, VkSwapchainKHR client_sw if (!swapchain) return; device->p_vkDestroySwapchainKHR(device->host.device, swapchain->obj.host.swapchain, NULL); - remove_handle_mapping(instance, &swapchain->wrapper_entry); + vulkan_instance_remove_object(instance, &swapchain->obj.obj); free(swapchain); } @@ -2042,9 +2028,9 @@ VkResult wine_vkAllocateMemory(VkDevice client_device, const VkMemoryAllocateInf vulkan_object_init(&memory->obj, host_device_memory, NULL); memory->size = info.allocationSize; memory->vm_map = mapping; + vulkan_instance_insert_object(instance, &memory->obj); - *ret = (VkDeviceMemory)(uintptr_t)memory; - add_handle_mapping(instance, *ret, memory->host.device_memory, &memory->wrapper_entry); + *ret = memory->client.device_memory; return VK_SUCCESS; } @@ -2071,7 +2057,7 @@ void wine_vkFreeMemory(VkDevice client_device, VkDeviceMemory memory_handle, con } device->p_vkFreeMemory(device->host.device, memory->host.device_memory, NULL); - remove_handle_mapping(instance, &memory->wrapper_entry); + vulkan_instance_remove_object(instance, &memory->obj); if (memory->vm_map) { @@ -2427,9 +2413,9 @@ VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance client_instance, object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnUserCallback; object->user_data = (UINT_PTR)create_info->pUserData; + vulkan_instance_insert_object(instance, &object->obj); *messenger = object->client.debug_messenger; - add_handle_mapping(instance, *messenger, object->host.debug_messenger, &object->wrapper_entry); return VK_SUCCESS; } @@ -2445,7 +2431,7 @@ void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance client_instance, VkDebugUti return; instance->p_vkDestroyDebugUtilsMessengerEXT(instance->host.instance, object->host.debug_messenger, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj); free(object); } @@ -2483,9 +2469,9 @@ VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance client_instance, object->instance = instance; object->user_callback = (UINT_PTR)create_info->pfnCallback; object->user_data = (UINT_PTR)create_info->pUserData; + vulkan_instance_insert_object(instance, &object->obj); *callback = object->client.debug_callback; - add_handle_mapping(instance, *callback, object->host.debug_callback, &object->wrapper_entry); return VK_SUCCESS; } @@ -2501,7 +2487,7 @@ void wine_vkDestroyDebugReportCallbackEXT(VkInstance client_instance, VkDebugRep return; instance->p_vkDestroyDebugReportCallbackEXT(instance->host.instance, object->host.debug_callback, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj); free(object); } @@ -2531,9 +2517,9 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice device_handle, vulkan_object_init(&object->obj, host_deferred_operation, NULL); init_conversion_context(&object->ctx); + vulkan_instance_insert_object(instance, &object->obj); *operation = object->client.deferred_operation; - add_handle_mapping(instance, *operation, object->host.deferred_operation, &object->wrapper_entry); return VK_SUCCESS; } @@ -2551,7 +2537,7 @@ void wine_vkDestroyDeferredOperationKHR(VkDevice device_handle, return; device->p_vkDestroyDeferredOperationKHR(device->host.device, object->host.deferred_operation, NULL); - remove_handle_mapping(instance, &object->wrapper_entry); + vulkan_instance_remove_object(instance, &object->obj); free_conversion_context(&object->ctx); free(object); diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index bcf24bdd5ef..e6b983f5112 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -30,21 +30,10 @@ #include "wine/rbtree.h" -/* Some extensions have callbacks for those we need to be able to - * get the wine wrapper for a host handle - */ -struct wrapper_entry -{ - struct rb_entry entry; - uint64_t host_handle; - uint64_t client_handle; -}; - struct wine_cmd_buffer { VULKAN_OBJECT_HEADER( VkCommandBuffer, command_buffer ); struct vulkan_device *device; - struct wrapper_entry wrapper_entry; }; static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffer handle) @@ -60,15 +49,11 @@ struct wine_queue uint32_t family_index; uint32_t queue_index; VkDeviceQueueCreateFlags flags; - - struct wrapper_entry wrapper_entry; }; struct wine_device { struct vulkan_device obj; - struct wrapper_entry wrapper_entry; - uint64_t queue_count; struct wine_queue queues[]; }; @@ -84,8 +69,6 @@ struct wine_debug_report_callback UINT64 user_callback; /* client pointer */ UINT64 user_data; /* client pointer */ - - struct wrapper_entry wrapper_entry; }; struct wine_phys_dev @@ -98,8 +81,6 @@ struct wine_phys_dev uint32_t external_memory_align; uint32_t map_placed_align; - - struct wrapper_entry wrapper_entry; }; struct wine_debug_report_callback; @@ -109,9 +90,6 @@ struct wine_instance struct vulkan_instance obj; VkBool32 enable_win32_surface; - VkBool32 enable_wrapper_list; - struct rb_tree wrappers; - pthread_rwlock_t wrapper_lock; struct wine_debug_utils_messenger *utils_messengers; uint32_t utils_messenger_count; @@ -120,7 +98,8 @@ struct wine_instance unsigned int quirks; - struct wrapper_entry wrapper_entry; + struct rb_tree objects; + pthread_rwlock_t objects_lock; /* We cache devices as we need to wrap them as they are dispatchable objects. */ uint32_t phys_dev_count; @@ -132,7 +111,6 @@ C_ASSERT(sizeof(struct wine_instance) == offsetof(struct wine_instance, phys_dev struct wine_cmd_pool { VULKAN_OBJECT_HEADER( VkCommandPool, command_pool ); - struct wrapper_entry wrapper_entry; }; static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle) @@ -146,8 +124,6 @@ struct wine_device_memory VULKAN_OBJECT_HEADER( VkDeviceMemory, device_memory ); VkDeviceSize size; void *vm_map; - - struct wrapper_entry wrapper_entry; }; static inline struct wine_device_memory *wine_device_memory_from_handle(VkDeviceMemory handle) @@ -162,8 +138,6 @@ struct wine_debug_utils_messenger UINT64 user_callback; /* client pointer */ UINT64 user_data; /* client pointer */ - - struct wrapper_entry wrapper_entry; }; static inline struct wine_debug_utils_messenger *wine_debug_utils_messenger_from_handle( @@ -185,7 +159,6 @@ struct wine_surface HWND hwnd; struct rb_entry window_entry; - struct wrapper_entry wrapper_entry; }; static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) @@ -199,8 +172,6 @@ struct wine_swapchain struct vulkan_swapchain obj; struct wine_surface *surface; VkExtent2D extents; - - struct wrapper_entry wrapper_entry; }; static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR handle) @@ -264,7 +235,6 @@ struct wine_deferred_operation { VULKAN_OBJECT_HEADER( VkDeferredOperationKHR, deferred_operation ); struct conversion_context ctx; /* to keep params alive. */ - struct wrapper_entry wrapper_entry; }; static inline struct wine_deferred_operation *wine_deferred_operation_from_handle( diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 833cfa8119e..a81ad72cc5d 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -44,6 +44,7 @@ struct vulkan_client_object #define WINE_VK_HOST #include "wine/vulkan.h" +#include "wine/rbtree.h" /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ #define WINE_VULKAN_DRIVER_VERSION 35 @@ -52,6 +53,7 @@ struct vulkan_object { UINT64 host_handle; UINT64 client_handle; + struct rb_entry entry; }; #define VULKAN_OBJECT_HEADER( type, name ) \ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6931