Module: Mesa
Branch: master
Commit: 198f514aa6f08bc43a3002519843b0fe94f340bd
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=198f514aa6f08bc43a3002519843b0fe94f340bd

Author: Christoph Bumiller <e0425...@student.tuwien.ac.at>
Date:   Fri Mar 29 16:30:58 2013 +0100

nvc0: add some driver statistics queries

---

 src/gallium/drivers/nouveau/nouveau_buffer.c   |   30 ++++++
 src/gallium/drivers/nouveau/nouveau_fence.c    |    2 +
 src/gallium/drivers/nouveau/nouveau_screen.h   |   55 ++++++++++
 src/gallium/drivers/nv50/nv50_miptree.c        |    4 +
 src/gallium/drivers/nvc0/nvc0_context.c        |    4 +
 src/gallium/drivers/nvc0/nvc0_miptree.c        |    4 +
 src/gallium/drivers/nvc0/nvc0_query.c          |  134 ++++++++++++++++++++----
 src/gallium/drivers/nvc0/nvc0_screen.h         |   46 ++++++++-
 src/gallium/drivers/nvc0/nvc0_state_validate.c |    2 +
 src/gallium/drivers/nvc0/nvc0_surface.c        |    4 +
 src/gallium/drivers/nvc0/nvc0_tex.c            |    1 +
 src/gallium/drivers/nvc0/nvc0_transfer.c       |    6 +
 src/gallium/drivers/nvc0/nvc0_vbo.c            |   10 ++
 src/gallium/drivers/nvc0/nvc0_vbo_translate.c  |    2 +
 14 files changed, 279 insertions(+), 25 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c 
b/src/gallium/drivers/nouveau/nouveau_buffer.c
index e3cbaf6..5c9a44e 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -51,12 +51,14 @@ nouveau_buffer_allocate(struct nouveau_screen *screen,
                                     &buf->bo, &buf->offset);
       if (!buf->bo)
          return nouveau_buffer_allocate(screen, buf, NOUVEAU_BO_GART);
+      NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_vid, buf->base.width0);
    } else
    if (domain == NOUVEAU_BO_GART) {
       buf->mm = nouveau_mm_allocate(screen->mm_GART, size,
                                     &buf->bo, &buf->offset);
       if (!buf->bo)
          return FALSE;
+      NOUVEAU_DRV_STAT(screen, buf_obj_current_bytes_sys, buf->base.width0);
    } else {
       assert(domain == 0);
       if (!nouveau_buffer_malloc(buf))
@@ -85,6 +87,11 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
    if (buf->mm)
       release_allocation(&buf->mm, buf->fence);
 
+   if (buf->domain == NOUVEAU_BO_VRAM)
+      NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, 
-(uint64_t)buf->base.width0);
+   if (buf->domain == NOUVEAU_BO_GART)
+      NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_sys, 
-(uint64_t)buf->base.width0);
+
    buf->domain = 0;
 }
 
@@ -117,6 +124,8 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen,
    nouveau_fence_ref(NULL, &res->fence_wr);
 
    FREE(res);
+
+   NOUVEAU_DRV_STAT(nouveau_screen(pscreen), buf_obj_current_count, -1);
 }
 
 static uint8_t *
@@ -153,6 +162,8 @@ nouveau_transfer_read(struct nouveau_context *nv, struct 
nouveau_transfer *tx)
    const unsigned base = tx->base.box.x;
    const unsigned size = tx->base.box.width;
 
+   NOUVEAU_DRV_STAT(nv->screen, buf_read_bytes_staging_vid, size);
+
    nv->copy_data(nv, tx->bo, tx->offset, NOUVEAU_BO_GART,
                  buf->bo, buf->offset + base, buf->domain, size);
 
