[Mesa-dev] [PATCH 6/6] anv: add VK_KHR_descriptor_update_template support

Lionel Landwerlin lionel.g.landwerlin at intel.com
Mon Feb 27 19:34:35 UTC 2017


Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
---
 src/intel/vulkan/anv_cmd_buffer.c       |  33 ++++++++
 src/intel/vulkan/anv_descriptor_set.c   | 146 ++++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_device.c           |   4 +
 src/intel/vulkan/anv_entrypoints_gen.py |   1 +
 src/intel/vulkan/anv_private.h          |  48 +++++++++++
 5 files changed, 232 insertions(+)

diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c
index 3ce8827971..a6addd7029 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -907,3 +907,36 @@ void anv_CmdPushDescriptorSetKHR(
    cmd_buffer->state.descriptors[_set] = set;
    cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
 }
+
+void anv_CmdPushDescriptorSetWithTemplateKHR(
+    VkCommandBuffer                             commandBuffer,
+    VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
+    VkPipelineLayout                            _layout,
+    uint32_t                                    _set,
+    const void*                                 pData)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_descriptor_update_template, template,
+                   descriptorUpdateTemplate);
+   ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
+
+   assert(_set < MAX_PUSH_DESCRIPTORS);
+
+   const struct anv_descriptor_set_layout *set_layout =
+      layout->set[_set].layout;
+   struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set;
+
+   set->layout = set_layout;
+   set->size = anv_descriptor_set_layout_size(set_layout);
+   set->buffer_count = set_layout->buffer_count;
+   set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views;
+
+   anv_descriptor_set_write_template(set,
+                                     cmd_buffer->device,
+                                     &cmd_buffer->surface_state_stream,
+                                     template,
+                                     pData);
+
+   cmd_buffer->state.descriptors[_set] = set;
+   cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
+}
diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c
index e4224743ee..bbd3f0f13b 100644
--- a/src/intel/vulkan/anv_descriptor_set.c
+++ b/src/intel/vulkan/anv_descriptor_set.c
@@ -780,3 +780,149 @@ void anv_UpdateDescriptorSets(
          dst_desc[j] = src_desc[j];
    }
 }
