From 87b1a46d887739a8d29fe06009342c9972d95bd5 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Sat, 26 Jul 2025 04:21:00 +0000 Subject: [PATCH] venus: adopt vk_common_GetAndroidHardwareBufferPropertiesANDROID This is based on: 1. external format handling has been made passive 2. blob mapping size has been made passive 3. common helper has improved mem type reporting Reviewed-by: Antonio Ospite Part-of: --- src/virtio/vulkan/vn_android.c | 270 --------------------------------- src/virtio/vulkan/vn_android.h | 9 -- src/virtio/vulkan/vn_image.c | 18 +-- src/virtio/vulkan/vn_image.h | 4 - 4 files changed, 6 insertions(+), 295 deletions(-) diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c index 31c3b6660b3..44966c6f1a6 100644 --- a/src/virtio/vulkan/vn_android.c +++ b/src/virtio/vulkan/vn_android.c @@ -26,7 +26,6 @@ #include "vn_queue.h" struct vn_android_gralloc_buffer_properties { - uint32_t drm_fourcc; uint32_t num_planes; uint64_t modifier; @@ -67,7 +66,6 @@ vn_android_gralloc_get_buffer_properties( assert(info.num_planes <= 4); - out_props->drm_fourcc = info.drm_fourcc; out_props->num_planes = info.num_planes; for (uint32_t i = 0; i < info.num_planes; i++) { if (!info.strides[i]) { @@ -153,99 +151,6 @@ vn_android_format_to_view_formats(VkFormat format, uint32_t *out_count) } } -VkFormat -vn_android_drm_format_to_vk_format(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_XBGR8888: - return VK_FORMAT_R8G8B8A8_UNORM; - case DRM_FORMAT_BGR888: - return VK_FORMAT_R8G8B8_UNORM; - case DRM_FORMAT_RGB565: - return VK_FORMAT_R5G6B5_UNORM_PACK16; - case DRM_FORMAT_ABGR16161616F: - return VK_FORMAT_R16G16B16A16_SFLOAT; - case DRM_FORMAT_ABGR2101010: - return VK_FORMAT_A2B10G10R10_UNORM_PACK32; - case DRM_FORMAT_R8: - return VK_FORMAT_R8_UNORM; - case DRM_FORMAT_YVU420: - return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; - case DRM_FORMAT_NV12: - return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; - default: - return VK_FORMAT_UNDEFINED; - } -} - -static bool -vn_android_drm_format_is_yuv(uint32_t format) -{ - assert(vn_android_drm_format_to_vk_format(format) != VK_FORMAT_UNDEFINED); - - switch (format) { - case DRM_FORMAT_YVU420: - case DRM_FORMAT_NV12: - return true; - default: - return false; - } -} - -static VkResult -vn_android_get_modifier_properties(struct vn_device *dev, - VkFormat format, - uint64_t modifier, - VkDrmFormatModifierPropertiesEXT *out_props) -{ - VkPhysicalDevice physical_device = - vn_physical_device_to_handle(dev->physical_device); - VkDrmFormatModifierPropertiesListEXT mod_prop_list = { - .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, - }; - VkFormatProperties2 format_prop = { - .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, - .pNext = &mod_prop_list, - }; - - vn_GetPhysicalDeviceFormatProperties2(physical_device, format, - &format_prop); - - if (!mod_prop_list.drmFormatModifierCount) { - vn_log(dev->instance, "No compatible modifier for VkFormat(%u)", - format); - return VK_ERROR_INVALID_EXTERNAL_HANDLE; - } - - STACK_ARRAY(VkDrmFormatModifierPropertiesEXT, mod_props, - mod_prop_list.drmFormatModifierCount); - - mod_prop_list.pDrmFormatModifierProperties = mod_props; - vn_GetPhysicalDeviceFormatProperties2(physical_device, format, - &format_prop); - - bool modifier_found = false; - for (uint32_t i = 0; i < mod_prop_list.drmFormatModifierCount; i++) { - if (mod_props[i].drmFormatModifier == modifier) { - *out_props = mod_props[i]; - modifier_found = true; - break; - } - } - - STACK_ARRAY_FINISH(mod_props); - - if (!modifier_found) { - vn_log(dev->instance, - "No matching modifier(%" PRIu64 ") properties for VkFormat(%u)", - modifier, format); - return VK_ERROR_INVALID_EXTERNAL_HANDLE; - } - - return VK_SUCCESS; -} - struct vn_android_image_builder { VkImageCreateInfo create; VkSubresourceLayout layouts[4]; @@ -513,181 +418,6 @@ vn_android_get_wsi_memory_from_bind_info( return img->wsi.memory; } -static VkResult -vn_android_get_ahb_format_properties( - struct vn_device *dev, - const struct AHardwareBuffer *ahb, - VkAndroidHardwareBufferFormatPropertiesANDROID *out_props) -{ - AHardwareBuffer_Desc desc; - VkFormat format; - struct vn_android_gralloc_buffer_properties buf_props; - VkDrmFormatModifierPropertiesEXT mod_props; - - AHardwareBuffer_describe(ahb, &desc); - if (!(desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | - AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER | - AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER))) { - vn_log(dev->instance, - "AHB usage(%" PRIu64 ") must include at least one GPU bit", - desc.usage); - 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_gralloc_get_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_drm_format_to_vk_format(buf_props.drm_fourcc); - if (format == VK_FORMAT_UNDEFINED) { - 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, &mod_props); - if (result != VK_SUCCESS) - return result; - - if (mod_props.drmFormatModifierPlaneCount != buf_props.num_planes) { - vn_log(dev->instance, - "drmFormatModifierPlaneCount(%u) != buf_props.num_planes(%u) " - "for DRM format modifier(%" PRIu64 ")", - mod_props.drmFormatModifierPlaneCount, buf_props.num_planes, - buf_props.modifier); - return VK_ERROR_INVALID_EXTERNAL_HANDLE; - } - - /* The spec requires that formatFeatures must include at least one of - * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or - * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT. - */ - const VkFormatFeatureFlags format_features = - mod_props.drmFormatModifierTilingFeatures | - VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; - - /* 11.2.7. Android Hardware Buffer External Memory - * - * 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. - */ - const bool is_yuv = vn_android_drm_format_is_yuv(buf_props.drm_fourcc); - const VkSamplerYcbcrModelConversion model = - is_yuv ? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 - : VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; - - /* ANGLE expects VK_FORMAT_UNDEFINED with externalFormat resolved from - * AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED and any supported planar - * AHB formats. Venus supports below explicit ones: - * - AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 (DRM_FORMAT_NV12) - * - AHARDWAREBUFFER_FORMAT_YV12 (DRM_FORMAT_YVU420) - */ - if (desc.format == AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED || is_yuv) - format = VK_FORMAT_UNDEFINED; - - *out_props = (VkAndroidHardwareBufferFormatPropertiesANDROID) { - .sType = out_props->sType, - .pNext = out_props->pNext, - .format = format, - .externalFormat = buf_props.drm_fourcc, - .formatFeatures = format_features, - .samplerYcbcrConversionComponents = { - .r = VK_COMPONENT_SWIZZLE_IDENTITY, - .g = VK_COMPONENT_SWIZZLE_IDENTITY, - .b = VK_COMPONENT_SWIZZLE_IDENTITY, - .a = VK_COMPONENT_SWIZZLE_IDENTITY, - }, - .suggestedYcbcrModel = model, - /* match EGL_YUV_NARROW_RANGE_EXT used in egl platform_android */ - .suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - .suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, - .suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, - }; - - return VK_SUCCESS; -} - -VkResult -vn_GetAndroidHardwareBufferPropertiesANDROID( - VkDevice device, - const struct AHardwareBuffer *buffer, - VkAndroidHardwareBufferPropertiesANDROID *pProperties) -{ - VN_TRACE_FUNC(); - struct vn_device *dev = vn_device_from_handle(device); - VkResult result = VK_SUCCESS; - int dma_buf_fd = -1; - uint64_t alloc_size = 0; - uint32_t mem_type_bits = 0; - - VkAndroidHardwareBufferFormatProperties2ANDROID *format_props2 = - vk_find_struct(pProperties->pNext, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID); - VkAndroidHardwareBufferFormatPropertiesANDROID *format_props = - vk_find_struct(pProperties->pNext, - ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID); - if (format_props2 || format_props) { - VkAndroidHardwareBufferFormatPropertiesANDROID local_props = { - .sType = - VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID, - }; - if (!format_props) - format_props = &local_props; - - result = - vn_android_get_ahb_format_properties(dev, buffer, format_props); - if (result != VK_SUCCESS) - return vn_error(dev->instance, result); - - if (format_props2) { - format_props2->format = format_props->format; - format_props2->externalFormat = format_props->externalFormat; - format_props2->formatFeatures = - (VkFormatFeatureFlags2)format_props->formatFeatures; - format_props2->samplerYcbcrConversionComponents = - format_props->samplerYcbcrConversionComponents; - format_props2->suggestedYcbcrModel = - format_props->suggestedYcbcrModel; - format_props2->suggestedYcbcrRange = - format_props->suggestedYcbcrRange; - format_props2->suggestedXChromaOffset = - format_props->suggestedXChromaOffset; - format_props2->suggestedYChromaOffset = - format_props->suggestedYChromaOffset; - } - } - - dma_buf_fd = vn_android_gralloc_get_dma_buf_fd( - AHardwareBuffer_getNativeHandle(buffer)); - if (dma_buf_fd < 0) - return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); - - result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size, - &mem_type_bits); - if (result != VK_SUCCESS) - return vn_error(dev->instance, result); - - pProperties->allocationSize = alloc_size; - pProperties->memoryTypeBits = mem_type_bits; - - return VK_SUCCESS; -} - static AHardwareBuffer * vn_android_ahb_allocate(uint32_t width, uint32_t height, diff --git a/src/virtio/vulkan/vn_android.h b/src/virtio/vulkan/vn_android.h index 9a08662e512..32d8fe26aad 100644 --- a/src/virtio/vulkan/vn_android.h +++ b/src/virtio/vulkan/vn_android.h @@ -42,9 +42,6 @@ vn_android_device_import_ahb(struct vn_device *dev, struct vn_device_memory *mem, const struct VkMemoryAllocateInfo *alloc_info); -VkFormat -vn_android_drm_format_to_vk_format(uint32_t format); - uint32_t vn_android_get_ahb_buffer_memory_type_bits(struct vn_device *dev); @@ -91,12 +88,6 @@ vn_android_device_import_ahb( return VK_ERROR_OUT_OF_HOST_MEMORY; } -static inline VkFormat -vn_android_drm_format_to_vk_format(UNUSED uint32_t format) -{ - return VK_FORMAT_UNDEFINED; -} - static inline uint32_t vn_android_get_ahb_buffer_memory_type_bits(UNUSED struct vn_device *dev) { diff --git a/src/virtio/vulkan/vn_image.c b/src/virtio/vulkan/vn_image.c index f49e4a5e053..0ad5871102c 100644 --- a/src/virtio/vulkan/vn_image.c +++ b/src/virtio/vulkan/vn_image.c @@ -431,13 +431,10 @@ vn_image_deferred_info_init(struct vn_image *img, pnext = &info->stencil; break; case VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID: { - const uint32_t drm_format = + const uint32_t external_format = (uint32_t)((const VkExternalFormatANDROID *)src)->externalFormat; - if (drm_format) { - info->create.format = - vn_android_drm_format_to_vk_format(drm_format); - info->from_external_format = true; - } + if (external_format != 0) + info->create.format = external_format; } break; case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR: img->wsi.is_wsi = true; @@ -923,11 +920,9 @@ vn_CreateImageView(VkDevice device, pAllocator ? pAllocator : &dev->base.vk.alloc; VkImageViewCreateInfo local_info; - if (img->deferred_info && img->deferred_info->from_external_format) { - assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); - + if (pCreateInfo->format == VK_FORMAT_UNDEFINED) { local_info = *pCreateInfo; - local_info.format = img->deferred_info->create.format; + local_info.format = img->base.vk.format; pCreateInfo = &local_info; assert(pCreateInfo->format != VK_FORMAT_UNDEFINED); @@ -1038,8 +1033,7 @@ vn_CreateSamplerYcbcrConversion( assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); local_info = *pCreateInfo; - local_info.format = - vn_android_drm_format_to_vk_format(ext_info->externalFormat); + local_info.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; diff --git a/src/virtio/vulkan/vn_image.h b/src/virtio/vulkan/vn_image.h index c15ae8dd9fb..869664a862f 100644 --- a/src/virtio/vulkan/vn_image.h +++ b/src/virtio/vulkan/vn_image.h @@ -47,10 +47,6 @@ struct vn_image_create_deferred_info { VkImageFormatListCreateInfo list; VkImageStencilUsageCreateInfo stencil; - /* True if VkImageCreateInfo::format is translated from a non-zero - * VkExternalFormatANDROID::externalFormat for the AHB image. - */ - bool from_external_format; /* track whether vn_image_init_deferred succeeds */ bool initialized; };