@@ -179,6 +190,11 @@ nouveau_transfer_write(struct nouveau_context *nv, struct 
nouveau_transfer *tx,
    else
       buf->status |= NOUVEAU_BUFFER_STATUS_DIRTY;
 
+   if (buf->domain == NOUVEAU_BO_VRAM)
+      NOUVEAU_DRV_STAT(nv->screen, buf_write_bytes_staging_vid, size);
+   if (buf->domain == NOUVEAU_BO_GART)
+      NOUVEAU_DRV_STAT(nv->screen, buf_write_bytes_staging_sys, size);
+
    if (tx->bo)
       nv->copy_data(nv, buf->bo, buf->offset + base, buf->domain,
                     tx->bo, tx->offset + offset, NOUVEAU_BO_GART, size);
@@ -197,11 +213,15 @@ nouveau_buffer_sync(struct nv04_resource *buf, unsigned 
rw)
    if (rw == PIPE_TRANSFER_READ) {
       if (!buf->fence_wr)
          return TRUE;
+      NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
+                           !nouveau_fence_signalled(buf->fence_wr));
       if (!nouveau_fence_wait(buf->fence_wr))
          return FALSE;
    } else {
       if (!buf->fence)
          return TRUE;
+      NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
+                           !nouveau_fence_signalled(buf->fence));
       if (!nouveau_fence_wait(buf->fence))
          return FALSE;
 
@@ -320,6 +340,11 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
    nouveau_buffer_transfer_init(tx, resource, box, usage);
    *ptransfer = &tx->base;
 
+   if (usage & PIPE_TRANSFER_READ)
+      NOUVEAU_DRV_STAT(nv->screen, buf_transfers_rd, 1);
+   if (usage & PIPE_TRANSFER_WRITE)
+      NOUVEAU_DRV_STAT(nv->screen, buf_transfers_wr, 1);
+
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & NOUVEAU_TRANSFER_DISCARD) {
          if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)
@@ -427,6 +452,9 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
       }
    }
 
+   if (!tx->bo && (tx->base.usage & PIPE_TRANSFER_WRITE))
+      NOUVEAU_DRV_STAT(nv->screen, buf_write_bytes_direct, tx->base.box.width);
+
    nouveau_buffer_transfer_del(nv, tx);
    FREE(tx);
 }
@@ -525,6 +553,8 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
    if (buffer->domain == NOUVEAU_BO_VRAM && screen->hint_buf_keep_sysmem_copy)
       nouveau_buffer_cache(NULL, buffer);
 
+   NOUVEAU_DRV_STAT(screen, buf_obj_current_count, 1);
+
    return &buffer->base;
 
 fail:
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c 
b/src/gallium/drivers/nouveau/nouveau_fence.c
index 669aced..2a483b0 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -205,6 +205,8 @@ nouveau_fence_wait(struct nouveau_fence *fence)
 
       if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
          return TRUE;
+      if (!spins)
+         NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
       spins++;
 #ifdef PIPE_OS_UNIX
       if (!(spins % 8)) /* donate a few cycles */
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h 
b/src/gallium/drivers/nouveau/nouveau_screen.h
index d5bc817..7f15d10 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -4,6 +4,10 @@
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 
+#ifdef DEBUG
+# define NOUVEAU_ENABLE_DRIVER_STATISTICS
+#endif
+
 typedef uint32_t u32;
 typedef uint16_t u16;
 
