Mesa (main): v3dv: implement VK_KHR_descriptor_update_template

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jun 7 11:24:25 UTC 2021


Module: Mesa
Branch: main
Commit: 4886773fc049a20b937cff7648f6528df6bf45dc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4886773fc049a20b937cff7648f6528df6bf45dc

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Mon Jun  7 09:08:22 2021 +0200

v3dv: implement VK_KHR_descriptor_update_template

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

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11213>

---

 docs/features.txt                         |   2 +-
 src/broadcom/vulkan/v3dv_descriptor_set.c | 129 ++++++++++++++++++++++++++++++
 src/broadcom/vulkan/v3dv_device.c         |   1 +
 src/broadcom/vulkan/v3dv_private.h        |  40 +++++++++
 4 files changed, 171 insertions(+), 1 deletion(-)

diff --git a/docs/features.txt b/docs/features.txt
index 41789286a88..74980b01cf8 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -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)
diff --git a/src/broadcom/vulkan/v3dv_descriptor_set.c b/src/broadcom/vulkan/v3dv_descriptor_set.c
index c55d4773f56..15f23912b65 100644
--- a/src/broadcom/vulkan/v3dv_descriptor_set.c
+++ b/src/broadcom/vulkan/v3dv_descriptor_set.c
@@ -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");
+      }
+   }
+}
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index 60db2a0db7a..551302bccb3 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -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,
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 7d689409502..2efe9c6701f 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -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)



More information about the mesa-commit mailing list