From 5277e4584948be8d5eea15ecdf0e29f5ecdea7bb Mon Sep 17 00:00:00 2001 From: Karmjit Mahil Date: Fri, 28 Oct 2022 10:47:02 +0100 Subject: [PATCH] pvr: Add support to copy descriptors on vkUpdateDescriptorSets() Signed-off-by: Karmjit Mahil Reviewed-by: Frank Binns Part-of: --- src/imagination/vulkan/pvr_descriptor_set.c | 118 +++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/src/imagination/vulkan/pvr_descriptor_set.c b/src/imagination/vulkan/pvr_descriptor_set.c index ece7a600562..385aee209e7 100644 --- a/src/imagination/vulkan/pvr_descriptor_set.c +++ b/src/imagination/vulkan/pvr_descriptor_set.c @@ -1929,6 +1929,120 @@ static void pvr_write_descriptor_set(struct pvr_device *device, } } +static void pvr_copy_descriptor_set(struct pvr_device *device, + const VkCopyDescriptorSet *copy_set) +{ + PVR_FROM_HANDLE(pvr_descriptor_set, src_set, copy_set->srcSet); + PVR_FROM_HANDLE(pvr_descriptor_set, dst_set, copy_set->dstSet); + const struct pvr_descriptor_set_layout_binding *src_binding = + pvr_get_descriptor_binding(src_set->layout, copy_set->srcBinding); + const struct pvr_descriptor_set_layout_binding *dst_binding = + pvr_get_descriptor_binding(dst_set->layout, copy_set->dstBinding); + struct pvr_descriptor_size_info size_info; + uint32_t *src_mem_ptr; + uint32_t *dst_mem_ptr; + + switch (src_binding->type) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + break; + + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { + const uint32_t src_idx = + src_binding->descriptor_index + copy_set->srcArrayElement; + const uint32_t dst_idx = + dst_binding->descriptor_index + copy_set->dstArrayElement; + + for (uint32_t j = 0; j < copy_set->descriptorCount; j++) { + assert(src_set->descriptors[src_idx + j].type == src_binding->type); + + dst_set->descriptors[dst_idx + j] = src_set->descriptors[src_idx + j]; + } + + break; + } + + default: + unreachable("Unknown descriptor type"); + break; + } + + /* Dynamic buffer descriptors don't have any data stored in the descriptor + * set memory. They only exist in the set->descriptors list which we've + * already updated above. + */ + if (src_binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + src_binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { + return; + } + + src_mem_ptr = src_set->pvr_bo->bo->map; + dst_mem_ptr = dst_set->pvr_bo->bo->map; + + /* From the Vulkan 1.3.232 spec VUID-VkCopyDescriptorSet-dstBinding-02632: + * + * The type of dstBinding within dstSet must be equal to the type of + * srcBinding within srcSet. + * + * So both bindings have the same descriptor size and we don't need to + * handle size differences. + */ + pvr_descriptor_size_info_init(device, src_binding->type, &size_info); + + assert(src_binding->shader_stage_mask == dst_binding->shader_stage_mask); + + u_foreach_bit (stage, dst_binding->shader_stage_mask) { + uint16_t src_secondary_offset; + uint16_t dst_secondary_offset; + uint16_t src_primary_offset; + uint16_t dst_primary_offset; + + /* Offset calculation functions expect descriptor_index to be + * binding relative not layout relative. + */ + src_primary_offset = + pvr_get_descriptor_primary_offset(device, + src_set->layout, + src_binding, + stage, + copy_set->srcArrayElement); + dst_primary_offset = + pvr_get_descriptor_primary_offset(device, + dst_set->layout, + dst_binding, + stage, + copy_set->dstArrayElement); + src_secondary_offset = + pvr_get_descriptor_secondary_offset(device, + src_set->layout, + src_binding, + stage, + copy_set->srcArrayElement); + dst_secondary_offset = + pvr_get_descriptor_secondary_offset(device, + dst_set->layout, + dst_binding, + stage, + copy_set->dstArrayElement); + + memcpy(dst_mem_ptr + dst_primary_offset, + src_mem_ptr + src_primary_offset, + size_info.primary * 4U * copy_set->descriptorCount); + + memcpy(dst_mem_ptr + dst_secondary_offset, + src_mem_ptr + src_secondary_offset, + size_info.secondary * 4U * copy_set->descriptorCount); + } +} + void pvr_UpdateDescriptorSets(VkDevice _device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, @@ -1940,6 +2054,6 @@ void pvr_UpdateDescriptorSets(VkDevice _device, for (uint32_t i = 0; i < descriptorWriteCount; i++) pvr_write_descriptor_set(device, &pDescriptorWrites[i]); - if (descriptorCopyCount > 0) - pvr_finishme("Descriptor copying support missing\n"); + for (uint32_t i = 0; i < descriptorCopyCount; i++) + pvr_copy_descriptor_set(device, &pDescriptorCopies[i]); }