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.pitoi...@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@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev