From dea6221a65800c1d015effa20cffdd4fa57d7784 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Wed, 11 Feb 2026 22:54:13 -0800 Subject: [PATCH] venus: take care of combined image sampler descriptor for ycbcr We'd have to query it by reconstructing the sampler ycbcr conversion image format props query. It's straightforward except having to consider the modifier tiling case. Part-of: --- src/virtio/vulkan/vn_descriptor_heap.c | 76 +++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/src/virtio/vulkan/vn_descriptor_heap.c b/src/virtio/vulkan/vn_descriptor_heap.c index efa8749289a..7dbc68ddbb0 100644 --- a/src/virtio/vulkan/vn_descriptor_heap.c +++ b/src/virtio/vulkan/vn_descriptor_heap.c @@ -38,6 +38,74 @@ vn_WriteSamplerDescriptorsEXT(VkDevice device, return VK_SUCCESS; } +static uint32_t +vn_descriptor_heap_get_descriptor_count( + struct vn_device *dev, const VkResourceDescriptorInfoEXT *resource) +{ + switch (resource->type) { + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + break; + default: + return 1; + } + + if (!resource->data.pImage) + return 1; + + const VkSamplerYcbcrConversionInfo *ycbcr = vk_find_struct_const( + resource->data.pImage->pView->pNext, SAMPLER_YCBCR_CONVERSION_INFO); + if (!ycbcr) + return 1; + + VkImage img_handle = resource->data.pImage->pView->image; + VK_FROM_HANDLE(vk_image, img, img_handle); + + const bool has_mod = + img->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; + uint64_t mod = 0; + if (has_mod) { + VkImageDrmFormatModifierPropertiesEXT mod_props = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT, + }; + ASSERTED VkResult result = vn_GetImageDrmFormatModifierPropertiesEXT( + vn_device_to_handle(dev), img_handle, &mod_props); + assert(result == VK_SUCCESS); + mod = mod_props.drmFormatModifier; + } + + const VkPhysicalDeviceImageDrmFormatModifierInfoEXT mod_info = { + .sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .drmFormatModifier = mod, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + const VkPhysicalDeviceImageFormatInfo2 format_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + .pNext = has_mod ? &mod_info : NULL, + .format = img->format, + .type = img->image_type, + .tiling = img->tiling, + .usage = img->usage, + .flags = img->create_flags, + }; + VkSamplerYcbcrConversionImageFormatProperties ycbcr_props = { + .sType = + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, + }; + VkImageFormatProperties2 format_props = { + .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + .pNext = &ycbcr_props, + }; + ASSERTED VkResult result = vn_GetPhysicalDeviceImageFormatProperties2( + vn_physical_device_to_handle(dev->physical_device), &format_info, + &format_props); + assert(result == VK_SUCCESS); + + return ycbcr_props.combinedImageSamplerDescriptorCount; +} + VKAPI_ATTR VkResult VKAPI_CALL vn_WriteResourceDescriptorsEXT(VkDevice device, uint32_t resourceCount, @@ -50,8 +118,12 @@ vn_WriteResourceDescriptorsEXT(VkDevice device, /* TODO move out from primary ring? */ for (uint32_t i = 0; i < resourceCount; i++) { - const VkDeviceSize size = vn_GetPhysicalDeviceDescriptorSizeEXT( - physical_dev_handle, pResources[i].type); + const uint32_t descriptor_count = + vn_descriptor_heap_get_descriptor_count(dev, &pResources[i]); + const VkDeviceSize descriptor_size = + vn_GetPhysicalDeviceDescriptorSizeEXT(physical_dev_handle, + pResources[i].type); + const VkDeviceSize size = descriptor_size * descriptor_count; assert(pDescriptors[i].size >= size); VkResult result = vn_call_vkWriteResourceDescriptorMESA(