-/* -*- mode: C; c-file-style: "k&r"; ttxab-width 4; indent-tabs-mode: t; -*- */
-
/*
* Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
*
fd_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index)
{
struct fd_context *ctx = fd_context(pctx);
- struct fd_query *q;
+ struct fd_query *q = NULL;
- q = fd_sw_create_query(ctx, query_type);
- if (!q && ctx->create_query)
- q = ctx->create_query(ctx, query_type);
+ if (ctx->create_query)
+ q = ctx->create_query(ctx, query_type, index);
+ if (!q)
+ q = fd_sw_create_query(ctx, query_type, index);
return (struct pipe_query *) q;
}
q->funcs->destroy_query(fd_context(pctx), q);
}
-static boolean
+static bool
fd_begin_query(struct pipe_context *pctx, struct pipe_query *pq)
{
struct fd_query *q = fd_query(pq);
- return q->funcs->begin_query(fd_context(pctx), q);
+ bool ret;
+
+ if (q->active)
+ return false;
+
+ ret = q->funcs->begin_query(fd_context(pctx), q);
+ q->active = ret;
+
+ return ret;
}
static bool
fd_end_query(struct pipe_context *pctx, struct pipe_query *pq)
{
struct fd_query *q = fd_query(pq);
+
+ /* there are a couple special cases, which don't have
+ * a matching ->begin_query():
+ */
+ if (skip_begin_query(q->type) && !q->active)
+ fd_begin_query(pctx, pq);
+
+ if (!q->active)
+ return false;
+
q->funcs->end_query(fd_context(pctx), q);
+ q->active = false;
+
return true;
}
-static boolean
+static bool
fd_get_query_result(struct pipe_context *pctx, struct pipe_query *pq,
- boolean wait, union pipe_query_result *result)
+ bool wait, union pipe_query_result *result)
{
struct fd_query *q = fd_query(pq);
+
+ if (q->active)
+ return false;
+
+ util_query_clear_result(result, q->type);
+
return q->funcs->get_query_result(fd_context(pctx), q, wait, result);
}
static void
fd_render_condition(struct pipe_context *pctx, struct pipe_query *pq,
- boolean condition, enum pipe_render_cond_flag mode)
+ bool condition, enum pipe_render_cond_flag mode)
{
struct fd_context *ctx = fd_context(pctx);
ctx->cond_query = pq;
ctx->cond_mode = mode;
}
+#define _Q(_name, _query_type, _type, _result_type) { \
+ .name = _name, \
+ .query_type = _query_type, \
+ .type = PIPE_DRIVER_QUERY_TYPE_ ## _type, \
+ .result_type = PIPE_DRIVER_QUERY_RESULT_TYPE_ ## _result_type, \
+ .group_id = ~(unsigned)0, \
+}
+
+#define FQ(_name, _query_type, _type, _result_type) \
+ _Q(_name, FD_QUERY_ ## _query_type, _type, _result_type)
+
+#define PQ(_name, _query_type, _type, _result_type) \
+ _Q(_name, PIPE_QUERY_ ## _query_type, _type, _result_type)
+
+static const struct pipe_driver_query_info sw_query_list[] = {
+ FQ("draw-calls", DRAW_CALLS, UINT64, AVERAGE),
+ FQ("batches", BATCH_TOTAL, UINT64, AVERAGE),
+ FQ("batches-sysmem", BATCH_SYSMEM, UINT64, AVERAGE),
+ FQ("batches-gmem", BATCH_GMEM, UINT64, AVERAGE),
+ FQ("batches-nondraw", BATCH_NONDRAW, UINT64, AVERAGE),
+ FQ("restores", BATCH_RESTORE, UINT64, AVERAGE),
+ PQ("prims-emitted", PRIMITIVES_EMITTED, UINT64, AVERAGE),
+ FQ("staging", STAGING_UPLOADS, UINT64, AVERAGE),
+ FQ("shadow", SHADOW_UPLOADS, UINT64, AVERAGE),
+ FQ("vsregs", VS_REGS, FLOAT, AVERAGE),
+ FQ("fsregs", FS_REGS, FLOAT, AVERAGE),
+};
+
static int
fd_get_driver_query_info(struct pipe_screen *pscreen,
unsigned index, struct pipe_driver_query_info *info)
{
- struct pipe_driver_query_info list[] = {
- {"draw-calls", FD_QUERY_DRAW_CALLS, {0}},
- {"batches", FD_QUERY_BATCH_TOTAL, {0}},
- {"batches-sysmem", FD_QUERY_BATCH_SYSMEM, {0}},
- {"batches-gmem", FD_QUERY_BATCH_GMEM, {0}},
- {"restores", FD_QUERY_BATCH_RESTORE, {0}},
- {"prims-emitted", PIPE_QUERY_PRIMITIVES_EMITTED, {0}},
- };
+ struct fd_screen *screen = fd_screen(pscreen);
if (!info)
- return ARRAY_SIZE(list);
+ return ARRAY_SIZE(sw_query_list) + screen->num_perfcntr_queries;
- if (index >= ARRAY_SIZE(list))
+ if (index >= ARRAY_SIZE(sw_query_list)) {
+ index -= ARRAY_SIZE(sw_query_list);
+ if (index >= screen->num_perfcntr_queries)
+ return 0;
+ *info = screen->perfcntr_queries[index];
+ return 1;
+ }
+
+ *info = sw_query_list[index];
+ return 1;
+}
+
+static int
+fd_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned index,
+ struct pipe_driver_query_group_info *info)
+{
+ struct fd_screen *screen = fd_screen(pscreen);
+
+ if (!info)
+ return screen->num_perfcntr_groups;
+
+ if (index >= screen->num_perfcntr_groups)
return 0;
- *info = list[index];
+ const struct fd_perfcntr_group *g = &screen->perfcntr_groups[index];
+
+ info->name = g->name;
+ info->max_active_queries = g->num_counters;
+ info->num_queries = g->num_countables;
+
return 1;
}
static void
-fd_set_active_query_state(struct pipe_context *pipe, boolean enable)
+fd_set_active_query_state(struct pipe_context *pipe, bool enable)
+{
+}
+
+static void
+setup_perfcntr_query_info(struct fd_screen *screen)
{
+ unsigned num_queries = 0;
+
+ for (unsigned i = 0; i < screen->num_perfcntr_groups; i++)
+ num_queries += screen->perfcntr_groups[i].num_countables;
+
+ screen->perfcntr_queries =
+ calloc(num_queries, sizeof(screen->perfcntr_queries[0]));
+ screen->num_perfcntr_queries = num_queries;
+
+ unsigned idx = 0;
+ for (unsigned i = 0; i < screen->num_perfcntr_groups; i++) {
+ const struct fd_perfcntr_group *g = &screen->perfcntr_groups[i];
+ for (unsigned j = 0; j < g->num_countables; j++) {
+ struct pipe_driver_query_info *info =
+ &screen->perfcntr_queries[idx];
+ const struct fd_perfcntr_countable *c =
+ &g->countables[j];
+
+ info->name = c->name;
+ info->query_type = FD_QUERY_FIRST_PERFCNTR + idx;
+ info->type = c->query_type;
+ info->result_type = c->result_type;
+ info->group_id = i;
+ info->flags = PIPE_DRIVER_QUERY_FLAG_BATCH;
+
+ idx++;
+ }
+ }
}
void
fd_query_screen_init(struct pipe_screen *pscreen)
{
pscreen->get_driver_query_info = fd_get_driver_query_info;
+ pscreen->get_driver_query_group_info = fd_get_driver_query_group_info;
+ setup_perfcntr_query_info(fd_screen(pscreen));
}
void