r600g: add a driver query returning the number of draw_vbo calls
authorMarek Olšák <maraeo@gmail.com>
Thu, 21 Mar 2013 18:44:18 +0000 (19:44 +0100)
committerMarek Olšák <maraeo@gmail.com>
Tue, 26 Mar 2013 00:28:19 +0000 (01:28 +0100)
between begin_query and end_query

src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_query.c
src/gallium/drivers/r600/r600_state_common.c

index 81448d49ee965ef80f0849ecb5d4bfdeb35b34c5..0e113a1b82749cce861aef2bd7fcf110f0e0ebc0 100644 (file)
@@ -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();
index 285d45fd371404604b92b68b15decb7578ff5a9f..9c3a4c2b2296a7b47bfa38c22287b19cd941cadd 100644 (file)
@@ -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;
index 782ad26e3b26a275e285f98fbf6484be737c5f9a..6ee4bbd3a001947cd54d54d9657ae4bdba9ee359 100644 (file)
@@ -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));
index 34c70edf575cdd9195aa0a7edf3ac802e63b6a54..8190873ce7b53f7bea229ef0db55daea75047cec 100644 (file)
@@ -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,