Tweaking YCBCR conversion to return correct VK Format
* Adding a drm format field in cb_handler
* Convert android->vulkan format mapping into drm->vulkan format mapping
Bug: b/323896722
Test: atest android.graphics.cts.MediaVulkanGpuTest#testMediaImportAndRendering
Change-Id: I9068be712c07704fde1f8f648f1c18aa281ef3fa
diff --git a/guest/vulkan_enc/AndroidHardwareBuffer.cpp b/guest/vulkan_enc/AndroidHardwareBuffer.cpp
index 814a780..b62509b 100644
--- a/guest/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/guest/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -17,6 +17,12 @@
#if defined(__ANDROID__) || defined(__linux__)
#include <drm_fourcc.h>
#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7')
+#define DRM_FORMAT_D16_UNORM fourcc_code('9', '9', '9', '6')
+#define DRM_FORMAT_D24_UNORM fourcc_code('9', '9', '9', '5')
+#define DRM_FORMAT_D24_UNORM_S8_UINT fourcc_code('9', '9', '9', '4')
+#define DRM_FORMAT_D32_FLOAT fourcc_code('9', '9', '9', '3')
+#define DRM_FORMAT_D32_FLOAT_S8_UINT fourcc_code('9', '9', '9', '2')
+#define DRM_FORMAT_S8_UINT fourcc_code('9', '9', '9', '1')
#endif
#include <assert.h>
@@ -68,47 +74,60 @@
switch (format) {
case AHARDWAREBUFFER_FORMAT_R8_UNORM:
ahbFormatProps->format = VK_FORMAT_R8_UNORM;
+ ahbFormatProps->externalFormat = DRM_FORMAT_R8;
break;
case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+ ahbFormatProps->externalFormat = DRM_FORMAT_ABGR8888;
break;
case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+ ahbFormatProps->externalFormat = DRM_FORMAT_XBGR8888;
break;
case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
ahbFormatProps->format = VK_FORMAT_R8G8B8_UNORM;
+ ahbFormatProps->externalFormat = DRM_FORMAT_BGR888;
break;
case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
ahbFormatProps->format = VK_FORMAT_R5G6B5_UNORM_PACK16;
+ ahbFormatProps->externalFormat = DRM_FORMAT_RGB565;
break;
case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
ahbFormatProps->format = VK_FORMAT_R16G16B16A16_SFLOAT;
+ ahbFormatProps->externalFormat = DRM_FORMAT_ABGR16161616F;
break;
case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
ahbFormatProps->format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+ ahbFormatProps->externalFormat = DRM_FORMAT_ABGR2101010;
break;
case AHARDWAREBUFFER_FORMAT_D16_UNORM:
ahbFormatProps->format = VK_FORMAT_D16_UNORM;
+ ahbFormatProps->externalFormat = DRM_FORMAT_D16_UNORM;
break;
case AHARDWAREBUFFER_FORMAT_D24_UNORM:
ahbFormatProps->format = VK_FORMAT_X8_D24_UNORM_PACK32;
+ ahbFormatProps->externalFormat = DRM_FORMAT_D24_UNORM;
break;
case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
ahbFormatProps->format = VK_FORMAT_D24_UNORM_S8_UINT;
+ ahbFormatProps->externalFormat = DRM_FORMAT_D24_UNORM_S8_UINT;
break;
case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
ahbFormatProps->format = VK_FORMAT_D32_SFLOAT;
+ ahbFormatProps->externalFormat = DRM_FORMAT_D32_FLOAT;
break;
case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
ahbFormatProps->format = VK_FORMAT_D32_SFLOAT_S8_UINT;
+ ahbFormatProps->externalFormat = DRM_FORMAT_D32_FLOAT_S8_UINT;
break;
case AHARDWAREBUFFER_FORMAT_S8_UINT:
ahbFormatProps->format = VK_FORMAT_S8_UINT;
+ ahbFormatProps->externalFormat = DRM_FORMAT_S8_UINT;
break;
default:
ahbFormatProps->format = VK_FORMAT_UNDEFINED;
+ ahbFormatProps->externalFormat = DRM_FORMAT_INVALID;
}
- ahbFormatProps->externalFormat = format;
// The formatFeatures member must include
// VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
@@ -140,6 +159,7 @@
#if defined(__ANDROID__) || defined(__linux__)
if (android_format_is_yuv(format)) {
uint32_t drmFormat = grallocHelper->getFormatDrmFourcc(buffer);
+ ahbFormatProps->externalFormat = static_cast<uint64_t>(drmFormat);
if (drmFormat) {
// The host renderer is not aware of the plane ordering for YUV formats used
// in the guest and simply knows that the format "layout" is one of:
@@ -169,16 +189,20 @@
case DRM_FORMAT_NV12:
// NV12 is a Y-plane followed by a interleaved UV-plane and is
// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM on the host.
+ break;
case DRM_FORMAT_P010:
// P010 is a Y-plane followed by a interleaved UV-plane and is
// VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 on the host.
break;
-
+ case DRM_FORMAT_YUV420:
+ // YUV420 is a Y-plane, then a U-plane, and then a V-plane and is
+ // VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM on the host.
+ break;
case DRM_FORMAT_NV21:
// NV21 is a Y-plane followed by a interleaved VU-plane and is
// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM on the host.
case DRM_FORMAT_YVU420:
- // YV12 is a Y-plane, then a V-plane, and then a U-plane and is
+ // YVU420 is a Y-plane, then a V-plane, and then a U-plane and is
// VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM on the host.
case DRM_FORMAT_YVU420_ANDROID:
// DRM_FORMAT_YVU420_ANDROID is the same as DRM_FORMAT_YVU420 with
diff --git a/guest/vulkan_enc/ResourceTracker.cpp b/guest/vulkan_enc/ResourceTracker.cpp
index 8c70b17..0c97523 100644
--- a/guest/vulkan_enc/ResourceTracker.cpp
+++ b/guest/vulkan_enc/ResourceTracker.cpp
@@ -28,6 +28,7 @@
#include "goldfish_vk_private_defs.h"
#include "util.h"
#include "virtgpu_gfxstream_protocol.h"
+#include "vulkan/vk_enum_string_helper.h"
#include "vulkan/vulkan_core.h"
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include "vk_format_info.h"
@@ -4164,7 +4165,7 @@
// instead, replace the local image localCreateInfo format
// with the corresponding Vulkan format
if (extFormatAndroidPtr->externalFormat) {
- localCreateInfo.format = vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
if (localCreateInfo.format == VK_FORMAT_UNDEFINED)
return VK_ERROR_VALIDATION_FAILED_EXT;
}
@@ -4298,7 +4299,7 @@
#ifdef VK_USE_PLATFORM_ANDROID_KHR
if (extFormatAndroidPtr && extFormatAndroidPtr->externalFormat) {
info.hasExternalFormat = true;
- info.androidFormat = extFormatAndroidPtr->externalFormat;
+ info.externalFourccFormat = extFormatAndroidPtr->externalFormat;
}
#endif // VK_USE_PLATFORM_ANDROID_KHR
@@ -4347,7 +4348,7 @@
const VkExternalFormatANDROID* extFormatAndroidPtr =
vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
if (extFormatAndroidPtr) {
- if (extFormatAndroidPtr->externalFormat == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) {
+ if (extFormatAndroidPtr->externalFormat == DRM_FORMAT_RGB565) {
// We don't support external formats on host and it causes RGB565
// to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
// when passed as an external format.
@@ -4356,7 +4357,7 @@
*pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
return VK_SUCCESS;
} else if (extFormatAndroidPtr->externalFormat) {
- localCreateInfo.format = vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
}
}
#endif
@@ -4393,7 +4394,7 @@
const VkExternalFormatANDROID* extFormatAndroidPtr =
vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
if (extFormatAndroidPtr) {
- if (extFormatAndroidPtr->externalFormat == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) {
+ if (extFormatAndroidPtr->externalFormat == DRM_FORMAT_RGB565) {
// We don't support external formats on host and it causes RGB565
// to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
// when passed as an external format.
@@ -4402,7 +4403,7 @@
*pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
return VK_SUCCESS;
} else if (extFormatAndroidPtr->externalFormat) {
- localCreateInfo.format = vk_format_from_android(extFormatAndroidPtr->externalFormat);
+ localCreateInfo.format = vk_format_from_fourcc(extFormatAndroidPtr->externalFormat);
}
}
#endif
@@ -6845,7 +6846,7 @@
auto it = info_VkImage.find(pCreateInfo->image);
if (it != info_VkImage.end() && it->second.hasExternalFormat) {
- localCreateInfo.format = vk_format_from_android(it->second.androidFormat);
+ localCreateInfo.format = vk_format_from_fourcc(it->second.externalFourccFormat);
}
}
VkSamplerYcbcrConversionInfo localVkSamplerYcbcrConversionInfo;
diff --git a/guest/vulkan_enc/ResourceTracker.h b/guest/vulkan_enc/ResourceTracker.h
index a93c369..ac22849 100644
--- a/guest/vulkan_enc/ResourceTracker.h
+++ b/guest/vulkan_enc/ResourceTracker.h
@@ -775,7 +775,7 @@
VkMemoryRequirements baseRequirements;
#ifdef VK_USE_PLATFORM_ANDROID_KHR
bool hasExternalFormat = false;
- unsigned androidFormat = 0;
+ unsigned externalFourccFormat = 0;
std::vector<int> pendingQsriSyncFds;
#endif
#ifdef VK_USE_PLATFORM_FUCHSIA
diff --git a/guest/vulkan_enc/vk_format_info.h b/guest/vulkan_enc/vk_format_info.h
index 5bf26e5..8235ac3 100644
--- a/guest/vulkan_enc/vk_format_info.h
+++ b/guest/vulkan_enc/vk_format_info.h
@@ -27,6 +27,8 @@
#define VK_FORMAT_INFO_H
#include <stdbool.h>
+#include <drm_fourcc.h>
+#define DRM_FORMAT_YVU420_ANDROID fourcc_code('9', '9', '9', '7')
#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include <system/graphics.h>
#else
@@ -53,41 +55,32 @@
#define OMX_COLOR_FormatYUV420Planar 0x13
-// TODO: update users of this function to query the DRM fourcc
-// code using the standard Gralloc4 metadata type and instead
-// translate the DRM fourcc code to a Vulkan format as Android
-// formats such as AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 could be
-// either VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM or
-// VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
-static inline VkFormat vk_format_from_android(unsigned android_format) {
- switch (android_format) {
- case AHARDWAREBUFFER_FORMAT_R8_UNORM:
+static inline VkFormat vk_format_from_fourcc(unsigned fourcc_format) {
+ switch (fourcc_format) {
+ case DRM_FORMAT_R8:
return VK_FORMAT_R8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ case DRM_FORMAT_ABGR8888:
return VK_FORMAT_R8G8B8A8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case DRM_FORMAT_XBGR8888:
return VK_FORMAT_R8G8B8A8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ case DRM_FORMAT_BGR888:
return VK_FORMAT_R8G8B8_UNORM;
- case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ case DRM_FORMAT_RGB565:
return VK_FORMAT_R5G6B5_UNORM_PACK16;
- case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ case DRM_FORMAT_ABGR16161616F:
return VK_FORMAT_R16G16B16A16_SFLOAT;
- case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ case DRM_FORMAT_ABGR2101010:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
- case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
- case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
- return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
-#if __ANDROID_API__ >= 30
- case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
+ case DRM_FORMAT_P010:
return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
-#endif
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
- case HAL_PIXEL_FORMAT_YV12:
- case OMX_COLOR_FormatYUV420Planar:
+ case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+ case DRM_FORMAT_NV12:
+ case DRM_FORMAT_NV21:
+ return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420_ANDROID:
+ case DRM_FORMAT_YVU420:
return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
- case AHARDWAREBUFFER_FORMAT_BLOB:
-#endif
default:
return VK_FORMAT_UNDEFINED;
}