venus: refactor vn_device_memory to prepare for async alloc
authorYiwei Zhang <zzyiwei@chromium.org>
Sun, 8 Oct 2023 08:13:08 +0000 (01:13 -0700)
committerMarge Bot <emma+marge@anholt.net>
Tue, 10 Oct 2023 01:59:34 +0000 (01:59 +0000)
Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25611>

src/virtio/vulkan/vn_device_memory.c

index ebb1998..4149990 100644 (file)
 
 /* 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)