[Mesa-dev] [PATCH v3 6/9] st/mesa: maintain active perfmon counters in an array
Nicolai Hähnle
nhaehnle at gmail.com
Wed Nov 18 03:49:36 PST 2015
It is easy enough to pre-determine the required size, and arrays are
generally better behaved especially when they get large.
v2: make sure init_perf_monitor returns true when no counters are active
(spotted by Samuel Pitoiset)
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
src/mesa/state_tracker/st_cb_perfmon.c | 81 ++++++++++++++++++++--------------
src/mesa/state_tracker/st_cb_perfmon.h | 18 ++++----
2 files changed, 58 insertions(+), 41 deletions(-)
diff --git a/src/mesa/state_tracker/st_cb_perfmon.c b/src/mesa/state_tracker/st_cb_perfmon.c
index ec12eb2..8628e23 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.c
+++ b/src/mesa/state_tracker/st_cb_perfmon.c
@@ -42,15 +42,14 @@ init_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
struct st_context *st = st_context(ctx);
struct st_perf_monitor_object *stm = st_perf_monitor_object(m);
struct pipe_context *pipe = st->pipe;
+ unsigned num_active_counters = 0;
int gid, cid;
st_flush_bitmap_cache(st);
- /* Create a query for each active counter. */
+ /* Determine the number of active counters. */
for (gid = 0; gid < ctx->PerfMonitor.NumGroups; gid++) {
const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[gid];
- const struct st_perf_monitor_group *stg = &st->perfmon[gid];
- BITSET_WORD tmp;
if (m->ActiveGroups[gid] > g->MaxActiveCounters) {
/* Maximum number of counters reached. Cannot start the session. */
@@ -61,19 +60,32 @@ init_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
return false;
}
+ num_active_counters += m->ActiveGroups[gid];
+ }
+
+ if (!num_active_counters)
+ return true;
+
+ stm->active_counters = CALLOC(num_active_counters,
+ sizeof(*stm->active_counters));
+ if (!stm->active_counters)
+ return false;
+
+ /* Create a query for each active counter. */
+ for (gid = 0; gid < ctx->PerfMonitor.NumGroups; gid++) {
+ const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[gid];
+ const struct st_perf_monitor_group *stg = &st->perfmon[gid];
+ BITSET_WORD tmp;
+
BITSET_FOREACH_SET(cid, tmp, m->ActiveCounters[gid], g->NumCounters) {
const struct st_perf_monitor_counter *stc = &stg->counters[cid];
- struct st_perf_counter_object *cntr;
-
- cntr = CALLOC_STRUCT(st_perf_counter_object);
- if (!cntr)
- return false;
+ struct st_perf_counter_object *cntr =
+ &stm->active_counters[stm->num_active_counters];
cntr->query = pipe->create_query(pipe, stc->query_type, 0);
cntr->id = cid;
cntr->group_id = gid;
-
- list_addtail(&cntr->list, &stm->active_counters);
+ ++stm->num_active_counters;
}
}
return true;
@@ -83,24 +95,24 @@ static void
reset_perf_monitor(struct st_perf_monitor_object *stm,
struct pipe_context *pipe)
{
- struct st_perf_counter_object *cntr, *tmp;
+ unsigned i;
- LIST_FOR_EACH_ENTRY_SAFE(cntr, tmp, &stm->active_counters, list) {
- if (cntr->query)
- pipe->destroy_query(pipe, cntr->query);
- list_del(&cntr->list);
- free(cntr);
+ for (i = 0; i < stm->num_active_counters; ++i) {
+ struct pipe_query *query = stm->active_counters[i].query;
+ if (query)
+ pipe->destroy_query(pipe, query);
}
+ FREE(stm->active_counters);
+ stm->active_counters = NULL;
+ stm->num_active_counters = 0;
}
static struct gl_perf_monitor_object *
st_NewPerfMonitor(struct gl_context *ctx)
{
struct st_perf_monitor_object *stq = ST_CALLOC_STRUCT(st_perf_monitor_object);
- if (stq) {
- list_inithead(&stq->active_counters);
+ if (stq)
return &stq->base;
- }
return NULL;
}
@@ -119,9 +131,9 @@ st_BeginPerfMonitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
{
struct st_perf_monitor_object *stm = st_perf_monitor_object(m);
struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_perf_counter_object *cntr;
+ unsigned i;
- if (LIST_IS_EMPTY(&stm->active_counters)) {
+ if (!stm->num_active_counters) {
/* Create a query for each active counter before starting
* a new monitoring session. */
if (!init_perf_monitor(ctx, m))
@@ -129,8 +141,9 @@ st_BeginPerfMonitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
}
/* Start the query for each active counter. */
- LIST_FOR_EACH_ENTRY(cntr, &stm->active_counters, list) {
- if (!pipe->begin_query(pipe, cntr->query))
+ for (i = 0; i < stm->num_active_counters; ++i) {
+ struct pipe_query *query = stm->active_counters[i].query;
+ if (!pipe->begin_query(pipe, query))
goto fail;
}
return true;
@@ -146,11 +159,13 @@ st_EndPerfMonitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
{
struct st_perf_monitor_object *stm = st_perf_monitor_object(m);
struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_perf_counter_object *cntr;
+ unsigned i;
/* Stop the query for each active counter. */
- LIST_FOR_EACH_ENTRY(cntr, &stm->active_counters, list)
- pipe->end_query(pipe, cntr->query);
+ for (i = 0; i < stm->num_active_counters; ++i) {
+ struct pipe_query *query = stm->active_counters[i].query;
+ pipe->end_query(pipe, query);
+ }
}
static void
@@ -174,16 +189,17 @@ st_IsPerfMonitorResultAvailable(struct gl_context *ctx,
{
struct st_perf_monitor_object *stm = st_perf_monitor_object(m);
struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_perf_counter_object *cntr;
+ unsigned i;
- if (LIST_IS_EMPTY(&stm->active_counters))
+ if (!stm->num_active_counters)
return false;
/* The result of a monitoring session is only available if the query of
* each active counter is idle. */
- LIST_FOR_EACH_ENTRY(cntr, &stm->active_counters, list) {
+ for (i = 0; i < stm->num_active_counters; ++i) {
+ struct pipe_query *query = stm->active_counters[i].query;
union pipe_query_result result;
- if (!pipe->get_query_result(pipe, cntr->query, FALSE, &result)) {
+ if (!pipe->get_query_result(pipe, query, FALSE, &result)) {
/* The query is busy. */
return false;
}
@@ -200,7 +216,7 @@ st_GetPerfMonitorResult(struct gl_context *ctx,
{
struct st_perf_monitor_object *stm = st_perf_monitor_object(m);
struct pipe_context *pipe = st_context(ctx)->pipe;
- struct st_perf_counter_object *cntr;
+ unsigned i;
/* Copy data to the supplied array (data).
*
@@ -210,7 +226,8 @@ st_GetPerfMonitorResult(struct gl_context *ctx,
GLsizei offset = 0;
/* Read query results for each active counter. */
- LIST_FOR_EACH_ENTRY(cntr, &stm->active_counters, list) {
+ for (i = 0; i < stm->num_active_counters; ++i) {
+ struct st_perf_counter_object *cntr = &stm->active_counters[i];
union pipe_query_result result = { 0 };
int gid, cid;
GLenum type;
diff --git a/src/mesa/state_tracker/st_cb_perfmon.h b/src/mesa/state_tracker/st_cb_perfmon.h
index 9864b0a..79e0421 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.h
+++ b/src/mesa/state_tracker/st_cb_perfmon.h
@@ -26,21 +26,21 @@
#include "util/list.h"
+struct st_perf_counter_object
+{
+ struct pipe_query *query;
+ int id;
+ int group_id;
+};
+
/**
* Subclass of gl_perf_monitor_object
*/
struct st_perf_monitor_object
{
struct gl_perf_monitor_object base;
- struct list_head active_counters;
-};
-
-struct st_perf_counter_object
-{
- struct list_head list;
- struct pipe_query *query;
- int id;
- int group_id;
+ unsigned num_active_counters;
+ struct st_perf_counter_object *active_counters;
};
/**
--
2.5.0
More information about the mesa-dev
mailing list