summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2013-03-29 16:30:58 +0100
committerChristoph Bumiller <[email protected]>2013-04-03 12:54:43 +0200
commit198f514aa6f08bc43a3002519843b0fe94f340bd (patch)
tree1f9a3038e554dceadcd27ddc1b829815206f7432
parent7628cc247feecfb31aff97f47f039ebe476f0ca8 (diff)
nvc0: add some driver statistics queries
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c30
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.c2
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h55
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_miptree.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_query.c134
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h46
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_transfer.c6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c10
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo_translate.c2
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 e3cbaf60a25..5c9a44e368a 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 669aced7815..2a483b09568 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 d5bc8171bb5..7f15d10e11c 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 b6eddb43d3f..5c839a81104 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 dc0c4b922db..12b890d9c0d 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 412cca42c62..9fcd7886323 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 2c8fcfa51e3..52fff45ed87 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 b7cfd05a2c0..8ba993fc58b 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 28573b51193..1e14723244c 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 8ed92232d0b..95f3ff43679 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 7fbe1e6736b..b0e02fc4ec8 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 16467cee489..bdba83d90fb 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 3ae437a0778..dddeb2ca115 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 033a5d05d3e..ec52de2b568 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