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