Mesa (staging/21.2): anv/android: handle image bindings from gralloc buffers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 13 22:06:01 UTC 2021


Module: Mesa
Branch: staging/21.2
Commit: 809b4d1356f86b13c50ebf30cfb399f0cf55e78e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=809b4d1356f86b13c50ebf30cfb399f0cf55e78e

Author: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Date:   Wed Aug 11 12:57:37 2021 +0300

anv/android: handle image bindings from gralloc buffers

When creating an image out of a swapchain on Android, the android
layer call will detect a VkBindImageMemorySwapchainInfoKHR in the
pNext chain of the vkBindImageMemory2() call and add a
VkNativeBufferANDROID in the chain. This is what we should use as
backing memory for that image.

v2: Fix a couple of obvious mistakes (Tapani)

v3: Silence build warning (Lionel)
    Fix invalid object argument to vk_error() (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Fixes: bc3c71b87ae0b8 ("anv: don't try to access Android swapchains")
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5180
Reviewed-by: Tapani Pälli <tapani.palli at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12244>
(cherry picked from commit 19b7bbba7300c013dca67f931cad3e55dfc3722b)

---

 .pick_status.json                    |  2 +-
 src/intel/vulkan/anv_android.c       | 53 ++++++++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_android.h       |  4 +++
 src/intel/vulkan/anv_android_stubs.c |  7 +++++
 src/intel/vulkan/anv_image.c         | 18 ++++++++++++
 5 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/.pick_status.json b/.pick_status.json
index 7349fad831b..7ce6639c4dc 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -130,7 +130,7 @@
         "description": "anv/android: handle image bindings from gralloc buffers",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "main_sha": null,
         "because_sha": "bc3c71b87ae0b8e053f45c26c1179560e462db04"
     },
diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c
index 8e02aae92d7..5c769e3fee1 100644
--- a/src/intel/vulkan/anv_android.c
+++ b/src/intel/vulkan/anv_android.c
@@ -623,6 +623,59 @@ anv_image_from_gralloc(VkDevice device_h,
    return result;
 }
 
+VkResult
+anv_image_bind_from_gralloc(struct anv_device *device,
+                            struct anv_image *image,
+                            const VkNativeBufferANDROID *gralloc_info)
+{
+   /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
+    * must exceed that of the gralloc handle, and we do not own the gralloc
+    * handle.
+    */
+   int dma_buf = gralloc_info->handle->data[0];
+
+   /* We need to set the WRITE flag on window system buffers so that GEM will
+    * know we're writing to them and synchronize uses on other rings (for
+    * example, if the display server uses the blitter ring).
+    *
+    * If this function fails and if the imported bo was resident in the cache,
+    * we should avoid updating the bo's flags. Therefore, we defer updating
+    * the flags until success is certain.
+    *
+    */
+   struct anv_bo *bo = NULL;
+   VkResult result = anv_device_import_bo(device, dma_buf,
+                                          ANV_BO_ALLOC_IMPLICIT_SYNC |
+                                          ANV_BO_ALLOC_IMPLICIT_WRITE,
+                                          0 /* client_address */,
+                                          &bo);
+   if (result != VK_SUCCESS) {
+      return vk_errorf(device, &device->vk.base, result,
+                       "failed to import dma-buf from VkNativeBufferANDROID");
+   }
+
+   uint64_t img_size = image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].memory_range.size;
+   if (img_size < bo->size) {
+      result = vk_errorf(device, &device->vk.base, VK_ERROR_INVALID_EXTERNAL_HANDLE,
+                         "dma-buf from VkNativeBufferANDROID is too small for "
+                         "VkImage: %"PRIu64"B < %"PRIu64"B",
+                         bo->size, img_size);
+      anv_device_release_bo(device, bo);
+      return result;
+   }
+
+   assert(!image->disjoint);
+   assert(image->n_planes == 1);
+   assert(image->planes[0].primary_surface.memory_range.binding ==
+          ANV_IMAGE_MEMORY_BINDING_MAIN);
+   assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo == NULL);
+   assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.offset == 0);
+   image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo = bo;
+   image->from_gralloc = true;
+
+   return VK_SUCCESS;
+}
+
 static VkResult
 format_supported_with_usage(VkDevice device_h, VkFormat format,
                             VkImageUsageFlags imageUsage)
diff --git a/src/intel/vulkan/anv_android.h b/src/intel/vulkan/anv_android.h
index 81ecf67f87e..2e329b3029c 100644
--- a/src/intel/vulkan/anv_android.h
+++ b/src/intel/vulkan/anv_android.h
@@ -41,6 +41,10 @@ VkResult anv_image_from_gralloc(VkDevice device_h,
                                 const VkAllocationCallbacks *alloc,
                                 VkImage *pImage);
 
+VkResult anv_image_bind_from_gralloc(struct anv_device *device,
+                                     struct anv_image *image,
+                                     const VkNativeBufferANDROID *gralloc_info);
+
 VkResult anv_image_from_external(VkDevice device_h,
                                  const VkImageCreateInfo *base_info,
                                  const VkExternalMemoryImageCreateInfo *create_info,
diff --git a/src/intel/vulkan/anv_android_stubs.c b/src/intel/vulkan/anv_android_stubs.c
index 3e773dfe710..f6b2d1c8dd1 100644
--- a/src/intel/vulkan/anv_android_stubs.c
+++ b/src/intel/vulkan/anv_android_stubs.c
@@ -33,6 +33,13 @@ anv_image_from_gralloc(VkDevice device_h,
    return VK_ERROR_EXTENSION_NOT_PRESENT;
 }
 
+VkResult anv_image_bind_from_gralloc(struct anv_device *device,
+                                     struct anv_image *image,
+                                     const VkNativeBufferANDROID *gralloc_info)
+{
+   return VK_ERROR_EXTENSION_NOT_PRESENT;
+}
+
 uint64_t
 anv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create,
                             const VkImageUsageFlags vk_usage)
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 9bafb842ef0..9ea64bde16e 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -1770,6 +1770,10 @@ VkResult anv_BindImageMemory2(
             break;
          }
          case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
+            /* Ignore this struct on Android, we cannot access swapchain
+             * structures threre.
+             */
+#ifndef VK_USE_PLATFORM_ANDROID_KHR
             const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
                (const VkBindImageMemorySwapchainInfoKHR *) s;
             struct anv_image *swapchain_image =
@@ -1791,8 +1795,22 @@ VkResult anv_BindImageMemory2(
                anv_bo_ref(private_bo);
 
             did_bind = true;
+#endif
+            break;
+         }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch"
+         case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID: {
+            const VkNativeBufferANDROID *gralloc_info =
+               (const VkNativeBufferANDROID *)s;
+            VkResult result = anv_image_bind_from_gralloc(device, image,
+                                                          gralloc_info);
+            if (result != VK_SUCCESS)
+               return result;
+            did_bind = true;
             break;
          }
+#pragma GCC diagnostic pop
          default:
             anv_debug_ignored_stype(s->sType);
             break;



More information about the mesa-commit mailing list