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 <antonio.ospite@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36388>
This commit is contained in:
Yiwei Zhang
2025-07-26 04:21:00 +00:00
committed by Marge Bot
parent aac51c3a0b
commit 87b1a46d88
4 changed files with 6 additions and 295 deletions
-270
View File
@@ -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,
-9
View File
@@ -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)
{
+6 -12
View File
@@ -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;
-4
View File
@@ -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;
};