[Mesa-dev] [PATCH 4/6] radeonsi: Implement PIPE_QUERY_TIMESTAMP

Niels Ole Salscheider niels_ole at salscheider-online.de
Fri Aug 9 02:59:28 PDT 2013


Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>
---
 src/gallium/drivers/radeonsi/r600.h            |  1 +
 src/gallium/drivers/radeonsi/r600_hw_context.c | 31 ++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/r600_query.c      | 14 +++++++++++-
 src/gallium/drivers/radeonsi/radeonsi_pipe.c   |  2 +-
 4 Dateien geändert, 46 Zeilen hinzugefügt(+), 2 Zeilen entfernt(-)

diff --git a/src/gallium/drivers/radeonsi/r600.h b/src/gallium/drivers/radeonsi/r600.h
index 8f35cc2..ce0468d 100644
--- a/src/gallium/drivers/radeonsi/r600.h
+++ b/src/gallium/drivers/radeonsi/r600.h
@@ -102,6 +102,7 @@ void si_context_emit_fence(struct r600_context *ctx, struct si_resource *fence,
                            unsigned offset, unsigned value);
 
 void r600_context_draw_opaque_count(struct r600_context *ctx, struct r600_so_target *t);
+bool si_query_needs_begin(unsigned type);
 void si_need_cs_space(struct r600_context *ctx, unsigned num_dw, boolean count_draw_in);
 
 int si_context_init(struct r600_context *ctx);
diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c b/src/gallium/drivers/radeonsi/r600_hw_context.c
index 25c972b..7de3745 100644
--- a/src/gallium/drivers/radeonsi/r600_hw_context.c
+++ b/src/gallium/drivers/radeonsi/r600_hw_context.c
@@ -110,6 +110,11 @@ err:
 	return;
 }
 
+bool si_query_needs_begin(unsigned type)
+{
+	return type != PIPE_QUERY_TIMESTAMP;
+}
+
 /* initialize */
 void si_need_cs_space(struct r600_context *ctx, unsigned num_dw,
 			boolean count_draw_in)
@@ -340,6 +345,12 @@ static boolean r600_query_result(struct r600_context *ctx, struct r600_query *qu
 			results_base = (results_base + 16) % query->buffer->b.b.width0;
 		}
 		break;
+	case PIPE_QUERY_TIMESTAMP:
+	{
+		uint32_t *current_result = (uint32_t*)map;
+		query->result.u64 = (uint64_t)current_result[0] | (uint64_t)current_result[1] << 32;
+		break;
+	}
 	case PIPE_QUERY_TIME_ELAPSED:
 		while (results_base != query->results_end) {
 			query->result.u64 +=
@@ -485,6 +496,19 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query)
 {
 	struct radeon_winsys_cs *cs = ctx->cs;
 	uint64_t va;
+	unsigned new_results_end;
+
+	/* The queries which need begin already called this in begin_query. */
+	if (!si_query_needs_begin(query->type)) {
+		si_need_cs_space(ctx, query->num_cs_dw, TRUE);
+
+		new_results_end = (query->results_end + query->result_size) % query->buffer->b.b.width0;
+
+		/* collect current results if query buffer is full */
+		if (new_results_end == query->results_start) {
+		r600_query_result(ctx, query, TRUE);
+		}
+	}
 
 	va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer);
 	/* emit end query */
@@ -508,6 +532,8 @@ void r600_query_end(struct r600_context *ctx, struct r600_query *query)
 		break;
 	case PIPE_QUERY_TIME_ELAPSED:
 		va += query->results_end + query->result_size/2;
+		/* fall through */
+	case PIPE_QUERY_TIMESTAMP:
 		cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
 		cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
 		cs->buf[cs->cdw++] = va;
@@ -585,6 +611,10 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned
 		query->result_size = 16 * ctx->max_db;
 		query->num_cs_dw = 6;
 		break;
+	case PIPE_QUERY_TIMESTAMP:
+		query->result_size = 8;
+		query->num_cs_dw = 8;
+		break;
 	case PIPE_QUERY_TIME_ELAPSED:
 		query->result_size = 16;
 		query->num_cs_dw = 8;
@@ -648,6 +678,7 @@ boolean r600_context_query_result(struct r600_context *ctx,
 	case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
 		*result_b = query->result.b;
 		break;
+	case PIPE_QUERY_TIMESTAMP:
 	case PIPE_QUERY_TIME_ELAPSED:
 		*result_u64 = (1000000 * query->result.u64) / ctx->screen->info.r600_clock_crystal_freq;
 		break;
diff --git a/src/gallium/drivers/radeonsi/r600_query.c b/src/gallium/drivers/radeonsi/r600_query.c
index 0162cce..927577c 100644
--- a/src/gallium/drivers/radeonsi/r600_query.c
+++ b/src/gallium/drivers/radeonsi/r600_query.c
@@ -42,6 +42,11 @@ static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct r600_query *rquery = (struct r600_query *)query;
 
+	if (!si_query_needs_begin(rquery->type)) {
+		assert(0);
+		return;
+	}
+
 	memset(&rquery->result, 0, sizeof(rquery->result));
 	rquery->results_start = rquery->results_end;
 	r600_query_begin(rctx, (struct r600_query *)query);
@@ -53,8 +58,15 @@ static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct r600_query *rquery = (struct r600_query *)query;
 
+	if (!si_query_needs_begin(rquery->type)) {
+		memset(&rquery->result, 0, sizeof(rquery->result));
+	}
+
 	r600_query_end(rctx, rquery);
-	LIST_DELINIT(&rquery->list);
+
+	if (si_query_needs_begin(rquery->type)) {
+		LIST_DELINIT(&rquery->list);
+	}
 }
 
 static boolean r600_get_query_result(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index 69b9ca9..3ba8232 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -391,7 +391,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
 	case PIPE_CAP_USER_VERTEX_BUFFERS:
 	case PIPE_CAP_TEXTURE_MULTISAMPLE:
-	case PIPE_CAP_QUERY_TIMESTAMP:
 	case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
 	case PIPE_CAP_CUBE_MAP_ARRAY:
 	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
@@ -432,6 +431,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 		return 8;
 
 	/* Timer queries, present when the clock frequency is non zero. */
+	case PIPE_CAP_QUERY_TIMESTAMP:
 	case PIPE_CAP_QUERY_TIME_ELAPSED:
 		return rscreen->info.r600_clock_crystal_freq != 0;
 
-- 
1.7.11.7



More information about the mesa-dev mailing list