Module: wine Branch: master Commit: aaeb221f52052f870fee4b3c59ef4694aaaa7b08 URL: https://gitlab.winehq.org/wine/wine/-/commit/aaeb221f52052f870fee4b3c59ef469...
Author: Rémi Bernon rbernon@codeweavers.com Date: Wed Mar 13 18:06:49 2024 +0100
winevulkan: Use a single allocation for instance and physical devices.
---
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 6df610e7e36..b2c386dbd2a 100644 --- a/dlls/winevulkan/vulkan.c +++ b/dlls/winevulkan/vulkan.c @@ -217,30 +217,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; @@ -363,12 +355,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, @@ -643,7 +635,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; @@ -676,32 +668,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, @@ -711,7 +694,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; }
@@ -724,19 +707,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) { @@ -891,7 +868,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; @@ -928,7 +905,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); @@ -1102,7 +1079,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;