From 53e35f716e26c2074a286e97fcc6ba1dd656b851 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Sun, 23 May 2021 21:05:15 +0000 Subject: [PATCH] venus: fix AHB image format properties query 1. bail early if there's no compatiable AHB format 2. check against the corresponding drm format modifier Signed-off-by: Yiwei Zhang Reviewed-by: Chia-I Wu Part-of: --- src/virtio/vulkan/vn_android.c | 80 ++++++++++++++++++++++++++++++++++ src/virtio/vulkan/vn_android.h | 13 ++++++ src/virtio/vulkan/vn_device.c | 19 +++++++- 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c index cf7d99e8793..463c1662c6d 100644 --- a/src/virtio/vulkan/vn_android.c +++ b/src/virtio/vulkan/vn_android.c @@ -867,3 +867,83 @@ vn_GetAndroidHardwareBufferPropertiesANDROID( return VK_SUCCESS; } + +static AHardwareBuffer * +vn_android_ahb_allocate(uint32_t width, + uint32_t height, + uint32_t layers, + uint32_t format, + uint64_t usage) +{ + AHardwareBuffer *ahb = NULL; + AHardwareBuffer_Desc desc; + int ret = 0; + + memset(&desc, 0, sizeof(desc)); + desc.width = width; + desc.height = height; + desc.layers = layers; + desc.format = format; + desc.usage = usage; + + ret = AHardwareBuffer_allocate(&desc, &ahb); + if (ret) { + /* We just log the error code here for now since the platform falsely + * maps all gralloc allocation failures to oom. + */ + vn_log(NULL, "AHB alloc(w=%u,h=%u,l=%u,f=%u,u=%" PRIu64 ") failed(%d)", + width, height, layers, format, usage, ret); + return NULL; + } + + return ahb; +} + +bool +vn_android_get_drm_format_modifier_info( + const VkPhysicalDeviceImageFormatInfo2 *format_info, + VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info) +{ + /* To properly fill VkPhysicalDeviceImageDrmFormatModifierInfoEXT, we have + * to allocate an ahb to retrieve the drm format modifier. For the image + * sharing mode, we assume VK_SHARING_MODE_EXCLUSIVE for now. + */ + AHardwareBuffer *ahb = NULL; + const native_handle_t *handle = NULL; + uint32_t format = 0; + uint64_t usage = 0; + uint32_t strides[4] = { 0, 0, 0, 0 }; + uint32_t offsets[4] = { 0, 0, 0, 0 }; + uint64_t format_modifier = 0; + + assert(format_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT); + + format = vn_android_ahb_format_from_vk_format(format_info->format); + if (!format) + return false; + + usage = vn_android_get_ahb_usage(format_info->usage, format_info->flags); + ahb = vn_android_ahb_allocate(16, 16, 1, format, usage); + if (!ahb) + return false; + + handle = AHardwareBuffer_getNativeHandle(ahb); + if (!vn_android_get_gralloc_buffer_info(handle, strides, offsets, + &format_modifier)) { + AHardwareBuffer_release(ahb); + return false; + } + + *out_info = (VkPhysicalDeviceImageDrmFormatModifierInfoEXT){ + .sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .pNext = NULL, + .drmFormatModifier = format_modifier, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = NULL, + }; + + AHardwareBuffer_release(ahb); + return true; +} diff --git a/src/virtio/vulkan/vn_android.h b/src/virtio/vulkan/vn_android.h index 72d0a230ef3..fdb2b6c0604 100644 --- a/src/virtio/vulkan/vn_android.h +++ b/src/virtio/vulkan/vn_android.h @@ -52,6 +52,11 @@ vn_android_image_from_anb(struct vn_device *dev, const VkAllocationCallbacks *alloc, struct vn_image **out_img); +bool +vn_android_get_drm_format_modifier_info( + const VkPhysicalDeviceImageFormatInfo2 *format_info, + VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info); + uint64_t vn_android_get_ahb_usage(const VkImageUsageFlags usage, const VkImageCreateFlags flags); @@ -88,6 +93,14 @@ vn_android_image_from_anb(UNUSED struct vn_device *dev, return VK_ERROR_OUT_OF_HOST_MEMORY; } +static inline bool +vn_android_get_drm_format_modifier_info( + UNUSED const VkPhysicalDeviceImageFormatInfo2 *format_info, + UNUSED VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info) +{ + return false; +} + static inline uint64_t vn_android_get_ahb_usage(UNUSED const VkImageUsageFlags usage, UNUSED const VkImageCreateFlags flags) diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c index f324329f5a1..ab387769888 100644 --- a/src/virtio/vulkan/vn_device.c +++ b/src/virtio/vulkan/vn_device.c @@ -2718,6 +2718,7 @@ struct vn_physical_device_image_format_info { VkPhysicalDeviceExternalImageFormatInfo external; VkImageFormatListCreateInfo list; VkImageStencilUsageCreateInfo stencil_usage; + VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifier; }; static const VkPhysicalDeviceImageFormatInfo2 * @@ -2729,12 +2730,16 @@ vn_physical_device_fix_image_format_info( local_info->format = *info; VkBaseOutStructure *dst = (void *)&local_info->format; + bool use_modifier = false; /* we should generate deep copy functions... */ vk_foreach_struct_const(src, info->pNext) { void *pnext = NULL; switch (src->sType) { case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: memcpy(&local_info->external, src, sizeof(local_info->external)); + use_modifier = + local_info->external.handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; local_info->external.handleType = physical_dev->external_memory.renderer_handle_type; pnext = &local_info->external; @@ -2758,7 +2763,15 @@ vn_physical_device_fix_image_format_info( } } - dst->pNext = NULL; + if (use_modifier) { + local_info->format.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; + if (!vn_android_get_drm_format_modifier_info(&local_info->format, + &local_info->modifier)) + return NULL; + } + + dst->pNext = use_modifier ? (void *)&local_info->modifier : NULL; + return &local_info->format; } @@ -2791,6 +2804,10 @@ vn_GetPhysicalDeviceImageFormatProperties2( if (external_info->handleType != renderer_handle_type) { pImageFormatInfo = vn_physical_device_fix_image_format_info( physical_dev, pImageFormatInfo, &local_info); + if (!pImageFormatInfo) { + return vn_error(physical_dev->instance, + VK_ERROR_FORMAT_NOT_SUPPORTED); + } } }