From 04e955f19bb760b88acad414425cd4708a58e58e Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Fri, 9 Oct 2020 20:01:16 +1300 Subject: [PATCH] panfrost: Precise occlusion query support In the "counter" occlusion query mode, each shader core has a separate counter. When MSAA is disabled, counter values need to be divided by four. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_context.c | 36 +++++++++++++++++++++--------- src/gallium/drivers/panfrost/pan_context.h | 3 +++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index adc0cd8..5728ec6 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -402,7 +402,10 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch, pan_emit_draw_descs(batch, &cfg, PIPE_SHADER_FRAGMENT); if (ctx->occlusion_query) { - cfg.occlusion_query = MALI_OCCLUSION_MODE_PREDICATE; + if (ctx->occlusion_query->type == PIPE_QUERY_OCCLUSION_COUNTER) + cfg.occlusion_query = MALI_OCCLUSION_MODE_COUNTER; + else + cfg.occlusion_query = MALI_OCCLUSION_MODE_PREDICATE; cfg.occlusion = ctx->occlusion_query->bo->gpu; panfrost_batch_add_bo(ctx->batch, ctx->occlusion_query->bo, PAN_BO_ACCESS_SHARED | @@ -1347,23 +1350,28 @@ static bool panfrost_begin_query(struct pipe_context *pipe, struct pipe_query *q) { struct panfrost_context *ctx = pan_context(pipe); + struct panfrost_device *dev = pan_device(ctx->base.screen); struct panfrost_query *query = (struct panfrost_query *) q; switch (query->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: - case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { + unsigned size = sizeof(uint64_t) * dev->core_count; + /* Allocate a bo for the query results to be stored */ if (!query->bo) { - query->bo = panfrost_bo_create( - pan_device(ctx->base.screen), - sizeof(unsigned), 0); + query->bo = panfrost_bo_create(dev, size, 0); } - unsigned *result = (unsigned *)query->bo->cpu; - *result = 0; /* Default to 0 if nothing at all drawn. */ + /* Default to 0 if nothing at all drawn. */ + memset(query->bo->cpu, 0, size); + + query->msaa = (ctx->pipe_framebuffer.samples > 1); + ctx->occlusion_query = query; break; + } /* Geometry statistics are computed in the driver. XXX: geom/tess * shaders.. */ @@ -1414,7 +1422,7 @@ panfrost_get_query_result(struct pipe_context *pipe, { struct panfrost_query *query = (struct panfrost_query *) q; struct panfrost_context *ctx = pan_context(pipe); - + struct panfrost_device *dev = pan_device(ctx->base.screen); switch (query->type) { case PIPE_QUERY_OCCLUSION_COUNTER: @@ -1424,13 +1432,19 @@ panfrost_get_query_result(struct pipe_context *pipe, panfrost_bo_wait(query->bo, INT64_MAX, false); /* Read back the query results */ - unsigned *result = (unsigned *) query->bo->cpu; - unsigned passed = *result; + uint64_t *result = (uint64_t *) query->bo->cpu; if (query->type == PIPE_QUERY_OCCLUSION_COUNTER) { + uint64_t passed = 0; + for (int i = 0; i < dev->core_count; ++i) + passed += result[i]; + + if (!query->msaa) + passed /= 4; + vresult->u64 = passed; } else { - vresult->b = !!passed; + vresult->b = !!result[0]; } break; diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 4452328..3e9a150 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -79,6 +79,9 @@ struct panfrost_query { /* Memory for the GPU to writeback the value of the query */ struct panfrost_bo *bo; + + /* Whether an occlusion query is for a MSAA framebuffer */ + bool msaa; }; struct panfrost_fence { -- 2.7.4