diff --git a/src/vulkan/runtime/vk_android.c b/src/vulkan/runtime/vk_android.c index 505ada00b46..361f4f79e6f 100644 --- a/src/vulkan/runtime/vk_android.c +++ b/src/vulkan/runtime/vk_android.c @@ -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) diff --git a/src/vulkan/runtime/vk_android.h b/src/vulkan/runtime/vk_android.h index 05258786b8d..a25cc18f650 100644 --- a/src/vulkan/runtime/vk_android.h +++ b/src/vulkan/runtime/vk_android.h @@ -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 diff --git a/src/vulkan/runtime/vk_image.c b/src/vulkan/runtime/vk_image.c index 0e30c25a32e..f5e67646c61 100644 --- a/src/vulkan/runtime/vk_image.c +++ b/src/vulkan/runtime/vk_image.c @@ -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); } diff --git a/src/vulkan/runtime/vk_image.h b/src/vulkan/runtime/vk_image.h index dfabbcfa3c6..c8db60a1ba9 100644 --- a/src/vulkan/runtime/vk_image.h +++ b/src/vulkan/runtime/vk_image.h @@ -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,