From ad3375478cbb69f8478170212a403f13a09fad76 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sun, 12 Feb 2023 12:14:13 -0500 Subject: [PATCH] asahi: Refactor index buffer upload for indirect We need to avoid the reference to draws->count when indirect draws are used, as it is not available CPU side. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_state.c | 45 ++++++++++++++++++++------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index ccf3094b779..c08fcf978bc 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -49,6 +49,7 @@ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_prim.h" +#include "util/u_resource.h" #include "util/u_transfer.h" #include "agx_state.h" #include "agx_disk_cache.h" @@ -2312,21 +2313,35 @@ agx_primitive_for_pipe(enum pipe_prim_type mode) } static uint64_t -agx_index_buffer_ptr(struct agx_batch *batch, - const struct pipe_draw_start_count_bias *draw, - const struct pipe_draw_info *info) +agx_index_buffer_rsrc_ptr(struct agx_batch *batch, + const struct pipe_draw_info *info, size_t *extent) +{ + assert(!info->has_user_indices && "cannot use user pointers with indirect"); + + struct agx_resource *rsrc = agx_resource(info->index.resource); + agx_batch_reads(batch, rsrc); + + *extent = ALIGN_POT(util_resource_size(&rsrc->base), 4); + return rsrc->bo->ptr.gpu; +} + +static uint64_t +agx_index_buffer_direct_ptr(struct agx_batch *batch, + const struct pipe_draw_start_count_bias *draw, + const struct pipe_draw_info *info, size_t *extent) { off_t offset = draw->start * info->index_size; if (!info->has_user_indices) { - struct agx_resource *rsrc = agx_resource(info->index.resource); - agx_batch_reads(batch, rsrc); + uint64_t base = agx_index_buffer_rsrc_ptr(batch, info, extent); - return rsrc->bo->ptr.gpu + offset; + *extent = ALIGN_POT(*extent - offset, 4); + return base + offset; } else { - return agx_pool_upload_aligned(&batch->pool, - ((uint8_t *)info->index.user) + offset, - draw->count * info->index_size, 64); + *extent = ALIGN_POT(draw->count * info->index_size, 4); + + return agx_pool_upload_aligned( + &batch->pool, ((uint8_t *)info->index.user) + offset, *extent, 64); } } @@ -2461,7 +2476,15 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, enum agx_primitive prim = agx_primitive_for_pipe(info->mode); unsigned idx_size = info->index_size; - uint64_t ib = idx_size ? agx_index_buffer_ptr(batch, draws, info) : 0; + uint64_t ib = 0; + size_t ib_extent = 0; + + if (idx_size) { + if (indirect != NULL) + ib = agx_index_buffer_rsrc_ptr(batch, info, &ib_extent); + else + ib = agx_index_buffer_direct_ptr(batch, draws, info, &ib_extent); + } if (idx_size) { /* Index sizes are encoded logarithmically */ @@ -2518,7 +2541,7 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, if (idx_size) { agx_pack(out, INDEX_LIST_BUFFER_SIZE, cfg) { - cfg.size = ALIGN_POT(draws->count * idx_size, 4); + cfg.size = ib_extent; } out += AGX_INDEX_LIST_BUFFER_SIZE_LENGTH; }