[Mesa-dev] [PATCH v2 6/6] radeonsi: try to re-use previously deleted bindless descriptor slots
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Aug 4 08:06:06 UTC 2017
On 08/01/2017 09:54 PM, Marek Olšák wrote:
> Hi Samuel,
>
> Can you move this slot allocator into a util module? It seems generic
> enough that it could be reused for "handle" and "ID" allocations.
>
> Some additional notes:
> - a bit array of uin32_t would be better. bool is too large (1 byte).
> - "free" is the inverse of "used", so the "used" array is redundant.
Yeah, but we have to keep track of two different arrays. When a texture
handle is destroyed, the ID can be re-used but not right now, because
the GPU can still use the descriptor. The names are probably bad, maybe
bindless_free_slots and bindless_deleted_slots is better?
>
> Thanks,
> Marek
>
> On Wed, Jul 26, 2017 at 4:21 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.
>>
>> The idea is to maintain two simple lists which keep track of
>> which slots is used and which ones have been deleted. When the
>> array is resized, previously deleted slots can be marked as
>> free because we are going to upload a new fresh buffer.
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>> ---
>> src/gallium/drivers/radeonsi/si_descriptors.c | 85 +++++++++++++++++++++++----
>> src/gallium/drivers/radeonsi/si_pipe.h | 2 +
>> 2 files changed, 75 insertions(+), 12 deletions(-)
>>
>> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
>> index 543a19ba1e..95f0479be7 100644
>> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
>> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
>> @@ -2299,11 +2299,72 @@ static void si_init_bindless_descriptors(struct si_context *sctx,
>> * considered to be a valid handle.
>> */
>> sctx->num_bindless_descriptors = 1;
>> +
>> + /* Allocate two simple arrays for re-using previously deleted slots. */
>> + sctx->bindless_used_slots = CALLOC(num_elements, sizeof(bool));
>> + sctx->bindless_free_slots = CALLOC(num_elements, sizeof(bool));
>> }
>>
>> static inline void si_release_bindless_descriptors(struct si_context *sctx)
>> {
>> si_release_descriptors(&sctx->bindless_descriptors);
>> + FREE(sctx->bindless_used_slots);
>> + FREE(sctx->bindless_free_slots);
>> +}
>> +
>> +static unsigned si_get_next_free_bindless_slot(struct si_context *sctx)
>> +{
>> + struct si_descriptors *desc = &sctx->bindless_descriptors;
>> + unsigned i;
>> +
>> + for (i = 1; i < desc->num_elements; i++) {
>> + if (!sctx->bindless_used_slots[i]) {
>> + /* Lock this descriptor slot. */
>> + sctx->bindless_used_slots[i] = true;
>> + return i;
>> + }
>> + }
>> +
>> + /* No available descriptor slots. */
>> + return 0;
>> +}
>> +
>> +static void si_resize_bindless_descriptor(struct si_context *sctx)
>> +{
>> + struct si_descriptors *desc = &sctx->bindless_descriptors;
>> + unsigned slot_size = desc->element_dw_size * 4;
>> + unsigned old_num_elements = desc->num_elements;
>> + unsigned new_num_elements = old_num_elements * 2;
>> + unsigned i;
>> +
>> + /* All previously deleted slots can now be re-used because we are going
>> + * to upload a new buffer.
>> + */
>> + for (i = 1; i < old_num_elements; i++) {
>> + if (sctx->bindless_free_slots[i]) {
>> + /* Unlock this descriptor slot. */
>> + sctx->bindless_used_slots[i] = false;
>> + }
>> + sctx->bindless_free_slots[i] = false;
>> + }
>> +
>> + /* Resize the array of descriptors. */
>> + desc->list = REALLOC(desc->list, desc->num_elements * slot_size,
>> + new_num_elements * slot_size);
>> + desc->num_elements = new_num_elements;
>> + desc->num_active_slots = new_num_elements;
>> +
>> + /* Resize the two simple arrays and mark all slots as free. */
>> + sctx->bindless_used_slots = REALLOC(sctx->bindless_used_slots,
>> + old_num_elements,
>> + new_num_elements);
>> + sctx->bindless_free_slots = REALLOC(sctx->bindless_free_slots,
>> + old_num_elements,
>> + new_num_elements);
>> + for (i = old_num_elements; i < new_num_elements; i++) {
>> + sctx->bindless_used_slots[i] = false;
>> + sctx->bindless_free_slots[i] = false;
>> + }
>> }
>>
>> static unsigned
>> @@ -2315,19 +2376,16 @@ si_create_bindless_descriptor(struct si_context *sctx, uint32_t *desc_list,
>> unsigned desc_slot, desc_slot_offset;
>> bool resized = false;
>>
>> - /* Reserve a new slot for this bindless descriptor. */
>> - desc_slot = sctx->num_bindless_descriptors++;
>> -
>> - if (desc_slot >= desc->num_elements) {
>> - /* The array of bindless descriptors is full, resize it. */
>> - unsigned slot_size = desc->element_dw_size * 4;
>> - unsigned new_num_elements = desc->num_elements * 2;
>> -
>> - desc->list = REALLOC(desc->list, desc->num_elements * slot_size,
>> - new_num_elements * slot_size);
>> - desc->num_elements = new_num_elements;
>> - desc->num_active_slots = new_num_elements;
>> + /* Find a free slot. */
>> + desc_slot = si_get_next_free_bindless_slot(sctx);
>> + if (!desc_slot) {
>> + /* The array of descriptors is full, resize it. */
>> + si_resize_bindless_descriptor(sctx);
>> resized = true;
>> +
>> + /* Get a new slot. */
>> + desc_slot = si_get_next_free_bindless_slot(sctx);
>> + assert(desc_slot);
>> }
>>
>> /* For simplicity, sampler and image bindless descriptors use fixed
>> @@ -2459,6 +2517,9 @@ static void si_delete_texture_handle(struct pipe_context *ctx, uint64_t handle)
>>
>> tex_handle = (struct si_texture_handle *)entry->data;
>>
>> + /* Mark this descriptor slot as free in order to re-use it. */
>> + sctx->bindless_free_slots[tex_handle->desc_slot] = true;
>> +
>> 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 cfdf4a5571..c79be578f9 100644
>> --- a/src/gallium/drivers/radeonsi/si_pipe.h
>> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
>> @@ -414,6 +414,8 @@ struct si_context {
>>
>> /* Bindless descriptors. */
>> struct si_descriptors bindless_descriptors;
>> + bool *bindless_used_slots;
>> + bool *bindless_free_slots;
>> unsigned num_bindless_descriptors;
>> bool bindless_descriptors_dirty;
>> bool graphics_bindless_pointer_dirty;
>> --
>> 2.13.3
>>
>> _______________________________________________
>> 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