minigbm: support GPU_DATA_BUFFER in gralloc virtgpu_virgl backend

VK_ANDROID_external_memory_android_hardware_buffer spec requires gralloc
to support AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER. This patch adds a new
BO_USE_GPU_DATA_BUFFER flag accordingly and maps the new flag to
VIRGL_BIND_LINEAR, which aligns with the workarounds carried by existing
implementations as well as still going through the blob resource path to
be correctly mappable at the guest side.

BUG=b:191591725
TEST=AHardwareBuffer_allocate with AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
TEST=CtsNativeHardwareTestCases
TEST=dEQP-VK.api.external.memory.android_hardware_buffer.*

Change-Id: Ib0d9b1cb90e3b7ff614d556954b6abb9018c92a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2974800
Tested-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Yiwei Zhang <zzyiwei@chromium.org>
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index 8bab6b2..386a90a 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -66,6 +66,11 @@
 // entirety, so we can detect the video decoder flag passed by IAllocator clients.
 #define BUFFER_USAGE_VIDEO_DECODER (1 << 22)
 
+// Gralloc0 doesn't define the BufferUsage::GPU_DATA_BUFFER flag. Define here to
+// align accordingly since AHardwareBuffer and Vulkan interop requires gralloc
+// to support allocating with AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER.
+#define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24)
+
 // Reserve the GRALLOC_USAGE_PRIVATE_0 bit for buffers used for front rendering.
 // minigbm backend later decides to use BO_USE_FRONT_RENDERING or BO_USE_LINEAR
 // upon buffer allocaton.
@@ -120,6 +125,8 @@
 		use_flags |= BO_USE_HW_VIDEO_DECODER;
 	if (usage & BUFFER_USAGE_FRONT_RENDERING)
 		use_flags |= BO_USE_FRONT_RENDERING;
+	if (usage & BUFFER_USAGE_GPU_DATA_BUFFER)
+		use_flags |= BO_USE_GPU_DATA_BUFFER;
 
 	return use_flags;
 }
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc b/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
index 3f39305..f0ac207 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
+++ b/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
@@ -157,6 +157,10 @@
         usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER);
         usages.push_back("BufferUsage::VIDEO_ENCODER");
     }
+    if (usage & BufferUsage::GPU_DATA_BUFFER) {
+        usage &= ~static_cast<Underlying>(BufferUsage::GPU_DATA_BUFFER);
+        usages.push_back("BufferUsage::GPU_DATA_BUFFER");
+    }
 
     if (usage) {
         usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage));
@@ -301,6 +305,9 @@
     if (grallocUsage & BufferUsage::VIDEO_DECODER) {
         bufferUsage |= BO_USE_HW_VIDEO_DECODER;
     }
+    if (grallocUsage & BufferUsage::GPU_DATA_BUFFER) {
+        bufferUsage |= BO_USE_GPU_DATA_BUFFER;
+    }
 
     *outBufferUsage = bufferUsage;
     return 0;
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
index 9bc27cb..55c0855 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
@@ -161,6 +161,10 @@
         usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER);
         usages.push_back("BufferUsage::VIDEO_ENCODER");
     }
+    if (usage & BufferUsage::GPU_DATA_BUFFER) {
+        usage &= ~static_cast<Underlying>(BufferUsage::GPU_DATA_BUFFER);
+        usages.push_back("BufferUsage::GPU_DATA_BUFFER");
+    }
 
     if (usage) {
         usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage));
@@ -305,6 +309,9 @@
     if (grallocUsage & BufferUsage::VIDEO_DECODER) {
         bufferUsage |= BO_USE_HW_VIDEO_DECODER;
     }
+    if (grallocUsage & BufferUsage::GPU_DATA_BUFFER) {
+        bufferUsage |= BO_USE_GPU_DATA_BUFFER;
+    }
 
     *outBufferUsage = bufferUsage;
     return 0;
diff --git a/drv.h b/drv.h
index 4689558..29c1334 100644
--- a/drv.h
+++ b/drv.h
@@ -39,6 +39,7 @@
 #define BO_USE_TEST_ALLOC		(1ull << 15)
 #define BO_USE_FRONT_RENDERING		(1ull << 16)
 #define BO_USE_RENDERSCRIPT		(1ull << 17)
+#define BO_USE_GPU_DATA_BUFFER		(1ull << 18)
 
 /* Quirks for allocating a buffer. */
 #define BO_QUIRK_NONE			0
diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c
index 7aaa3a0..a40bc0b 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -391,6 +391,7 @@
 	handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT);
 	handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR);
 	handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR);
+	handle_flag(&use_flags, BO_USE_GPU_DATA_BUFFER, &bind, VIRGL_BIND_LINEAR);
 
 	if (use_flags & BO_USE_PROTECTED) {
 		handle_flag(&use_flags, BO_USE_PROTECTED, &bind, VIRGL_BIND_MINIGBM_PROTECTED);
@@ -618,7 +619,7 @@
 				   BO_USE_HW_VIDEO_ENCODER);
 	drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
-				   BO_USE_HW_VIDEO_ENCODER);
+				   BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER);
 
 	if (!priv->host_gbm_enabled) {
 		drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA,
@@ -713,9 +714,10 @@
 	if (!priv->host_gbm_enabled)
 		return false;
 
-	// Use regular resources if only the GPU needs efficient access
-	if (!(use_flags &
-	      (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR | BO_USE_NON_GPU_HW)))
+	// Use regular resources if only the GPU needs efficient access. Blob resource is a better
+	// fit for BO_USE_GPU_DATA_BUFFER which is mapped to VIRGL_BIND_LINEAR.
+	if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR |
+			   BO_USE_NON_GPU_HW | BO_USE_GPU_DATA_BUFFER)))
 		return false;
 
 	switch (format) {