From 95d90cdf3d31e3a5e5af81d1134bb821f0c37dfd Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Sun, 8 Oct 2023 01:13:08 -0700 Subject: [PATCH] venus: refactor vn_device_memory to prepare for async alloc Signed-off-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_device_memory.c | 146 ++++++++++++++++------------------- 1 file changed, 68 insertions(+), 78 deletions(-) diff --git a/src/virtio/vulkan/vn_device_memory.c b/src/virtio/vulkan/vn_device_memory.c index ebb1998..4149990 100644 --- a/src/virtio/vulkan/vn_device_memory.c +++ b/src/virtio/vulkan/vn_device_memory.c @@ -21,20 +21,41 @@ /* device memory commands */ +static inline VkResult +vn_device_memory_alloc_simple(struct vn_device *dev, + struct vn_device_memory *mem, + const VkMemoryAllocateInfo *alloc_info) +{ + VkDevice dev_handle = vn_device_to_handle(dev); + VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); + return vn_call_vkAllocateMemory(dev->instance, dev_handle, alloc_info, + NULL, &mem_handle); +} + +static inline void +vn_device_memory_free_simple(struct vn_device *dev, + struct vn_device_memory *mem) +{ + VkDevice dev_handle = vn_device_to_handle(dev); + VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); + vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); +} + static VkResult vn_device_memory_pool_grow_alloc(struct vn_device *dev, uint32_t mem_type_index, VkDeviceSize size, struct vn_device_memory **out_mem) { - VkDevice dev_handle = vn_device_to_handle(dev); const VkAllocationCallbacks *alloc = &dev->base.base.alloc; - struct vn_device_memory *mem = NULL; - VkDeviceMemory mem_handle = VK_NULL_HANDLE; - VkResult result; - - mem = vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); + const VkMemoryAllocateInfo alloc_info = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = size, + .memoryTypeIndex = mem_type_index, + }; + struct vn_device_memory *mem = + vk_zalloc(alloc, sizeof(*mem), VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); if (!mem) return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -43,43 +64,31 @@ vn_device_memory_pool_grow_alloc(struct vn_device *dev, mem->type = dev->physical_device->memory_properties.memoryTypes[mem_type_index]; - mem_handle = vn_device_memory_to_handle(mem); - result = vn_call_vkAllocateMemory( - dev->instance, dev_handle, - &(const VkMemoryAllocateInfo){ - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = size, - .memoryTypeIndex = mem_type_index, - }, - NULL, &mem_handle); - if (result != VK_SUCCESS) { - mem_handle = VK_NULL_HANDLE; - goto fail; - } + VkResult result = vn_device_memory_alloc_simple(dev, mem, &alloc_info); + if (result != VK_SUCCESS) + goto obj_fini; result = vn_renderer_bo_create_from_device_memory( dev->renderer, mem->size, mem->base.id, mem->type.propertyFlags, 0, &mem->base_bo); - if (result != VK_SUCCESS) { - assert(!mem->base_bo); - goto fail; - } + if (result != VK_SUCCESS) + goto mem_free; result = vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); if (result != VK_SUCCESS) - goto fail; + goto bo_unref; mem->bo_roundtrip_seqno_valid = true; *out_mem = mem; return VK_SUCCESS; -fail: - if (mem->base_bo) - vn_renderer_bo_unref(dev->renderer, mem->base_bo); - if (mem_handle != VK_NULL_HANDLE) - vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); +bo_unref: + vn_renderer_bo_unref(dev->renderer, mem->base_bo); +mem_free: + vn_device_memory_free_simple(dev, mem); +obj_fini: vn_object_base_fini(&mem->base); vk_free(alloc, mem); return result; @@ -111,8 +120,7 @@ vn_device_memory_pool_unref(struct vn_device *dev, if (pool_mem->bo_roundtrip_seqno_valid) vn_instance_wait_roundtrip(dev->instance, pool_mem->bo_roundtrip_seqno); - vn_async_vkFreeMemory(dev->instance, vn_device_to_handle(dev), - vn_device_memory_to_handle(pool_mem), NULL); + vn_device_memory_free_simple(dev, pool_mem); vn_object_base_fini(&pool_mem->base); vk_free(alloc, pool_mem); } @@ -152,16 +160,15 @@ vn_device_memory_pool_suballocate(struct vn_device *dev, struct vn_device_memory *mem, uint32_t mem_type_index) { - const VkDeviceSize pool_size = 16 * 1024 * 1024; + static const VkDeviceSize pool_size = 16 * 1024 * 1024; /* TODO fix https://gitlab.freedesktop.org/mesa/mesa/-/issues/9351 * Before that, we use 64K default alignment because some GPUs have 64K * pages. It is also required by newer Intel GPUs. Meanwhile, use prior 4K * align on implementations known to fit. */ - const VkDeviceSize pool_align = - dev->physical_device->renderer_driver_id == VK_DRIVER_ID_ARM_PROPRIETARY - ? 4096 - : 64 * 1024; + const bool is_renderer_mali = dev->physical_device->renderer_driver_id == + VK_DRIVER_ID_ARM_PROPRIETARY; + const VkDeviceSize pool_align = is_renderer_mali ? 4096 : 64 * 1024; struct vn_device_memory_pool *pool = &dev->memory_pools[mem_type_index]; assert(mem->size <= pool_size); @@ -250,26 +257,19 @@ vn_device_memory_import_dma_buf(struct vn_device *dev, bool force_unmappable, int fd) { - VkDevice device = vn_device_to_handle(dev); - VkDeviceMemory memory = vn_device_memory_to_handle(mem); - const VkPhysicalDeviceMemoryProperties *mem_props = - &dev->physical_device->memory_properties; - VkMemoryPropertyFlags mem_flags = - mem_props->memoryTypes[alloc_info->memoryTypeIndex].propertyFlags; - struct vn_renderer_bo *bo; - VkResult result = VK_SUCCESS; - - if (force_unmappable) - mem_flags &= ~VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + const VkMemoryType *mem_type = + &dev->physical_device->memory_properties + .memoryTypes[alloc_info->memoryTypeIndex]; - result = vn_renderer_bo_create_from_dma_buf( - dev->renderer, alloc_info->allocationSize, fd, mem_flags, &bo); + struct vn_renderer_bo *bo; + VkResult result = vn_renderer_bo_create_from_dma_buf( + dev->renderer, alloc_info->allocationSize, fd, + force_unmappable ? 0 : mem_type->propertyFlags, &bo); if (result != VK_SUCCESS) return result; vn_instance_roundtrip(dev->instance); - /* XXX fix VkImportMemoryResourceInfoMESA to support memory planes */ const VkImportMemoryResourceInfoMESA import_memory_resource_info = { .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_RESOURCE_INFO_MESA, .pNext = alloc_info->pNext, @@ -281,8 +281,7 @@ vn_device_memory_import_dma_buf(struct vn_device *dev, .allocationSize = alloc_info->allocationSize, .memoryTypeIndex = alloc_info->memoryTypeIndex, }; - result = vn_call_vkAllocateMemory(dev->instance, device, - &memory_allocate_info, NULL, &memory); + result = vn_device_memory_alloc_simple(dev, mem, &memory_allocate_info); if (result != VK_SUCCESS) { vn_renderer_bo_unref(dev->renderer, bo); return result; @@ -302,11 +301,7 @@ vn_device_memory_alloc_guest_vram( const VkMemoryAllocateInfo *alloc_info, VkExternalMemoryHandleTypeFlags external_handles) { - VkDevice dev_handle = vn_device_to_handle(dev); - VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); - VkResult result = VK_SUCCESS; - - result = vn_renderer_bo_create_from_device_memory( + VkResult result = vn_renderer_bo_create_from_device_memory( dev->renderer, mem->size, 0, mem->type.propertyFlags, external_handles, &mem->base_bo); if (result != VK_SUCCESS) { @@ -328,8 +323,7 @@ vn_device_memory_alloc_guest_vram( vn_instance_roundtrip(dev->instance); - result = vn_call_vkAllocateMemory( - dev->instance, dev_handle, &memory_allocate_info, NULL, &mem_handle); + result = vn_device_memory_alloc_simple(dev, mem, &memory_allocate_info); if (result != VK_SUCCESS) { vn_renderer_bo_unref(dev->renderer, mem->base_bo); return result; @@ -339,26 +333,20 @@ vn_device_memory_alloc_guest_vram( } static VkResult -vn_device_memory_alloc_generic( - struct vn_device *dev, - struct vn_device_memory *mem, - const VkMemoryAllocateInfo *alloc_info, - VkExternalMemoryHandleTypeFlags external_handles) +vn_device_memory_alloc_export(struct vn_device *dev, + struct vn_device_memory *mem, + const VkMemoryAllocateInfo *alloc_info, + VkExternalMemoryHandleTypeFlags external_handles) { - VkDevice dev_handle = vn_device_to_handle(dev); - VkDeviceMemory mem_handle = vn_device_memory_to_handle(mem); - VkResult result = VK_SUCCESS; - - result = vn_call_vkAllocateMemory(dev->instance, dev_handle, alloc_info, - NULL, &mem_handle); - if (result != VK_SUCCESS || !external_handles) + VkResult result = vn_device_memory_alloc_simple(dev, mem, alloc_info); + if (result != VK_SUCCESS) return result; result = vn_renderer_bo_create_from_device_memory( dev->renderer, mem->size, mem->base.id, mem->type.propertyFlags, external_handles, &mem->base_bo); if (result != VK_SUCCESS) { - vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); + vn_device_memory_free_simple(dev, mem); return result; } @@ -366,7 +354,7 @@ vn_device_memory_alloc_generic( vn_instance_submit_roundtrip(dev->instance, &mem->bo_roundtrip_seqno); if (result != VK_SUCCESS) { vn_renderer_bo_unref(dev->renderer, mem->base_bo); - vn_async_vkFreeMemory(dev->instance, dev_handle, mem_handle, NULL); + vn_device_memory_free_simple(dev, mem); return result; } @@ -455,10 +443,12 @@ vn_device_memory_alloc(struct vn_device *dev, if (renderer_info->has_guest_vram) { return vn_device_memory_alloc_guest_vram(dev, mem, alloc_info, external_handles); + } else if (external_handles) { + return vn_device_memory_alloc_export(dev, mem, alloc_info, + external_handles); + } else { + return vn_device_memory_alloc_simple(dev, mem, alloc_info); } - - return vn_device_memory_alloc_generic(dev, mem, alloc_info, - external_handles); } static void @@ -603,7 +593,7 @@ vn_FreeMemory(VkDevice device, if (mem->bo_roundtrip_seqno_valid) vn_instance_wait_roundtrip(dev->instance, mem->bo_roundtrip_seqno); - vn_async_vkFreeMemory(dev->instance, device, memory, NULL); + vn_device_memory_free_simple(dev, mem); } if (mem->ahb) -- 2.7.4