Mesa (main): venus: fix mismatched bo mmap_size for export and multiple imports

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat May 29 04:55:24 UTC 2021


Module: Mesa
Branch: main
Commit: 60f513279cf8713a1e241d8b0edde18ea3c271e3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=60f513279cf8713a1e241d8b0edde18ea3c271e3

Author: Yiwei Zhang <zzyiwei at chromium.org>
Date:   Fri May 28 05:00:24 2021 +0000

venus: fix mismatched bo mmap_size for export and multiple imports

Spec requires apps to use the size returned from
vkGetAndroidHardwareBufferPropertiesANDROID for AHB import, which
includes dedicated image/buffer import and non-dedicated buffer import.

Spec requires venus to use the size from image and buffer memory
requirement for dma_buf fd import if it's dedicated. If not dedicated,
the actual payload size should be used.

For AHB export allocation of VkImage, the app provided size will be 0,
and internally we must use the size from image memory requirement.

For AHB export allocation of VkBuffer, the app provided size comes from
buffer memory requirements and it can be smaller than the actual AHB
size due to page alignment. Internally that's the size we must use.

For AHB import, app must use the size from AHB prop query. Internally,
we have to override that with the size from memory requirement if the
import operation is dedicated to a VkImage or a VkBuffer. If not
dedicated, the actual payload size should be used.

The not working scenario is:
1. App creates an AHB backed VkBuffer, and the exported AHB size is
   larger than the buffer memory requirement (very common).
2. App imports the AHB without a dedicated VkBuffer. Then the entire
   AHB payload will be imported and the mmap_size might increase.

Test: dEQP-VK.api.external.memory.android_hardware_buffer.*

Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Chia-I Wu <olvaffe at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11055>

---

 src/virtio/vulkan/vn_android.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c
index 0311a5807f4..7b834df8912 100644
--- a/src/virtio/vulkan/vn_android.c
+++ b/src/virtio/vulkan/vn_android.c
@@ -968,12 +968,14 @@ vn_android_device_import_ahb(struct vn_device *dev,
                              const VkMemoryAllocateInfo *alloc_info,
                              struct AHardwareBuffer *ahb)
 {
+   VkDevice device = vn_device_to_handle(dev);
    const VkMemoryDedicatedAllocateInfo *dedicated_info =
       vk_find_struct_const(alloc_info->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
    const native_handle_t *handle = NULL;
    int dma_buf_fd = -1;
    int dup_fd = -1;
-   VkDeviceSize alloc_size = alloc_info->allocationSize;
+   uint64_t alloc_size = 0;
+   uint32_t mem_type_bits = 0;
    VkResult result = VK_SUCCESS;
 
    handle = AHardwareBuffer_getNativeHandle(ahb);
@@ -981,6 +983,14 @@ vn_android_device_import_ahb(struct vn_device *dev,
    if (result != VK_SUCCESS)
       return result;
 
+   result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size,
+                                             &mem_type_bits);
+   if (result != VK_SUCCESS)
+      return result;
+
+   if (((1 << alloc_info->memoryTypeIndex) & mem_type_bits) == 0)
+      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+
    /* If ahb is for an image, finish the deferred image creation first */
    if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
       const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
@@ -1034,13 +1044,21 @@ vn_android_device_import_ahb(struct vn_device *dev,
       if (result != VK_SUCCESS)
          return result;
 
-      /* For AHB memory allocation of a dedicated image, allocationSize must
-       * be zero from the app side. So we need to get the proper allocation
-       * size here used to override memory allocation info.
+      /* TODO When alloc_size is fixed to return host storage size, we will
+       * also check alloc_size is not smaller than mem_req.size here.
+       */
+      VkMemoryRequirements mem_req;
+      vn_GetImageMemoryRequirements(device, dedicated_info->image, &mem_req);
+      alloc_size = mem_req.size;
+   }
+
+   if (dedicated_info && dedicated_info->buffer != VK_NULL_HANDLE) {
+      /* TODO When alloc_size is fixed to return host storage size, we will
+       * also check alloc_size is not smaller than mem_req.size here.
        */
       VkMemoryRequirements mem_req;
-      vn_GetImageMemoryRequirements(vn_device_to_handle(dev),
-                                    dedicated_info->image, &mem_req);
+      vn_GetBufferMemoryRequirements(device, dedicated_info->buffer,
+                                     &mem_req);
       alloc_size = mem_req.size;
    }
 



More information about the mesa-commit mailing list