venus: resolve AHB external format with DRM format
authorYiwei Zhang <zzyiwei@chromium.org>
Fri, 18 Jun 2021 21:45:28 +0000 (21:45 +0000)
committerMarge Bot <eric+marge@anholt.net>
Mon, 28 Jun 2021 22:18:19 +0000 (22:18 +0000)
AHardwareBuffer_Format is lossier than DRM_FORMAT_*, which ends up with
unable to resolve implementation defined format upon creating sampler
ycbcr conversion. So we now use DRM format as AHB external format.

An external format error return in vkCreateSamplerYcbcrConversion is
also removed here since that is already an invalid usage per spec
(partly because there is no proper error code to return here).

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11480>

src/virtio/vulkan/vn_android.c
src/virtio/vulkan/vn_android.h
src/virtio/vulkan/vn_image.c

index d153fa4..acf8439 100644 (file)
@@ -126,25 +126,22 @@ vn_android_ahb_format_from_vk_format(VkFormat format)
 }
 
 VkFormat
-vn_android_ahb_format_to_vk_format(uint32_t format)
+vn_android_drm_format_to_vk_format(uint32_t format)
 {
    switch (format) {
-   case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
-   case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+   case DRM_FORMAT_ABGR8888:
+   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 AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
-   /* XXX Add a gralloc query for the resolved drm format and then map to a
-    * compatiable VkFormat.
-    */
-   case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
+   case DRM_FORMAT_YVU420:
+   case DRM_FORMAT_NV12:
       return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    default:
       return VK_FORMAT_UNDEFINED;
@@ -209,7 +206,7 @@ vn_GetSwapchainGrallocUsage2ANDROID(
 }
 
 struct cros_gralloc0_buffer_info {
-   uint32_t drm_fourcc; /* ignored */
+   uint32_t drm_fourcc;
    int num_fds;         /* ignored */
    int fds[4];          /* ignored */
    uint64_t modifier;
@@ -218,6 +215,7 @@ struct cros_gralloc0_buffer_info {
 };
 
 struct vn_android_gralloc_buffer_properties {
+   uint32_t drm_fourcc;
    uint64_t modifier;
    uint32_t offset[4];
    uint32_t stride[4];
@@ -259,6 +257,7 @@ vn_android_get_gralloc_buffer_properties(
    if (info.modifier == DRM_FORMAT_MOD_INVALID)
       return false;
 
+   out_props->drm_fourcc = info.drm_fourcc;
    for (uint32_t i = 0; i < 4; i++) {
       out_props->stride[i] = info.stride[i];
       out_props->offset[i] = info.offset[i];
@@ -691,26 +690,27 @@ vn_android_get_ahb_format_properties(
       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
    }
 
+   /* Handle the special AHARDWAREBUFFER_FORMAT_BLOB for VkBuffer case. */
+   if (desc.format == AHARDWAREBUFFER_FORMAT_BLOB) {
+      out_props->format = VK_FORMAT_UNDEFINED;
+      return VK_SUCCESS;
+   }
+
+   if (!vn_android_get_gralloc_buffer_properties(
+          AHardwareBuffer_getNativeHandle(ahb), &buf_props))
+      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+
    /* We implement AHB extension support with EXT_image_drm_format_modifier.
     * It requires us to have a compatible VkFormat but not DRM formats. So if
     * the ahb is not intended for backing a VkBuffer, error out early if the
     * format is VK_FORMAT_UNDEFINED.
     */
-   format = vn_android_ahb_format_to_vk_format(desc.format);
+   format = vn_android_drm_format_to_vk_format(buf_props.drm_fourcc);
    if (format == VK_FORMAT_UNDEFINED) {
-      if (desc.format != AHARDWAREBUFFER_FORMAT_BLOB) {
-         vn_log(dev->instance, "Unknown AHB format(0x%X)", desc.format);
-         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
-      }
-
-      out_props->format = format;
-      out_props->externalFormat = desc.format;
-      return VK_SUCCESS;
-   }
-
-   if (!vn_android_get_gralloc_buffer_properties(
-          AHardwareBuffer_getNativeHandle(ahb), &buf_props))
+      vn_log(dev->instance, "Unknown drm_fourcc(%u) from AHB format(0x%X)",
+             buf_props.drm_fourcc, desc.format);
       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+   }
 
    VkResult result = vn_android_get_modifier_properties(
       dev, format, buf_props.modifier, &dev->base.base.alloc, &mod_props);
@@ -728,7 +728,7 @@ vn_android_get_ahb_format_properties(
       .sType = out_props->sType,
       .pNext = out_props->pNext,
       .format = format,
-      .externalFormat = desc.format,
+      .externalFormat = buf_props.drm_fourcc,
       .formatFeatures = format_features,
       .samplerYcbcrConversionComponents = {
          .r = VK_COMPONENT_SWIZZLE_IDENTITY,
@@ -877,7 +877,7 @@ vn_android_image_from_ahb(struct vn_device *dev,
 
       local_info = *create_info;
       local_info.format =
-         vn_android_ahb_format_to_vk_format(ext_info->externalFormat);
+         vn_android_drm_format_to_vk_format(ext_info->externalFormat);
       create_info = &local_info;
    }
 
index 0c50f19..587ad83 100644 (file)
@@ -67,7 +67,7 @@ void
 vn_android_release_ahb(struct AHardwareBuffer *ahb);
 
 VkFormat
-vn_android_ahb_format_to_vk_format(uint32_t format);
+vn_android_drm_format_to_vk_format(uint32_t format);
 
 #else
 
@@ -137,7 +137,7 @@ vn_android_release_ahb(UNUSED struct AHardwareBuffer *ahb)
 }
 
 static inline VkFormat
-vn_android_ahb_format_to_vk_format(UNUSED uint32_t format)
+vn_android_drm_format_to_vk_format(UNUSED uint32_t format)
 {
    return VK_FORMAT_UNDEFINED;
 }
index b7337bf..8665f3f 100644 (file)
@@ -596,18 +596,16 @@ vn_CreateSamplerYcbcrConversion(
    if (ext_info && ext_info->externalFormat) {
       assert(pCreateInfo->format == VK_FORMAT_UNDEFINED);
 
-      VkFormat format =
-         vn_android_ahb_format_to_vk_format(ext_info->externalFormat);
-      if (format == VK_FORMAT_UNDEFINED)
-         return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
       local_info = *pCreateInfo;
-      local_info.format = format;
+      local_info.format =
+         vn_android_drm_format_to_vk_format(ext_info->externalFormat);
       local_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
       local_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
       local_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
       local_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
       pCreateInfo = &local_info;
+
+      assert(pCreateInfo->format != VK_FORMAT_UNDEFINED);
    }
 
    struct vn_sampler_ycbcr_conversion *conv =