@@ -44,8 +48,59 @@ struct nouveau_screen {
        int64_t cpu_gpu_time_delta;
 
        boolean hint_buf_keep_sysmem_copy;
+
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+   union {
+      uint64_t v[29];
+      struct {
+         uint64_t tex_obj_current_count;
+         uint64_t tex_obj_current_bytes;
+         uint64_t buf_obj_current_count;
+         uint64_t buf_obj_current_bytes_vid;
+         uint64_t buf_obj_current_bytes_sys;
+         uint64_t tex_transfers_rd;
+         uint64_t tex_transfers_wr;
+         uint64_t tex_copy_count;
+         uint64_t tex_blit_count;
+         uint64_t tex_cache_flush_count;
+         uint64_t buf_transfers_rd;
+         uint64_t buf_transfers_wr;
+         uint64_t buf_read_bytes_staging_vid;
+         uint64_t buf_write_bytes_direct;
+         uint64_t buf_write_bytes_staging_vid;
+         uint64_t buf_write_bytes_staging_sys;
+         uint64_t buf_copy_bytes;
+         uint64_t buf_non_kernel_fence_sync_count;
+         uint64_t any_non_kernel_fence_sync_count;
+         uint64_t query_sync_count;
+         uint64_t gpu_serialize_count;
+         uint64_t draw_calls_array;
+         uint64_t draw_calls_indexed;
+         uint64_t draw_calls_fallback_count;
+         uint64_t user_buffer_upload_bytes;
+         uint64_t constbuf_upload_count;
+         uint64_t constbuf_upload_bytes;
+         uint64_t pushbuf_count;
+         uint64_t resource_validate_count;
+      } named;
+   } stats;
+#endif
 };
 
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+# define NOUVEAU_DRV_STAT(s, n, v) do {         \
+      (s)->stats.named.n += (v);               \
+   } while(0)
+# define NOUVEAU_DRV_STAT_RES(r, n, v) do {                       \
+      nouveau_screen((r)->base.screen)->stats.named.n += (v);    \
+   } while(0)
+# define NOUVEAU_DRV_STAT_IFD(x) x
+#else
+# define NOUVEAU_DRV_STAT(s, n, v)     do { } while(0)
+# define NOUVEAU_DRV_STAT_RES(r, n, v) do { } while(0)
+# define NOUVEAU_DRV_STAT_IFD(x)
+#endif
+
 static INLINE struct nouveau_screen *
 nouveau_screen(struct pipe_screen *pscreen)
 {
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c 
b/src/gallium/drivers/nv50/nv50_miptree.c
index b6eddb4..5c839a8 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -147,6 +147,10 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct 
pipe_resource *pt)
    nouveau_fence_ref(NULL, &mt->base.fence);
    nouveau_fence_ref(NULL, &mt->base.fence_wr);
 
+   NOUVEAU_DRV_STAT(nouveau_screen(pscreen), tex_obj_current_count, -1);
+   NOUVEAU_DRV_STAT(nouveau_screen(pscreen), tex_obj_current_bytes,
+                    -(uint64_t)mt->total_size);
+
    FREE(mt);
 }
 
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c 
b/src/gallium/drivers/nvc0/nvc0_context.c
index dc0c4b9..12b890d 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -130,6 +130,7 @@ nvc0_default_kick_notify(struct nouveau_pushbuf *push)
       if (screen->cur_ctx)
          screen->cur_ctx->state.flushed = TRUE;
    }
+   NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
 }
 
 static int
@@ -341,11 +342,14 @@ nvc0_bufctx_fence(struct nvc0_context *nvc0, struct 
nouveau_bufctx *bufctx,
 {
    struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
    struct nouveau_list *it;
+   NOUVEAU_DRV_STAT_IFD(unsigned count = 0);
 
    for (it = list->next; it != list; it = it->next) {
       struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
       struct nv04_resource *res = ref->priv;
       if (res)
          nvc0_resource_validate(res, (unsigned)ref->priv_data);
+      NOUVEAU_DRV_STAT_IFD(count++);
    }
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, resource_validate_count, count);
 }
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c 
b/src/gallium/drivers/nvc0/nvc0_miptree.c
index 412cca4..9fcd788 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -294,6 +294,10 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
    }
    mt->base.address = mt->base.bo->offset;
 
+   NOUVEAU_DRV_STAT(nouveau_screen(pscreen), tex_obj_current_count, 1);
+   NOUVEAU_DRV_STAT(nouveau_screen(pscreen), tex_obj_current_bytes,
+                    mt->total_size);
+
    return pt;
 }
 
diff --git a/src/gallium/drivers/nvc0/nvc0_query.c 
b/src/gallium/drivers/nvc0/nvc0_query.c
index 2c8fcfa..52fff45 100644
--- a/src/gallium/drivers/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nvc0/nvc0_query.c
@@ -46,8 +46,11 @@ struct nvc0_query {
    boolean is64bit;
    uint8_t rotate;
    int nesting; /* only used for occlusion queries */
+   union {
+      struct nouveau_mm_allocation *mm;
+      uint64_t value;
+   } u;
    struct nouveau_fence *fence;
-   struct nouveau_mm_allocation *mm;
 };
 
 #define NVC0_QUERY_ALLOC_SPACE 256
