void radv_update_descriptor_sets( struct radv_device* device, struct radv_cmd_buffer* cmd_buffer, VkDescriptorSet dstSetOverride, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies) { uint32_t i, j; for (i = 0; i < descriptorWriteCount; i++) { const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i]; RADV_FROM_HANDLE(radv_descriptor_set, set, dstSetOverride ? dstSetOverride : writeset->dstSet); const struct radv_descriptor_set_binding_layout *binding_layout = set->layout->binding + writeset->dstBinding; uint32_t *ptr = set->mapped_ptr; struct radeon_winsys_bo **buffer_list = set->descriptors; /* Immutable samplers are not copied into push descriptors when they are * allocated, so if we are writing push descriptors we have to copy the * immutable samplers into them now. */ const bool copy_immutable_samplers = cmd_buffer && binding_layout->immutable_samplers_offset && !binding_layout->immutable_samplers_equal; const uint32_t *samplers = radv_immutable_samplers(set->layout, binding_layout); ptr += binding_layout->offset / 4; ptr += binding_layout->size * writeset->dstArrayElement / 4; buffer_list += binding_layout->buffer_offset; buffer_list += writeset->dstArrayElement; for (j = 0; j < writeset->descriptorCount; ++j) { switch(writeset->descriptorType) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { unsigned idx = writeset->dstArrayElement + j; idx += binding_layout->dynamic_offset_offset; assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx, buffer_list, writeset->pBufferInfo + j); break; } case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: write_buffer_descriptor(device, cmd_buffer, ptr, buffer_list, writeset->pBufferInfo + j); break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: write_texel_buffer_descriptor(device, cmd_buffer, ptr, buffer_list, writeset->pTexelBufferView[j]); break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: write_image_descriptor(device, cmd_buffer, ptr, buffer_list, writeset->descriptorType, writeset->pImageInfo + j); break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: write_combined_image_sampler_descriptor(device, cmd_buffer, ptr, buffer_list, writeset->descriptorType, writeset->pImageInfo + j, !binding_layout->immutable_samplers_offset); if (copy_immutable_samplers) { const unsigned idx = writeset->dstArrayElement + j; memcpy(ptr + 16, samplers + 4 * idx, 16); } break; case VK_DESCRIPTOR_TYPE_SAMPLER: if (!binding_layout->immutable_samplers_offset) { write_sampler_descriptor(device, ptr, writeset->pImageInfo + j); } else if (copy_immutable_samplers) { unsigned idx = writeset->dstArrayElement + j; memcpy(ptr, samplers + 4 * idx, 16); } break; default: unreachable("unimplemented descriptor type"); break; } ptr += binding_layout->size / 4; ++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_update_descriptor_set_with_template(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, struct radv_descriptor_set *set, VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate, const void *pData) { RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate); uint32_t i; for (i = 0; i < templ->entry_count; ++i) { struct radeon_winsys_bo **buffer_list = set->descriptors + templ->entry[i].buffer_offset; uint32_t *pDst = set->mapped_ptr + templ->entry[i].dst_offset; const uint8_t *pSrc = ((const uint8_t *) pData) + templ->entry[i].src_offset; uint32_t j; for (j = 0; j < templ->entry[i].descriptor_count; ++j) { switch (templ->entry[i].descriptor_type) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { const unsigned idx = templ->entry[i].dst_offset + j; assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR)); write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx, buffer_list, (struct VkDescriptorBufferInfo *) pSrc); break; } case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: write_buffer_descriptor(device, cmd_buffer, pDst, buffer_list, (struct VkDescriptorBufferInfo *) pSrc); break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: write_texel_buffer_descriptor(device, cmd_buffer, pDst, buffer_list, *(VkBufferView *) pSrc); break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: write_image_descriptor(device, cmd_buffer, pDst, buffer_list, templ->entry[i].descriptor_type, (struct VkDescriptorImageInfo *) pSrc); break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: write_combined_image_sampler_descriptor(device, cmd_buffer, pDst, buffer_list, templ->entry[i].descriptor_type, (struct VkDescriptorImageInfo *) pSrc, templ->entry[i].has_sampler); if (templ->entry[i].immutable_samplers) memcpy(pDst + 16, templ->entry[i].immutable_samplers + 4 * j, 16); break; case VK_DESCRIPTOR_TYPE_SAMPLER: if (templ->entry[i].has_sampler) write_sampler_descriptor(device, pDst, (struct VkDescriptorImageInfo *) pSrc); else if (templ->entry[i].immutable_samplers) memcpy(pDst, templ->entry[i].immutable_samplers + 4 * j, 16); break; default: unreachable("unimplemented descriptor type"); break; } pSrc += templ->entry[i].src_stride; pDst += templ->entry[i].dst_stride; ++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); uint32_t i, j; for (i = 0; i < descriptorWriteCount; i++) { const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i]; RADV_FROM_HANDLE(radv_descriptor_set, set, writeset->dstSet); const struct radv_descriptor_set_binding_layout *binding_layout = set->layout->binding + writeset->dstBinding; uint32_t *ptr = set->mapped_ptr; struct radeon_winsys_bo **buffer_list = set->descriptors; ptr += binding_layout->offset / 4; ptr += binding_layout->size * writeset->dstArrayElement / 4; buffer_list += binding_layout->buffer_offset; buffer_list += binding_layout->buffer_count * writeset->dstArrayElement; for (j = 0; j < writeset->descriptorCount; ++j) { switch(writeset->descriptorType) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { unsigned idx = writeset->dstArrayElement + j; idx += binding_layout->dynamic_offset_offset; write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx, buffer_list, writeset->pBufferInfo + j); break; } case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: write_buffer_descriptor(device, ptr, buffer_list, writeset->pBufferInfo + j); break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: write_texel_buffer_descriptor(device, ptr, buffer_list, writeset->pTexelBufferView[j]); break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: write_image_descriptor(device, ptr, buffer_list, writeset->pImageInfo + j); break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: write_combined_image_sampler_descriptor(device, ptr, buffer_list, writeset->pImageInfo + j, !binding_layout->immutable_samplers); break; case VK_DESCRIPTOR_TYPE_SAMPLER: assert(!binding_layout->immutable_samplers); write_sampler_descriptor(device, ptr, writeset->pImageInfo + j); break; default: unreachable("unimplemented descriptor type"); break; } ptr += binding_layout->size / 4; buffer_list += binding_layout->buffer_count; } } if (descriptorCopyCount) radv_finishme("copy descriptors"); }