From 22402dadd32250df3c176a12955e4acc97da049c Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 11 Jun 2025 10:14:55 +0200 Subject: [PATCH] radv: add a separate path for writing ycbcr combined image+sampler desc This will allow us to remove the ycbcr hack and to reduce the number of bytes written for combined image+sampler from 80 to 64. Signed-off-by: Samuel Pitoiset Part-of: --- src/amd/vulkan/radv_descriptor_set.c | 86 +++++++++++++++++++++++++--- src/amd/vulkan/radv_descriptor_set.h | 3 + 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c index ed75215585d..ab64c07db23 100644 --- a/src/amd/vulkan/radv_descriptor_set.c +++ b/src/amd/vulkan/radv_descriptor_set.c @@ -292,6 +292,7 @@ radv_CreateDescriptorSetLayout(VkDevice _device, const VkDescriptorSetLayoutCrea set_layout->binding[b].offset = set_layout->size; set_layout->binding[b].buffer_offset = buffer_count; set_layout->binding[b].dynamic_offset_offset = dynamic_offset_count; + set_layout->binding[b].has_ycbcr_sampler = has_ycbcr_sampler; if (variable_flags && binding->binding < variable_flags->bindingCount && (variable_flags->pBindingFlags[binding->binding] & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)) { @@ -1192,6 +1193,51 @@ write_image_descriptor_impl(struct radv_device *device, struct radv_cmd_buffer * } } +static ALWAYS_INLINE void +write_image_descriptor_ycbcr(unsigned *dst, const VkDescriptorImageInfo *image_info) +{ + const uint32_t size = RADV_COMBINED_IMAGE_SAMPLER_DESC_SIZE - RADV_SAMPLER_DESC_SIZE; + struct radv_image_view *iview = NULL; + + if (image_info) + iview = radv_image_view_from_handle(image_info->imageView); + + if (!iview) { + memset(dst, 0, size); + return; + } + + memcpy(dst, iview->descriptor.plane_descriptors[0], size); +} + +static ALWAYS_INLINE void +write_image_descriptor_ycbcr_impl(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, unsigned *dst, + struct radeon_winsys_bo **buffer_list, const VkDescriptorImageInfo *image_info) +{ + VK_FROM_HANDLE(radv_image_view, iview, image_info->imageView); + + write_image_descriptor_ycbcr(dst, image_info); + + if (device->use_global_bo_list) + return; + + if (!iview) { + if (!cmd_buffer) + *buffer_list = NULL; + return; + } + + for (uint32_t b = 0; b < ARRAY_SIZE(iview->image->bindings); b++) { + if (cmd_buffer) { + if (iview->image->bindings[b].bo) + radv_cs_add_buffer(device->ws, cmd_buffer->cs, iview->image->bindings[b].bo); + } else { + *buffer_list = iview->image->bindings[b].bo; + buffer_list++; + } + } +} + static ALWAYS_INLINE void write_combined_image_sampler_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, unsigned sampler_offset, unsigned *dst, struct radeon_winsys_bo **buffer_list, @@ -1290,9 +1336,14 @@ radv_update_descriptor_sets_impl(struct radv_device *device, struct radv_cmd_buf case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { const uint32_t sampler_offset = RADV_COMBINED_IMAGE_SAMPLER_DESC_SAMPLER_OFFSET; - write_combined_image_sampler_descriptor(device, cmd_buffer, sampler_offset, ptr, buffer_list, - writeset->descriptorType, writeset->pImageInfo + j, - !binding_layout->immutable_samplers_offset); + if (binding_layout->has_ycbcr_sampler) { + write_image_descriptor_ycbcr_impl(device, cmd_buffer, ptr, buffer_list, writeset->pImageInfo + j); + } else { + write_combined_image_sampler_descriptor(device, cmd_buffer, sampler_offset, ptr, buffer_list, + writeset->descriptorType, writeset->pImageInfo + j, + !binding_layout->immutable_samplers_offset); + } + if (copy_immutable_samplers) { const unsigned idx = writeset->dstArrayElement + j; memcpy((char *)ptr + sampler_offset, samplers + 4 * idx, RADV_SAMPLER_DESC_SIZE); @@ -1495,6 +1546,7 @@ radv_CreateDescriptorUpdateTemplate(VkDevice _device, const VkDescriptorUpdateTe .dst_stride = dst_stride, .buffer_offset = buffer_offset, .has_sampler = !binding_layout->immutable_samplers_offset, + .has_ycbcr_sampler = binding_layout->has_ycbcr_sampler, .immutable_samplers = immutable_samplers}; } @@ -1566,9 +1618,15 @@ radv_update_descriptor_set_with_template_impl(struct radv_device *device, struct case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { const uint32_t sampler_offset = RADV_COMBINED_IMAGE_SAMPLER_DESC_SAMPLER_OFFSET; - write_combined_image_sampler_descriptor(device, cmd_buffer, sampler_offset, pDst, buffer_list, - templ->entry[i].descriptor_type, - (struct VkDescriptorImageInfo *)pSrc, templ->entry[i].has_sampler); + if (templ->entry[i].has_ycbcr_sampler) { + write_image_descriptor_ycbcr_impl(device, cmd_buffer, pDst, buffer_list, + (struct VkDescriptorImageInfo *)pSrc); + } else { + write_combined_image_sampler_descriptor( + device, cmd_buffer, sampler_offset, pDst, buffer_list, templ->entry[i].descriptor_type, + (struct VkDescriptorImageInfo *)pSrc, templ->entry[i].has_sampler); + } + if (cmd_buffer && templ->entry[i].immutable_samplers) { memcpy((char *)pDst + sampler_offset, templ->entry[i].immutable_samplers + 4 * j, RADV_SAMPLER_DESC_SIZE); @@ -1645,12 +1703,22 @@ radv_GetDescriptorEXT(VkDevice _device, const VkDescriptorGetInfoEXT *pDescripto case VK_DESCRIPTOR_TYPE_SAMPLER: { write_sampler_descriptor(pDescriptor, *pDescriptorInfo->data.pSampler); break; - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - write_image_descriptor(pDescriptor, 80, pDescriptorInfo->type, pDescriptorInfo->data.pCombinedImageSampler); + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { if (pDescriptorInfo->data.pCombinedImageSampler) { - write_sampler_descriptor((uint32_t *)pDescriptor + 20, pDescriptorInfo->data.pCombinedImageSampler->sampler); + VK_FROM_HANDLE(radv_sampler, sampler, pDescriptorInfo->data.pCombinedImageSampler->sampler); + + if (sampler->vk.ycbcr_conversion) { + write_image_descriptor_ycbcr(pDescriptor, pDescriptorInfo->data.pCombinedImageSampler); + } else { + write_image_descriptor(pDescriptor, 80, pDescriptorInfo->type, pDescriptorInfo->data.pCombinedImageSampler); + write_sampler_descriptor((uint32_t *)pDescriptor + 20, + pDescriptorInfo->data.pCombinedImageSampler->sampler); + } + } else { + memset(pDescriptor, 0, RADV_COMBINED_IMAGE_SAMPLER_DESC_SIZE); } break; + } case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { const VkDescriptorImageInfo *image_info = pDescriptorInfo->type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT diff --git a/src/amd/vulkan/radv_descriptor_set.h b/src/amd/vulkan/radv_descriptor_set.h index 2881f0096a8..5d5382c4abd 100644 --- a/src/amd/vulkan/radv_descriptor_set.h +++ b/src/amd/vulkan/radv_descriptor_set.h @@ -33,6 +33,8 @@ struct radv_descriptor_set_binding_layout { /* Offset in the radv_descriptor_set_layout of the immutable samplers, or 0 * if there are no immutable samplers. */ uint32_t immutable_samplers_offset; + + bool has_ycbcr_sampler; }; struct radv_descriptor_set_layout { @@ -150,6 +152,7 @@ struct radv_descriptor_update_template_entry { /* Only valid for combined image samplers and samplers */ uint8_t has_sampler; + uint8_t has_ycbcr_sampler; /* In bytes */ size_t src_offset;