v3dv: implement VK_KHR_descriptor_update_template

Relevant tests:
dEQP-VK.binding_model.*.with_template.*

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11213>
This commit is contained in:
Iago Toral Quiroga 2021-06-07 09:08:22 +02:00 committed by Marge Bot
parent a48cb7534d
commit 4886773fc0
4 changed files with 171 additions and 1 deletions

View File

@ -424,7 +424,7 @@ Vulkan 1.1 -- all DONE: anv, lvp, radv, tu, vn
VK_KHR_16bit_storage DONE (anv/gen8+, lvp, radv, tu/a650, vn)
VK_KHR_bind_memory2 DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_dedicated_allocation DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_descriptor_update_template DONE (anv, lvp, radv, tu, vn)
VK_KHR_descriptor_update_template DONE (anv, lvp, radv, tu, v3dv, vn)
VK_KHR_device_group DONE (lvp, tu, v3dv, vn)
VK_KHR_device_group_creation DONE (lvp, tu, v3dv, vn)
VK_KHR_external_fence DONE (anv, lvp, radv, tu, v3dv, vn)

View File

@ -1148,3 +1148,132 @@ v3dv_GetDescriptorSetLayoutSupport(
pSupport->supported = supported;
}
VkResult
v3dv_CreateDescriptorUpdateTemplate(
VkDevice _device,
const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
{
V3DV_FROM_HANDLE(v3dv_device, device, _device);
struct v3dv_descriptor_update_template *template;
size_t size = sizeof(*template) +
pCreateInfo->descriptorUpdateEntryCount * sizeof(template->entries[0]);
template = vk_object_alloc(&device->vk, pAllocator, size,
VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
if (template == NULL)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
template->bind_point = pCreateInfo->pipelineBindPoint;
assert(pCreateInfo->templateType ==
VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET);
template->set = pCreateInfo->set;
template->entry_count = pCreateInfo->descriptorUpdateEntryCount;
for (uint32_t i = 0; i < template->entry_count; i++) {
const VkDescriptorUpdateTemplateEntry *pEntry =
&pCreateInfo->pDescriptorUpdateEntries[i];
template->entries[i] = (struct v3dv_descriptor_template_entry) {
.type = pEntry->descriptorType,
.binding = pEntry->dstBinding,
.array_element = pEntry->dstArrayElement,
.array_count = pEntry->descriptorCount,
.offset = pEntry->offset,
.stride = pEntry->stride,
};
}
*pDescriptorUpdateTemplate =
v3dv_descriptor_update_template_to_handle(template);
return VK_SUCCESS;
}
void
v3dv_DestroyDescriptorUpdateTemplate(
VkDevice _device,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
const VkAllocationCallbacks *pAllocator)
{
V3DV_FROM_HANDLE(v3dv_device, device, _device);
V3DV_FROM_HANDLE(v3dv_descriptor_update_template, template,
descriptorUpdateTemplate);
if (!template)
return;
vk_object_free(&device->vk, pAllocator, template);
}
void
v3dv_UpdateDescriptorSetWithTemplate(
VkDevice _device,
VkDescriptorSet descriptorSet,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
const void *pData)
{
V3DV_FROM_HANDLE(v3dv_descriptor_set, set, descriptorSet);
V3DV_FROM_HANDLE(v3dv_descriptor_update_template, template,
descriptorUpdateTemplate);
for (int i = 0; i < template->entry_count; i++) {
const struct v3dv_descriptor_template_entry *entry =
&template->entries[i];
const struct v3dv_descriptor_set_binding_layout *binding_layout =
set->layout->binding + entry->binding;
struct v3dv_descriptor *descriptor =
set->descriptors +
binding_layout->descriptor_index +
entry->array_element;
switch (entry->type) {
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:
for (uint32_t j = 0; j < entry->array_count; j++) {
const VkDescriptorBufferInfo *info =
pData + entry->offset + j * entry->stride;
write_buffer_descriptor(descriptor + j, entry->type, info);
}
break;
case VK_DESCRIPTOR_TYPE_SAMPLER:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
for (uint32_t j = 0; j < entry->array_count; j++) {
const VkDescriptorImageInfo *info =
pData + entry->offset + j * entry->stride;
V3DV_FROM_HANDLE(v3dv_image_view, iview, info->imageView);
V3DV_FROM_HANDLE(v3dv_sampler, sampler, info->sampler);
write_image_descriptor(descriptor + j, entry->type,
set, binding_layout, iview, sampler,
entry->array_element + j);
}
break;
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
for (uint32_t j = 0; j < entry->array_count; j++) {
const VkBufferView *_bview =
pData + entry->offset + j * entry->stride;
V3DV_FROM_HANDLE(v3dv_buffer_view, bview, *_bview);
write_buffer_view_descriptor(descriptor + j, entry->type,
set, binding_layout, bview,
entry->array_element + j);
}
break;
default:
unreachable("Unsupported descriptor type");
}
}
}

View File

@ -109,6 +109,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
.KHR_bind_memory2 = true,
.KHR_dedicated_allocation = true,
.KHR_device_group = true,
.KHR_descriptor_update_template = true,
.KHR_external_fence = true,
.KHR_external_fence_fd = true,
.KHR_external_memory = true,

View File

@ -1597,6 +1597,45 @@ struct v3dv_sampler {
uint8_t sampler_state[cl_packet_length(SAMPLER_STATE)];
};
struct v3dv_descriptor_template_entry {
/* The type of descriptor in this entry */
VkDescriptorType type;
/* Binding in the descriptor set */
uint32_t binding;
/* Offset at which to write into the descriptor set binding */
uint32_t array_element;
/* Number of elements to write into the descriptor set binding */
uint32_t array_count;
/* Offset into the user provided data */
size_t offset;
/* Stride between elements into the user provided data */
size_t stride;
};
struct v3dv_descriptor_update_template {
struct vk_object_base base;
VkPipelineBindPoint bind_point;
/* The descriptor set this template corresponds to. This value is only
* valid if the template was created with the templateType
* VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET.
*/
uint8_t set;
/* Number of entries in this template */
uint32_t entry_count;
/* Entries of the template */
struct v3dv_descriptor_template_entry entries[0];
};
/* We keep two special values for the sampler idx that represents exactly when a
* sampler is not needed/provided. The main use is that even if we don't have
* sampler, we still need to do the output unpacking (through
@ -2038,6 +2077,7 @@ V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_device_memory, VkDeviceMemory)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_pool, VkDescriptorPool)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set, VkDescriptorSet)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set_layout, VkDescriptorSetLayout)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_update_template, VkDescriptorUpdateTemplate)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_event, VkEvent)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_fence, VkFence)
V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_framebuffer, VkFramebuffer)