Module: wine Branch: master Commit: 5ef47e916ade51dc6634c5d5bdbe9e0c65949de3 URL: https://gitlab.winehq.org/wine/wine/-/commit/5ef47e916ade51dc6634c5d5bdbe9e0...
Author: Rémi Bernon rbernon@codeweavers.com Date: Wed Mar 13 17:53:19 2024 +0100
winevulkan: Use a single allocation for device and queues.
---
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 39ecf1698b2..a6169f4f824 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -511,22 +511,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) @@ -817,7 +810,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) @@ -834,7 +827,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; @@ -862,20 +859,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++) @@ -889,6 +872,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;