summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c19
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h6
-rw-r--r--src/gallium/drivers/r600/r600_query.c44
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c1
4 files changed, 65 insertions, 5 deletions
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 81448d49ee9..0e113a1b827 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -1077,6 +1077,24 @@ static uint64_t r600_get_timestamp(struct pipe_screen *screen)
rscreen->info.r600_clock_crystal_freq;
}
+static int r600_get_driver_query_info(struct pipe_screen *screen,
+ unsigned index,
+ struct pipe_driver_query_info *info)
+{
+ struct pipe_driver_query_info list[] = {
+ {"draw-calls", R600_QUERY_DRAW_CALLS, 0},
+ };
+
+ if (!info)
+ return Elements(list);
+
+ if (index >= Elements(list))
+ return 0;
+
+ *info = list[index];
+ return 1;
+}
+
struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
{
struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
@@ -1183,6 +1201,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
rscreen->screen.fence_reference = r600_fence_reference;
rscreen->screen.fence_signalled = r600_fence_signalled;
rscreen->screen.fence_finish = r600_fence_finish;
+ rscreen->screen.get_driver_query_info = r600_get_driver_query_info;
r600_init_screen_resource_functions(&rscreen->screen);
util_format_s3tc_init();
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 285d45fd371..9c3a4c2b229 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -75,6 +75,8 @@
#define R600_CONTEXT_PS_PARTIAL_FLUSH (1 << 6)
#define R600_CONTEXT_FLUSH_AND_INV_DB_META (1 << 7)
+#define R600_QUERY_DRAW_CALLS (PIPE_QUERY_DRIVER_SPECIFIC + 0)
+
struct r600_context;
struct r600_bytecode;
struct r600_shader_key;
@@ -476,6 +478,9 @@ struct r600_query {
unsigned num_cs_dw;
/* linked list of queries */
struct list_head list;
+ /* for custom non-GPU queries */
+ uint64_t begin_result;
+ uint64_t end_result;
};
struct r600_so_target {
@@ -621,6 +626,7 @@ struct r600_context {
unsigned num_cs_dw_nontimer_queries_suspend;
/* If queries have been suspended. */
bool nontimer_queries_suspended;
+ unsigned num_draw_calls;
/* Render condition. */
struct pipe_query *current_render_cond;
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
index 782ad26e3b2..6ee4bbd3a00 100644
--- a/src/gallium/drivers/r600/r600_query.c
+++ b/src/gallium/drivers/r600/r600_query.c
@@ -41,6 +41,13 @@ static struct r600_resource *r600_new_query_buffer(struct r600_context *ctx, uns
{
unsigned j, i, num_results, buf_size = 4096;
uint32_t *results;
+
+ /* Non-GPU queries. */
+ switch (type) {
+ case R600_QUERY_DRAW_CALLS:
+ return NULL;
+ }
+
/* Queries are normally read by the CPU after
* being written by the gpu, hence staging is probably a good
* usage pattern.
@@ -270,8 +277,8 @@ static void r600_emit_query_predication(struct r600_context *ctx, struct r600_qu
static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type)
{
struct r600_context *rctx = (struct r600_context *)ctx;
-
struct r600_query *query;
+ bool skip_allocation = false;
query = CALLOC_STRUCT(r600_query);
if (query == NULL)
@@ -301,16 +308,22 @@ static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned q
query->result_size = 32;
query->num_cs_dw = 6;
break;
+ /* Non-GPU queries. */
+ case R600_QUERY_DRAW_CALLS:
+ skip_allocation = true;
+ break;
default:
assert(0);
FREE(query);
return NULL;
}
- query->buffer.buf = r600_new_query_buffer(rctx, query_type);
- if (!query->buffer.buf) {
- FREE(query);
- return NULL;
+ if (!skip_allocation) {
+ query->buffer.buf = r600_new_query_buffer(rctx, query_type);
+ if (!query->buffer.buf) {
+ FREE(query);
+ return NULL;
+ }
}
return (struct pipe_query*)query;
}
@@ -343,6 +356,13 @@ static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
return;
}
+ /* Non-GPU queries. */
+ switch (rquery->type) {
+ case R600_QUERY_DRAW_CALLS:
+ rquery->begin_result = rctx->num_draw_calls;
+ return;
+ }
+
/* Discard the old query buffers. */
while (prev) {
struct r600_query_buffer *qbuf = prev;
@@ -373,6 +393,13 @@ 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;
+ /* Non-GPU queries. */
+ switch (rquery->type) {
+ case R600_QUERY_DRAW_CALLS:
+ rquery->end_result = rctx->num_draw_calls;
+ return;
+ }
+
r600_emit_query_end(rctx, rquery);
if (r600_query_needs_begin(rquery->type) && !r600_is_timer_query(rquery->type)) {
@@ -407,6 +434,13 @@ static boolean r600_get_query_buffer_result(struct r600_context *ctx,
unsigned results_base = 0;
char *map;
+ /* Non-GPU queries. */
+ switch (query->type) {
+ case R600_QUERY_DRAW_CALLS:
+ result->u64 = query->end_result - query->begin_result;
+ return TRUE;
+ }
+
map = r600_buffer_mmap_sync_with_rings(ctx, qbuf->buf,
PIPE_TRANSFER_READ |
(wait ? 0 : PIPE_TRANSFER_DONTBLOCK));
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 34c70edf575..8190873ce7b 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1517,6 +1517,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
}
pipe_resource_reference(&ib.buffer, NULL);
+ rctx->num_draw_calls++;
}
void r600_draw_rectangle(struct blitter_context *blitter,