@@ -71,16 +74,16 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct 
nvc0_query *q, int size)
 
    if (q->bo) {
       nouveau_bo_ref(NULL, &q->bo);
-      if (q->mm) {
+      if (q->u.mm) {
          if (q->state == NVC0_QUERY_STATE_READY)
-            nouveau_mm_free(q->mm);
+            nouveau_mm_free(q->u.mm);
          else
             nouveau_fence_work(screen->base.fence.current,
-                               nouveau_mm_free_work, q->mm);
+                               nouveau_mm_free_work, q->u.mm);
       }
    }
    if (size) {
-      q->mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, 
&q->base);
+      q->u.mm = nouveau_mm_allocate(screen->base.mm_GART, size, &q->bo, 
&q->base);
       if (!q->bo)
          return FALSE;
       q->offset = q->base;
@@ -144,10 +147,18 @@ nvc0_query_create(struct pipe_context *pipe, unsigned 
type)
       space = 16;
       break;
    default:
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+      if (type >= NVC0_QUERY_DRV_STAT(0) && type <= NVC0_QUERY_DRV_STAT_LAST) {
+         space = 0;
+         q->is64bit = true;
+         q->index = type - NVC0_QUERY_DRV_STAT(0);
+         break;
+      } else
+#endif
       if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS &&
           nvc0->screen->base.device->drm_version >= 0x01000101) {
          if (type >= NVE4_PM_QUERY(0) &&
-             type <= NVE4_PM_QUERY_MAX) {
+             type <= NVE4_PM_QUERY_LAST) {
             /* 8 counters per MP + clock */
             space = 12 * nvc0->screen->mp_count * sizeof(uint32_t);
             break;
@@ -266,8 +277,18 @@ nvc0_query_begin(struct pipe_context *pipe, struct 
pipe_query *pq)
       nvc0_query_get(push, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
       break;
    default:
-      if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_MAX)
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+      if (q->type >= NVC0_QUERY_DRV_STAT(0) &&
+          q->type <= NVC0_QUERY_DRV_STAT_LAST) {
+         if (q->index >= 5)
+            q->u.value = nvc0->screen->base.stats.v[q->index];
+         else
+            q->u.value = 0;
+      } else
+#endif
+      if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST) {
          nve4_mp_pm_query_begin(nvc0, q);
+      }
       break;
    }
    q->state = NVC0_QUERY_STATE_ACTIVE;
@@ -338,7 +359,14 @@ nvc0_query_end(struct pipe_context *pipe, struct 
pipe_query *pq)
       nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5));
       break;
    default:
-      if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_MAX)
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+      if (q->type >= NVC0_QUERY_DRV_STAT(0) &&
+          q->type <= NVC0_QUERY_DRV_STAT_LAST) {
+         q->u.value = nvc0->screen->base.stats.v[q->index] - q->u.value;
+         return;
+      } else
+#endif
+      if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST)
          nve4_mp_pm_query_end(nvc0, q);
       break;
    }
@@ -370,8 +398,16 @@ nvc0_query_result(struct pipe_context *pipe, struct 
pipe_query *pq,
    uint64_t *data64 = (uint64_t *)q->data;
    unsigned i;
 
-   if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_MAX)
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+   if (q->type >= NVC0_QUERY_DRV_STAT(0) &&
+       q->type <= NVC0_QUERY_DRV_STAT_LAST) {
+      res64[0] = q->u.value;
+      return TRUE;
+   } else
+#endif
+   if (q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST) {
       return nve4_mp_pm_query_result(nvc0, q, result, wait);
+   }
 
    if (q->state != NVC0_QUERY_STATE_READY)
       nvc0_query_update(nvc0->screen->base.client, q);
