mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
winevulkan: Use a single allocation for instance and physical devices.
This commit is contained in:
parent
bda48ed85e
commit
aaeb221f52
2 changed files with 59 additions and 80 deletions
|
@ -217,30 +217,22 @@ static VkBool32 debug_report_callback_conversion(VkDebugReportFlagsEXT flags, Vk
|
||||||
return VK_FALSE;
|
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);
|
remove_handle_mapping(phys_dev->instance, &phys_dev->wrapper_entry);
|
||||||
free(phys_dev->extensions);
|
free(phys_dev->extensions);
|
||||||
free(phys_dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wine_phys_dev *wine_vk_physical_device_alloc(struct wine_instance *instance,
|
static VkResult wine_vk_physical_device_init(struct wine_phys_dev *object, VkPhysicalDevice host_handle,
|
||||||
VkPhysicalDevice host_handle, VkPhysicalDevice client_handle)
|
VkPhysicalDevice client_handle, struct wine_instance *instance)
|
||||||
{
|
{
|
||||||
BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE;
|
BOOL have_memory_placed = FALSE, have_map_memory2 = FALSE;
|
||||||
struct wine_phys_dev *object;
|
|
||||||
uint32_t num_host_properties, num_properties = 0;
|
uint32_t num_host_properties, num_properties = 0;
|
||||||
VkExtensionProperties *host_properties = NULL;
|
VkExtensionProperties *host_properties = NULL;
|
||||||
BOOL have_external_memory_host = FALSE;
|
BOOL have_external_memory_host = FALSE;
|
||||||
VkResult res;
|
VkResult res;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
if (!(object = calloc(1, sizeof(*object))))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
object->instance = instance;
|
object->instance = instance;
|
||||||
object->handle = client_handle;
|
object->handle = client_handle;
|
||||||
object->host_physical_device = host_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);
|
free(host_properties);
|
||||||
return object;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
wine_vk_physical_device_free(object);
|
wine_phys_dev_cleanup(object);
|
||||||
free(host_properties);
|
free(host_properties);
|
||||||
return NULL;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wine_vk_free_command_buffers(struct wine_device *device,
|
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. */
|
/* 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;
|
VkPhysicalDevice *host_handles;
|
||||||
uint32_t phys_dev_count;
|
uint32_t phys_dev_count;
|
||||||
|
@ -676,32 +668,23 @@ static VkResult wine_vk_instance_load_physical_devices(struct wine_instance *ins
|
||||||
return res;
|
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. */
|
/* Wrap each host physical device handle into a dispatchable object for the ICD loader. */
|
||||||
for (i = 0; i < phys_dev_count; i++)
|
for (i = 0; i < phys_dev_count; i++)
|
||||||
{
|
{
|
||||||
struct wine_phys_dev *phys_dev = wine_vk_physical_device_alloc(instance, host_handles[i],
|
struct wine_phys_dev *phys_dev = instance->phys_devs + i;
|
||||||
&instance->handle->phys_devs[i]);
|
res = wine_vk_physical_device_init(phys_dev, host_handles[i], &instance->handle->phys_devs[i], instance);
|
||||||
if (!phys_dev)
|
if (res != VK_SUCCESS)
|
||||||
{
|
goto err;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
instance->phys_dev_count = phys_dev_count;
|
instance->phys_dev_count = phys_dev_count;
|
||||||
|
|
||||||
free(host_handles);
|
free(host_handles);
|
||||||
return VK_SUCCESS;
|
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,
|
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)
|
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;
|
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)
|
static void wine_vk_instance_free(struct wine_instance *instance)
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
if (!instance)
|
if (!instance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (instance->phys_devs)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < instance->phys_dev_count; i++)
|
for (i = 0; i < instance->phys_dev_count; i++)
|
||||||
{
|
wine_phys_dev_cleanup(&instance->phys_devs[i]);
|
||||||
wine_vk_physical_device_free(instance->phys_devs[i]);
|
|
||||||
}
|
|
||||||
free(instance->phys_devs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance->host_instance)
|
if (instance->host_instance)
|
||||||
{
|
{
|
||||||
|
@ -891,7 +868,7 @@ VkResult wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
|
||||||
if (allocator)
|
if (allocator)
|
||||||
FIXME("Support for allocation callbacks not implemented yet\n");
|
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");
|
ERR("Failed to allocate memory for instance\n");
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
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.
|
* the host physical devices and present those to the application.
|
||||||
* Cleanup happens as part of wine_vkDestroyInstance.
|
* 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)
|
if (res != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
ERR("Failed to load physical devices, res=%d\n", res);
|
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);
|
*count = min(*count, instance->phys_dev_count);
|
||||||
for (i = 0; i < *count; i++)
|
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);
|
TRACE("Returning %u devices.\n", *count);
|
||||||
|
|
|
@ -109,39 +109,6 @@ struct wine_debug_report_callback
|
||||||
struct wrapper_entry wrapper_entry;
|
struct wrapper_entry wrapper_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wine_instance
|
|
||||||
{
|
|
||||||
struct vulkan_instance_funcs funcs;
|
|
||||||
|
|
||||||
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;
|
|
||||||
pthread_rwlock_t wrapper_lock;
|
|
||||||
|
|
||||||
struct wine_debug_utils_messenger *utils_messengers;
|
|
||||||
uint32_t utils_messenger_count;
|
|
||||||
|
|
||||||
struct wine_debug_report_callback default_callback;
|
|
||||||
|
|
||||||
unsigned int quirks;
|
|
||||||
|
|
||||||
struct wrapper_entry wrapper_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
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_phys_dev
|
||||||
{
|
{
|
||||||
struct wine_instance *instance; /* parent */
|
struct wine_instance *instance; /* parent */
|
||||||
|
@ -164,6 +131,41 @@ static inline struct wine_phys_dev *wine_phys_dev_from_handle(VkPhysicalDevice h
|
||||||
return (struct wine_phys_dev *)(uintptr_t)handle->base.unix_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;
|
||||||
|
|
||||||
|
VkInstance handle; /* client instance */
|
||||||
|
VkInstance host_instance;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
struct wine_debug_report_callback default_callback;
|
||||||
|
|
||||||
|
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_cmd_pool
|
struct wine_cmd_pool
|
||||||
{
|
{
|
||||||
VkCommandPool handle;
|
VkCommandPool handle;
|
||||||
|
|
Loading…
Reference in a new issue