turnip: Detect Qualcomm gralloc and its UBWC flag on gralloc surfaces.

And document where to find information on qcom gralloc's private handle
layout.  I chose not to #include the gralloc_priv because it seems that
there's not much we need yet, and I'm hoping we can avoid the build-time
dependency on the specific platform.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7015>
diff --git a/src/freedreno/vulkan/tu_android.c b/src/freedreno/vulkan/tu_android.c
index 7203757..e04a2bb 100644
--- a/src/freedreno/vulkan/tu_android.c
+++ b/src/freedreno/vulkan/tu_android.c
@@ -109,6 +109,12 @@
    return -1;
 }
 
+/**
+ * Creates the VkImage using the gralloc handle in *gralloc_info.
+ *
+ * We support two different grallocs here, gbm_gralloc, and the qcom gralloc
+ * used on Android phones.
+ */
 VkResult
 tu_image_from_gralloc(VkDevice device_h,
                       const VkImageCreateInfo *base_info,
@@ -121,24 +127,62 @@
    VkImage image_h = VK_NULL_HANDLE;
    struct tu_image *image = NULL;
    VkResult result;
+   bool ubwc = false;
 
-   result = tu_image_create(device_h, base_info, alloc, &image_h,
-                            DRM_FORMAT_MOD_LINEAR, NULL);
-   if (result != VK_SUCCESS)
-      return result;
+   const uint32_t *handle_fds = (uint32_t *)gralloc_info->handle->data;
+   const uint32_t *handle_data = &handle_fds[gralloc_info->handle->numFds];
+   int dma_buf;
 
-   if (gralloc_info->handle->numFds != 1) {
+   if (gralloc_info->handle->numFds == 1) {
+      /* gbm_gralloc.  TODO: modifiers support */
+      dma_buf = handle_fds[0];
+   } else if (gralloc_info->handle->numFds == 2) {
+      /* Qualcomm gralloc, find it at:
+       *
+       * https://android.googlesource.com/platform/hardware/qcom/display/.
+       *
+       * The gralloc_info->handle is a pointer to a struct private_handle_t
+       * from your platform's gralloc.  On msm8996 (a5xx) and newer grallocs
+       * that's libgralloc1/gr_priv_handle.h, while previously it was
+       * libgralloc/gralloc_priv.h.
+       */
+
+      if (gralloc_info->handle->numInts < 2) {
+         return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
+                          "VkNativeBufferANDROID::handle::numInts is %d, "
+                          "expected at least 2 for qcom gralloc",
+                          gralloc_info->handle->numFds);
+      }
+
+      uint32_t gmsm = ('g' << 24) | ('m' << 16) | ('s' << 8) | 'm';
+      if (handle_data[0] != gmsm) {
+         return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
+                          "private_handle_t::magic is %x, expected %x",
+                          handle_data[0], gmsm);
+      }
+
+      /* This UBWC flag was introduced in a5xx. */
+      ubwc = handle_data[1] & 0x08000000;
+
+      /* QCOM gralloc has two fds passed in: the actual GPU buffer, and a buffer
+       * of CPU-side metadata.  I haven't found any need for the metadata buffer
+       * yet.  See qdMetaData.h for what's in the metadata fd.
+       */
+      dma_buf = handle_fds[0];
+   } else {
       return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
                        "VkNativeBufferANDROID::handle::numFds is %d, "
-                       "expected 1",
+                       "expected 1 (gbm_gralloc) or 2 (qcom gralloc)",
                        gralloc_info->handle->numFds);
    }
 
-   /* 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];
+   result = tu_image_create(device_h, base_info, alloc, &image_h,
+                            ubwc ?
+                            DRM_FORMAT_MOD_QCOM_COMPRESSED :
+                            DRM_FORMAT_MOD_LINEAR,
+                            NULL);
+   if (result != VK_SUCCESS)
+      return result;
 
    image = tu_image_from_handle(image_h);