From 850ede0970af69ea9ed78ca6980ca2edb174b531 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 15 Jul 2025 18:43:18 +0000 Subject: [PATCH] vulkan/android: add vk_android_get_ahb_image_properties This is to assist GetPhysicalDeviceImageFormatProperties2 query. Acked-by: Rob Clark Part-of: --- src/vulkan/runtime/vk_android.c | 78 ++++++++++++++++++++++++++++++++- src/vulkan/runtime/vk_android.h | 14 ++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/vulkan/runtime/vk_android.c b/src/vulkan/runtime/vk_android.c index 04b594ce629..2336479fa0d 100644 --- a/src/vulkan/runtime/vk_android.c +++ b/src/vulkan/runtime/vk_android.c @@ -645,11 +645,15 @@ vk_ahb_probe_format(VkFormat vk_format, VkImageCreateFlags vk_create, VkImageUsageFlags vk_usage) { + const uint32_t ahb_format = vk_image_format_to_ahb_format(vk_format); + if (!ahb_format) + return false; + AHardwareBuffer_Desc desc = { .width = 16, .height = 16, .layers = 1, - .format = vk_image_format_to_ahb_format(vk_format), + .format = ahb_format, .usage = vk_image_usage_to_ahb_usage(vk_create, vk_usage), }; #if ANDROID_API_LEVEL >= 29 @@ -909,4 +913,76 @@ vk_common_GetAndroidHardwareBufferPropertiesANDROID( return VK_SUCCESS; } +/* AHB image support per spec: + * + * - Any Android hardware buffer successfully allocated outside Vulkan with + * usage that includes AHARDWAREBUFFER_USAGE_GPU_* must be supported when + * using equivalent Vulkan image parameters. + * + * - If a given choice of image parameters are supported for import, they can + * also be used to create an image and memory that will be exported to an + * Android hardware buffer. + * + * An additional constraint derived from above is: + * + * - If that AHB cannot get allocated out, then the Vulkan driver must not + * advertise support for the AHB backed image. + * + * Based on all above, this helper implements the AHB validation as well as + * the AHB external and usage props filling. + */ +VkResult +vk_android_get_ahb_image_properties( + VkPhysicalDevice pdev_handle, + const VkPhysicalDeviceImageFormatInfo2 *info, + VkImageFormatProperties2 *props) +{ + VK_FROM_HANDLE(vk_physical_device, pdevice, pdev_handle); + VkExternalImageFormatProperties *external_props; + VkAndroidHardwareBufferUsageANDROID *ahb_usage; + + ASSERTED const VkPhysicalDeviceExternalImageFormatInfo *external_info = + vk_find_struct_const(info->pNext, + PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO); + assert( + external_info && + external_info->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID); + + if (info->type != VK_IMAGE_TYPE_2D) { + return vk_errorf(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED, + "type (%u) unsupported for AHB", info->type); + } + + if (!vk_ahb_probe_format(info->format, info->flags, info->usage)) { + return vk_errorf(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED, + "format (%x) flags (%x) usage (%x) unsupported for AHB", + info->format, info->flags, info->usage); + } + + external_props = + vk_find_struct(props->pNext, EXTERNAL_IMAGE_FORMAT_PROPERTIES); + if (external_props) { + external_props->externalMemoryProperties = (VkExternalMemoryProperties){ + .externalMemoryFeatures = + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT | + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, + .exportFromImportedHandleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, + .compatibleHandleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, + }; + } + + ahb_usage = + vk_find_struct(props->pNext, ANDROID_HARDWARE_BUFFER_USAGE_ANDROID); + if (ahb_usage) { + ahb_usage->androidHardwareBufferUsage = + vk_image_usage_to_ahb_usage(info->flags, info->usage); + } + + return VK_SUCCESS; +} + #endif /* ANDROID_API_LEVEL >= 26 */ diff --git a/src/vulkan/runtime/vk_android.h b/src/vulkan/runtime/vk_android.h index b1adcc878d2..120889f3160 100644 --- a/src/vulkan/runtime/vk_android.h +++ b/src/vulkan/runtime/vk_android.h @@ -104,6 +104,11 @@ VkResult vk_android_get_ahb_layout( VkImageDrmFormatModifierExplicitCreateInfoEXT *out, VkSubresourceLayout *out_layouts, int max_planes); +VkResult vk_android_get_ahb_image_properties( + VkPhysicalDevice pdev_handle, + const VkPhysicalDeviceImageFormatInfo2 *info, + VkImageFormatProperties2 *props); + #else /* DETECT_OS_ANDROID && ANDROID_API_LEVEL >= 26 */ static inline uint64_t @@ -154,6 +159,15 @@ vk_android_get_ahb_layout( return VK_ERROR_FEATURE_NOT_PRESENT; } +static inline VkResult +vk_android_get_ahb_image_properties( + VkPhysicalDevice pdev_handle, + const VkPhysicalDeviceImageFormatInfo2 *info, + VkImageFormatProperties2 *props) +{ + return VK_ERROR_FORMAT_NOT_SUPPORTED; +} + #endif /* ANDROID_API_LEVEL >= 26 */ #ifdef __cplusplus