[Mesa-dev] [PATCH v3 6/6] radeonsi: try to re-use previously deleted bindless descriptor slots

Marek Olšák maraeo at gmail.com
Fri Aug 11 17:37:42 UTC 2017


This patch needs to be updated for the latest version of util_idalloc.

Marek

On Tue, Aug 8, 2017 at 6:57 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Currently, when the array is full it is resized but it can grow
> over and over because we don't try to re-use descriptor slots.
>
> v3: - use new idalloc gallium module
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  src/gallium/drivers/radeonsi/si_descriptors.c | 57 +++++++++++++++++++++------
>  src/gallium/drivers/radeonsi/si_pipe.h        |  2 +
>  2 files changed, 47 insertions(+), 12 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index 2e8f1320a1..29eb5bf3d1 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -61,6 +61,7 @@
>  #include "gfx9d.h"
>
>  #include "util/hash_table.h"
> +#include "util/u_idalloc.h"
>  #include "util/u_format.h"
>  #include "util/u_memory.h"
>  #include "util/u_upload_mgr.h"
> @@ -2333,33 +2334,62 @@ static void si_init_bindless_descriptors(struct si_context *sctx,
>          * considered to be a valid handle.
>          */
>         sctx->num_bindless_descriptors = 1;
> +
> +       /* Keep track of which bindless slots are used (or not). */
> +       util_idalloc_init(&sctx->bindless_used_slots);
> +       util_idalloc_resize(&sctx->bindless_used_slots, num_elements);
> +
> +       /* Lock slot 0 because it's an invalid handle for bindless. */
> +       util_idalloc_lock(&sctx->bindless_used_slots, 0);
>  }
>
>  static inline void si_release_bindless_descriptors(struct si_context *sctx)
>  {
>         si_release_descriptors(&sctx->bindless_descriptors);
> +       util_idalloc_fini(&sctx->bindless_used_slots);
>  }
>
> -static unsigned
> -si_create_bindless_descriptor(struct si_context *sctx, uint32_t *desc_list,
> -                             unsigned size)
> +static unsigned si_get_next_free_bindless_slot(struct si_context *sctx)
>  {
> -       struct si_descriptors *desc = &sctx->bindless_descriptors;
> -       unsigned desc_slot, desc_slot_offset;
> -
> -       /* Reserve a new slot for this bindless descriptor. */
> -       desc_slot = sctx->num_bindless_descriptors++;
> +       int desc_slot;
>
> -       if (desc_slot >= desc->num_elements) {
> -               /* The array of bindless descriptors is full, resize it. */
> +       desc_slot = util_idalloc_get_next_free(&sctx->bindless_used_slots);
> +       if (desc_slot < 0) {
> +               /* No slots are available. */
> +               struct si_descriptors *desc = &sctx->bindless_descriptors;
>                 unsigned slot_size = desc->element_dw_size * 4;
> -               unsigned new_num_elements = desc->num_elements * 2;
> +               unsigned old_num_elements = desc->num_elements;
> +               unsigned new_num_elements = old_num_elements * 2;
>
> -               desc->list = REALLOC(desc->list, desc->num_elements * slot_size,
> +               /* Resize the array of descriptors. */
> +               desc->list = REALLOC(desc->list, old_num_elements * slot_size,
>                                      new_num_elements * slot_size);
>                 desc->num_elements = new_num_elements;
>                 desc->num_active_slots = new_num_elements;
> +
> +               /* Resize the array of slots. */
> +               util_idalloc_resize(&sctx->bindless_used_slots, new_num_elements);
> +
> +               /* Get a new slot. */
> +               desc_slot = util_idalloc_get_next_free(&sctx->bindless_used_slots);
>         }
> +       assert(desc_slot);
> +
> +       /* Prevent this bindless descriptor slot to be re-used. */
> +       util_idalloc_lock(&sctx->bindless_used_slots, desc_slot);
> +
> +       return desc_slot;
> +}
> +
> +static unsigned
> +si_create_bindless_descriptor(struct si_context *sctx, uint32_t *desc_list,
> +                             unsigned size)
> +{
> +       struct si_descriptors *desc = &sctx->bindless_descriptors;
> +       unsigned desc_slot, desc_slot_offset;
> +
> +       /* Find a free slot. */
> +       desc_slot = si_get_next_free_bindless_slot(sctx);
>
>         /* For simplicity, sampler and image bindless descriptors use fixed
>          * 16-dword slots for now. Image descriptors only need 8-dword but this
> @@ -2473,6 +2503,9 @@ static void si_delete_texture_handle(struct pipe_context *ctx, uint64_t handle)
>
>         tex_handle = (struct si_texture_handle *)entry->data;
>
> +       /* Unlock this descriptor slot. */
> +       util_idalloc_unlock(&sctx->bindless_used_slots, tex_handle->desc_slot);
> +
>         pipe_sampler_view_reference(&tex_handle->view, NULL);
>         _mesa_hash_table_remove(sctx->tex_handles, entry);
>         FREE(tex_handle);
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
> index c44d6d5dff..447795d97b 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -29,6 +29,7 @@
>  #include "si_shader.h"
>
>  #include "util/u_dynarray.h"
> +#include "util/u_idalloc.h"
>
>  #ifdef PIPE_ARCH_BIG_ENDIAN
>  #define SI_BIG_ENDIAN 1
> @@ -429,6 +430,7 @@ struct si_context {
>
>         /* Bindless descriptors. */
>         struct si_descriptors   bindless_descriptors;
> +       struct util_idalloc     bindless_used_slots;
>         unsigned                num_bindless_descriptors;
>         bool                    bindless_descriptors_dirty;
>         bool                    graphics_bindless_pointer_dirty;
> --
> 2.14.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