Hi,

Attached is a patch to implement timer queries for r600g.

I have not found much documentation about the frequency of the gpu's timestamp 
counter. But What I have found indicates that it runs at 27MHz which is 
implemented in the patch and gives 'reasonable' query results with osgviewer.

Please review and may be apply.

Thanks,
 Mathias
From edf603c14f054b10fae25c76e8ef0ab909264939 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <[email protected]>
Date: Sun, 23 Jan 2011 22:35:13 +0100
Subject: [PATCH 3/3] r600g: Implement timer queries.

---
 src/gallium/drivers/r600/r600_pipe.c          |    2 +-
 src/gallium/winsys/r600/drm/r600_hw_context.c |   56 +++++++++++++++++++------
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 53d2c10..104f635 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -280,10 +280,10 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
 	case PIPE_CAP_DEPTH_CLAMP:
 	case PIPE_CAP_SHADER_STENCIL_EXPORT:
+	case PIPE_CAP_TIMER_QUERY:
 		return 1;
 
 	/* Unsupported features (boolean caps). */
-	case PIPE_CAP_TIMER_QUERY:
 	case PIPE_CAP_STREAM_OUTPUT:
 	case PIPE_CAP_PRIMITIVE_RESTART:
 	case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 61d09a6..71f5e11 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -1262,7 +1262,8 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
 	for (i = 0; i < query->num_results; i += 4) {
 		start = (u64)results[i] | (u64)results[i + 1] << 32;
 		end = (u64)results[i + 2] | (u64)results[i + 3] << 32;
-		if ((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL)) {
+		if (((start & 0x8000000000000000UL) && (end & 0x8000000000000000UL))
+                    || query->type == PIPE_QUERY_TIME_ELAPSED) {
 			query->result += end - start;
 		}
 	}
@@ -1274,8 +1275,15 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
 
 void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
 {
-	/* query request needs 6 dwords for begin + 6 dwords for end */
-	if ((12 + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
+	unsigned required_space;
+
+	/* query request needs 6/8 dwords for begin + 6/8 dwords for end */
+	if (query->type == PIPE_QUERY_TIME_ELAPSED)
+		required_space = 16;
+	else
+		required_space = 12;
+
+	if ((required_space + ctx->pm4_cdwords) > ctx->pm4_ndwords) {
 		/* need to flush */
 		r600_context_flush(ctx);
 	}
@@ -1287,10 +1295,19 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
 	}
 
 	/* emit begin query */
-	ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
-	ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
-	ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
-	ctx->pm4[ctx->pm4_cdwords++] = 0;
+	if (query->type == PIPE_QUERY_TIME_ELAPSED) {
+		ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
+		ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
+		ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
+		ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+	} else {
+		ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
+		ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
+		ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + r600_bo_offset(query->buffer);
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+	}
 	ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
 	ctx->pm4[ctx->pm4_cdwords++] = 0;
 	r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
@@ -1303,10 +1320,19 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
 void r600_query_end(struct r600_context *ctx, struct r600_query *query)
 {
 	/* emit begin query */
-	ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
-	ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
-	ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
-	ctx->pm4[ctx->pm4_cdwords++] = 0;
+	if (query->type == PIPE_QUERY_TIME_ELAPSED) {
+		ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4);
+		ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
+		ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
+		ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+	} else {
+		ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2);
+		ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
+		ctx->pm4[ctx->pm4_cdwords++] = query->num_results*4 + 8 + r600_bo_offset(query->buffer);
+		ctx->pm4[ctx->pm4_cdwords++] = 0;
+	}
 	ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
 	ctx->pm4[ctx->pm4_cdwords++] = 0;
 	r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], query->buffer);
@@ -1321,7 +1347,7 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned
 {
 	struct r600_query *query;
 
-	if (query_type != PIPE_QUERY_OCCLUSION_COUNTER)
+	if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && query_type != PIPE_QUERY_TIME_ELAPSED)
 		return NULL;
 
 	query = calloc(1, sizeof(struct r600_query));
@@ -1365,7 +1391,11 @@ boolean r600_context_query_result(struct r600_context *ctx,
 	}
 	if (!r600_query_result(ctx, query, wait))
 		return FALSE;
-	*result = query->result;
+	if (query->type == PIPE_QUERY_TIME_ELAPSED)
+		/* The GPU counter seems to run at 27 MHz */
+		*result = (1000*query->result)/27;
+	else
+		*result = query->result;
 	query->result = 0;
 	return TRUE;
 }
-- 
1.7.3.4

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to