[Mesa-dev] [PATCH 04/10] radeon: add query handler function pointers

Nicolai Hähnle nhaehnle at gmail.com
Fri Nov 13 08:10:05 PST 2015


The goal here is to be able to move the implementation details of hardware-
specific queries (in particular, performance counters) out of the common code.
---
 src/gallium/drivers/radeon/r600_query.c | 73 +++++++++++++++++++++++++++++----
 src/gallium/drivers/radeon/r600_query.h | 16 ++++++++
 2 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
index b79d2d0..fdab8e3 100644
--- a/src/gallium/drivers/radeon/r600_query.c
+++ b/src/gallium/drivers/radeon/r600_query.c
@@ -26,7 +26,6 @@
 #include "r600_cs.h"
 #include "util/u_memory.h"
 
-
 struct r600_query_buffer {
 	/* The buffer where query results are stored. */
 	struct r600_resource			*buf;
@@ -39,6 +38,8 @@ struct r600_query_buffer {
 };
 
 struct r600_query {
+	struct r600_query_ops *ops;
+
 	/* The query buffer and how many results are in it. */
 	struct r600_query_buffer		buffer;
 	/* The type of query */
@@ -59,6 +60,23 @@ struct r600_query {
 	unsigned stream;
 };
 
+static void r600_do_destroy_query(struct r600_common_context *, struct r600_query *);
+static boolean r600_do_begin_query(struct r600_common_context *, struct r600_query *);
+static void r600_do_end_query(struct r600_common_context *, struct r600_query *);
+static boolean r600_do_get_query_result(struct r600_common_context *,
+					struct r600_query *, boolean wait,
+					union pipe_query_result *result);
+static void r600_do_render_condition(struct r600_common_context *,
+				     struct r600_query *, boolean condition,
+				     uint mode);
+
+static struct r600_query_ops legacy_query_ops = {
+	.destroy = r600_do_destroy_query,
+	.begin = r600_do_begin_query,
+	.end = r600_do_end_query,
+	.get_result = r600_do_get_query_result,
+	.render_condition = r600_do_render_condition,
+};
 
 static bool r600_is_timer_query(unsigned type)
 {
@@ -366,6 +384,7 @@ static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned q
 		return NULL;
 
 	query->type = query_type;
+	query->ops = &legacy_query_ops;
 
 	switch (query_type) {
 	case PIPE_QUERY_OCCLUSION_COUNTER:
@@ -373,7 +392,6 @@ static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned q
 		query->result_size = 16 * rctx->max_db;
 		query->num_cs_dw = 6;
 		break;
-		break;
 	case PIPE_QUERY_TIME_ELAPSED:
 		query->result_size = 16;
 		query->num_cs_dw = 8;
@@ -433,7 +451,15 @@ static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned q
 
 static void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
 {
-	struct r600_query *rquery = (struct r600_query*)query;
+	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+	struct r600_query *rquery = (struct r600_query *)query;
+
+	rquery->ops->destroy(rctx, rquery);
+}
+
+static void r600_do_destroy_query(struct r600_common_context *rctx,
+				  struct r600_query *rquery)
+{
 	struct r600_query_buffer *prev = rquery->buffer.previous;
 
 	/* Release all query buffers. */
@@ -445,7 +471,7 @@ static void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *quer
 	}
 
 	pipe_resource_reference((struct pipe_resource**)&rquery->buffer.buf, NULL);
-	FREE(query);
+	FREE(rquery);
 }
 
 static boolean r600_begin_query(struct pipe_context *ctx,
@@ -453,6 +479,13 @@ static boolean r600_begin_query(struct pipe_context *ctx,
 {
 	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
 	struct r600_query *rquery = (struct r600_query *)query;
+
+	return rquery->ops->begin(rctx, rquery);
+}
+
+static boolean r600_do_begin_query(struct r600_common_context *rctx,
+				   struct r600_query *rquery)
+{
 	struct r600_query_buffer *prev = rquery->buffer.previous;
 
 	if (!r600_query_needs_begin(rquery->type)) {
@@ -528,6 +561,12 @@ static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
 	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
 	struct r600_query *rquery = (struct r600_query *)query;
 
+	rquery->ops->end(rctx, rquery);
+}
+
+static void r600_do_end_query(struct r600_common_context *rctx,
+			      struct r600_query *rquery)
+{
 	/* Non-GPU queries. */
 	switch (rquery->type) {
 	case PIPE_QUERY_TIMESTAMP_DISJOINT:
@@ -792,11 +831,19 @@ static boolean r600_get_query_buffer_result(struct r600_common_context *ctx,
 }
 
 static boolean r600_get_query_result(struct pipe_context *ctx,
-					struct pipe_query *query,
-					boolean wait, union pipe_query_result *result)
+				     struct pipe_query *query, boolean wait,
+				     union pipe_query_result *result)
 {
 	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
 	struct r600_query *rquery = (struct r600_query *)query;
+
+	return rquery->ops->get_result(rctx, rquery, wait, result);
+}
+
+static boolean r600_do_get_query_result(struct r600_common_context *rctx,
+					struct r600_query *rquery,
+					boolean wait, union pipe_query_result *result)
+{
 	struct r600_query_buffer *qbuf;
 
 	util_query_clear_result(result, rquery->type);
@@ -821,8 +868,6 @@ static void r600_render_condition(struct pipe_context *ctx,
 				  uint mode)
 {
 	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
-	struct r600_query *rquery = (struct r600_query *)query;
-	bool wait_flag = false;
 
 	rctx->current_render_cond = query;
 	rctx->current_render_cond_cond = condition;
@@ -833,8 +878,18 @@ static void r600_render_condition(struct pipe_context *ctx,
 			rctx->predicate_drawing = false;
 			r600_emit_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, false);
 		}
-		return;
+	} else {
+		struct r600_query *rquery = (struct r600_query *)query;
+
+		rquery->ops->render_condition(rctx, rquery, condition, mode);
 	}
+}
+
+static void r600_do_render_condition(struct r600_common_context *rctx,
+				     struct r600_query *rquery,
+				     boolean condition, uint mode)
+{
+	bool wait_flag = false;
 
 	if (mode == PIPE_RENDER_COND_WAIT ||
 	    mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
diff --git a/src/gallium/drivers/radeon/r600_query.h b/src/gallium/drivers/radeon/r600_query.h
index fc8b47b..3d83588 100644
--- a/src/gallium/drivers/radeon/r600_query.h
+++ b/src/gallium/drivers/radeon/r600_query.h
@@ -30,6 +30,9 @@
 
 #include "pipe/p_defines.h"
 
+struct r600_common_context;
+struct r600_query;
+
 #define R600_QUERY_DRAW_CALLS		(PIPE_QUERY_DRIVER_SPECIFIC + 0)
 #define R600_QUERY_REQUESTED_VRAM	(PIPE_QUERY_DRIVER_SPECIFIC + 1)
 #define R600_QUERY_REQUESTED_GTT	(PIPE_QUERY_DRIVER_SPECIFIC + 2)
@@ -46,4 +49,17 @@
 #define R600_QUERY_NUM_SHADERS_CREATED	(PIPE_QUERY_DRIVER_SPECIFIC + 13)
 #define R600_QUERY_FIRST_PERFCOUNTER	(PIPE_QUERY_DRIVER_SPECIFIC + 100)
 
+struct r600_query_ops {
+	void (*destroy)(struct r600_common_context *, struct r600_query *);
+	boolean (*begin)(struct r600_common_context *, struct r600_query *);
+	void (*end)(struct r600_common_context *, struct r600_query *);
+	boolean (*get_result)(struct r600_common_context *,
+			      struct r600_query *, boolean wait,
+			      union pipe_query_result *result);
+	void (*render_condition)(struct r600_common_context *,
+				 struct r600_query *,
+				 boolean condition,
+				 uint mode);
+};
+
 #endif /* R600_QUERY_H */
-- 
2.5.0



More information about the mesa-dev mailing list