Merge "Tweaking YCBCR conversion to return correct VK Format" into main
diff --git a/guest/android/GrallocGoldfish.cpp b/guest/android/GrallocGoldfish.cpp
index 7df87da..113cb6d 100644
--- a/guest/android/GrallocGoldfish.cpp
+++ b/guest/android/GrallocGoldfish.cpp
@@ -79,6 +79,15 @@
     return getFormat(handle);
 }
 
+uint32_t GoldfishGralloc::getFormatDrmFourcc(const native_handle_t* handle) {
+    return cb_handle_t::from(handle)->drmformat;
+}
+
+uint32_t GoldfishGralloc::getFormatDrmFourcc(const AHardwareBuffer* ahb) {
+    const native_handle_t* handle = AHardwareBuffer_getNativeHandle(ahb);
+    return getFormatDrmFourcc(handle);
+}
+
 uint32_t GoldfishGralloc::getWidth(const AHardwareBuffer* ahb) {
     AHardwareBuffer_Desc desc = {};
     AHardwareBuffer_describe(ahb, &desc);
diff --git a/guest/android/GrallocGoldfish.h b/guest/android/GrallocGoldfish.h
index 505d14f..183c110 100644
--- a/guest/android/GrallocGoldfish.h
+++ b/guest/android/GrallocGoldfish.h
@@ -39,6 +39,9 @@
     int getFormat(const native_handle_t* handle) override;
     int getFormat(const AHardwareBuffer* handle) override;
 
+    uint32_t getFormatDrmFourcc(const native_handle_t* handle) override;
+    uint32_t getFormatDrmFourcc(const AHardwareBuffer* handle) override;
+
     uint32_t getWidth(const AHardwareBuffer* ahb) override;
     uint32_t getHeight(const AHardwareBuffer* ahb) override;
 
diff --git a/guest/gralloc_cb/include/gralloc_cb_bp.h b/guest/gralloc_cb/include/gralloc_cb_bp.h
index 7283e9d..7817671 100644
--- a/guest/gralloc_cb/include/gralloc_cb_bp.h
+++ b/guest/gralloc_cb/include/gralloc_cb_bp.h
@@ -32,12 +32,14 @@
     cb_handle_t(uint32_t p_magic,
                 uint32_t p_hostHandle,
                 int32_t p_format,
+                uint32_t p_drmformat,
                 uint32_t p_stride,
                 uint32_t p_bufSize,
                 uint64_t p_mmapedOffset)
         : magic(p_magic),
           hostHandle(p_hostHandle),
           format(p_format),
+          drmformat(p_drmformat),
           bufferSize(p_bufSize),
           stride(p_stride),
           mmapedOffsetLo(static_cast<uint32_t>(p_mmapedOffset)),
@@ -78,6 +80,7 @@
     uint32_t magic;         // magic number in order to validate a pointer
     uint32_t hostHandle;    // the host reference to this buffer
     uint32_t format;        // real internal pixel format format
+    uint32_t drmformat;     // drm format
     uint32_t bufferSize;
     uint32_t stride;
     uint32_t mmapedOffsetLo;
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;
     }