@@ -387,6 +423,7 @@ nvc0_query_result(struct pipe_context *pipe, struct 
pipe_query *pq,
       }
       if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
          return FALSE;
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, query_sync_count, 1);
    }
    q->state = NVC0_QUERY_STATE_READY;
 
@@ -537,6 +574,8 @@ nvc0_so_target_save_offset(struct pipe_context *pipe,
       *serialize = FALSE;
       PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1);
       IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0);
+
+      NOUVEAU_DRV_STAT(nouveau_screen(pipe->screen), gpu_serialize_count, 1);
    }
 
    nvc0_query(targ->pq)->index = index;
@@ -545,6 +584,46 @@ nvc0_so_target_save_offset(struct pipe_context *pipe,
 }
 
 
+/* === DRIVER STATISTICS === */
+
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+
+static const char *nvc0_drv_stat_names[] =
+{
+   "drv-tex_obj_current_count",
+   "drv-tex_obj_current_bytes",
+   "drv-buf_obj_current_count",
+   "drv-buf_obj_current_bytes_vid",
+   "drv-buf_obj_current_bytes_sys",
+   "drv-tex_transfers_rd",
+   "drv-tex_transfers_wr",
+   "drv-tex_copy_count",
+   "drv-tex_blit_count",
+   "drv-tex_cache_flush_count",
+   "drv-buf_transfers_rd",
+   "drv-buf_transfers_wr",
+   "drv-buf_read_bytes_staging_vid",
+   "drv-buf_write_bytes_direct",
+   "drv-buf_write_bytes_staging_vid",
+   "drv-buf_write_bytes_staging_sys",
+   "drv-buf_copy_bytes",
+   "drv-buf_non_kernel_fence_sync_count",
+   "drv-any_non_kernel_fence_sync_count",
+   "drv-query_sync_count",
+   "drv-gpu_serialize_count",
+   "drv-draw_calls_array",
+   "drv-draw_calls_indexed",
+   "drv-draw_calls_fallback_count",
+   "drv-user_buffer_upload_bytes",
+   "drv-constbuf_upload_count",
+   "drv-constbuf_upload_bytes",
+   "drv-pushbuf_count",
+   "drv-resource_validate_count"
+};
+
+#endif /* NOUVEAU_ENABLE_DRIVER_STATISTICS */
+
+
 /* === PERFORMANCE MONITORING COUNTERS === */
 
 /* Code to read out MP counters: They are accessible via mmio, too, but let's
@@ -885,23 +964,32 @@ nvc0_screen_get_driver_query_info(struct pipe_screen 
*pscreen,
                                   struct pipe_driver_query_info *info)
 {
    struct nvc0_screen *screen = nvc0_screen(pscreen);
+   int count = 0;
+
+   count += NVC0_QUERY_DRV_STAT_COUNT;
 
    if (screen->base.class_3d >= NVE4_3D_CLASS) {
-      unsigned count = 0;
       if (screen->base.device->drm_version >= 0x01000101)
-         count = NVE4_PM_QUERY_COUNT;
-      if (!info)
-         return count;
-      if (id < count) {
-         info->name = nve4_pm_query_names[id];
-         info->query_type = NVE4_PM_QUERY(id);
-         info->max_value = ~0ULL;
-         info->uses_byte_units = FALSE;
-         return 1;
-      }
-   } else {
-      if (!info)
-         return 0;
+         count += NVE4_PM_QUERY_COUNT;
+   }
+   if (!info)
+      return count;
+
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+   if (id < NVC0_QUERY_DRV_STAT_COUNT) {
+      info->name = nvc0_drv_stat_names[id];
+      info->query_type = NVC0_QUERY_DRV_STAT(id);
+      info->max_value = ~0ULL;
+      info->uses_byte_units = !!strstr(info->name, "bytes");
+      return 1;
+   } else
+#endif
+   if (id < count) {
+      info->name = nve4_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
+      info->query_type = NVE4_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
+      info->max_value = ~0ULL;
+      info->uses_byte_units = FALSE;
+      return 1;
    }
    /* user asked for info about non-existing query */
    info->name = "this_is_not_the_query_you_are_looking_for";
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h 
b/src/gallium/drivers/nvc0/nvc0_screen.h
index b7cfd05..8ba993f 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -89,8 +89,7 @@ nvc0_screen(struct pipe_screen *screen)
  */
 #define NVE4_PM_QUERY_COUNT  32
 #define NVE4_PM_QUERY(i)    (PIPE_QUERY_DRIVER_SPECIFIC + (i))
