[Mesa-dev] [PATCH v2 1/4] anv/descriptor_set: add reference counting for descriptor set layouts

Jason Ekstrand jason at jlekstrand.net
Fri Jan 26 09:39:29 UTC 2018


Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

Thanks for fixing this!

On Fri, Jan 26, 2018 at 1:26 AM, Iago Toral Quiroga <itoral at igalia.com>
wrote:

> The spec states that descriptor set layouts can be destroyed almost
> at any time:
>
>    "VkDescriptorSetLayout objects may be accessed by commands that
>     operate on descriptor sets allocated using that layout, and those
>     descriptor sets must not be updated with vkUpdateDescriptorSets
>     after the descriptor set layout has been destroyed. Otherwise,
>     descriptor set layouts can be destroyed any time they are not in
>     use by an API command."
>
> v2: allocate off the device allocator with DEVICE scope. This is
>     expected to warnings in some CTS tests (Jason)
>
> Fixes the following work-in-progress CTS tests:
> dEQP-VK.api.descriptor_set.descriptor_set_layout_lifetime.graphics
> dEQP-VK.api.descriptor_set.descriptor_set_layout_lifetime.compute
>
> Suggested-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>
> As expected, this patch adds the following warnings in CTS:
>
> Test case 'dEQP-VK.api.object_management.alloc_callback_
> fail.descriptor_set_layout_empty'..
>   QualityWarning (Allocation callbacks not called)
>
> Test case 'dEQP-VK.api.object_management.alloc_callback_
> fail.descriptor_set_layout_single'..
>   QualityWarning (Allocation callbacks not called)
>
>  src/intel/vulkan/anv_cmd_buffer.c     |  6 ++----
>  src/intel/vulkan/anv_descriptor_set.c | 23 ++++++++++++++++++-----
>  src/intel/vulkan/anv_private.h        | 23 +++++++++++++++++++++--
>  3 files changed, 41 insertions(+), 11 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_
> buffer.c
> index bf80061c6d..521cf6b6a5 100644
> --- a/src/intel/vulkan/anv_cmd_buffer.c
> +++ b/src/intel/vulkan/anv_cmd_buffer.c
> @@ -913,8 +913,7 @@ void anv_CmdPushDescriptorSetKHR(
>
>     assert(_set < MAX_SETS);
>
> -   const struct anv_descriptor_set_layout *set_layout =
> -      layout->set[_set].layout;
> +   struct anv_descriptor_set_layout *set_layout =
> layout->set[_set].layout;
>
>     struct anv_push_descriptor_set *push_set =
>        anv_cmd_buffer_get_push_descriptor_set(cmd_buffer,
> @@ -1006,8 +1005,7 @@ void anv_CmdPushDescriptorSetWithTemplateKHR(
>
>     assert(_set < MAX_PUSH_DESCRIPTORS);
>
> -   const struct anv_descriptor_set_layout *set_layout =
> -      layout->set[_set].layout;
> +   struct anv_descriptor_set_layout *set_layout =
> layout->set[_set].layout;
>
>     struct anv_push_descriptor_set *push_set =
>        anv_cmd_buffer_get_push_descriptor_set(cmd_buffer,
> diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_
> descriptor_set.c
> index 1d4df264ae..edb829601e 100644
> --- a/src/intel/vulkan/anv_descriptor_set.c
> +++ b/src/intel/vulkan/anv_descriptor_set.c
> @@ -57,16 +57,21 @@ VkResult anv_CreateDescriptorSetLayout(
>     struct anv_descriptor_set_binding_layout *bindings;
>     struct anv_sampler **samplers;
>
> +   /* We need to allocate decriptor set layouts off the device allocator
> +    * with DEVICE scope because they are reference counted and may not be
> +    * destroyed when vkDestroyDescriptorSetLayout is called.
> +    */
>     ANV_MULTIALLOC(ma);
>     anv_multialloc_add(&ma, &set_layout, 1);
>     anv_multialloc_add(&ma, &bindings, max_binding + 1);
>     anv_multialloc_add(&ma, &samplers, immutable_sampler_count);
>
> -   if (!anv_multialloc_alloc2(&ma, &device->alloc, pAllocator,
> -                              VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
> +   if (!anv_multialloc_alloc(&ma, &device->alloc,
> +                             VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
>        return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
>
>     memset(set_layout, 0, sizeof(*set_layout));
> +   set_layout->ref_cnt = 1;
>     set_layout->binding_count = max_binding + 1;
>
>     for (uint32_t b = 0; b <= max_binding; b++) {
> @@ -204,7 +209,7 @@ void anv_DestroyDescriptorSetLayout(
>     if (!set_layout)
>        return;
>
> -   vk_free2(&device->alloc, pAllocator, set_layout);
> +   anv_descriptor_set_layout_unref(device, set_layout);
>  }
>
>  static void
> @@ -246,6 +251,7 @@ VkResult anv_CreatePipelineLayout(
>        ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
>                        pCreateInfo->pSetLayouts[set]);
>        layout->set[set].layout = set_layout;
> +      anv_descriptor_set_layout_ref(set_layout);
>
>        layout->set[set].dynamic_offset_start = dynamic_offset_count;
>        for (uint32_t b = 0; b < set_layout->binding_count; b++) {
> @@ -290,6 +296,9 @@ void anv_DestroyPipelineLayout(
>     if (!pipeline_layout)
>        return;
>
> +   for (uint32_t i = 0; i < pipeline_layout->num_sets; i++)
> +      anv_descriptor_set_layout_unref(device, pipeline_layout->set[i].
> layout);
> +
>     vk_free2(&device->alloc, pAllocator, pipeline_layout);
>  }
>
> @@ -423,7 +432,7 @@ struct surface_state_free_list_entry {
>  VkResult
>  anv_descriptor_set_create(struct anv_device *device,
>                            struct anv_descriptor_pool *pool,
> -                          const struct anv_descriptor_set_layout *layout,
> +                          struct anv_descriptor_set_layout *layout,
>                            struct anv_descriptor_set **out_set)
>  {
>     struct anv_descriptor_set *set;
> @@ -455,8 +464,10 @@ anv_descriptor_set_create(struct anv_device *device,
>        }
>     }
>
> -   set->size = size;
>     set->layout = layout;
> +   anv_descriptor_set_layout_ref(layout);
> +
> +   set->size = size;
>     set->buffer_views =
>        (struct anv_buffer_view *) &set->descriptors[layout->size];
>     set->buffer_count = layout->buffer_count;
> @@ -512,6 +523,8 @@ anv_descriptor_set_destroy(struct anv_device *device,
>                             struct anv_descriptor_pool *pool,
>                             struct anv_descriptor_set *set)
>  {
> +   anv_descriptor_set_layout_unref(device, set->layout);
> +
>     /* Put the buffer view surface state back on the free list. */
>     for (uint32_t b = 0; b < set->buffer_count; b++) {
>        struct surface_state_free_list_entry *entry =
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_
> private.h
> index b351c6f63b..701a49823e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1199,6 +1199,9 @@ struct anv_descriptor_set_binding_layout {
>  };
>
>  struct anv_descriptor_set_layout {
> +   /* Descriptor set layouts can be destroyed at almost any time */
> +   uint32_t ref_cnt;
> +
>     /* Number of bindings in this descriptor set */
>     uint16_t binding_count;
>
> @@ -1218,6 +1221,22 @@ struct anv_descriptor_set_layout {
>     struct anv_descriptor_set_binding_layout binding[0];
>  };
>
> +static inline void
> +anv_descriptor_set_layout_ref(struct anv_descriptor_set_layout *layout)
> +{
> +   assert(layout && layout->ref_cnt >= 1);
> +   p_atomic_inc(&layout->ref_cnt);
> +}
> +
> +static inline void
> +anv_descriptor_set_layout_unref(struct anv_device *device,
> +                                struct anv_descriptor_set_layout *layout)
> +{
> +   assert(layout && layout->ref_cnt >= 1);
> +   if (p_atomic_dec_zero(&layout->ref_cnt))
> +      vk_free(&device->alloc, layout);
> +}
> +
>  struct anv_descriptor {
>     VkDescriptorType type;
>
> @@ -1239,7 +1258,7 @@ struct anv_descriptor {
>  };
>
>  struct anv_descriptor_set {
> -   const struct anv_descriptor_set_layout *layout;
> +   struct anv_descriptor_set_layout *layout;
>     uint32_t size;
>     uint32_t buffer_count;
>     struct anv_buffer_view *buffer_views;
> @@ -1363,7 +1382,7 @@ anv_descriptor_set_write_template(struct
> anv_descriptor_set *set,
>  VkResult
>  anv_descriptor_set_create(struct anv_device *device,
>                            struct anv_descriptor_pool *pool,
> -                          const struct anv_descriptor_set_layout *layout,
> +                          struct anv_descriptor_set_layout *layout,
>                            struct anv_descriptor_set **out_set);
>
>  void
> --
> 2.14.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180126/d1dde7c8/attachment-0001.html>


More information about the mesa-dev mailing list