vulkan/android: Add deferred image helper

Add a new helper based on panvk's implementation added in
075d78115e ("panvk: implement deferred image creation").

vk_android_init_deferred_image  deep-copies and sanitizes a
VkImageCreateInfo chain for deferred Android native buffer (ANB)
alias image creation.

Signed-off-by: Valentine Burley <valentine.burley@collabora.com>
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40635>
This commit is contained in:
Valentine Burley 2026-03-25 10:57:40 +01:00 committed by Marge Bot
parent ba92143ef2
commit 013dee3b8f
4 changed files with 106 additions and 0 deletions

View file

@ -261,6 +261,91 @@ vk_android_get_anb_layout(
out_layouts, max_planes);
}
VkResult
vk_android_init_deferred_image(struct vk_device *device,
struct vk_image *image,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator)
{
/* collect all dynamic array infos */
uint32_t queue_family_count = 0;
uint32_t view_format_count = 0;
if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT)
queue_family_count = pCreateInfo->queueFamilyIndexCount;
const VkImageFormatListCreateInfo *raw_list =
vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
if (raw_list)
view_format_count = raw_list->viewFormatCount;
/* Extend below when drivers support more extensions that interact with ANB
* or AHB. e.g. VK_EXT_image_compression_control
*/
VK_MULTIALLOC(ma);
VK_MULTIALLOC_DECL(&ma, VkImageCreateInfo, create_info, 1);
VK_MULTIALLOC_DECL(&ma, VkImageFormatListCreateInfo, list_info, 1);
VK_MULTIALLOC_DECL(&ma, VkImageStencilUsageCreateInfo, stencil_info, 1);
VK_MULTIALLOC_DECL(&ma, uint32_t, queue_families, queue_family_count);
VK_MULTIALLOC_DECL(&ma, VkFormat, view_formats, view_format_count);
if (!vk_multialloc_zalloc2(&ma, &device->alloc, pAllocator,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
return VK_ERROR_OUT_OF_HOST_MEMORY;
/* prepare the deferred VkImageCreateInfo chain */
*create_info = *pCreateInfo;
create_info->pNext = NULL;
/* Assign resolved AHB external format */
create_info->format = image->format;
create_info->tiling = image->tiling =
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
typed_memcpy(queue_families, pCreateInfo->pQueueFamilyIndices,
pCreateInfo->queueFamilyIndexCount);
create_info->pQueueFamilyIndices = queue_families;
}
/* Per spec section 12.3. Images
*
* - If tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and flags contains
* VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, then the pNext chain must include a
* VkImageFormatListCreateInfo structure with non-zero viewFormatCount.
*
* ANB and aliased ANB always chain proper format list for mutable swapchain
* image support, but AHB is allowed to mutate without an explicit format
* list due to legacy spec issue. So we chain a view format of the create
* format itself to satisfy VK_EXT_image_drm_format_modifier VUs.
*/
if (view_format_count ||
image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
if (view_format_count) {
typed_memcpy(view_formats, raw_list->pViewFormats, view_format_count);
} else {
view_format_count = 1;
view_formats = &create_info->format;
}
*list_info = (VkImageFormatListCreateInfo){
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
.viewFormatCount = view_format_count,
.pViewFormats = view_formats,
};
__vk_append_struct(create_info, list_info);
}
if (image->stencil_usage) {
*stencil_info = (VkImageStencilUsageCreateInfo){
.sType = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
.stencilUsage = image->stencil_usage,
};
__vk_append_struct(create_info, stencil_info);
}
image->android_deferred_create_info = create_info;
return VK_SUCCESS;
}
static VkResult
setup_gralloc0_usage(VkFormat format, VkImageUsageFlags image_usage,
int *out_gralloc_usage)

View file

@ -51,6 +51,11 @@ VkResult vk_android_get_anb_layout(
VkImageDrmFormatModifierExplicitCreateInfoEXT *out,
VkSubresourceLayout *out_layouts, int max_planes);
VkResult vk_android_init_deferred_image(struct vk_device *device,
struct vk_image *image,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator);
#else
static inline struct u_gralloc *
@ -77,6 +82,15 @@ vk_android_get_anb_layout(
return VK_ERROR_FEATURE_NOT_PRESENT;
}
static inline VkResult
vk_android_init_deferred_image(struct vk_device *device,
struct vk_image *image,
const VkImageCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator)
{
return VK_ERROR_FEATURE_NOT_PRESENT;
}
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR) && ANDROID_API_LEVEL >= 26

View file

@ -171,6 +171,7 @@ vk_image_destroy(struct vk_device *device,
device->dispatch_table.FreeMemory(
(VkDevice)device, image->anb_memory, alloc);
}
vk_free2(&device->alloc, alloc, image->android_deferred_create_info);
#endif
vk_object_free(device, alloc, image);
}

View file

@ -99,6 +99,12 @@ struct vk_image {
* but it may be overridden by the driver as needed.
*/
uint32_t ahb_format;
/* Deep-copied and sanitized VkImageCreateInfo for deferred ANB alias
* images. Set by vk_android_init_deferred_image() and freed automatically
* by vk_image_destroy(). NULL for non-deferred images.
*/
VkImageCreateInfo *android_deferred_create_info;
#endif
};
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image, base, VkImage,