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:
parent
a48cb7534d
commit
4886773fc0
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue