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) {