+ ++buffer_list;
+ }
+
+ }
+
+ for (i = 0; i < descriptorCopyCount; i++) {
+ const VkCopyDescriptorSet *copyset = &pDescriptorCopies[i];
+ RADV_FROM_HANDLE(radv_descriptor_set, src_set,
+ copyset->srcSet);
+ RADV_FROM_HANDLE(radv_descriptor_set, dst_set,
+ copyset->dstSet);
+ const struct radv_descriptor_set_binding_layout *src_binding_layout =
+ src_set->layout->binding + copyset->srcBinding;
+ const struct radv_descriptor_set_binding_layout *dst_binding_layout =
+ dst_set->layout->binding + copyset->dstBinding;
+ uint32_t *src_ptr = src_set->mapped_ptr;
+ uint32_t *dst_ptr = dst_set->mapped_ptr;
+ struct radeon_winsys_bo **src_buffer_list = src_set->descriptors;
+ struct radeon_winsys_bo **dst_buffer_list = dst_set->descriptors;
+
+ src_ptr += src_binding_layout->offset / 4;
+ dst_ptr += dst_binding_layout->offset / 4;
+
+ src_ptr += src_binding_layout->size * copyset->srcArrayElement / 4;
+ dst_ptr += dst_binding_layout->size * copyset->dstArrayElement / 4;
+
+ src_buffer_list += src_binding_layout->buffer_offset;
+ src_buffer_list += copyset->srcArrayElement;
+
+ dst_buffer_list += dst_binding_layout->buffer_offset;
+ dst_buffer_list += copyset->dstArrayElement;
+
+ for (j = 0; j < copyset->descriptorCount; ++j) {
+ switch (src_binding_layout->type) {
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
+ unsigned src_idx = copyset->srcArrayElement + j;
+ unsigned dst_idx = copyset->dstArrayElement + j;
+ struct radv_descriptor_range *src_range, *dst_range;
+ src_idx += src_binding_layout->dynamic_offset_offset;
+ dst_idx += dst_binding_layout->dynamic_offset_offset;
+
+ src_range = src_set->dynamic_descriptors + src_idx;
+ dst_range = dst_set->dynamic_descriptors + dst_idx;
+ *dst_range = *src_range;
+ break;
+ }
+ default:
+ memcpy(dst_ptr, src_ptr, src_binding_layout->size);
+ }
+ src_ptr += src_binding_layout->size / 4;
+ dst_ptr += dst_binding_layout->size / 4;
+ dst_buffer_list[j] = src_buffer_list[j];
+ ++src_buffer_list;
+ ++dst_buffer_list;
+ }
+ }
+}
+
+void radv_UpdateDescriptorSets(
+ VkDevice _device,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites,
+ uint32_t descriptorCopyCount,
+ const VkCopyDescriptorSet* pDescriptorCopies)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
+ radv_update_descriptor_sets(device, NULL, VK_NULL_HANDLE, descriptorWriteCount, pDescriptorWrites,
+ descriptorCopyCount, pDescriptorCopies);
+}
+
+VkResult radv_CreateDescriptorUpdateTemplate(VkDevice _device,
+ const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate)
+{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->descriptorSetLayout);
+ const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount;
+ const size_t size = sizeof(struct radv_descriptor_update_template) +
+ sizeof(struct radv_descriptor_update_template_entry) * entry_count;
+ struct radv_descriptor_update_template *templ;
+ uint32_t i;
+
+ templ = vk_alloc2(&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!templ)
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ templ->entry_count = entry_count;
+ templ->bind_point = pCreateInfo->pipelineBindPoint;
+
+ for (i = 0; i < entry_count; i++) {
+ const VkDescriptorUpdateTemplateEntryKHR *entry = &pCreateInfo->pDescriptorUpdateEntries[i];
+ const struct radv_descriptor_set_binding_layout *binding_layout =
+ set_layout->binding + entry->dstBinding;
+ const uint32_t buffer_offset = binding_layout->buffer_offset + entry->dstArrayElement;
+ const uint32_t *immutable_samplers = NULL;
+ uint32_t dst_offset;
+ uint32_t dst_stride;
+
+ /* dst_offset is an offset into dynamic_descriptors when the descriptor
+ is dynamic, and an offset into mapped_ptr otherwise */
+ switch (entry->descriptorType) {
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR);
+ dst_offset = binding_layout->dynamic_offset_offset + entry->dstArrayElement;
+ dst_stride = 0; /* Not used */
+ break;
+ default:
+ switch (entry->descriptorType) {
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ /* Immutable samplers are copied into push descriptors when they are pushed */
+ if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR &&
+ binding_layout->immutable_samplers_offset && !binding_layout->immutable_samplers_equal) {
+ immutable_samplers = radv_immutable_samplers(set_layout, binding_layout) + entry->dstArrayElement * 4;
+ }
+ break;
+ default:
+ break;
+ }
+ dst_offset = binding_layout->offset / 4 + binding_layout->size * entry->dstArrayElement / 4;
+ dst_stride = binding_layout->size / 4;
+ break;