diff options
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_query.c | 44 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 1 |
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, |