From 1a460d1c7e89461f7939563036a8eef565d5f58b Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 5 Sep 2022 14:59:19 -0400 Subject: [PATCH] asahi: Make BO list growable Back it by a simple dynamic array, ralloc'd off the batch (and make the context/batch ralloc'd so stuff gets cleaned up). Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_pipe.c | 14 ++++++++------ src/gallium/drivers/asahi/agx_state.h | 34 +++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index acf6237..8a38fb8 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -510,14 +510,14 @@ agx_flush(struct pipe_context *pctx, } unsigned handle_count = - BITSET_COUNT(batch->bo_list) + + agx_batch_num_bo(batch) + agx_pool_num_bos(&batch->pool) + agx_pool_num_bos(&batch->pipeline_pool); uint32_t *handles = calloc(sizeof(uint32_t), handle_count); unsigned handle = 0, handle_i = 0; - BITSET_FOREACH_SET(handle, batch->bo_list, sizeof(batch->bo_list) * 8) { + AGX_BATCH_FOREACH_BO_HANDLE(batch, handle) { handles[handle_i++] = handle; } @@ -564,7 +564,7 @@ agx_flush(struct pipe_context *pctx, agxdecode_next_frame(); } - memset(batch->bo_list, 0, sizeof(batch->bo_list)); + memset(batch->bo_list.set, 0, batch->bo_list.word_count * sizeof(BITSET_WORD)); agx_pool_cleanup(&ctx->batch->pool); agx_pool_cleanup(&ctx->batch->pipeline_pool); agx_pool_init(&ctx->batch->pool, dev, AGX_MEMORY_TYPE_FRAMEBUFFER, true); @@ -592,7 +592,7 @@ agx_destroy_context(struct pipe_context *pctx) util_unreference_framebuffer_state(&ctx->framebuffer); - FREE(ctx); + ralloc_free(ctx); } static void @@ -605,7 +605,7 @@ static struct pipe_context * agx_create_context(struct pipe_screen *screen, void *priv, unsigned flags) { - struct agx_context *ctx = CALLOC_STRUCT(agx_context); + struct agx_context *ctx = rzalloc(NULL, struct agx_context); struct pipe_context *pctx = &ctx->base; if (!ctx) @@ -614,7 +614,9 @@ agx_create_context(struct pipe_screen *screen, pctx->screen = screen; pctx->priv = priv; - ctx->batch = CALLOC_STRUCT(agx_batch); + ctx->batch = rzalloc(ctx, struct agx_batch); + ctx->batch->bo_list.set = rzalloc_array(ctx->batch, BITSET_WORD, 128); + ctx->batch->bo_list.word_count = 128; agx_pool_init(&ctx->batch->pool, agx_device(screen), AGX_MEMORY_TYPE_FRAMEBUFFER, true); agx_pool_init(&ctx->batch->pipeline_pool, diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 2221ea5..fd50cf8 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -111,8 +111,12 @@ struct agx_batch { uint32_t varyings; /* Resource list requirements, represented as a bit set indexed by BO - * handles (GEM handles on Linux, or IOGPU's equivalent on macOS) */ - BITSET_WORD bo_list[256]; + * handles (GEM handles on Linux, or IOGPU's equivalent on macOS) + */ + struct { + BITSET_WORD *set; + unsigned word_count; + } bo_list; struct agx_pool pool, pipeline_pool; struct agx_bo *encoder; @@ -343,15 +347,35 @@ agx_build_reload_pipeline(struct agx_context *ctx, uint32_t code, struct pipe_su /* Add a BO to a batch. This needs to be amortized O(1) since it's called in * hot paths. To achieve this we model BO lists by bit sets */ +static unsigned +agx_batch_bo_list_bits(struct agx_batch *batch) +{ + return batch->bo_list.word_count * sizeof(BITSET_WORD) * 8; +} + static inline void agx_batch_add_bo(struct agx_batch *batch, struct agx_bo *bo) { - if (unlikely(bo->handle > (sizeof(batch->bo_list) * 8))) - unreachable("todo: growable"); + /* Double the size of the BO list if we run out, this is amortized O(1) */ + if (unlikely(bo->handle > agx_batch_bo_list_bits(batch))) { + batch->bo_list.set = rerzalloc(batch, batch->bo_list.set, BITSET_WORD, + batch->bo_list.word_count, + batch->bo_list.word_count * 2); + batch->bo_list.word_count *= 2; + } + + BITSET_SET(batch->bo_list.set, bo->handle); +} - BITSET_SET(batch->bo_list, bo->handle); +static unsigned +agx_batch_num_bo(struct agx_batch *batch) +{ + return __bitset_count(batch->bo_list.set, batch->bo_list.word_count); } +#define AGX_BATCH_FOREACH_BO_HANDLE(batch, handle) \ + BITSET_FOREACH_SET(handle, (batch)->bo_list.set, agx_batch_bo_list_bits(batch)) + /* Blit shaders */ void agx_blitter_save(struct agx_context *ctx, struct blitter_context *blitter, -- 2.7.4