diff --git a/src/virtio/vulkan/vn_physical_device.c b/src/virtio/vulkan/vn_physical_device.c index 6ce785dd138..858f58626dd 100644 --- a/src/virtio/vulkan/vn_physical_device.c +++ b/src/virtio/vulkan/vn_physical_device.c @@ -1259,40 +1259,32 @@ vn_instance_enumerate_physical_device_groups_locked( } static VkResult -vn_instance_enumerate_physical_devices(struct vn_instance *instance) +enumerate_physical_devices(struct vn_instance *instance, + struct vn_physical_device **out_physical_devs, + uint32_t *out_count) { const VkAllocationCallbacks *alloc = &instance->base.base.alloc; struct vn_physical_device *physical_devs = NULL; + VkPhysicalDevice *handles = NULL; VkResult result; - mtx_lock(&instance->physical_device.mutex); - - if (instance->physical_device.initialized) { - result = VK_SUCCESS; - goto out; - } - instance->physical_device.initialized = true; - uint32_t count; result = vn_call_vkEnumeratePhysicalDevices( instance, vn_instance_to_handle(instance), &count, NULL); if (result != VK_SUCCESS || !count) - goto out; + return result; physical_devs = vk_zalloc(alloc, sizeof(*physical_devs) * count, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); - if (!physical_devs) { - result = VK_ERROR_OUT_OF_HOST_MEMORY; - goto out; - } + if (!physical_devs) + return VK_ERROR_OUT_OF_HOST_MEMORY; - VkPhysicalDevice *handles = - vk_alloc(alloc, sizeof(*handles) * count, VN_DEFAULT_ALIGN, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); + handles = vk_alloc(alloc, sizeof(*handles) * count, VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); if (!handles) { - result = VK_ERROR_OUT_OF_HOST_MEMORY; - goto out; + vk_free(alloc, physical_devs); + return VK_ERROR_OUT_OF_HOST_MEMORY; } for (uint32_t i = 0; i < count; i++) { @@ -1305,7 +1297,7 @@ vn_instance_enumerate_physical_devices(struct vn_instance *instance) &physical_dev->base, &instance->base, NULL, &dispatch_table); if (result != VK_SUCCESS) { count = i; - goto out; + goto fail; } physical_dev->instance = instance; @@ -1315,8 +1307,38 @@ vn_instance_enumerate_physical_devices(struct vn_instance *instance) result = vn_call_vkEnumeratePhysicalDevices( instance, vn_instance_to_handle(instance), &count, handles); - vk_free(alloc, handles); + if (result != VK_SUCCESS) + goto fail; + vk_free(alloc, handles); + *out_physical_devs = physical_devs; + *out_count = count; + + return VK_SUCCESS; + +fail: + for (uint32_t i = 0; i < count; i++) + vn_physical_device_base_fini(&physical_devs[i].base); + vk_free(alloc, physical_devs); + vk_free(alloc, handles); + return result; +} + +static VkResult +vn_instance_enumerate_physical_devices_and_groups(struct vn_instance *instance) +{ + const VkAllocationCallbacks *alloc = &instance->base.base.alloc; + struct vn_physical_device *physical_devs = NULL; + uint32_t count = 0; + VkResult result = VK_SUCCESS; + + mtx_lock(&instance->physical_device.mutex); + + if (instance->physical_device.initialized) + goto out; + instance->physical_device.initialized = true; + + result = enumerate_physical_devices(instance, &physical_devs, &count); if (result != VK_SUCCESS) goto out; @@ -1343,7 +1365,6 @@ vn_instance_enumerate_physical_devices(struct vn_instance *instance) if (result != VK_SUCCESS) { for (uint32_t i = 0; i < count; i++) vn_physical_device_fini(&physical_devs[i]); - count = 0; goto out; } } else { @@ -1357,11 +1378,8 @@ vn_instance_enumerate_physical_devices(struct vn_instance *instance) instance->physical_device.device_count = count; out: - if (result != VK_SUCCESS && physical_devs) { - for (uint32_t i = 0; i < count; i++) - vn_physical_device_base_fini(&physical_devs[i].base); + if (result != VK_SUCCESS && physical_devs) vk_free(alloc, physical_devs); - } mtx_unlock(&instance->physical_device.mutex); return result; @@ -1376,7 +1394,8 @@ vn_EnumeratePhysicalDevices(VkInstance _instance, { struct vn_instance *instance = vn_instance_from_handle(_instance); - VkResult result = vn_instance_enumerate_physical_devices(instance); + VkResult result = + vn_instance_enumerate_physical_devices_and_groups(instance); if (result != VK_SUCCESS) return vn_error(instance, result); @@ -1399,7 +1418,8 @@ vn_EnumeratePhysicalDeviceGroups( { struct vn_instance *instance = vn_instance_from_handle(_instance); - VkResult result = vn_instance_enumerate_physical_devices(instance); + VkResult result = + vn_instance_enumerate_physical_devices_and_groups(instance); if (result != VK_SUCCESS) return vn_error(instance, result);