From 7e63a2050b95c7c0f17e486936b7dabc78811937 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Thu, 26 Jun 2025 12:58:29 +0200 Subject: [PATCH] radv: implement vkWrite{Resource,Sampler}DescriptorsEXT() Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_descriptor_set.c | 2 +- .../vulkan/radv_descriptor_update_template.c | 2 +- src/amd/vulkan/radv_descriptors.c | 103 +++++++++++++++++- src/amd/vulkan/radv_descriptors.h | 7 +- 4 files changed, 109 insertions(+), 5 deletions(-) diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c index d5d8b4bd206..58a999478c2 100644 --- a/src/amd/vulkan/radv_descriptor_set.c +++ b/src/amd/vulkan/radv_descriptor_set.c @@ -610,7 +610,7 @@ radv_update_descriptor_sets_impl(struct radv_device *device, struct radv_cmd_buf break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { if (binding_layout->has_ycbcr_sampler) { - radv_write_image_descriptor_ycbcr(device, ptr, writeset->pImageInfo + j); + radv_write_image_descriptor_ycbcr(device, ptr, writeset->pImageInfo + j, true); } else { radv_write_combined_image_sampler_descriptor(device, ptr, writeset->descriptorType, writeset->pImageInfo + j, diff --git a/src/amd/vulkan/radv_descriptor_update_template.c b/src/amd/vulkan/radv_descriptor_update_template.c index f696d151d9c..d618e98ad1c 100644 --- a/src/amd/vulkan/radv_descriptor_update_template.c +++ b/src/amd/vulkan/radv_descriptor_update_template.c @@ -160,7 +160,7 @@ radv_update_descriptor_set_with_template_impl(struct radv_device *device, struct break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { if (templ->entry[i].has_ycbcr_sampler) { - radv_write_image_descriptor_ycbcr(device, pDst, (struct VkDescriptorImageInfo *)pSrc); + radv_write_image_descriptor_ycbcr(device, pDst, (struct VkDescriptorImageInfo *)pSrc, true); } else { radv_write_combined_image_sampler_descriptor(device, pDst, templ->entry[i].descriptor_type, (struct VkDescriptorImageInfo *)pSrc, diff --git a/src/amd/vulkan/radv_descriptors.c b/src/amd/vulkan/radv_descriptors.c index 3b2b0f1fabb..670e1e6a33e 100644 --- a/src/amd/vulkan/radv_descriptors.c +++ b/src/amd/vulkan/radv_descriptors.c @@ -113,7 +113,7 @@ radv_GetDescriptorEXT(VkDevice _device, const VkDescriptorGetInfoEXT *pDescripto VK_FROM_HANDLE(radv_sampler, sampler, pDescriptorInfo->data.pCombinedImageSampler->sampler); if (sampler->vk.ycbcr_conversion) { - radv_write_image_descriptor_ycbcr(device, pDescriptor, pDescriptorInfo->data.pCombinedImageSampler); + radv_write_image_descriptor_ycbcr(device, pDescriptor, pDescriptorInfo->data.pCombinedImageSampler, true); } else { radv_write_image_descriptor(pDescriptor, radv_get_sampled_image_desc_size(pdev), pDescriptorInfo->type, pDescriptorInfo->data.pCombinedImageSampler); @@ -171,3 +171,104 @@ radv_GetDescriptorEXT(VkDevice _device, const VkDescriptorGetInfoEXT *pDescripto UNREACHABLE("invalid descriptor type"); } } + +/* VK_EXT_descriptor_heap */ +VKAPI_ATTR VkResult VKAPI_CALL +radv_WriteSamplerDescriptorsEXT(VkDevice _device, uint32_t samplerCount, const VkSamplerCreateInfo *pSamplers, + const VkHostAddressRangeEXT *pDescriptors) +{ + VK_FROM_HANDLE(radv_device, device, _device); + + for (uint32_t i = 0; i < samplerCount; i++) { + const VkHostAddressRangeEXT *host_addr_range = &pDescriptors[i]; + struct radv_sampler sampler; + + radv_sampler_init(device, &sampler, &pSamplers[i]); + + radv_write_sampler_descriptor(host_addr_range->address, radv_sampler_to_handle(&sampler)); + + radv_sampler_finish(device, &sampler); + } + + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +radv_WriteResourceDescriptorsEXT(VkDevice _device, uint32_t resourceCount, + const VkResourceDescriptorInfoEXT *pResources, + const VkHostAddressRangeEXT *pDescriptors) +{ + VK_FROM_HANDLE(radv_device, device, _device); + const struct radv_physical_device *pdev = radv_device_physical(device); + + for (uint32_t i = 0; i < resourceCount; i++) { + const VkResourceDescriptorInfoEXT *resource = &pResources[i]; + const VkHostAddressRangeEXT *host_addr_range = &pDescriptors[i]; + + switch (resource->type) { + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { + const VkImageDescriptorInfoEXT *desc_info = resource->data.pImage; + const uint32_t size = resource->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE + ? RADV_STORAGE_IMAGE_DESC_SIZE + : radv_get_sampled_image_desc_size(pdev); + + if (desc_info) { + struct radv_image_view iview; + + radv_image_view_init(&iview, device, desc_info->pView, + &(struct radv_image_view_extra_create_info){.from_client = true}); + + const VkDescriptorImageInfo desc_image_info = { + .imageView = radv_image_view_to_handle(&iview), + .imageLayout = desc_info->layout, + }; + + const VkSamplerYcbcrConversionInfo *ycbcr_conversion = + vk_find_struct_const(desc_info->pView->pNext, SAMPLER_YCBCR_CONVERSION_INFO); + if (ycbcr_conversion) { + radv_write_image_descriptor_ycbcr(device, host_addr_range->address, &desc_image_info, false); + } else { + radv_write_image_descriptor(host_addr_range->address, size, resource->type, &desc_image_info); + } + + radv_image_view_finish(&iview); + } else { + memset(host_addr_range->address, 0, size); + } + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { + const VkDeviceAddressRangeEXT *addr_range = resource->data.pAddressRange; + + radv_write_buffer_descriptor(device, host_addr_range->address, addr_range ? addr_range->address : 0, + addr_range ? addr_range->size : 0); + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { + const VkTexelBufferDescriptorInfoEXT *desc_info = resource->data.pTexelBuffer; + + if (desc_info && desc_info->addressRange.address) { + radv_make_texel_buffer_descriptor(device, desc_info->addressRange.address, desc_info->format, + desc_info->addressRange.size, host_addr_range->address); + } else { + memset(host_addr_range->address, 0, RADV_BUFFER_DESC_SIZE); + } + break; + } + case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { + const VkDeviceAddressRangeEXT *addr_range = resource->data.pAddressRange; + + radv_write_accel_struct_descriptor(device, host_addr_range->address, addr_range ? addr_range->address : 0); + break; + } + default: + UNREACHABLE("invalid descriptor type"); + } + } + + return VK_SUCCESS; +} diff --git a/src/amd/vulkan/radv_descriptors.h b/src/amd/vulkan/radv_descriptors.h index d2f3828792c..8046cafbc4b 100644 --- a/src/amd/vulkan/radv_descriptors.h +++ b/src/amd/vulkan/radv_descriptors.h @@ -137,7 +137,8 @@ radv_write_image_descriptor(unsigned *dst, unsigned size, VkDescriptorType descr } static ALWAYS_INLINE void -radv_write_image_descriptor_ycbcr(struct radv_device *device, unsigned *dst, const VkDescriptorImageInfo *image_info) +radv_write_image_descriptor_ycbcr(struct radv_device *device, unsigned *dst, const VkDescriptorImageInfo *image_info, + bool use_combined_image_sampler) { const struct radv_physical_device *pdev = radv_device_physical(device); struct radv_image_view *iview = NULL; @@ -151,7 +152,9 @@ radv_write_image_descriptor_ycbcr(struct radv_device *device, unsigned *dst, con } const uint32_t plane_count = vk_format_get_plane_count(iview->vk.format); - const uint32_t stride = radv_get_combined_image_sampler_desc_size(pdev) / 4; + const uint32_t desc_size = use_combined_image_sampler ? radv_get_combined_image_sampler_desc_size(pdev) + : radv_get_sampled_image_desc_size(pdev); + const uint32_t stride = desc_size / 4; for (uint32_t i = 0; i < plane_count; i++) { memcpy(dst, iview->descriptor.plane_descriptors[i], 32);