Mesa (main): dzn: Add support for KHR_descriptor_update_template
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Apr 21 10:51:16 UTC 2022
Module: Mesa
Branch: main
Commit: b8d41d5919a4216898f5f42938a312b6ce79a227
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b8d41d5919a4216898f5f42938a312b6ce79a227
Author: Boris Brezillon <boris.brezillon at collabora.com>
Date: Mon Mar 28 10:12:57 2022 +0200
dzn: Add support for KHR_descriptor_update_template
Create update templates where the offset in the descriptor heap is
pre-calculated.
Reviewed-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15691>
---
src/microsoft/vulkan/dzn_descriptor_set.c | 265 ++++++++++++++++++++++++++++++
src/microsoft/vulkan/dzn_device.c | 1 +
src/microsoft/vulkan/dzn_private.h | 25 +++
3 files changed, 291 insertions(+)
diff --git a/src/microsoft/vulkan/dzn_descriptor_set.c b/src/microsoft/vulkan/dzn_descriptor_set.c
index 4af5dc85337..9423384f018 100644
--- a/src/microsoft/vulkan/dzn_descriptor_set.c
+++ b/src/microsoft/vulkan/dzn_descriptor_set.c
@@ -1870,3 +1870,268 @@ dzn_UpdateDescriptorSets(VkDevice _device,
for (unsigned i = 0; i < descriptorCopyCount; i++)
dzn_descriptor_set_copy(&pDescriptorCopies[i]);
}
+
+static void
+dzn_descriptor_update_template_destroy(struct dzn_descriptor_update_template *templ,
+ const VkAllocationCallbacks *alloc)
+{
+ if (!templ)
+ return;
+
+ struct dzn_device *device =
+ container_of(templ->base.device, struct dzn_device, vk);
+
+ vk_object_base_finish(&templ->base);
+ vk_free2(&device->vk.alloc, alloc, templ);
+}
+
+static VkResult
+dzn_descriptor_update_template_create(struct dzn_device *device,
+ const VkDescriptorUpdateTemplateCreateInfo *info,
+ const VkAllocationCallbacks *alloc,
+ VkDescriptorUpdateTemplate *out)
+{
+ assert(info->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET);
+
+ VK_FROM_HANDLE(dzn_descriptor_set_layout, set_layout, info->descriptorSetLayout);
+
+ uint32_t entry_count = 0;
+ for (uint32_t e = 0; e < info->descriptorUpdateEntryCount; e++) {
+ struct dzn_descriptor_set_ptr ptr;
+ dzn_descriptor_set_ptr_init(set_layout, &ptr,
+ info->pDescriptorUpdateEntries[e].dstBinding,
+ info->pDescriptorUpdateEntries[e].dstArrayElement);
+ uint32_t desc_count = info->pDescriptorUpdateEntries[e].descriptorCount;
+ VkDescriptorType type = info->pDescriptorUpdateEntries[e].descriptorType;
+ uint32_t d = 0;
+
+ while (dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count) {
+ uint32_t ndescs = dzn_descriptor_set_remaining_descs_in_binding(set_layout, &ptr);
+
+ assert(dzn_descriptor_set_ptr_get_vk_type(set_layout, &ptr) == type);
+ d += ndescs;
+ dzn_descriptor_set_ptr_move(set_layout, &ptr, ndescs);
+ entry_count++;
+ }
+
+ assert(d >= desc_count);
+ }
+
+ VK_MULTIALLOC(ma);
+ VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_update_template, templ, 1);
+ VK_MULTIALLOC_DECL(&ma, struct dzn_descriptor_update_template_entry, entries, entry_count);
+
+ if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, alloc,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
+ return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &templ->base, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
+ templ->entry_count = entry_count;
+ templ->entries = entries;
+
+ struct dzn_descriptor_update_template_entry *entry = entries;
+
+ for (uint32_t e = 0; e < info->descriptorUpdateEntryCount; e++) {
+ struct dzn_descriptor_set_ptr ptr;
+ dzn_descriptor_set_ptr_init(set_layout, &ptr,
+ info->pDescriptorUpdateEntries[e].dstBinding,
+ info->pDescriptorUpdateEntries[e].dstArrayElement);
+ uint32_t desc_count = info->pDescriptorUpdateEntries[e].descriptorCount;
+ VkDescriptorType type = info->pDescriptorUpdateEntries[e].descriptorType;
+ size_t user_data_offset = info->pDescriptorUpdateEntries[e].offset;
+ size_t user_data_stride = info->pDescriptorUpdateEntries[e].stride;
+ uint32_t d = 0;
+
+ while (dzn_descriptor_set_ptr_is_valid(&ptr) && d < desc_count) {
+ uint32_t ndescs = dzn_descriptor_set_remaining_descs_in_binding(set_layout, &ptr);
+
+ entry->type = type;
+ entry->desc_count = MIN2(desc_count - d, ndescs);
+ entry->user_data.stride = user_data_stride;
+ entry->user_data.offset = user_data_offset;
+ memset(&entry->heap_offsets, ~0, sizeof(entry->heap_offsets));
+
+ assert(dzn_descriptor_set_ptr_get_vk_type(set_layout, &ptr) == type);
+ if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
+ type == VK_DESCRIPTOR_TYPE_SAMPLER) {
+ entry->heap_offsets.sampler =
+ dzn_descriptor_set_ptr_get_heap_offset(set_layout,
+ D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER,
+ &ptr, false);
+ }
+
+ if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
+ type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
+ entry->dynamic_buffer_idx =
+ dzn_descriptor_set_ptr_get_dynamic_buffer_idx(set_layout, &ptr);
+ } else if (type != VK_DESCRIPTOR_TYPE_SAMPLER) {
+ entry->heap_offsets.cbv_srv_uav =
+ dzn_descriptor_set_ptr_get_heap_offset(set_layout,
+ D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
+ &ptr, false);
+ if (dzn_descriptor_type_depends_on_shader_usage(type)) {
+ entry->heap_offsets.extra_uav =
+ dzn_descriptor_set_ptr_get_heap_offset(set_layout,
+ D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
+ &ptr, true);
+ }
+ }
+
+ d += ndescs;
+ dzn_descriptor_set_ptr_move(set_layout, &ptr, ndescs);
+ user_data_offset += user_data_stride * ndescs;
+ ++entry;
+ }
+ }
+
+ *out = dzn_descriptor_update_template_to_handle(templ);
+ return VK_SUCCESS;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL
+dzn_CreateDescriptorUpdateTemplate(VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
+{
+ return dzn_descriptor_update_template_create(dzn_device_from_handle(device),
+ pCreateInfo, pAllocator,
+ pDescriptorUpdateTemplate);
+}
+
+VKAPI_ATTR void VKAPI_CALL
+dzn_DestroyDescriptorUpdateTemplate(VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks *pAllocator)
+{
+ dzn_descriptor_update_template_destroy(dzn_descriptor_update_template_from_handle(descriptorUpdateTemplate),
+ pAllocator);
+}
+
+static const void *
+dzn_descriptor_update_template_get_desc_data(const struct dzn_descriptor_update_template *templ,
+ uint32_t e, uint32_t d,
+ const void *user_data)
+{
+ return (const void *)((const uint8_t *)user_data +
+ templ->entries[e].user_data.offset +
+ (d * templ->entries[e].user_data.stride));
+}
+
+VKAPI_ATTR void VKAPI_CALL
+dzn_UpdateDescriptorSetWithTemplate(VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void *pData)
+{
+ VK_FROM_HANDLE(dzn_descriptor_set, set, descriptorSet);
+ VK_FROM_HANDLE(dzn_descriptor_update_template, templ, descriptorUpdateTemplate);
+
+ for (uint32_t e = 0; e < templ->entry_count; e++) {
+ const struct dzn_descriptor_update_template_entry *entry = &templ->entries[e];
+ bool cube_as_2darray =
+ entry->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+
+ switch (entry->type) {
+ case VK_DESCRIPTOR_TYPE_SAMPLER:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ VK_FROM_HANDLE(dzn_sampler, sampler, info->sampler);
+
+ if (sampler)
+ dzn_descriptor_set_write_sampler_desc(set, entry->heap_offsets.sampler + d, sampler);
+ }
+ break;
+
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ VK_FROM_HANDLE(dzn_sampler, sampler, info->sampler);
+ VK_FROM_HANDLE(dzn_image_view, iview, info->imageView);
+
+ if (sampler)
+ dzn_descriptor_set_write_sampler_desc(set, entry->heap_offsets.sampler + d, sampler);
+
+ if (iview)
+ dzn_descriptor_set_write_image_view_desc(set, entry->heap_offsets.cbv_srv_uav + d, ~0, cube_as_2darray, iview);
+ }
+ break;
+
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ const VkDescriptorImageInfo *info = (const VkDescriptorImageInfo *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ uint32_t srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d;
+ uint32_t uav_heap_offset =
+ entry->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ?
+ entry->heap_offsets.extra_uav + d : ~0;
+ VK_FROM_HANDLE(dzn_image_view, iview, info->imageView);
+
+ if (iview)
+ dzn_descriptor_set_write_image_view_desc(set, srv_heap_offset, uav_heap_offset, cube_as_2darray, iview);
+ }
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ const VkDescriptorBufferInfo *info = (const VkDescriptorBufferInfo *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ uint32_t cbv_srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d;
+ uint32_t uav_heap_offset =
+ entry->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ?
+ entry->heap_offsets.extra_uav + d : ~0;
+
+ struct dzn_buffer_desc desc = {
+ entry->type,
+ dzn_buffer_from_handle(info->buffer),
+ info->range, info->offset
+ };
+
+ if (desc.buffer)
+ dzn_descriptor_set_write_buffer_desc(set, cbv_srv_heap_offset, uav_heap_offset, &desc);
+ }
+ break;
+
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ const VkDescriptorBufferInfo *info = (const VkDescriptorBufferInfo *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ uint32_t dyn_buf_idx = entry->dynamic_buffer_idx + d;
+
+ struct dzn_buffer_desc desc = {
+ entry->type,
+ dzn_buffer_from_handle(info->buffer),
+ info->range, info->offset
+ };
+
+ if (desc.buffer)
+ dzn_descriptor_set_write_dynamic_buffer_desc(set, dyn_buf_idx, &desc);
+ }
+ break;
+
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ for (uint32_t d = 0; d < entry->desc_count; d++) {
+ VkBufferView *info = (VkBufferView *)
+ dzn_descriptor_update_template_get_desc_data(templ, e, d, pData);
+ VK_FROM_HANDLE(dzn_buffer_view, bview, *info);
+ uint32_t srv_heap_offset = entry->heap_offsets.cbv_srv_uav + d;
+ uint32_t uav_heap_offset =
+ entry->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER ?
+ entry->heap_offsets.extra_uav + d : ~0;
+
+ if (bview)
+ dzn_descriptor_set_write_buffer_view_desc(set, srv_heap_offset, uav_heap_offset, bview);
+ }
+ break;
+
+ default:
+ unreachable("invalid descriptor type");
+ }
+ }
+}
diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c
index f78904b6351..f00b2388877 100644
--- a/src/microsoft/vulkan/dzn_device.c
+++ b/src/microsoft/vulkan/dzn_device.c
@@ -77,6 +77,7 @@ static void
dzn_physical_device_get_extensions(struct dzn_physical_device *pdev)
{
pdev->vk.supported_extensions = (struct vk_device_extension_table) {
+ .KHR_descriptor_update_template = true,
#ifdef DZN_USE_WSI_PLATFORM
.KHR_swapchain = true,
#endif
diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h
index 55ba1ed7c34..58e8cdf7244 100644
--- a/src/microsoft/vulkan/dzn_private.h
+++ b/src/microsoft/vulkan/dzn_private.h
@@ -638,6 +638,30 @@ dzn_pipeline_layout_ref(struct dzn_pipeline_layout *layout);
void
dzn_pipeline_layout_unref(struct dzn_pipeline_layout *layout);
+struct dzn_descriptor_update_template_entry {
+ VkDescriptorType type;
+ uint32_t desc_count;
+ union {
+ struct {
+ uint32_t cbv_srv_uav;
+ union {
+ uint32_t sampler, extra_uav;
+ };
+ } heap_offsets;
+ uint32_t dynamic_buffer_idx;
+ };
+ struct {
+ size_t offset;
+ size_t stride;
+ } user_data;
+};
+
+struct dzn_descriptor_update_template {
+ struct vk_object_base base;
+ uint32_t entry_count;
+ const struct dzn_descriptor_update_template_entry *entries;
+};
+
#define MAX_RTS 8
#define MAX_INPUT_ATTACHMENTS 4
@@ -1002,6 +1026,7 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_device_memory, base, VkDeviceMemory, VK_OBJEC
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_pool, base, VkDescriptorPool, VK_OBJECT_TYPE_DESCRIPTOR_POOL)
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set, base, VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET)
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set_layout, base, VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
+VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_update_template, base, VkDescriptorUpdateTemplate, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_framebuffer, base, VkFramebuffer, VK_OBJECT_TYPE_FRAMEBUFFER)
VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
More information about the mesa-commit
mailing list