asahi: Add non-occlusion query tracking

For other GPU queries, handled similarly.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24847>
This commit is contained in:
Alyssa Rosenzweig
2023-08-14 15:34:04 -04:00
committed by Marge Bot
parent 9845814c98
commit a620e86f35
3 changed files with 35 additions and 10 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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);