From dcffe932a09fed978e9bdbced377f56ff9b4d4e4 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 20 Aug 2025 18:37:38 -0700 Subject: [PATCH] anv: adopt common GetAndroidHardwareBufferPropertiesANDROID ANV currently carries a partial copy of the gralloc mapper's format resolving code, while the ground truth solely resides inside the gralloc. The local copy is delicate and unable to maintain compatibility with different gralloc implementations because AHB formats like Y8Cb8Cr8_420 and IMPLEMENTATION_DEFINED are flexible formats, and can be resolved to different underlying drm fourcc formats depending on the usage and media IPs. The common impl is more correct as it relies on the info from gralloc mapper side, and it only sets the minimal set of explicit formats to avoid hitting spec corner case of allocating out AHB with flexible formats (missing half of the media usage bits might end up allocating something different that potentially get resolved to a different VkFormat as well). Reviewed-by: Lucas Fryzek Part-of: --- src/intel/vulkan/anv_android.c | 169 --------------------------------- 1 file changed, 169 deletions(-) diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_android.c index 1d5e63f8c41..5e95149dbfa 100644 --- a/src/intel/vulkan/anv_android.c +++ b/src/intel/vulkan/anv_android.c @@ -21,176 +21,7 @@ * IN THE SOFTWARE. */ -#include -#include - #include "anv_private.h" -#include "vk_android.h" -#include "vk_common_entrypoints.h" -#include "vk_util.h" - -#if ANDROID_API_LEVEL >= 26 -#include - -static inline VkFormat -vk_format_from_android(unsigned android_format, unsigned android_usage) -{ - switch (android_format) { - case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: - return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; - case AHARDWAREBUFFER_FORMAT_YV12: - return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; - case AHARDWAREBUFFER_FORMAT_YCbCr_P010: - return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16; - case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED: - if (android_usage & AHARDWAREBUFFER_USAGE_CAMERA_MASK) - return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; - else - return VK_FORMAT_R8G8B8_UNORM; - default: - return vk_ahb_format_to_image_format(android_format); - } -} - -static VkResult -get_ahw_buffer_format_properties2( - VkDevice device_h, - const struct AHardwareBuffer *buffer, - VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties) -{ - ANV_FROM_HANDLE(anv_device, device, device_h); - - /* Get a description of buffer contents . */ - AHardwareBuffer_Desc desc; - AHardwareBuffer_describe(buffer, &desc); - - /* Verify description. */ - uint64_t gpu_usage = - AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | - AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | - AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER; - - /* "Buffer must be a valid Android hardware buffer object with at least - * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags." - */ - if (!(desc.usage & (gpu_usage))) - return VK_ERROR_INVALID_EXTERNAL_HANDLE; - - /* Fill properties fields based on description. */ - VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties; - - p->format = vk_format_from_android(desc.format, desc.usage); - p->externalFormat = p->format; - - const struct anv_format *anv_format = - anv_get_format(device->physical, p->format); - - /* Default to OPTIMAL tiling but set to linear in case - * of AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER usage. - */ - VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; - - if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) - tiling = VK_IMAGE_TILING_LINEAR; - - p->formatFeatures = - anv_get_image_format_features2(device->physical, p->format, anv_format, - tiling, 0 /* usage */, 0 /* flags */, - NULL); - - /* "Images can be created with an external format even if the Android hardware - * buffer has a format which has an equivalent Vulkan format to enable - * consistent handling of images from sources that might use either category - * of format. However, all images created with an external format are subject - * to the valid usage requirements associated with external formats, even if - * the Android hardware buffer’s format has a Vulkan equivalent." - * - * "The formatFeatures member *must* include - * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of - * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or - * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT" - */ - p->formatFeatures |= - VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT; - - /* "Implementations may not always be able to determine the color model, - * numerical range, or chroma offsets of the image contents, so the values - * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions. - * Applications should treat these values as sensible defaults to use in - * the absence of more reliable information obtained through some other - * means." - */ - p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY; - p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY; - p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY; - p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY; - - p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601; - p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW; - - p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT; - p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT; - - return VK_SUCCESS; -} - -VkResult -anv_GetAndroidHardwareBufferPropertiesANDROID( - VkDevice device_h, - const struct AHardwareBuffer *buffer, - VkAndroidHardwareBufferPropertiesANDROID *pProperties) -{ - ANV_FROM_HANDLE(anv_device, dev, device_h); - - VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop = - vk_find_struct(pProperties->pNext, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID); - /* Fill format properties of an Android hardware buffer. */ - if (format_prop) { - VkAndroidHardwareBufferFormatProperties2ANDROID format_prop2 = { - .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID, - }; - get_ahw_buffer_format_properties2(device_h, buffer, &format_prop2); - - format_prop->format = format_prop2.format; - format_prop->externalFormat = format_prop2.externalFormat; - format_prop->formatFeatures = - vk_format_features2_to_features(format_prop2.formatFeatures); - format_prop->samplerYcbcrConversionComponents = - format_prop2.samplerYcbcrConversionComponents; - format_prop->suggestedYcbcrModel = format_prop2.suggestedYcbcrModel; - format_prop->suggestedYcbcrRange = format_prop2.suggestedYcbcrRange; - format_prop->suggestedXChromaOffset = format_prop2.suggestedXChromaOffset; - format_prop->suggestedYChromaOffset = format_prop2.suggestedYChromaOffset; - } - - VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 = - vk_find_struct(pProperties->pNext, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID); - if (format_prop2) - get_ahw_buffer_format_properties2(device_h, buffer, format_prop2); - - /* NOTE - We support buffers with only one handle but do not error on - * multiple handle case. Reason is that we want to support YUV formats - * where we have many logical planes but they all point to the same - * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM. - */ - const native_handle_t *handle = - AHardwareBuffer_getNativeHandle(buffer); - int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1; - if (dma_buf < 0) - return VK_ERROR_INVALID_EXTERNAL_HANDLE; - - /* All memory types. */ - uint32_t memory_types = (1ull << dev->physical->memory.type_count) - 1; - - pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END); - pProperties->memoryTypeBits = memory_types; - - return VK_SUCCESS; -} - -#endif /* * Called from anv_AllocateMemory when import AHardwareBuffer.