[Mesa-dev] [PATCH 4/5] radv: implement VK_KHR_descriptor_update_template

Fredrik Höglund fredrik at kde.org
Thu Apr 6 17:43:35 UTC 2017


On Wednesday 05 April 2017, Bas Nieuwenhuizen wrote:
> Could you move the declarations you add in radv_descriptor_set.h to
> radv_private.h? I'd like to keep it limited to whatever is necessary
> for the compiler, which is only the set & pipeline layouts. You could
> just put it next to the radv_descriptor_set declaration.

Will do.
 
> Otherwise, nice work! The series is
> 
> Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
> 
> Did you have push access?

Yes; I'll push the series in a couple of hours with a v2 of patch 4.

Thanks for the review!

> On Tue, Apr 4, 2017 at 11:29 PM, Fredrik Höglund <fredrik at kde.org> wrote:
> > All offsets and strides are precomputed by
> > radv_CreateDescriptorUpdateTemplateKHR and stored in the template.
> >
> > Signed-off-by: Fredrik Höglund <fredrik at kde.org>
> > ---
> >  src/amd/vulkan/radv_cmd_buffer.c       |  24 +++++
> >  src/amd/vulkan/radv_descriptor_set.c   | 163 +++++++++++++++++++++++++++++++++
> >  src/amd/vulkan/radv_descriptor_set.h   |  31 +++++++
> >  src/amd/vulkan/radv_device.c           |   4 +
> >  src/amd/vulkan/radv_entrypoints_gen.py |   1 +
> >  src/amd/vulkan/radv_private.h          |   8 ++
> >  6 files changed, 231 insertions(+)
> >
> > diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> > index 46c139a8fc..992dc123a2 100644
> > --- a/src/amd/vulkan/radv_cmd_buffer.c
> > +++ b/src/amd/vulkan/radv_cmd_buffer.c
> > @@ -1988,6 +1988,30 @@ void radv_CmdPushDescriptorSetKHR(
> >         cmd_buffer->state.push_descriptors_dirty = true;
> >  }
> >
> > +void radv_CmdPushDescriptorSetWithTemplateKHR(
> > +       VkCommandBuffer                             commandBuffer,
> > +       VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
> > +       VkPipelineLayout                            _layout,
> > +       uint32_t                                    set,
> > +       const void*                                 pData)
> > +{
> > +       RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
> > +       RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
> > +       struct radv_descriptor_set *push_set = &cmd_buffer->push_descriptors.set;
> > +
> > +       assert(layout->set[set].layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
> > +
> > +       if (!radv_init_push_descriptor_set(cmd_buffer, push_set, layout->set[set].layout))
> > +               return;
> > +
> > +       radv_update_descriptor_set_with_template(cmd_buffer->device, cmd_buffer, push_set,
> > +                                                descriptorUpdateTemplate, pData);
> > +
> > +       cmd_buffer->state.descriptors[set] = push_set;
> > +       cmd_buffer->state.descriptors_dirty |= (1 << set);
> > +       cmd_buffer->state.push_descriptors_dirty = true;
> > +}
> > +
> >  void radv_CmdPushConstants(VkCommandBuffer commandBuffer,
> >                            VkPipelineLayout layout,
> >                            VkShaderStageFlags stageFlags,
> > diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
> > index 0ff9aa206d..c2bf006f34 100644
> > --- a/src/amd/vulkan/radv_descriptor_set.c
> > +++ b/src/amd/vulkan/radv_descriptor_set.c
> > @@ -742,3 +742,166 @@ void radv_UpdateDescriptorSets(
> >         radv_update_descriptor_sets(device, NULL, VK_NULL_HANDLE, descriptorWriteCount, pDescriptorWrites,
> >                                     descriptorCopyCount, pDescriptorCopies);
> >  }
> > +
> > +VkResult radv_CreateDescriptorUpdateTemplateKHR(VkDevice _device,
> > +                                                const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
> > +                                                const VkAllocationCallbacks *pAllocator,
> > +                                                VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate)
> > +{
> > +       RADV_FROM_HANDLE(radv_device, device, _device);
> > +       RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->descriptorSetLayout);
> > +       const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount;
> > +       const size_t size = sizeof(struct radv_descriptor_update_template) +
> > +               sizeof(struct radv_descriptor_update_template_entry) * entry_count;
> > +       struct radv_descriptor_update_template *templ;
> > +       uint32_t i;
> > +
> > +       templ = vk_alloc2(&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> > +       if (!templ)
> > +               return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> > +
> > +       templ->entry_count = entry_count;
> > +
> > +       for (i = 0; i < entry_count; i++) {
> > +               const VkDescriptorUpdateTemplateEntryKHR *entry = &pCreateInfo->pDescriptorUpdateEntries[i];
> > +               const struct radv_descriptor_set_binding_layout *binding_layout =
> > +                       set_layout->binding + entry->dstBinding;
> > +               const uint32_t buffer_offset = binding_layout->buffer_offset +
> > +                       binding_layout->buffer_count * entry->dstArrayElement;
> > +               uint32_t *immutable_samplers = NULL;
> > +               uint16_t dst_offset;
> > +               uint16_t dst_stride;
> > +
> > +               /* dst_offset is an offset into dynamic_descriptors when the descriptor
> > +                  is dynamic, and an offset into mapped_ptr otherwise */
> > +               switch (entry->descriptorType) {
> > +               case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
> > +               case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
> > +                       assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR);
> > +                       dst_offset = binding_layout->dynamic_offset_offset + entry->dstArrayElement;
> > +                       dst_stride = 0; /* Not used */
> > +                       break;
> > +               default:
> > +                       switch (entry->descriptorType) {
> > +                       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
> > +                       case VK_DESCRIPTOR_TYPE_SAMPLER:
> > +                               /* Immutable samplers are copied into push descriptors when they are pushed */
> > +                               if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR &&
> > +                                   binding_layout->immutable_samplers && !binding_layout->immutable_samplers_equal)
> > +                                       immutable_samplers = binding_layout->immutable_samplers + entry->dstArrayElement * 4;
> > +                               break;
> > +                       default:
> > +                               break;
> > +                       }
> > +                       dst_offset = binding_layout->offset / 4 + binding_layout->size * entry->dstArrayElement / 4;
> > +                       dst_stride = binding_layout->size / 4;
> > +                       break;
> > +               }
> > +
> > +               templ->entry[i] = (struct radv_descriptor_update_template_entry) {
> > +                       .descriptor_type = entry->descriptorType,
> > +                       .descriptor_count = entry->descriptorCount,
> > +                       .src_offset = entry->offset,
> > +                       .src_stride = entry->stride,
> > +                       .dst_offset = dst_offset,
> > +                       .dst_stride = dst_stride,
> > +                       .buffer_offset = buffer_offset,
> > +                       .buffer_count = binding_layout->buffer_count,
> > +                       .has_sampler = !binding_layout->immutable_samplers,
> > +                       .immutable_samplers = immutable_samplers
> > +               };
> > +       }
> > +
> > +       *pDescriptorUpdateTemplate = radv_descriptor_update_template_to_handle(templ);
> > +       return VK_SUCCESS;
> > +}
> > +
> > +void radv_DestroyDescriptorUpdateTemplateKHR(VkDevice _device,
> > +                                             VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
> > +                                             const VkAllocationCallbacks *pAllocator)
> > +{
> > +       RADV_FROM_HANDLE(radv_device, device, _device);
> > +       RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
> > +
> > +       if (!templ)
> > +               return;
> > +
> > +       vk_free2(&device->alloc, pAllocator, templ);
> > +}
> > +
> > +void radv_update_descriptor_set_with_template(struct radv_device *device,
> > +                                              struct radv_cmd_buffer *cmd_buffer,
> > +                                              struct radv_descriptor_set *set,
> > +                                              VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
> > +                                              const void *pData)
> > +{
> > +       RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
> > +       uint32_t i;
> > +
> > +       for (i = 0; i < templ->entry_count; ++i) {
> > +               struct radeon_winsys_bo **buffer_list = set->descriptors + templ->entry[i].buffer_offset;
> > +               uint32_t *pDst = set->mapped_ptr + templ->entry[i].dst_offset;
> > +               const uint8_t *pSrc = ((const uint8_t *) pData) + templ->entry[i].src_offset;
> > +               uint32_t j;
> > +
> > +               for (j = 0; j < templ->entry[i].descriptor_count; ++j) {
> > +                       switch (templ->entry[i].descriptor_type) {
> > +                       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
> > +                       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
> > +                               const unsigned idx = templ->entry[i].dst_offset + j;
> > +                               assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
> > +                               write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx,
> > +                                                               buffer_list, (struct VkDescriptorBufferInfo *) pSrc);
> > +                               break;
> > +                       }
> > +                       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
> > +                       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
> > +                               write_buffer_descriptor(device, cmd_buffer, pDst, buffer_list,
> > +                                                       (struct VkDescriptorBufferInfo *) pSrc);
> > +                               break;
> > +                       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
> > +                       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
> > +                               write_texel_buffer_descriptor(device, cmd_buffer, pDst, buffer_list,
> > +                                                             *(VkBufferView *) pSrc);
> > +                               break;
> > +                       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
> > +                       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
> > +                       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
> > +                               write_image_descriptor(device, cmd_buffer, pDst, buffer_list,
> > +                                                      (struct VkDescriptorImageInfo *) pSrc);
> > +                               break;
> > +                       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
> > +                               write_combined_image_sampler_descriptor(device, cmd_buffer, pDst, buffer_list,
> > +                                                                       (struct VkDescriptorImageInfo *) pSrc,
> > +                                                                       templ->entry[i].has_sampler);
> > +                               if (templ->entry[i].immutable_samplers)
> > +                                       memcpy(pDst + 16, templ->entry[i].immutable_samplers + 4 * j, 16);
> > +                               break;
> > +                       case VK_DESCRIPTOR_TYPE_SAMPLER:
> > +                               if (templ->entry[i].has_sampler)
> > +                                       write_sampler_descriptor(device, pDst,
> > +                                                                (struct VkDescriptorImageInfo *) pSrc);
> > +                               else if (templ->entry[i].immutable_samplers)
> > +                                       memcpy(pDst, templ->entry[i].immutable_samplers + 4 * j, 16);
> > +                               break;
> > +                       default:
> > +                               unreachable("unimplemented descriptor type");
> > +                               break;
> > +                       }
> > +                       pSrc += templ->entry[i].src_stride;
> > +                       pDst += templ->entry[i].dst_stride;
> > +                       buffer_list += templ->entry[i].buffer_count;
> > +               }
> > +       }
> > +}
> > +
> > +void radv_UpdateDescriptorSetWithTemplateKHR(VkDevice _device,
> > +                                             VkDescriptorSet descriptorSet,
> > +                                             VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
> > +                                             const void *pData)
> > +{
> > +       RADV_FROM_HANDLE(radv_device, device, _device);
> > +       RADV_FROM_HANDLE(radv_descriptor_set, set, descriptorSet);
> > +
> > +       radv_update_descriptor_set_with_template(device, NULL, set, descriptorUpdateTemplate, pData);
> > +}
> > diff --git a/src/amd/vulkan/radv_descriptor_set.h b/src/amd/vulkan/radv_descriptor_set.h
> > index b3bbb193e8..49d997fd8a 100644
> > --- a/src/amd/vulkan/radv_descriptor_set.h
> > +++ b/src/amd/vulkan/radv_descriptor_set.h
> > @@ -86,4 +86,35 @@ struct radv_pipeline_layout {
> >     unsigned char sha1[20];
> >  };
> >
> > +struct radv_descriptor_update_template_entry {
> > +   VkDescriptorType descriptor_type;
> > +
> > +   /* The number of descriptors to update */
> > +   uint16_t descriptor_count;
> > +
> > +   /* Into mapped_ptr or dynamic_descriptors, in units of the respective array */
> > +   uint16_t dst_offset;
> > +
> > +   /* In dwords. Not valid/used for dynamic descriptors */
> > +   uint16_t dst_stride;
> > +
> > +   uint16_t buffer_offset;
> > +   uint16_t buffer_count;
> > +
> > +   /* Only valid for combined image samplers and samplers */
> > +   uint16_t has_sampler;
> > +
> > +   /* In bytes */
> > +   size_t src_offset;
> > +   size_t src_stride;
> > +
> > +   /* For push descriptors */
> > +   uint32_t *immutable_samplers;
> > +};
> > +
> > +struct radv_descriptor_update_template {
> > +   uint32_t entry_count;
> > +   struct radv_descriptor_update_template_entry entry[0];
> > +};
> > +
> >  #endif /* RADV_DESCRIPTOR_SET_H */
> > diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> > index 059c013f35..9e8faa3da9 100644
> > --- a/src/amd/vulkan/radv_device.c
> > +++ b/src/amd/vulkan/radv_device.c
> > @@ -92,6 +92,10 @@ static const VkExtensionProperties instance_extensions[] = {
> >
> >  static const VkExtensionProperties common_device_extensions[] = {
> >         {
> > +               .extensionName = VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME,
> > +               .specVersion = 1,
> > +       },
> > +       {
> >                 .extensionName = VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
> >                 .specVersion = 1,
> >         },
> > diff --git a/src/amd/vulkan/radv_entrypoints_gen.py b/src/amd/vulkan/radv_entrypoints_gen.py
> > index 4651c63dcf..3474c789ea 100644
> > --- a/src/amd/vulkan/radv_entrypoints_gen.py
> > +++ b/src/amd/vulkan/radv_entrypoints_gen.py
> > @@ -30,6 +30,7 @@ max_api_version = 1.0
> >  supported_extensions = [
> >     'VK_AMD_draw_indirect_count',
> >     'VK_NV_dedicated_allocation',
> > +   'VK_KHR_descriptor_update_template',
> >     'VK_KHR_get_physical_device_properties2',
> >     'VK_KHR_incremental_present',
> >     'VK_KHR_maintenance1',
> > diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> > index e39819fff3..abbb9d69be 100644
> > --- a/src/amd/vulkan/radv_private.h
> > +++ b/src/amd/vulkan/radv_private.h
> > @@ -1363,6 +1363,13 @@ radv_update_descriptor_sets(struct radv_device *device,
> >                              uint32_t descriptorCopyCount,
> >                              const VkCopyDescriptorSet *pDescriptorCopies);
> >
> > +void
> > +radv_update_descriptor_set_with_template(struct radv_device *device,
> > +                                         struct radv_cmd_buffer *cmd_buffer,
> > +                                         struct radv_descriptor_set *set,
> > +                                         VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
> > +                                         const void *pData);
> > +
> >  void radv_initialise_cmask(struct radv_cmd_buffer *cmd_buffer,
> >                            struct radv_image *image, uint32_t value);
> >  void radv_initialize_dcc(struct radv_cmd_buffer *cmd_buffer,
> > @@ -1419,6 +1426,7 @@ RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_buffer_view, VkBufferView)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_descriptor_pool, VkDescriptorPool)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_descriptor_set, VkDescriptorSet)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_descriptor_set_layout, VkDescriptorSetLayout)
> > +RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_descriptor_update_template, VkDescriptorUpdateTemplateKHR)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_device_memory, VkDeviceMemory)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_fence, VkFence)
> >  RADV_DEFINE_NONDISP_HANDLE_CASTS(radv_event, VkEvent)
> > --
> > 2.11.0
> >
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 



More information about the mesa-dev mailing list