From a620e86f35e377a11bcac83a2c39dbbd131d30b5 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 14 Aug 2023 15:34:04 -0400 Subject: [PATCH] asahi: Add non-occlusion query tracking For other GPU queries, handled similarly. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/asahi/agx_batch.c | 7 +++---- src/gallium/drivers/asahi/agx_query.c | 27 ++++++++++++++++++++++----- src/gallium/drivers/asahi/agx_state.h | 11 ++++++++++- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/asahi/agx_batch.c b/src/gallium/drivers/asahi/agx_batch.c index a656d31a13d..717e2006065 100644 --- a/src/gallium/drivers/asahi/agx_batch.c +++ b/src/gallium/drivers/asahi/agx_batch.c @@ -108,6 +108,7 @@ agx_batch_init(struct agx_context *ctx, util_dynarray_init(&batch->scissor, ctx); util_dynarray_init(&batch->depth_bias, ctx); util_dynarray_init(&batch->occlusion_queries, ctx); + util_dynarray_init(&batch->nonocclusion_queries, ctx); batch->clear = 0; batch->draw = 0; @@ -146,7 +147,7 @@ agx_batch_cleanup(struct agx_context *ctx, struct agx_batch *batch, bool reset) assert(ctx->batch != batch); - agx_finish_batch_occlusion_queries(batch); + agx_finish_batch_queries(batch); batch->occlusion_buffer.cpu = NULL; batch->occlusion_buffer.gpu = 0; @@ -182,9 +183,7 @@ agx_batch_cleanup(struct agx_context *ctx, struct agx_batch *batch, bool reset) util_dynarray_fini(&batch->scissor); util_dynarray_fini(&batch->depth_bias); util_dynarray_fini(&batch->occlusion_queries); - util_unreference_framebuffer_state(&batch->key); - - agx_batch_mark_complete(batch); + util_dynarray_fini(&batch->nonocclusion_queries); if (!(dev->debug & (AGX_DBG_TRACE | AGX_DBG_SYNC))) { agx_batch_print_stats(dev, batch); diff --git a/src/gallium/drivers/asahi/agx_query.c b/src/gallium/drivers/asahi/agx_query.c index 9378b957780..dc64fc4ba96 100644 --- a/src/gallium/drivers/asahi/agx_query.c +++ b/src/gallium/drivers/asahi/agx_query.c @@ -196,9 +196,9 @@ agx_get_oq_index(struct agx_batch *batch, struct agx_query *query) } void -agx_finish_batch_occlusion_queries(struct agx_batch *batch) +agx_finish_batch_queries(struct agx_batch *batch) { - uint64_t *results = (uint64_t *)batch->occlusion_buffer.cpu; + uint64_t *occlusion = (uint64_t *)batch->occlusion_buffer.cpu; util_dynarray_foreach(&batch->occlusion_queries, struct agx_query *, it) { struct agx_query *query = *it; @@ -209,11 +209,11 @@ agx_finish_batch_occlusion_queries(struct agx_batch *batch) assert(query->writer == batch); - /* Get the result for this batch. If results is NULL, it means that no + /* Get the result for this batch. If occlusion is NULL, it means that no * draws actually enabled any occlusion queries, so there's no change. */ - if (results != NULL) { - uint64_t result = *(results++); + if (occlusion != NULL) { + uint64_t result = *(occlusion++); /* Accumulate with the previous result (e.g. in case we split a frame * into multiple batches so an API-level query spans multiple batches). @@ -227,6 +227,23 @@ agx_finish_batch_occlusion_queries(struct agx_batch *batch) query->writer = NULL; query->writer_index = 0; } + + /* Now handle non-occlusion queries in a similar way */ + util_dynarray_foreach(&batch->nonocclusion_queries, struct agx_query *, it) { + struct agx_query *query = *it; + if (query == NULL) + continue; + + assert(query->writer == batch); + + /* Accumulate */ + uint64_t *value = query->ptr.cpu; + query->value += (*value); + query->writer = NULL; + query->writer_index = 0; + query->ptr.cpu = NULL; + query->ptr.gpu = 0; + } } static void diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index d39dc14f16a..5ed86b6f521 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -268,6 +268,9 @@ struct agx_batch { struct util_dynarray occlusion_queries; struct agx_ptr occlusion_buffer; + /* Non-occlusion queries */ + struct util_dynarray nonocclusion_queries; + /* Result buffer where the kernel places command execution information */ union agx_batch_result *result; size_t result_off; @@ -529,6 +532,12 @@ struct agx_query { struct agx_batch *writer; unsigned writer_index; + /* For GPU queries other than occlusion queries, the value of the query as + * written by the `writer` if a writer is non-NULL, and irrelevant otherwise. + * When flushing the query, this value is read and added to agx_query::value. + */ + struct agx_ptr ptr; + /* Accumulator flushed to the CPU */ uint64_t value; }; @@ -797,7 +806,7 @@ uint64_t agx_build_meta(struct agx_batch *batch, bool store, /* Query management */ uint16_t agx_get_oq_index(struct agx_batch *batch, struct agx_query *query); -void agx_finish_batch_occlusion_queries(struct agx_batch *batch); +void agx_finish_batch_queries(struct agx_batch *batch); bool agx_render_condition_check_inner(struct agx_context *ctx);