Mesa (master): freedreno/a4xx: timestamp queries

Rob Clark robclark at kemper.freedesktop.org
Sat Jul 23 17:39:48 UTC 2016


Module: Mesa
Branch: master
Commit: 9253dcde585042242614c4b6677d8f2b13bd2237
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9253dcde585042242614c4b6677d8f2b13bd2237

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sun Feb 14 11:14:06 2016 -0500

freedreno/a4xx: timestamp queries

Signed-off-by: Rob Clark <robdclark at gmail.com>

---

 src/gallium/drivers/freedreno/a4xx/fd4_query.c     | 28 ++++++++++++++++++++++
 src/gallium/drivers/freedreno/freedreno_query_hw.c |  5 ++++
 src/gallium/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 69decbc..baa3787 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, &timestamp);
 }
diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c
index 141dc8a..7b528f5 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 0aaa4d0..568e6e2 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);




More information about the mesa-commit mailing list