From 7c9f6c9964647c4177b5ae7ced1c2628cef35a5d Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Mon, 14 Feb 2022 23:18:32 +0000 Subject: [PATCH] venus: pass necessary format list at ahb image format query Signed-off-by: Yiwei Zhang Part-of: --- src/virtio/vulkan/vn_android.c | 35 ++++++++++++++++++++++++++ src/virtio/vulkan/vn_android.h | 10 ++++++++ src/virtio/vulkan/vn_physical_device.c | 31 +++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c index 5c454066580..b86fa99ec31 100644 --- a/src/virtio/vulkan/vn_android.c +++ b/src/virtio/vulkan/vn_android.c @@ -128,6 +128,41 @@ vn_android_ahb_format_from_vk_format(VkFormat format) } } +const VkFormat * +vn_android_format_to_view_formats(VkFormat format, uint32_t *out_count) +{ + /* For AHB image prop query and creation, venus overrides the tiling to + * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, which requires to chain + * VkImageFormatListCreateInfo struct in the corresponding pNext when the + * VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is set. Those AHB images are assumed + * to be mutable no more than sRGB-ness, and the implementations can fail + * whenever going beyond. + * + * This helper provides the view formats that have sRGB variants for the + * image format that venus supports. + */ + static const VkFormat view_formats_r8g8b8a8[] = { + VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB + }; + static const VkFormat view_formats_r8g8b8[] = { VK_FORMAT_R8G8B8_UNORM, + VK_FORMAT_R8G8B8_SRGB }; + + switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM: + *out_count = ARRAY_SIZE(view_formats_r8g8b8a8); + return view_formats_r8g8b8a8; + break; + case VK_FORMAT_R8G8B8_UNORM: + *out_count = ARRAY_SIZE(view_formats_r8g8b8); + return view_formats_r8g8b8; + break; + default: + /* let the caller handle the fallback case */ + *out_count = 0; + return NULL; + } +} + VkFormat vn_android_drm_format_to_vk_format(uint32_t format) { diff --git a/src/virtio/vulkan/vn_android.h b/src/virtio/vulkan/vn_android.h index 02dca992170..873f214ff8d 100644 --- a/src/virtio/vulkan/vn_android.h +++ b/src/virtio/vulkan/vn_android.h @@ -40,6 +40,9 @@ vn_android_get_drm_format_modifier_info( const VkPhysicalDeviceImageFormatInfo2 *format_info, VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info); +const VkFormat * +vn_android_format_to_view_formats(VkFormat format, uint32_t *out_count); + uint64_t vn_android_get_ahb_usage(const VkImageUsageFlags usage, const VkImageCreateFlags flags); @@ -106,6 +109,13 @@ vn_android_get_drm_format_modifier_info( return false; } +static inline const VkFormat * +vn_android_format_to_view_formats(UNUSED VkFormat format, + UNUSED uint32_t *out_count) +{ + return NULL; +} + static inline uint64_t vn_android_get_ahb_usage(UNUSED const VkImageUsageFlags usage, UNUSED const VkImageCreateFlags flags) diff --git a/src/virtio/vulkan/vn_physical_device.c b/src/virtio/vulkan/vn_physical_device.c index e7f23a04f26..afe9cdc599a 100644 --- a/src/virtio/vulkan/vn_physical_device.c +++ b/src/virtio/vulkan/vn_physical_device.c @@ -2129,6 +2129,7 @@ vn_physical_device_fix_image_format_info( VkBaseOutStructure *dst = (void *)&local_info->format; bool is_ahb = false; + bool has_format_list = false; /* we should generate deep copy functions... */ vk_foreach_struct_const(src, info->pNext) { void *pnext = NULL; @@ -2143,6 +2144,7 @@ vn_physical_device_fix_image_format_info( pnext = &local_info->external; break; case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: + has_format_list = true; memcpy(&local_info->list, src, sizeof(local_info->list)); pnext = &local_info->list; break; @@ -2175,6 +2177,35 @@ vn_physical_device_fix_image_format_info( dst->pNext = (void *)&local_info->modifier; dst = dst->pNext; + + if ((info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && + !local_info->list.viewFormatCount) { + /* 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. + */ + VkImageFormatListCreateInfo *list = &local_info->list; + uint32_t vcount = 0; + const VkFormat *vformats = + vn_android_format_to_view_formats(info->format, &vcount); + if (!vformats) { + /* local_info persists through the image format query call */ + vformats = &local_info->format.format; + vcount = 1; + } + + list->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO; + list->viewFormatCount = vcount; + list->pViewFormats = vformats; + + if (!has_format_list) { + dst->pNext = (void *)list; + dst = dst->pNext; + } + } } dst->pNext = NULL;