From 9253dcde585042242614c4b6677d8f2b13bd2237 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 14 Feb 2016 11:14:06 -0500 Subject: [PATCH] freedreno/a4xx: timestamp queries Signed-off-by: Rob Clark --- .../drivers/freedreno/a4xx/fd4_query.c | 28 +++++++++++++++++++ .../drivers/freedreno/freedreno_query_hw.c | 5 ++++ .../drivers/freedreno/freedreno_screen.c | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_query.c b/src/gallium/drivers/freedreno/a4xx/fd4_query.c index 69decbcb251..baa3787f9d3 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_query.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_query.c @@ -224,6 +224,19 @@ time_elapsed_accumulate_result(struct fd_context *ctx, result->u64 += n * 1000000000 / ctx->screen->max_freq; } +static void +timestamp_accumulate_result(struct fd_context *ctx, + const void *start, const void *end, + union pipe_query_result *result) +{ + /* just return the value from fist tile: */ + if (result->u64 != 0) + return; + uint64_t n = *(uint64_t *)start; + /* max_freq is in Hz, convert cycle count to ns: */ + result->u64 = n * 1000000000 / ctx->screen->max_freq; +} + static const struct fd_hw_sample_provider occlusion_counter = { .query_type = PIPE_QUERY_OCCLUSION_COUNTER, .active = FD_STAGE_DRAW, @@ -246,9 +259,24 @@ static const struct fd_hw_sample_provider time_elapsed = { .accumulate_result = time_elapsed_accumulate_result, }; +/* NOTE: timestamp query isn't going to give terribly sensible results + * on a tiler. But it is needed by qapitrace profile heatmap. If you + * add in a binning pass, the results get even more non-sensical. So + * we just return the timestamp on the first tile and hope that is + * kind of good enough. + */ +static const struct fd_hw_sample_provider timestamp = { + .query_type = PIPE_QUERY_TIMESTAMP, + .active = FD_STAGE_ALL, + .enable = time_elapsed_enable, + .get_sample = time_elapsed_get_sample, + .accumulate_result = timestamp_accumulate_result, +}; + void fd4_query_context_init(struct pipe_context *pctx) { fd_hw_query_register_provider(pctx, &occlusion_counter); fd_hw_query_register_provider(pctx, &occlusion_predicate); fd_hw_query_register_provider(pctx, &time_elapsed); + fd_hw_query_register_provider(pctx, ×tamp); } diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c index 141dc8a28fe..7b528f5ccae 100644 --- a/src/gallium/drivers/freedreno/freedreno_query_hw.c +++ b/src/gallium/drivers/freedreno/freedreno_query_hw.c @@ -47,8 +47,13 @@ static int pidx(unsigned query_type) return 0; case PIPE_QUERY_OCCLUSION_PREDICATE: return 1; + /* TODO currently queries only emitted in main pass (not in binning pass).. + * which is fine for occlusion query, but pretty much not anything else. + */ case PIPE_QUERY_TIME_ELAPSED: return 2; + case PIPE_QUERY_TIMESTAMP: + return 3; default: return -1; } diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 0aaa4d04899..568e6e28401 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -332,11 +332,11 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return is_a3xx(screen) ? 1 : 0; /* Queries. */ - case PIPE_CAP_QUERY_TIMESTAMP: case PIPE_CAP_QUERY_BUFFER_OBJECT: return 0; case PIPE_CAP_OCCLUSION_QUERY: return is_a3xx(screen) || is_a4xx(screen); + case PIPE_CAP_QUERY_TIMESTAMP: case PIPE_CAP_QUERY_TIME_ELAPSED: /* only a4xx, requires new enough kernel so we know max_freq: */ return (screen->max_freq > 0) && is_a4xx(screen); -- 2.30.2