-#define NVE4_PM_QUERY_MAX    NVE4_PM_QUERY(NVE4_PM_QUERY_COUNT - 1)
-/* MP (NOTE: these are also used to index a table, so put them first) */
+#define NVE4_PM_QUERY_LAST   NVE4_PM_QUERY(NVE4_PM_QUERY_COUNT - 1)
 #define NVE4_PM_QUERY_PROF_TRIGGER_0            0
 #define NVE4_PM_QUERY_PROF_TRIGGER_1            1
 #define NVE4_PM_QUERY_PROF_TRIGGER_2            2
@@ -144,6 +143,49 @@ nvc0_screen(struct pipe_screen *screen)
 ...
 */
 
+/* Driver statistics queries:
+ */
+#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
+
+#define NVC0_QUERY_DRV_STAT(i)    (PIPE_QUERY_DRIVER_SPECIFIC + 1024 + (i))
+#define NVC0_QUERY_DRV_STAT_COUNT  29
+#define NVC0_QUERY_DRV_STAT_LAST   
NVC0_QUERY_DRV_STAT(NVC0_QUERY_DRV_STAT_COUNT - 1)
+#define NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_COUNT         0
+#define NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_BYTES         1
+#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_COUNT         2
+#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_VID     3
+#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_SYS     4
+#define NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_READ               5
+#define NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_WRITE              6
+#define NVC0_QUERY_DRV_STAT_TEX_COPY_COUNT                   7
+#define NVC0_QUERY_DRV_STAT_TEX_BLIT_COUNT                   8
+#define NVC0_QUERY_DRV_STAT_TEX_CACHE_FLUSH_COUNT            9
+#define NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_READ              10
+#define NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_WRITE             11
+#define NVC0_QUERY_DRV_STAT_BUF_READ_BYTES_STAGING_VID      12
+#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_DIRECT          13
+#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_VID     14
+#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_SYS     15
+#define NVC0_QUERY_DRV_STAT_BUF_COPY_BYTES                  16
+#define NVC0_QUERY_DRV_STAT_BUF_NON_KERNEL_FENCE_SYNC_COUNT 17
+#define NVC0_QUERY_DRV_STAT_ANY_NON_KERNEL_FENCE_SYNC_COUNT 18
+#define NVC0_QUERY_DRV_STAT_QUERY_SYNC_COUNT                19
+#define NVC0_QUERY_DRV_STAT_GPU_SERIALIZE_COUNT             20
+#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_ARRAY                21
+#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_INDEXED              22
+#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_FALLBACK_COUNT       23
+#define NVC0_QUERY_DRV_STAT_USER_BUFFER_UPLOAD_BYTES        24
+#define NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_COUNT           25
+#define NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_BYTES           26
+#define NVC0_QUERY_DRV_STAT_PUSHBUF_COUNT                   27
+#define NVC0_QUERY_DRV_STAT_RESOURCE_VALIDATE_COUNT         28
+
+#else
+
+#define NVC0_QUERY_DRV_STAT_COUNT 0
+
+#endif
+
 int nvc0_screen_get_driver_query_info(struct pipe_screen *, unsigned,
                                       struct pipe_driver_query_info *);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c 
b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 28573b5..1e14723 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -160,6 +160,8 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
 
     if (serialize)
        IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+
