From 280281f8f72e0934d08557f370f9e22b61a3bf68 Mon Sep 17 00:00:00 2001 From: Chris Spencer Date: Sun, 30 Jul 2023 09:23:05 +0100 Subject: [PATCH] anv/android: Add support for AHARDWAREBUFFER_FORMAT_YV12 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default MediaCodec software video decoder returns frames in this format. Signed-off-by: Chris Spencer Reviewed-by: Tapani Pälli Part-of: --- src/intel/vulkan/anv_android.c | 2 ++ src/intel/vulkan/anv_image.c | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index 76954d0304c..e7c27e980a4 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -119,6 +119,8 @@ vk_format_from_android(unsigned android_format, unsigned android_usage) case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL: return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; + case AHARDWAREBUFFER_FORMAT_YV12: + return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED: if (android_usage & BUFFER_USAGE_CAMERA_MASK) return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 148e7204499..a0760d23050 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -1137,8 +1137,29 @@ add_all_surfaces_implicit_layout( if (ycbcr_info) assert(ycbcr_info->n_planes == image->n_planes); + unsigned num_aspects = 0; + VkImageAspectFlagBits aspects[3]; u_foreach_bit(b, image->vk.aspects) { - VkImageAspectFlagBits aspect = 1 << b; + assert(num_aspects < 3); + aspects[num_aspects++] = 1 << b; + } + assert(num_aspects == image->n_planes); + + /* The Android hardware buffer YV12 format has the planes ordered as Y-Cr-Cb, + * while Vulkan expects VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM to be in Y-Cb-Cr. + * Adjust the order we add the ISL surfaces accordingly so the implicit + * offset gets calculated correctly. + */ + if (image->from_ahb && image->vk.format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { + assert(num_aspects == 3); + assert(aspects[1] == VK_IMAGE_ASPECT_PLANE_1_BIT); + assert(aspects[2] == VK_IMAGE_ASPECT_PLANE_2_BIT); + aspects[1] = VK_IMAGE_ASPECT_PLANE_2_BIT; + aspects[2] = VK_IMAGE_ASPECT_PLANE_1_BIT; + } + + for (unsigned i = 0; i < num_aspects; i++) { + VkImageAspectFlagBits aspect = aspects[i]; const uint32_t plane = anv_image_aspect_to_plane(image, aspect); const struct anv_format_plane plane_format = anv_get_format_plane(devinfo, image->vk.format, plane, image->vk.tiling);