pvr: Add support to copy descriptors on vkUpdateDescriptorSets()

Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21332>
This commit is contained in:
Karmjit Mahil 2022-10-28 10:47:02 +01:00 committed by Marge Bot
parent 30b7263419
commit 5277e45849

View file

@ -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]);
}