+    NOUVEAU_DRV_STAT(&nvc0->screen->base, gpu_serialize_count, serialize);
 }
 
 static void
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c 
b/src/gallium/drivers/nvc0/nvc0_surface.c
index 8ed9223..95f3ff4 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -205,8 +205,10 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
       util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
                                 src, src_level, src_box);
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width);
       return;
    }
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_copy_count, 1);
 
    /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */
    assert((src->nr_samples | 1) == (dst->nr_samples | 1));
@@ -1149,6 +1151,8 @@ nvc0_blit(struct pipe_context *pipe, const struct 
pipe_blit_info *info)
       nvc0_blit_eng2d(nvc0, info);
    else
       nvc0_blit_3d(nvc0, info);
+
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1);
 }
 
 boolean
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c 
b/src/gallium/drivers/nvc0/nvc0_tex.c
index 7fbe1e6..b0e02fc 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -265,6 +265,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
       if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
          BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
          PUSH_DATA (push, (tic->id << 4) | 1);
+         NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1);
       }
       nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c 
b/src/gallium/drivers/nvc0/nvc0_transfer.c
index 16467ce..bdba83d 100644
--- a/src/gallium/drivers/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nvc0/nvc0_transfer.c
@@ -447,7 +447,10 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
             tx->rect[0].base += mt->layer_stride;
          tx->rect[1].base += tx->nblocksy * tx->base.stride;
       }
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_transfers_wr, 1);
    }
+   if (tx->base.usage & PIPE_TRANSFER_READ)
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_transfers_rd, 1);
 
    nouveau_bo_ref(NULL, &tx->rect[1].bo);
    pipe_resource_reference(&transfer->resource, NULL);
@@ -464,6 +467,9 @@ nvc0_cb_push(struct nouveau_context *nv,
    struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
    struct nouveau_pushbuf *push = nv->pushbuf;
 
+   NOUVEAU_DRV_STAT(nv->screen, constbuf_upload_count, 1);
+   NOUVEAU_DRV_STAT(nv->screen, constbuf_upload_bytes, words * 4);
+
    assert(!(offset & 3));
    size = align(size, 0x100);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c 
b/src/gallium/drivers/nvc0/nvc0_vbo.c
index 3ae437a..dddeb2c 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -254,6 +254,8 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
                                            base, size, &bo);
          if (bo)
             BCTX_REFN_bo(nvc0->bufctx_3d, VTX_TMP, bo_flags, bo);
+
+         NOUVEAU_DRV_STAT(&nvc0->screen->base, user_buffer_upload_bytes, size);
       }
 
       BEGIN_1IC0(push, NVC0_3D(MACRO_VERTEX_ARRAY_SELECT), 5);
@@ -294,6 +296,8 @@ nvc0_update_user_vbufs_shared(struct nvc0_context *nvc0)
       PUSH_DATA (push, address + base + size - 1);
       PUSH_DATAh(push, address);
       PUSH_DATA (push, address);
+
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, user_buffer_upload_bytes, size);
    }
 
    mask = nvc0->state.constant_elts;
@@ -555,6 +559,8 @@ nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
    struct nvc0_screen *screen = push->user_priv;
 
    nouveau_fence_update(&screen->base, TRUE);
+
+   NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
 }
 
 static void
@@ -584,6 +590,7 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
 
       prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
    }
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, draw_calls_array, 1);
 }
 
 static void
@@ -746,6 +753,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean 
shorten,
          prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
       }
    }
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, draw_calls_indexed, 1);
 }
 
 static void
@@ -764,6 +772,8 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
       IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
       nvc0_query_fifo_wait(push, so->pq);
       IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
+
+      NOUVEAU_DRV_STAT(&nvc0->screen->base, gpu_serialize_count, 1);
    }
 
    while (num_instances--) {
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo_translate.c 
b/src/gallium/drivers/nvc0/nvc0_vbo_translate.c
index 033a5d0..ec52de2 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo_translate.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo_translate.c
@@ -535,6 +535,8 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct 
pipe_draw_info *info)
       nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer));
    for (i = 0; i < nvc0->num_vtxbufs; ++i)
       nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer));
+
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, draw_calls_fallback_count, 1);
 }
 
 static INLINE void

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to