-- v2: winevulkan: Get rid of the wine_vk_instance_free helper. winevulkan: Add handle mappings on creation success only. winevulkan: Simplify wine_vk_instance_free helper. winevulkan: Get rid of the wine_vk_device_free helper. winevulkan: Allocate all host command buffers at once. winevulkan: Use a single allocation for instance and physical devices. winevulkan: Rename wine_vk_physical_device_alloc parameters and variables. winevulkan: Pass VkDeviceQueueCreateInfo to wine_vk_device_init_queues. winevulkan: Use a single allocation for device and queues. winevulkan: Use an rb_tree and allocate entries for handle mappings.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 134 +++++++++++++++---------------- dlls/winevulkan/vulkan_private.h | 34 ++++---- 2 files changed, 83 insertions(+), 85 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index c8cb525929d..543a7c1afa5 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -61,48 +61,53 @@ static uint32_t wine_vk_count_struct_(void *s, VkStructureType t)
static const struct vulkan_funcs *vk_funcs;
-#define WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, client_handle, host_handle, object) \ - wine_vk_add_handle_mapping((instance), (uintptr_t)(client_handle), (uintptr_t)(host_handle), &(object)->mapping) -#define WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, client_handle, host_handle, object) \ - wine_vk_add_handle_mapping((instance), (uintptr_t)(client_handle), (host_handle), &(object)->mapping) -static void wine_vk_add_handle_mapping(struct wine_instance *instance, uint64_t wrapped_handle, - uint64_t host_handle, struct wine_vk_mapping *mapping) +static int wrapper_entry_compare(const void *key, const struct rb_entry *entry) +{ + struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); + const uint64_t *host_handle = key; + return *host_handle - wrapper->host_handle; +} + +static void add_handle_mapping(struct wine_instance *instance, uint64_t client_handle, + uint64_t host_handle, struct wrapper_entry *entry) { if (instance->enable_wrapper_list) { - mapping->host_handle = host_handle; - mapping->wine_wrapped_handle = wrapped_handle; + entry->host_handle = host_handle; + entry->client_handle = client_handle; + pthread_rwlock_wrlock(&instance->wrapper_lock); - list_add_tail(&instance->wrappers, &mapping->link); + rb_put(&instance->wrappers, &host_handle, &entry->entry); pthread_rwlock_unlock(&instance->wrapper_lock); } }
-#define WINE_VK_REMOVE_HANDLE_MAPPING(instance, object) \ - wine_vk_remove_handle_mapping((instance), &(object)->mapping) -static void wine_vk_remove_handle_mapping(struct wine_instance *instance, struct wine_vk_mapping *mapping) +static void add_handle_mapping_ptr(struct wine_instance *instance, void *client_handle, + void *host_handle, struct wrapper_entry *entry) +{ + add_handle_mapping(instance, (uintptr_t)client_handle, (uintptr_t)host_handle, entry); +} + +static void remove_handle_mapping(struct wine_instance *instance, struct wrapper_entry *entry) { if (instance->enable_wrapper_list) { pthread_rwlock_wrlock(&instance->wrapper_lock); - list_remove(&mapping->link); + rb_remove(&instance->wrappers, &entry->entry); pthread_rwlock_unlock(&instance->wrapper_lock); } }
-static uint64_t wine_vk_get_wrapper(struct wine_instance *instance, uint64_t host_handle) +static uint64_t client_handle_from_host(struct wine_instance *instance, uint64_t host_handle) { - struct wine_vk_mapping *mapping; + struct rb_entry *entry; uint64_t result = 0;
pthread_rwlock_rdlock(&instance->wrapper_lock); - LIST_FOR_EACH_ENTRY(mapping, &instance->wrappers, struct wine_vk_mapping, link) + if ((entry = rb_get(&instance->wrappers, &host_handle))) { - if (mapping->host_handle == host_handle) - { - result = mapping->wine_wrapped_handle; - break; - } + struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry); + result = wrapper->client_handle; } pthread_rwlock_unlock(&instance->wrapper_lock); return result; @@ -148,7 +153,7 @@ static VkBool32 debug_utils_callback_conversion(VkDebugUtilsMessageSeverityFlagB
if (wine_vk_is_type_wrapped(callback_data->pObjects[i].objectType)) { - object_name_infos[i].objectHandle = wine_vk_get_wrapper(object->instance, callback_data->pObjects[i].objectHandle); + object_name_infos[i].objectHandle = client_handle_from_host(object->instance, 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)); @@ -201,7 +206,7 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk params.layer_prefix = layer_prefix; params.message = message;
- params.object_handle = wine_vk_get_wrapper(object->instance, object_handle); + params.object_handle = client_handle_from_host(object->instance, object_handle); if (!params.object_handle) params.object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
@@ -215,7 +220,7 @@ static void wine_vk_physical_device_free(struct wine_phys_dev *phys_dev) if (!phys_dev) return;
- WINE_VK_REMOVE_HANDLE_MAPPING(phys_dev->instance, phys_dev); + remove_handle_mapping(phys_dev->instance, &phys_dev->wrapper_entry); free(phys_dev->extensions); free(phys_dev); } @@ -239,7 +244,7 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance object->host_physical_device = phys_dev;
handle->base.unix_handle = (uintptr_t)object; - WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, handle, phys_dev, object); + add_handle_mapping_ptr(instance, handle, phys_dev, &object->wrapper_entry);
instance->funcs.p_vkGetPhysicalDeviceMemoryProperties(phys_dev, &object->memory_properties);
@@ -378,7 +383,7 @@ static void wine_vk_free_command_buffers(struct wine_device *device,
device->funcs.p_vkFreeCommandBuffers(device->host_device, pool->host_command_pool, 1, &buffer->host_command_buffer); - WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, buffer); + remove_handle_mapping(device->phys_dev->instance, &buffer->wrapper_entry); buffer->handle->base.unix_handle = 0; free(buffer); } @@ -421,7 +426,7 @@ static void wine_vk_device_get_queues(struct wine_device *device, }
queue->handle->base.unix_handle = (uintptr_t)queue; - WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, queue->handle, queue->host_queue, queue); + add_handle_mapping_ptr(device->phys_dev->instance, queue->handle, queue->host_queue, &queue->wrapper_entry);
TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->host_queue); } @@ -516,7 +521,7 @@ static void wine_vk_device_free(struct wine_device *device) { queue = &device->queues[i]; if (queue && queue->host_queue) - WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, queue); + remove_handle_mapping(device->phys_dev->instance, &queue->wrapper_entry); } free(device->queues); device->queues = NULL; @@ -524,7 +529,7 @@ static void wine_vk_device_free(struct wine_device *device)
if (device->host_device && device->funcs.p_vkDestroyDevice) { - WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device); + remove_handle_mapping(device->phys_dev->instance, &device->wrapper_entry); device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */); }
@@ -738,10 +743,11 @@ static void wine_vk_instance_free(struct wine_instance *instance) if (instance->host_instance) { vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); - WINE_VK_REMOVE_HANDLE_MAPPING(instance, instance); + remove_handle_mapping(instance, &instance->wrapper_entry); }
pthread_rwlock_destroy(&instance->wrapper_lock); + rb_destroy(&instance->wrappers, NULL, NULL); free(instance->utils_messengers);
free(instance); @@ -783,7 +789,7 @@ VkResult wine_vkAllocateCommandBuffers(VkDevice handle, const VkCommandBufferAll res = device->funcs.p_vkAllocateCommandBuffers(device->host_device, &allocate_info_host, &buffer->host_command_buffer); buffer->handle->base.unix_handle = (uintptr_t)buffer; - WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, buffer->handle, buffer->host_command_buffer, buffer); + add_handle_mapping_ptr(device->phys_dev->instance, buffer->handle, buffer->host_command_buffer, &buffer->wrapper_entry); if (res != VK_SUCCESS) { ERR("Failed to allocate command buffer, res=%d.\n", res); @@ -838,7 +844,7 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre res = instance->funcs.p_vkCreateDevice(phys_dev->host_physical_device, &create_info_host, NULL /* allocator */, &object->host_device); free_conversion_context(&ctx); - WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, device_handle, object->host_device, object); + add_handle_mapping_ptr(instance, device_handle, object->host_device, &object->wrapper_entry); if (res != VK_SUCCESS) { WARN("Failed to create device, res=%d.\n", res); @@ -914,7 +920,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, ERR("Failed to allocate memory for instance\n"); return VK_ERROR_OUT_OF_HOST_MEMORY; } - list_init(&object->wrappers); + rb_init(&object->wrappers, wrapper_entry_compare); pthread_rwlock_init(&object->wrapper_lock, NULL);
init_conversion_context(&ctx); @@ -930,7 +936,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, }
object->handle = client_instance; - WINE_VK_ADD_DISPATCHABLE_MAPPING(object, object->handle, object->host_instance, object); + add_handle_mapping_ptr(object, object->handle, object->host_instance, &object->wrapper_entry);
/* Load all instance functions we are aware of. Note the loader takes care * of any filtering for extensions which were not requested, but which the @@ -1195,21 +1201,18 @@ VkResult wine_vkCreateCommandPool(VkDevice device_handle, const VkCommandPoolCre return VK_ERROR_OUT_OF_HOST_MEMORY;
res = device->funcs.p_vkCreateCommandPool(device->host_device, info, NULL, &object->host_command_pool); - - if (res == VK_SUCCESS) - { - object->handle = (uintptr_t)handle; - handle->unix_handle = (uintptr_t)object; - WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, object->handle, - object->host_command_pool, object); - *command_pool = object->handle; - } - else + if (res != VK_SUCCESS) { free(object); + return res; }
- return res; + object->handle = (uintptr_t)handle; + handle->unix_handle = (uintptr_t)object; + + *command_pool = object->handle; + add_handle_mapping(device->phys_dev->instance, *command_pool, object->host_command_pool, &object->wrapper_entry); + return VK_SUCCESS; }
void wine_vkDestroyCommandPool(VkDevice device_handle, VkCommandPool handle, @@ -1221,8 +1224,7 @@ void wine_vkDestroyCommandPool(VkDevice device_handle, VkCommandPool handle, if (allocator) FIXME("Support for allocation callbacks not implemented yet\n");
- WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, pool); - + remove_handle_mapping(device->phys_dev->instance, &pool->wrapper_entry); device->funcs.p_vkDestroyCommandPool(device->host_device, pool->host_command_pool, NULL); free(pool); } @@ -1604,13 +1606,10 @@ VkResult wine_vkCreateWin32SurfaceKHR(VkInstance handle, const VkWin32SurfaceCre }
object->host_surface = vk_funcs->p_wine_get_host_surface(object->driver_surface); - WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->host_surface, object); - - *surface = wine_surface_to_handle(object); if (dummy) NtUserDestroyWindow(dummy);
*surface = wine_surface_to_handle(object); - + add_handle_mapping(instance, *surface, object->host_surface, &object->wrapper_entry); return VK_SUCCESS; }
@@ -1624,7 +1623,7 @@ void wine_vkDestroySurfaceKHR(VkInstance handle, VkSurfaceKHR surface, return;
instance->funcs.p_vkDestroySurfaceKHR(instance->host_instance, object->driver_surface, NULL); - WINE_VK_REMOVE_HANDLE_MAPPING(instance, object); + remove_handle_mapping(instance, &object->wrapper_entry);
free(object); } @@ -1666,10 +1665,9 @@ VkResult wine_vkCreateSwapchainKHR(VkDevice device_handle, const VkSwapchainCrea return res; }
- WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, object, object->host_swapchain, object); *swapchain_handle = wine_swapchain_to_handle(object); - - return res; + add_handle_mapping(instance, *swapchain_handle, object->host_swapchain, &object->wrapper_entry); + return VK_SUCCESS; }
void wine_vkDestroySwapchainKHR(VkDevice device_handle, VkSwapchainKHR swapchain_handle, @@ -1682,7 +1680,7 @@ void wine_vkDestroySwapchainKHR(VkDevice device_handle, VkSwapchainKHR swapchain if (!swapchain) return;
device->funcs.p_vkDestroySwapchainKHR(device->host_device, swapchain->host_swapchain, NULL); - WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, swapchain); + remove_handle_mapping(device->phys_dev->instance, &swapchain->wrapper_entry);
free(swapchain); } @@ -1776,10 +1774,11 @@ VkResult wine_vkAllocateMemory(VkDevice handle, const VkMemoryAllocateInfo *allo return result; }
- WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, memory, memory->host_memory, memory); 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; }
@@ -1803,7 +1802,7 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); }
- WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, memory); + remove_handle_mapping(device->phys_dev->instance, &memory->wrapper_entry); device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL);
if (memory->vm_map) @@ -2155,9 +2154,8 @@ VkResult wine_vkCreateDebugUtilsMessengerEXT(VkInstance handle, return res; }
- WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->host_debug_messenger, object); *messenger = wine_debug_utils_messenger_to_handle(object); - + add_handle_mapping(instance, *messenger, object->host_debug_messenger, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2173,7 +2171,7 @@ void wine_vkDestroyDebugUtilsMessengerEXT(VkInstance handle, VkDebugUtilsMesseng return;
instance->funcs.p_vkDestroyDebugUtilsMessengerEXT(instance->host_instance, object->host_debug_messenger, NULL); - WINE_VK_REMOVE_HANDLE_MAPPING(instance, object); + remove_handle_mapping(instance, &object->wrapper_entry);
free(object); } @@ -2211,9 +2209,8 @@ VkResult wine_vkCreateDebugReportCallbackEXT(VkInstance handle, return res; }
- WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, object, object->host_debug_callback, object); *callback = wine_debug_report_callback_to_handle(object); - + add_handle_mapping(instance, *callback, object->host_debug_callback, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2229,14 +2226,14 @@ void wine_vkDestroyDebugReportCallbackEXT(VkInstance handle, VkDebugReportCallba return;
instance->funcs.p_vkDestroyDebugReportCallbackEXT(instance->host_instance, object->host_debug_callback, NULL); - WINE_VK_REMOVE_HANDLE_MAPPING(instance, object); + remove_handle_mapping(instance, &object->wrapper_entry);
free(object); }
VkResult wine_vkCreateDeferredOperationKHR(VkDevice handle, const VkAllocationCallbacks* allocator, - VkDeferredOperationKHR* deferredOperation) + VkDeferredOperationKHR* operation) { struct wine_device *device = wine_device_from_handle(handle); struct wine_deferred_operation *object; @@ -2258,9 +2255,8 @@ VkResult wine_vkCreateDeferredOperationKHR(VkDevice handle,
init_conversion_context(&object->ctx);
- WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(device->phys_dev->instance, object, object->host_deferred_operation, object); - *deferredOperation = wine_deferred_operation_to_handle(object); - + *operation = wine_deferred_operation_to_handle(object); + add_handle_mapping(device->phys_dev->instance, *operation, object->host_deferred_operation, &object->wrapper_entry); return VK_SUCCESS; }
@@ -2277,7 +2273,7 @@ void wine_vkDestroyDeferredOperationKHR(VkDevice handle, return;
device->funcs.p_vkDestroyDeferredOperationKHR(device->host_device, object->host_deferred_operation, NULL); - WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, object); + remove_handle_mapping(device->phys_dev->instance, &object->wrapper_entry);
free_conversion_context(&object->ctx); free(object); diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 94eecc5e5d5..7b1e24f3e56 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -28,14 +28,16 @@ #include "vulkan_loader.h" #include "vulkan_thunks.h"
+#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 wine_vk_mapping +struct wrapper_entry { - struct list link; + struct rb_entry entry; uint64_t host_handle; - uint64_t wine_wrapped_handle; + uint64_t client_handle; };
struct wine_cmd_buffer @@ -45,7 +47,7 @@ struct wine_cmd_buffer VkCommandBuffer handle; /* client command buffer */ VkCommandBuffer host_command_buffer;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffer handle) @@ -64,7 +66,7 @@ struct wine_device struct wine_queue *queues; uint32_t queue_count;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_device *wine_device_from_handle(VkDevice handle) @@ -83,7 +85,7 @@ struct wine_debug_report_callback PFN_vkDebugReportCallbackEXT user_callback; void *user_data;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
struct wine_instance @@ -101,7 +103,7 @@ struct wine_instance
VkBool32 enable_win32_surface; VkBool32 enable_wrapper_list; - struct list wrappers; + struct rb_tree wrappers; pthread_rwlock_t wrapper_lock;
struct wine_debug_utils_messenger *utils_messengers; @@ -111,7 +113,7 @@ struct wine_instance
unsigned int quirks;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_instance *wine_instance_from_handle(VkInstance handle) @@ -133,7 +135,7 @@ struct wine_phys_dev uint32_t external_memory_align; uint32_t map_placed_align;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_phys_dev *wine_phys_dev_from_handle(VkPhysicalDevice handle) @@ -152,7 +154,7 @@ struct wine_queue uint32_t queue_index; VkDeviceQueueCreateFlags flags;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_queue *wine_queue_from_handle(VkQueue handle) @@ -165,7 +167,7 @@ struct wine_cmd_pool VkCommandPool handle; VkCommandPool host_command_pool;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle) @@ -180,7 +182,7 @@ struct wine_device_memory VkDeviceSize size; void *vm_map;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_device_memory *wine_device_memory_from_handle(VkDeviceMemory handle) @@ -197,7 +199,7 @@ struct wine_debug_utils_messenger PFN_vkDebugUtilsMessengerCallbackEXT user_callback; void *user_data;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_debug_utils_messenger *wine_debug_utils_messenger_from_handle( @@ -230,7 +232,7 @@ struct wine_surface VkSurfaceKHR driver_surface; HWND hwnd;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_surface *wine_surface_from_handle(VkSurfaceKHR handle) @@ -247,7 +249,7 @@ struct wine_swapchain { VkSwapchainKHR host_swapchain;
- struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_swapchain *wine_swapchain_from_handle(VkSwapchainKHR handle) @@ -314,7 +316,7 @@ struct wine_deferred_operation { VkDeferredOperationKHR host_deferred_operation; struct conversion_context ctx; /* to keep params alive. */ - struct wine_vk_mapping mapping; + struct wrapper_entry wrapper_entry; };
static inline struct wine_deferred_operation *wine_deferred_operation_from_handle(
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 38 ++++++++------------------ dlls/winevulkan/vulkan_private.h | 46 +++++++++++++++++--------------- 2 files changed, 35 insertions(+), 49 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 543a7c1afa5..e41ff6a736d 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -509,22 +509,15 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de */ static void wine_vk_device_free(struct wine_device *device) { - struct wine_queue *queue; + unsigned int i;
if (!device) return;
- if (device->queues) + for (i = 0; i < device->queue_count; i++) { - unsigned int i; - for (i = 0; i < device->queue_count; i++) - { - queue = &device->queues[i]; - if (queue && queue->host_queue) - remove_handle_mapping(device->phys_dev->instance, &queue->wrapper_entry); - } - free(device->queues); - device->queues = NULL; + struct wine_queue *queue = device->queues + i; + if (queue->host_queue) remove_handle_mapping(device->phys_dev->instance, &queue->wrapper_entry); }
if (device->host_device && device->funcs.p_vkDestroyDevice) @@ -816,7 +809,7 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre struct wine_queue *next_queue; struct conversion_context ctx; struct wine_device *object; - unsigned int i; + unsigned int queue_count, i; VkResult res;
if (allocator) @@ -833,7 +826,11 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre TRACE("Driver version: %#x.\n", properties.driverVersion); }
- if (!(object = calloc(1, sizeof(*object)))) + /* We need to cache all queues within the device as each requires wrapping since queues are dispatchable objects. */ + for (queue_count = 0, i = 0; i < create_info->queueCreateInfoCount; i++) + queue_count += create_info->pQueueCreateInfos[i].queueCount; + + if (!(object = calloc(1, offsetof(struct wine_device, queues[queue_count])))) return VK_ERROR_OUT_OF_HOST_MEMORY;
object->phys_dev = phys_dev; @@ -861,20 +858,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre ALL_VK_DEVICE_FUNCS() #undef USE_VK_FUNC
- /* We need to cache all queues within the device as each requires wrapping since queues are - * dispatchable objects. - */ - for (i = 0; i < create_info_host.queueCreateInfoCount; i++) - { - object->queue_count += create_info_host.pQueueCreateInfos[i].queueCount; - } - - if (!(object->queues = calloc(object->queue_count, sizeof(*object->queues)))) - { - res = VK_ERROR_OUT_OF_HOST_MEMORY; - goto fail; - } - next_queue = object->queues; queue_handles = device_handle->queues; for (i = 0; i < create_info_host.queueCreateInfoCount; i++) @@ -888,6 +871,7 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre wine_vk_device_get_queues(object, family_index, queue_count, flags, next_queue, &queue_handles); next_queue += queue_count; } + object->queue_count = next_queue - object->queues;
device_handle->quirks = instance->quirks; device_handle->base.unix_handle = (uintptr_t)object; diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 7b1e24f3e56..31e9e981168 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -55,6 +55,25 @@ static inline struct wine_cmd_buffer *wine_cmd_buffer_from_handle(VkCommandBuffe return (struct wine_cmd_buffer *)(uintptr_t)handle->base.unix_handle; }
+struct wine_queue +{ + struct wine_device *device; /* parent */ + + VkQueue handle; /* client queue */ + VkQueue host_queue; + + uint32_t family_index; + uint32_t queue_index; + VkDeviceQueueCreateFlags flags; + + struct wrapper_entry wrapper_entry; +}; + +static inline struct wine_queue *wine_queue_from_handle(VkQueue handle) +{ + return (struct wine_queue *)(uintptr_t)handle->base.unix_handle; +} + struct wine_device { struct vulkan_device_funcs funcs; @@ -63,12 +82,14 @@ struct wine_device VkDevice handle; /* client device */ VkDevice host_device;
- struct wine_queue *queues; - uint32_t queue_count; - struct wrapper_entry wrapper_entry; + + uint32_t queue_count; + struct wine_queue queues[]; };
+C_ASSERT(sizeof(struct wine_device) == offsetof(struct wine_device, queues[0])); + static inline struct wine_device *wine_device_from_handle(VkDevice handle) { return (struct wine_device *)(uintptr_t)handle->base.unix_handle; @@ -143,25 +164,6 @@ static inline struct wine_phys_dev *wine_phys_dev_from_handle(VkPhysicalDevice h return (struct wine_phys_dev *)(uintptr_t)handle->base.unix_handle; }
-struct wine_queue -{ - struct wine_device *device; /* parent */ - - VkQueue handle; /* client queue */ - VkQueue host_queue; - - uint32_t family_index; - uint32_t queue_index; - VkDeviceQueueCreateFlags flags; - - struct wrapper_entry wrapper_entry; -}; - -static inline struct wine_queue *wine_queue_from_handle(VkQueue handle) -{ - return (struct wine_queue *)(uintptr_t)handle->base.unix_handle; -} - struct wine_cmd_pool { VkCommandPool handle;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 41 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 25 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index e41ff6a736d..434a487cd01 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -389,40 +389,41 @@ static void wine_vk_free_command_buffers(struct wine_device *device, } }
-static void wine_vk_device_get_queues(struct wine_device *device, - uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags, - struct wine_queue *queues, VkQueue *handles) +static void wine_vk_device_init_queues(struct wine_device *device, const VkDeviceQueueCreateInfo *info, + VkQueue *handles) { VkDeviceQueueInfo2 queue_info; - unsigned int i; + UINT i; + + TRACE("Queue family index %u, queue count %u.\n", info->queueFamilyIndex, info->queueCount);
- for (i = 0; i < queue_count; i++) + for (i = 0; i < info->queueCount; i++) { - struct wine_queue *queue = &queues[i]; + struct wine_queue *queue = device->queues + device->queue_count + i;
queue->device = device; queue->handle = (*handles)++; - queue->family_index = family_index; + queue->family_index = info->queueFamilyIndex; queue->queue_index = i; - queue->flags = flags; + queue->flags = info->flags;
/* The Vulkan spec says: * * "vkGetDeviceQueue must only be used to get queues that were created * with the flags parameter of VkDeviceQueueCreateInfo set to zero." */ - if (flags && device->funcs.p_vkGetDeviceQueue2) + if (info->flags && device->funcs.p_vkGetDeviceQueue2) { queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2; queue_info.pNext = NULL; - queue_info.flags = flags; - queue_info.queueFamilyIndex = family_index; + queue_info.flags = info->flags; + queue_info.queueFamilyIndex = info->queueFamilyIndex; queue_info.queueIndex = i; device->funcs.p_vkGetDeviceQueue2(device->host_device, &queue_info, &queue->host_queue); } else { - device->funcs.p_vkGetDeviceQueue(device->host_device, family_index, i, &queue->host_queue); + device->funcs.p_vkGetDeviceQueue(device->host_device, info->queueFamilyIndex, i, &queue->host_queue); }
queue->handle->base.unix_handle = (uintptr_t)queue; @@ -430,6 +431,8 @@ static void wine_vk_device_get_queues(struct wine_device *device,
TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->host_queue); } + + device->queue_count += info->queueCount; }
static const char *find_extension(const char *const *extensions, uint32_t count, const char *ext) @@ -806,7 +809,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre VkDevice device_handle = client_ptr; VkDeviceCreateInfo create_info_host; struct VkQueue_T *queue_handles; - struct wine_queue *next_queue; struct conversion_context ctx; struct wine_device *object; unsigned int queue_count, i; @@ -858,20 +860,9 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre ALL_VK_DEVICE_FUNCS() #undef USE_VK_FUNC
- next_queue = object->queues; queue_handles = device_handle->queues; for (i = 0; i < create_info_host.queueCreateInfoCount; i++) - { - uint32_t flags = create_info_host.pQueueCreateInfos[i].flags; - uint32_t family_index = create_info_host.pQueueCreateInfos[i].queueFamilyIndex; - uint32_t queue_count = create_info_host.pQueueCreateInfos[i].queueCount; - - TRACE("Queue family index %u, queue count %u.\n", family_index, queue_count); - - wine_vk_device_get_queues(object, family_index, queue_count, flags, next_queue, &queue_handles); - next_queue += queue_count; - } - object->queue_count = next_queue - object->queues; + wine_vk_device_init_queues(object, create_info_host.pQueueCreateInfos + i, &queue_handles);
device_handle->quirks = instance->quirks; device_handle->base.unix_handle = (uintptr_t)object;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 434a487cd01..78d40966e70 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -226,7 +226,7 @@ static void wine_vk_physical_device_free(struct wine_phys_dev *phys_dev) }
static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance *instance, - VkPhysicalDevice phys_dev, VkPhysicalDevice handle) + VkPhysicalDevice host_handle, VkPhysicalDevice client_handle) { BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE; struct wine_phys_dev *object; @@ -240,15 +240,15 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance return NULL;
object->instance = instance; - object->handle = handle; - object->host_physical_device = phys_dev; + object->handle = client_handle; + object->host_physical_device = host_handle;
- handle->base.unix_handle = (uintptr_t)object; - add_handle_mapping_ptr(instance, handle, phys_dev, &object->wrapper_entry); + client_handle->base.unix_handle = (uintptr_t)object; + add_handle_mapping_ptr(instance, client_handle, host_handle, &object->wrapper_entry);
- instance->funcs.p_vkGetPhysicalDeviceMemoryProperties(phys_dev, &object->memory_properties); + instance->funcs.p_vkGetPhysicalDeviceMemoryProperties(host_handle, &object->memory_properties);
- res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(phys_dev, + res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(host_handle, NULL, &num_host_properties, NULL); if (res != VK_SUCCESS) { @@ -263,7 +263,7 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance goto err; }
- res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(phys_dev, + res = instance->funcs.p_vkEnumerateDeviceExtensionProperties(host_handle, NULL, &num_host_properties, host_properties); if (res != VK_SUCCESS) { @@ -323,7 +323,7 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance .pNext = &map_placed_feature, };
- instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(phys_dev, &features); + instance->funcs.p_vkGetPhysicalDeviceFeatures2KHR(host_handle, &features); if (map_placed_feature.memoryMapPlaced && map_placed_feature.memoryUnmapReserve) { VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = @@ -336,7 +336,7 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance .pNext = &map_placed_props, };
- instance->funcs.p_vkGetPhysicalDeviceProperties2(phys_dev, &props); + instance->funcs.p_vkGetPhysicalDeviceProperties2(host_handle, &props); object->map_placed_align = map_placed_props.minPlacedMemoryMapAlignment; TRACE( "Using placed map with alignment %u\n", object->map_placed_align ); } @@ -353,7 +353,7 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = &host_mem_props, }; - instance->funcs.p_vkGetPhysicalDeviceProperties2KHR(phys_dev, &props); + instance->funcs.p_vkGetPhysicalDeviceProperties2KHR(host_handle, &props); object->external_memory_align = host_mem_props.minImportedHostPointerAlignment; if (object->external_memory_align) TRACE("Using VK_EXT_external_memory_host for memory mapping with alignment: %u\n", @@ -643,7 +643,7 @@ static VkResult wine_vk_instance_convert_create_info(struct conversion_context * /* Helper function which stores wrapped physical devices in the instance object. */ static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *instance) { - VkPhysicalDevice *tmp_phys_devs; + VkPhysicalDevice *host_handles; uint32_t phys_dev_count; unsigned int i; VkResult res; @@ -664,32 +664,32 @@ static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *ins } instance->handle->phys_dev_count = phys_dev_count;
- if (!(tmp_phys_devs = calloc(phys_dev_count, sizeof(*tmp_phys_devs)))) + if (!(host_handles = calloc(phys_dev_count, sizeof(*host_handles)))) return VK_ERROR_OUT_OF_HOST_MEMORY;
- res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->host_instance, &phys_dev_count, tmp_phys_devs); + res = instance->funcs.p_vkEnumeratePhysicalDevices(instance->host_instance, &phys_dev_count, host_handles); if (res != VK_SUCCESS) { - free(tmp_phys_devs); + free(host_handles); return res; }
instance->phys_devs = calloc(phys_dev_count, sizeof(*instance->phys_devs)); if (!instance->phys_devs) { - free(tmp_phys_devs); + free(host_handles); return VK_ERROR_OUT_OF_HOST_MEMORY; }
/* Wrap each host physical device handle into a dispatchable object for the ICD loader. */ for (i = 0; i < phys_dev_count; i++) { - struct wine_phys_dev *phys_dev = wine_vk_physical_device_alloc(instance, tmp_phys_devs[i], + struct wine_phys_dev *phys_dev = wine_vk_physical_device_alloc(instance, host_handles[i], &instance->handle->phys_devs[i]); if (!phys_dev) { ERR("Unable to allocate memory for physical device!\n"); - free(tmp_phys_devs); + free(host_handles); return VK_ERROR_OUT_OF_HOST_MEMORY; }
@@ -698,22 +698,22 @@ static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *ins } instance->phys_dev_count = phys_dev_count;
- free(tmp_phys_devs); + free(host_handles); return VK_SUCCESS; }
static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_instance *instance, - VkPhysicalDevice physical_device) + VkPhysicalDevice host_handle) { unsigned int i;
for (i = 0; i < instance->phys_dev_count; ++i) { struct wine_phys_dev *current = instance->phys_devs[i]; - if (current->host_physical_device == physical_device) return current; + if (current->host_physical_device == host_handle) return current; }
- ERR("Unrecognized physical device %p.\n", physical_device); + ERR("Unrecognized physical device %p.\n", host_handle); return NULL; }
@@ -1220,8 +1220,8 @@ static VkResult wine_vk_enumerate_physical_device_groups(struct wine_instance *i VkPhysicalDeviceGroupProperties *current = &properties[i]; for (j = 0; j < current->physicalDeviceCount; ++j) { - VkPhysicalDevice dev = current->physicalDevices[j]; - struct wine_phys_dev *phys_dev = wine_vk_instance_wrap_physical_device(instance, dev); + VkPhysicalDevice host_handle = current->physicalDevices[j]; + struct wine_phys_dev *phys_dev = wine_vk_instance_wrap_physical_device(instance, host_handle); if (!phys_dev) return VK_ERROR_INITIALIZATION_FAILED; current->physicalDevices[j] = phys_dev->handle;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 71 +++++++++++--------------------- dlls/winevulkan/vulkan_private.h | 58 +++++++++++++------------- 2 files changed, 54 insertions(+), 75 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 78d40966e70..2d43f81d98f 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -215,30 +215,22 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk return VK_FALSE; }
-static void wine_vk_physical_device_free(struct wine_phys_dev *phys_dev) +static void wine_phys_dev_cleanup(struct wine_phys_dev *phys_dev) { - if (!phys_dev) - return; - remove_handle_mapping(phys_dev->instance, &phys_dev->wrapper_entry); free(phys_dev->extensions); - free(phys_dev); }
-static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance *instance, - VkPhysicalDevice host_handle, VkPhysicalDevice client_handle) +static VkResult wine_vk_physical_device_init(struct wine_phys_dev *object, VkPhysicalDevice host_handle, + VkPhysicalDevice client_handle, struct wine_instance *instance) { BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE; - struct wine_phys_dev *object; uint32_t num_host_properties, num_properties = 0; VkExtensionProperties *host_properties = NULL; BOOL have_external_memory_host = FALSE; VkResult res; unsigned int i, j;
- if (!(object = calloc(1, sizeof(*object)))) - return NULL; - object->instance = instance; object->handle = client_handle; object->host_physical_device = host_handle; @@ -361,12 +353,12 @@ static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance }
free(host_properties); - return object; + return VK_SUCCESS;
err: - wine_vk_physical_device_free(object); + wine_phys_dev_cleanup(object); free(host_properties); - return NULL; + return res; }
static void wine_vk_free_command_buffers(struct wine_device *device, @@ -641,7 +633,7 @@ static VkResult wine_vk_instance_convert_create_info(struct conversion_context * }
/* Helper function which stores wrapped physical devices in the instance object. */ -static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *instance) +static VkResult wine_vk_instance_init_physical_devices(struct wine_instance *instance) { VkPhysicalDevice *host_handles; uint32_t phys_dev_count; @@ -674,32 +666,23 @@ static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *ins return res; }
- instance->phys_devs = calloc(phys_dev_count, sizeof(*instance->phys_devs)); - if (!instance->phys_devs) - { - free(host_handles); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - /* Wrap each host physical device handle into a dispatchable object for the ICD loader. */ for (i = 0; i < phys_dev_count; i++) { - struct wine_phys_dev *phys_dev = wine_vk_physical_device_alloc(instance, host_handles[i], - &instance->handle->phys_devs[i]); - if (!phys_dev) - { - ERR("Unable to allocate memory for physical device!\n"); - free(host_handles); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - instance->phys_devs[i] = phys_dev; - instance->phys_dev_count = i + 1; + struct wine_phys_dev *phys_dev = instance->phys_devs + i; + res = wine_vk_physical_device_init(phys_dev, host_handles[i], &instance->handle->phys_devs[i], instance); + if (res != VK_SUCCESS) + goto err; } instance->phys_dev_count = phys_dev_count;
free(host_handles); return VK_SUCCESS; + +err: + while (i) wine_phys_dev_cleanup(&instance->phys_devs[--i]); + free(host_handles); + return res; }
static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_instance *instance, @@ -709,7 +692,7 @@ static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_i
for (i = 0; i < instance->phys_dev_count; ++i) { - struct wine_phys_dev *current = instance->phys_devs[i]; + struct wine_phys_dev *current = instance->phys_devs + i; if (current->host_physical_device == host_handle) return current; }
@@ -722,19 +705,13 @@ static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_i */ static void wine_vk_instance_free(struct wine_instance *instance) { + unsigned int i; + if (!instance) return;
- if (instance->phys_devs) - { - unsigned int i; - - for (i = 0; i < instance->phys_dev_count; i++) - { - wine_vk_physical_device_free(instance->phys_devs[i]); - } - free(instance->phys_devs); - } + for (i = 0; i < instance->phys_dev_count; i++) + wine_phys_dev_cleanup(&instance->phys_devs[i]);
if (instance->host_instance) { @@ -890,7 +867,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, if (allocator) FIXME("Support for allocation callbacks not implemented yet\n");
- if (!(object = calloc(1, sizeof(*object)))) + if (!(object = calloc(1, offsetof(struct wine_instance, phys_devs[client_instance->phys_dev_count])))) { ERR("Failed to allocate memory for instance\n"); return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -927,7 +904,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, * the host physical devices and present those to the application. * Cleanup happens as part of wine_vkDestroyInstance. */ - res = wine_vk_instance_load_physical_devices(object); + res = wine_vk_instance_init_physical_devices(object); if (res != VK_SUCCESS) { ERR("Failed to load physical devices, res=%d\n", res); @@ -1101,7 +1078,7 @@ VkResult wine_vkEnumeratePhysicalDevices(VkInstance handle, uint32_t *count, VkP *count = min(*count, instance->phys_dev_count); for (i = 0; i < *count; i++) { - devices[i] = instance->phys_devs[i]->handle; + devices[i] = instance->phys_devs[i].handle; }
TRACE("Returning %u devices.\n", *count); diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h index 31e9e981168..f65b285e02a 100644 --- a/dlls/winevulkan/vulkan_private.h +++ b/dlls/winevulkan/vulkan_private.h @@ -109,6 +109,30 @@ struct wine_debug_report_callback struct wrapper_entry wrapper_entry; };
+struct wine_phys_dev +{ + struct wine_instance *instance; /* parent */ + + VkPhysicalDevice handle; /* client physical device */ + VkPhysicalDevice host_physical_device; + + VkPhysicalDeviceMemoryProperties memory_properties; + VkExtensionProperties *extensions; + uint32_t extension_count; + + uint32_t external_memory_align; + uint32_t map_placed_align; + + struct wrapper_entry wrapper_entry; +}; + +static inline struct wine_phys_dev *wine_phys_dev_from_handle(VkPhysicalDevice handle) +{ + return (struct wine_phys_dev *)(uintptr_t)handle->base.unix_handle; +} + +struct wine_debug_report_callback; + struct wine_instance { struct vulkan_instance_funcs funcs; @@ -116,12 +140,6 @@ struct wine_instance VkInstance handle; /* client instance */ VkInstance host_instance;
- /* We cache devices as we need to wrap them as they are - * dispatchable objects. - */ - struct wine_phys_dev **phys_devs; - uint32_t phys_dev_count; - VkBool32 enable_win32_surface; VkBool32 enable_wrapper_list; struct rb_tree wrappers; @@ -135,35 +153,19 @@ struct wine_instance unsigned int quirks;
struct wrapper_entry wrapper_entry; + + /* We cache devices as we need to wrap them as they are dispatchable objects. */ + uint32_t phys_dev_count; + struct wine_phys_dev phys_devs[]; };
+C_ASSERT(sizeof(struct wine_instance) == offsetof(struct wine_instance, phys_devs[0])); + static inline struct wine_instance *wine_instance_from_handle(VkInstance handle) { return (struct wine_instance *)(uintptr_t)handle->base.unix_handle; }
-struct wine_phys_dev -{ - struct wine_instance *instance; /* parent */ - - VkPhysicalDevice handle; /* client physical device */ - VkPhysicalDevice host_physical_device; - - VkPhysicalDeviceMemoryProperties memory_properties; - VkExtensionProperties *extensions; - uint32_t extension_count; - - uint32_t external_memory_align; - uint32_t map_placed_align; - - struct wrapper_entry wrapper_entry; -}; - -static inline struct wine_phys_dev *wine_phys_dev_from_handle(VkPhysicalDevice handle) -{ - return (struct wine_phys_dev *)(uintptr_t)handle->base.unix_handle; -} - struct wine_cmd_pool { VkCommandPool handle;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 91 +++++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 49 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 2d43f81d98f..a69c6c0c9cd 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -361,24 +361,11 @@ err: return res; }
-static void wine_vk_free_command_buffers(struct wine_device *device, - struct wine_cmd_pool *pool, uint32_t count, const VkCommandBuffer *buffers) +static void wine_cmd_buffer_destroy(struct wine_device *device, struct wine_cmd_buffer *buffer) { - unsigned int i; - - for (i = 0; i < count; i++) - { - struct wine_cmd_buffer *buffer = wine_cmd_buffer_from_handle(buffers[i]); - - if (!buffer) - continue; - - device->funcs.p_vkFreeCommandBuffers(device->host_device, pool->host_command_pool, 1, - &buffer->host_command_buffer); - remove_handle_mapping(device->phys_dev->instance, &buffer->wrapper_entry); - buffer->handle->base.unix_handle = 0; - free(buffer); - } + remove_handle_mapping(device->phys_dev->instance, &buffer->wrapper_entry); + buffer->handle->base.unix_handle = 0; + free(buffer); }
static void wine_vk_device_init_queues(struct wine_device *device, const VkDeviceQueueCreateInfo *info, @@ -727,54 +714,53 @@ static void wine_vk_instance_free(struct wine_instance *instance) }
VkResult wine_vkAllocateCommandBuffers(VkDevice handle, const VkCommandBufferAllocateInfo *allocate_info, - VkCommandBuffer *buffers ) + VkCommandBuffer *buffers) { + struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(allocate_info->commandPool); struct wine_device *device = wine_device_from_handle(handle); + VkCommandBufferAllocateInfo allocate_info_host; struct wine_cmd_buffer *buffer; - struct wine_cmd_pool *pool; + VkCommandBuffer *host_handles; VkResult res = VK_SUCCESS; - unsigned int i; + unsigned int i, buffer_count = allocate_info->commandBufferCount;
- pool = wine_cmd_pool_from_handle(allocate_info->commandPool); + TRACE("Allocating %u command buffer from pool %p.\n", buffer_count, pool);
- for (i = 0; i < allocate_info->commandBufferCount; i++) - { - VkCommandBufferAllocateInfo allocate_info_host; + if (!(host_handles = malloc(buffer_count * sizeof(*host_handles)))) return VK_ERROR_OUT_OF_HOST_MEMORY;
- /* TODO: future extensions (none yet) may require pNext conversion. */ - allocate_info_host.pNext = allocate_info->pNext; - allocate_info_host.sType = allocate_info->sType; - allocate_info_host.commandPool = pool->host_command_pool; - allocate_info_host.level = allocate_info->level; - allocate_info_host.commandBufferCount = 1; + /* TODO: future extensions (none yet) may require pNext conversion. */ + allocate_info_host.pNext = allocate_info->pNext; + allocate_info_host.sType = allocate_info->sType; + allocate_info_host.commandPool = pool->host_command_pool; + allocate_info_host.level = allocate_info->level; + allocate_info_host.commandBufferCount = buffer_count;
- TRACE("Allocating command buffer %u from pool 0x%s.\n", - i, wine_dbgstr_longlong(allocate_info_host.commandPool)); + if ((res = device->funcs.p_vkAllocateCommandBuffers(device->host_device, &allocate_info_host, host_handles)) != VK_SUCCESS) + { + ERR("Failed to allocate command buffers, res=%d.\n", res); + free(host_handles); + return res; + }
+ for (i = 0; i < buffer_count; i++) + { if (!(buffer = calloc(1, sizeof(*buffer)))) - { - res = VK_ERROR_OUT_OF_HOST_MEMORY; - break; - } - + goto err; buffer->handle = buffers[i]; buffer->device = device; - res = device->funcs.p_vkAllocateCommandBuffers(device->host_device, &allocate_info_host, - &buffer->host_command_buffer); + buffer->host_command_buffer = host_handles[i]; buffer->handle->base.unix_handle = (uintptr_t)buffer; add_handle_mapping_ptr(device->phys_dev->instance, buffer->handle, buffer->host_command_buffer, &buffer->wrapper_entry); - if (res != VK_SUCCESS) - { - ERR("Failed to allocate command buffer, res=%d.\n", res); - buffer->host_command_buffer = VK_NULL_HANDLE; - break; - } }
- if (res != VK_SUCCESS) - wine_vk_free_command_buffers(device, pool, i + 1, buffers); + free(host_handles); + return VK_SUCCESS;
- return res; +err: + device->funcs.p_vkFreeCommandBuffers(device->host_device, pool->host_command_pool, buffer_count, host_handles); + while (i) wine_cmd_buffer_destroy(device, wine_cmd_buffer_from_handle(buffers[--i])); + free(host_handles); + return VK_ERROR_OUT_OF_HOST_MEMORY; }
VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCreateInfo *create_info, @@ -1090,8 +1076,15 @@ void wine_vkFreeCommandBuffers(VkDevice handle, VkCommandPool command_pool, uint { struct wine_device *device = wine_device_from_handle(handle); struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(command_pool); + unsigned int i;
- wine_vk_free_command_buffers(device, pool, count, buffers); + for (i = 0; i < count; i++) + { + struct wine_cmd_buffer *buffer = wine_cmd_buffer_from_handle(buffers[i]); + device->funcs.p_vkFreeCommandBuffers(device->host_device, pool->host_command_pool, 1, + &buffer->host_command_buffer); + wine_cmd_buffer_destroy(device, buffer); + } }
static VkQueue wine_vk_device_find_queue(VkDevice handle, const VkDeviceQueueInfo2 *info)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 43 +++++++++++----------------------------- 1 file changed, 12 insertions(+), 31 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index a69c6c0c9cd..d245f338121 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -486,31 +486,6 @@ static VkResult wine_vk_device_convert_create_info(struct wine_phys_dev *phys_de return VK_SUCCESS; }
-/* Helper function used for freeing a device structure. This function supports full - * and partial object cleanups and can thus be used for vkCreateDevice failures. - */ -static void wine_vk_device_free(struct wine_device *device) -{ - unsigned int i; - - if (!device) - return; - - for (i = 0; i < device->queue_count; i++) - { - struct wine_queue *queue = device->queues + i; - if (queue->host_queue) remove_handle_mapping(device->phys_dev->instance, &queue->wrapper_entry); - } - - if (device->host_device && device->funcs.p_vkDestroyDevice) - { - remove_handle_mapping(device->phys_dev->instance, &device->wrapper_entry); - device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */); - } - - free(device); -} - NTSTATUS init_vulkan(void *args) { vk_funcs = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION); @@ -810,7 +785,9 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre if (res != VK_SUCCESS) { WARN("Failed to create device, res=%d.\n", res); - goto fail; + remove_handle_mapping(object->phys_dev->instance, &object->wrapper_entry); + free(object); + return res; }
/* Just load all function pointers we are aware off. The loader takes care of filtering. @@ -833,10 +810,6 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre
TRACE("Created device %p, host_device %p.\n", object, object->host_device); return VK_SUCCESS; - -fail: - wine_vk_device_free(object); - return res; }
VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, @@ -920,11 +893,19 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, void wine_vkDestroyDevice(VkDevice handle, const VkAllocationCallbacks *allocator) { struct wine_device *device = wine_device_from_handle(handle); + unsigned int i;
if (allocator) FIXME("Support for allocation callbacks not implemented yet\n"); + if (!device) + return;
- wine_vk_device_free(device); + for (i = 0; i < device->queue_count; i++) + remove_handle_mapping(device->phys_dev->instance, &device->queues[i].wrapper_entry); + remove_handle_mapping(device->phys_dev->instance, &device->wrapper_entry); + device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */); + + free(device); }
void wine_vkDestroyInstance(VkInstance handle, const VkAllocationCallbacks *allocator)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index d245f338121..ecd51cbb5fe 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -669,17 +669,11 @@ static void wine_vk_instance_free(struct wine_instance *instance) { unsigned int i;
- if (!instance) - return; - for (i = 0; i < instance->phys_dev_count; i++) wine_phys_dev_cleanup(&instance->phys_devs[i]);
- if (instance->host_instance) - { - vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); - remove_handle_mapping(instance, &instance->wrapper_entry); - } + vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); + remove_handle_mapping(instance, &instance->wrapper_entry);
pthread_rwlock_destroy(&instance->wrapper_lock); rb_destroy(&instance->wrappers, NULL, NULL); @@ -831,8 +825,6 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, ERR("Failed to allocate memory for instance\n"); return VK_ERROR_OUT_OF_HOST_MEMORY; } - rb_init(&object->wrappers, wrapper_entry_compare); - pthread_rwlock_init(&object->wrapper_lock, NULL);
init_conversion_context(&ctx); res = wine_vk_instance_convert_create_info(&ctx, create_info, &create_info_host, object); @@ -842,10 +834,14 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, if (res != VK_SUCCESS) { ERR("Failed to create instance, res=%d\n", res); - wine_vk_instance_free(object); + free(object->utils_messengers); + free(object); return res; }
+ rb_init(&object->wrappers, wrapper_entry_compare); + pthread_rwlock_init(&object->wrapper_lock, NULL); + object->handle = client_instance; add_handle_mapping_ptr(object, object->handle, object->host_instance, &object->wrapper_entry);
@@ -914,6 +910,8 @@ void wine_vkDestroyInstance(VkInstance handle, const VkAllocationCallbacks *allo
if (allocator) FIXME("Support allocation allocators\n"); + if (!instance) + return;
wine_vk_instance_free(instance); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index ecd51cbb5fe..72ce5278907 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -217,7 +217,6 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk
static void wine_phys_dev_cleanup(struct wine_phys_dev *phys_dev) { - remove_handle_mapping(phys_dev->instance, &phys_dev->wrapper_entry); free(phys_dev->extensions); }
@@ -236,7 +235,6 @@ static VkResult wine_vk_physical_device_init(struct wine_phys_dev *object, VkPhy object->host_physical_device = host_handle;
client_handle->base.unix_handle = (uintptr_t)object; - add_handle_mapping_ptr(instance, client_handle, host_handle, &object->wrapper_entry);
instance->funcs.p_vkGetPhysicalDeviceMemoryProperties(host_handle, &object->memory_properties);
@@ -406,8 +404,6 @@ static void wine_vk_device_init_queues(struct wine_device *device, const VkDevic }
queue->handle->base.unix_handle = (uintptr_t)queue; - add_handle_mapping_ptr(device->phys_dev->instance, queue->handle, queue->host_queue, &queue->wrapper_entry); - TRACE("Got device %p queue %p, host_queue %p.\n", device, queue, queue->host_queue); }
@@ -669,10 +665,12 @@ static void wine_vk_instance_free(struct wine_instance *instance) { unsigned int i;
+ vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); for (i = 0; i < instance->phys_dev_count; i++) + { + remove_handle_mapping(instance, &instance->phys_devs[i].wrapper_entry); wine_phys_dev_cleanup(&instance->phys_devs[i]); - - vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); + } remove_handle_mapping(instance, &instance->wrapper_entry);
pthread_rwlock_destroy(&instance->wrapper_lock); @@ -775,11 +773,9 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre res = instance->funcs.p_vkCreateDevice(phys_dev->host_physical_device, &create_info_host, NULL /* allocator */, &object->host_device); free_conversion_context(&ctx); - add_handle_mapping_ptr(instance, device_handle, object->host_device, &object->wrapper_entry); if (res != VK_SUCCESS) { WARN("Failed to create device, res=%d.\n", res); - remove_handle_mapping(object->phys_dev->instance, &object->wrapper_entry); free(object); return res; } @@ -800,9 +796,16 @@ VkResult wine_vkCreateDevice(VkPhysicalDevice phys_dev_handle, const VkDeviceCre
device_handle->quirks = instance->quirks; device_handle->base.unix_handle = (uintptr_t)object; - *ret_device = device_handle;
TRACE("Created device %p, host_device %p.\n", object, object->host_device); + for (i = 0; i < object->queue_count; i++) + { + struct wine_queue *queue = object->queues + i; + add_handle_mapping_ptr(instance, queue->handle, queue->host_queue, &queue->wrapper_entry); + } + + *ret_device = device_handle; + add_handle_mapping_ptr(instance, *ret_device, object->host_device, &object->wrapper_entry); return VK_SUCCESS; }
@@ -815,6 +818,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, const VkApplicationInfo *app_info; struct conversion_context ctx; struct wine_instance *object; + unsigned int i; VkResult res;
if (allocator) @@ -843,7 +847,6 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, pthread_rwlock_init(&object->wrapper_lock, NULL);
object->handle = client_instance; - add_handle_mapping_ptr(object, object->handle, object->host_instance, &object->wrapper_entry);
/* Load all instance functions we are aware of. Note the loader takes care * of any filtering for extensions which were not requested, but which the @@ -880,9 +883,16 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, }
client_instance->base.unix_handle = (uintptr_t)object; - *instance = client_instance; + TRACE("Created instance %p, host_instance %p.\n", object, object->host_instance); + for (i = 0; i < object->phys_dev_count; i++) + { + struct wine_phys_dev *phys_dev = &object->phys_devs[i]; + add_handle_mapping_ptr(object, phys_dev->handle, phys_dev->host_physical_device, &phys_dev->wrapper_entry); + }
+ *instance = client_instance; + add_handle_mapping_ptr(object, *instance, object->host_instance, &object->wrapper_entry); return VK_SUCCESS; }
@@ -896,10 +906,10 @@ void wine_vkDestroyDevice(VkDevice handle, const VkAllocationCallbacks *allocato if (!device) return;
+ device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */); for (i = 0; i < device->queue_count; i++) remove_handle_mapping(device->phys_dev->instance, &device->queues[i].wrapper_entry); remove_handle_mapping(device->phys_dev->instance, &device->wrapper_entry); - device->funcs.p_vkDestroyDevice(device->host_device, NULL /* pAllocator */);
free(device); } @@ -1148,8 +1158,8 @@ void wine_vkDestroyCommandPool(VkDevice device_handle, VkCommandPool handle, if (allocator) FIXME("Support for allocation callbacks not implemented yet\n");
- remove_handle_mapping(device->phys_dev->instance, &pool->wrapper_entry); device->funcs.p_vkDestroyCommandPool(device->host_device, pool->host_command_pool, NULL); + remove_handle_mapping(device->phys_dev->instance, &pool->wrapper_entry); free(pool); }
@@ -1726,8 +1736,8 @@ void wine_vkFreeMemory(VkDevice handle, VkDeviceMemory memory_handle, const VkAl device->funcs.p_vkUnmapMemory2KHR(device->host_device, &info); }
- remove_handle_mapping(device->phys_dev->instance, &memory->wrapper_entry); device->funcs.p_vkFreeMemory(device->host_device, memory->host_memory, NULL); + remove_handle_mapping(device->phys_dev->instance, &memory->wrapper_entry);
if (memory->vm_map) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winevulkan/vulkan.c | 48 ++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 27 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c index 72ce5278907..22913ed4414 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -658,28 +658,6 @@ static struct wine_phys_dev *wine_vk_instance_wrap_physical_device(struct wine_i return NULL; }
-/* Helper function used for freeing an instance structure. This function supports full - * and partial object cleanups and can thus be used for vkCreateInstance failures. - */ -static void wine_vk_instance_free(struct wine_instance *instance) -{ - unsigned int i; - - vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); - for (i = 0; i < instance->phys_dev_count; i++) - { - remove_handle_mapping(instance, &instance->phys_devs[i].wrapper_entry); - wine_phys_dev_cleanup(&instance->phys_devs[i]); - } - remove_handle_mapping(instance, &instance->wrapper_entry); - - pthread_rwlock_destroy(&instance->wrapper_lock); - rb_destroy(&instance->wrappers, NULL, NULL); - free(instance->utils_messengers); - - free(instance); -} - VkResult wine_vkAllocateCommandBuffers(VkDevice handle, const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers) { @@ -843,9 +821,6 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, return res; }
- rb_init(&object->wrappers, wrapper_entry_compare); - pthread_rwlock_init(&object->wrapper_lock, NULL); - object->handle = client_instance;
/* Load all instance functions we are aware of. Note the loader takes care @@ -866,7 +841,9 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, if (res != VK_SUCCESS) { ERR("Failed to load physical devices, res=%d\n", res); - wine_vk_instance_free(object); + vk_funcs->p_vkDestroyInstance(object->host_instance, NULL /* allocator */); + free(object->utils_messengers); + free(object); return res; }
@@ -885,6 +862,10 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info, client_instance->base.unix_handle = (uintptr_t)object;
TRACE("Created instance %p, host_instance %p.\n", object, object->host_instance); + + rb_init(&object->wrappers, wrapper_entry_compare); + pthread_rwlock_init(&object->wrapper_lock, NULL); + for (i = 0; i < object->phys_dev_count; i++) { struct wine_phys_dev *phys_dev = &object->phys_devs[i]; @@ -917,13 +898,26 @@ void wine_vkDestroyDevice(VkDevice handle, const VkAllocationCallbacks *allocato void wine_vkDestroyInstance(VkInstance handle, const VkAllocationCallbacks *allocator) { struct wine_instance *instance = wine_instance_from_handle(handle); + unsigned int i;
if (allocator) FIXME("Support allocation allocators\n"); if (!instance) return;
- wine_vk_instance_free(instance); + vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */); + for (i = 0; i < instance->phys_dev_count; i++) + { + remove_handle_mapping(instance, &instance->phys_devs[i].wrapper_entry); + wine_phys_dev_cleanup(&instance->phys_devs[i]); + } + remove_handle_mapping(instance, &instance->wrapper_entry); + + pthread_rwlock_destroy(&instance->wrapper_lock); + rb_destroy(&instance->wrappers, NULL, NULL); + + free(instance->utils_messengers); + free(instance); }
VkResult wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice phys_dev_handle, const char *layer_name,
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144028
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3dx10_34: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011B75E0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B75E0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011946B0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001194880. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B75E0.
d3dx10_35: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BBC50. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011F11F0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011F11F0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D3E00. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E3F30.
d3dx10_36: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011D1D50. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011F0D30. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011F0DF0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D1F20. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001195A10.
d3dx10_37: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239E10. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239E10. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001239E10. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001239E10. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E34D0.
d3dx10_38: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011A45D0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011A47A0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D19A0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011A47A0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011C3380.
d3dx10_39: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011D5730. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D5730. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011C36C0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011C3890. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001195C00.
d3dx10_40: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BBA30. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D57C0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011BCA30. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B2480. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E2E90.
d3dx10_41: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239F30. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239F30. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011C3D50. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001239F30. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011BFEB0.
d3dx10_42: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011C3710. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C3710. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D6590. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D6760. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D1820.
d3dx10_43: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239F90. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011C3550. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E37D0.
Updated with the other changes I had in that area, pretty much repurposing this MR to some allocation and mapping refactoring.
On Wed Mar 13 16:41:46 2024 +0000, Rémi Bernon wrote:
Well you still have object types and handles during construction, so callbacks could still be understandable. Whereas in Wine we simply cannot map these to any client handle because we don't yet have the mapping, so these callbacks are simply dropped.
I changed this to consistently remove the mapping *after* the destruction.
On Wed Mar 13 18:38:29 2024 +0000, Rémi Bernon wrote:
I changed this to consistently remove the mapping *after* the destruction.
Although another thing to consider with removing the mappings after the destruction is that this becomes racy if the host handle being destroyed is reused for a different object created in another thread before the destroying thread had a chance to remove its mapping. Not very likely but still.
Jacek Caban (@jacek) commented about dlls/winevulkan/vulkan.c:
if (instance->host_instance) { vk_funcs->p_vkDestroyInstance(instance->host_instance, NULL /* allocator */);
WINE_VK_REMOVE_HANDLE_MAPPING(instance, instance);
remove_handle_mapping(instance, &instance->wrapper_entry);
}
pthread_rwlock_destroy(&instance->wrapper_lock);
rb_destroy(&instance->wrappers, NULL, NULL);
This is redundant.
Jacek Caban (@jacek) commented about dlls/winevulkan/vulkan.c:
static const struct vulkan_funcs *vk_funcs;
-#define WINE_VK_ADD_DISPATCHABLE_MAPPING(instance, client_handle, host_handle, object) \
- wine_vk_add_handle_mapping((instance), (uintptr_t)(client_handle), (uintptr_t)(host_handle), &(object)->mapping)
-#define WINE_VK_ADD_NON_DISPATCHABLE_MAPPING(instance, client_handle, host_handle, object) \
- wine_vk_add_handle_mapping((instance), (uintptr_t)(client_handle), (host_handle), &(object)->mapping)
-static void wine_vk_add_handle_mapping(struct wine_instance *instance, uint64_t wrapped_handle,
uint64_t host_handle, struct wine_vk_mapping *mapping)
+static int wrapper_entry_compare(const void *key, const struct rb_entry *entry) +{
- struct wrapper_entry *wrapper = RB_ENTRY_VALUE(entry, struct wrapper_entry, entry);
- const uint64_t *host_handle = key;
- return *host_handle - wrapper->host_handle;
This is not enough, the result is truncated to int.
I also don't see what command buffers allocation achieves, but it's not wrong, so that's probably fine.
On Thu Mar 14 09:40:00 2024 +0000, Rémi Bernon wrote:
Although another thing to consider with removing the mappings after the destruction is that this becomes racy if the host handle being destroyed is reused for a different object created in another thread before the destroying thread had a chance to remove its mapping. Not very likely but still.
Yes, but that should be easy to fix. When adding a new mapping, we may remove the existing one. We'd also need to check if we're still a valid handle when removing it.