+
+/*
+ * Descriptor update templates.
+ */
+
+void
+anv_descriptor_set_write_template(struct anv_descriptor_set *set,
+                                  struct anv_device *device,
+                                  struct anv_state_stream *alloc_stream,
+                                  const struct anv_descriptor_update_template *template,
+                                  const void *data)
+{
+   const struct anv_descriptor_set_layout *layout = set->layout;
+
+   for (uint32_t i = 0; i < template->entry_count; i++) {
+      const struct anv_descriptor_template_entry *entry =
+         &template->entries[i];
+      const struct anv_descriptor_set_binding_layout *bind_layout =
+         &layout->binding[entry->binding];
+      struct anv_descriptor *desc = &set->descriptors[bind_layout->descriptor_index];
+      desc += entry->array_element;
+
+      switch (entry->type) {
+      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 =
+               data + entry->offset + j * entry->stride;
+            anv_descriptor_set_write_image_view(set,
+                                                entry->type,
+                                                info->imageView,
+                                                info->sampler,
+                                                entry->binding,
+                                                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 =
+               data + entry->offset + j * entry->stride;
+            ANV_FROM_HANDLE(anv_buffer_view, bview, *_bview);
+
+            anv_descriptor_set_write_buffer_view(set,
+                                                 entry->type,
+                                                 bview,
+                                                 entry->binding,
+                                                 entry->array_element + j);
+         }
+         break;
+
+      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 =
+               data + entry->offset + j * entry->stride;
+            ANV_FROM_HANDLE(anv_buffer, buffer, info->buffer);
+
+            anv_descriptor_set_write_buffer(set,
+                                            device,
+                                            alloc_stream,
+                                            entry->type,
+                                            buffer,
+                                            entry->binding,
+                                            entry->array_element + j,
+                                            info->offset, info->range);
+         }
+         break;
+
+      default:
+         break;
+      }
+   }
+}
+
+VkResult anv_CreateDescriptorUpdateTemplateKHR(
+    VkDevice                                    _device,
+    const VkDescriptorUpdateTemplateCreateInfoKHR* pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkDescriptorUpdateTemplateKHR*              pDescriptorUpdateTemplate)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_descriptor_update_template *template;
+
+   size_t size = sizeof(*template) +
+      pCreateInfo->descriptorUpdateEntryCount * sizeof(template->entries[0]);
+   template = vk_alloc2(&device->alloc, pAllocator, size, 8,
+                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (template == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR)
+      template->set = pCreateInfo->set;
+
+   template->entry_count = pCreateInfo->descriptorUpdateEntryCount;
+   for (uint32_t i = 0; i < template->entry_count; i++) {
+      const VkDescriptorUpdateTemplateEntryKHR *pEntry =
+         &pCreateInfo->pDescriptorUpdateEntries[i];
+
+      template->entries[i] = (struct anv_descriptor_template_entry) {
+         .type = pEntry->descriptorType,
+         .binding = pEntry->dstBinding,
+         .array_element = pEntry->dstArrayElement,
+         .array_count = pEntry->descriptorCount,
+         .offset = pEntry->offset,
+         .stride = pEntry->stride,
+      };
+   }
+
+   *pDescriptorUpdateTemplate =
+      anv_descriptor_update_template_to_handle(template);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyDescriptorUpdateTemplateKHR(
+    VkDevice                                    _device,
+    VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
+    const VkAllocationCallbacks*                pAllocator)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_descriptor_update_template, template,
+                   descriptorUpdateTemplate);
+
+   vk_free2(&device->alloc, pAllocator, template);
+}
+
+void anv_UpdateDescriptorSetWithTemplateKHR(
+    VkDevice                                    _device,
+    VkDescriptorSet                             descriptorSet,
+    VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
+    const void*                                 pData)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_descriptor_set, set, descriptorSet);
+   ANV_FROM_HANDLE(anv_descriptor_update_template, template,
+                   descriptorUpdateTemplate);
+
+   anv_descriptor_set_write_template(set, device, NULL, template, pData);
+}
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 9f8541938b..e5c2fa3414 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -265,6 +265,10 @@ static const VkExtensionProperties device_extensions[] = {
    {
       .extensionName = VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME,
       .specVersion = 1,
+   },
+   {
+      .extensionName = VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME,
+      .specVersion = 1,
    }
 };
 
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index b2b2b62961..4e5d2ee6c5 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -28,6 +28,7 @@ import xml.etree.ElementTree as ET
 max_api_version = 1.0
 
 supported_extensions = [
+   'VK_KHR_descriptor_update_template',
    'VK_KHR_get_physical_device_properties2',
    'VK_KHR_maintenance1',
    'VK_KHR_push_descriptor',
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 8ac910adf9..b3bc1b33a3 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -950,6 +950,46 @@ struct anv_descriptor_pool {
    char data[0];
 };
 
+enum anv_descriptor_template_entry_type {
+   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_IMAGE,
+   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER,
+   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER_VIEW
+};
+
+struct anv_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 anv_descriptor_update_template {
+   /* 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_KHR.
+    */
+   uint8_t set;
+
+   /* Number of entries in this template */
+   uint32_t entry_count;
+
+   /* Entries of the template */
+   struct anv_descriptor_template_entry entries[0];
+};
+
 size_t
 anv_descriptor_set_layout_size(const struct anv_descriptor_set_layout *layout);
 
@@ -979,6 +1019,13 @@ anv_descriptor_set_write_buffer(struct anv_descriptor_set *set,
                                 VkDeviceSize offset,
                                 VkDeviceSize range);
 
+void
+anv_descriptor_set_write_template(struct anv_descriptor_set *set,
+                                  struct anv_device *device,
+                                  struct anv_state_stream *alloc_stream,
+                                  const struct anv_descriptor_update_template *template,
+                                  const void *data);
+
 VkResult
 anv_descriptor_set_create(struct anv_device *device,
                           struct anv_descriptor_pool *pool,
@@ -1981,6 +2028,7 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, VkBufferView)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_pool, VkDescriptorPool)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, VkDescriptorSet)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, VkDescriptorSetLayout)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_update_template, VkDescriptorUpdateTemplateKHR)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, VkDeviceMemory)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, VkFence)
 ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_event, VkEvent)
-- 
2.11.0



More information about the mesa-dev mailing list