summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2015-11-12 11:53:22 +0100
committerNicolai Hähnle <[email protected]>2015-11-20 17:27:09 +0100
commit0aea83dc4ad8826648be7b400553083e0aeac004 (patch)
treeff09722e9e74a586d20a68d7287549a41e5017ac /src
parent4e1339691d3e04eb7e90d33ab5900ce1a40e628f (diff)
st/mesa: store mapping from perfmon counter to query type
Previously, when a performance monitor was initialized, an inner loop through all driver queries with string comparisons for each enabled performance monitor counter was used. This hurts when a driver exposes lots of queries. Reviewed-by: Samuel Pitoiset <[email protected]> Tested-by: Samuel Pitoiset <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/state_tracker/st_cb_perfmon.c74
-rw-r--r--src/mesa/state_tracker/st_cb_perfmon.h14
-rw-r--r--src/mesa/state_tracker/st_context.h3
3 files changed, 49 insertions, 42 deletions
diff --git a/src/mesa/state_tracker/st_cb_perfmon.c b/src/mesa/state_tracker/st_cb_perfmon.c
index dedb8f520f4..80ff1706966 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.c
+++ b/src/mesa/state_tracker/st_cb_perfmon.c
@@ -36,48 +36,20 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
-/**
- * Return a PIPE_QUERY_x type >= PIPE_QUERY_DRIVER_SPECIFIC, or -1 if
- * the driver-specific query doesn't exist.
- */
-static int
-find_query_type(struct pipe_screen *screen, const char *name)
-{
- int num_queries;
- int type = -1;
- int i;
-
- num_queries = screen->get_driver_query_info(screen, 0, NULL);
- if (!num_queries)
- return type;
-
- for (i = 0; i < num_queries; i++) {
- struct pipe_driver_query_info info;
-
- if (!screen->get_driver_query_info(screen, i, &info))
- continue;
-
- if (!strncmp(info.name, name, strlen(name))) {
- type = info.query_type;
- break;
- }
- }
- return type;
-}
-
static bool
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_screen *screen = st_context(ctx)->pipe->screen;
- struct pipe_context *pipe = st_context(ctx)->pipe;
+ struct pipe_context *pipe = st->pipe;
int gid, cid;
- st_flush_bitmap_cache(st_context(ctx));
+ st_flush_bitmap_cache(st);
/* 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];
if (m->ActiveGroups[gid] > g->MaxActiveCounters) {
/* Maximum number of counters reached. Cannot start the session. */
@@ -90,20 +62,17 @@ init_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
for (cid = 0; cid < g->NumCounters; cid++) {
const struct gl_perf_monitor_counter *c = &g->Counters[cid];
+ const struct st_perf_monitor_counter *stc = &stg->counters[cid];
struct st_perf_counter_object *cntr;
- int query_type;
if (!BITSET_TEST(m->ActiveCounters[gid], cid))
continue;
- query_type = find_query_type(screen, c->Name);
- assert(query_type != -1);
-
cntr = CALLOC_STRUCT(st_perf_counter_object);
if (!cntr)
return false;
- cntr->query = pipe->create_query(pipe, query_type, 0);
+ cntr->query = pipe->create_query(pipe, stc->query_type, 0);
cntr->id = cid;
cntr->group_id = gid;
@@ -286,6 +255,7 @@ st_init_perfmon(struct st_context *st)
struct gl_perf_monitor_state *perfmon = &st->ctx->PerfMonitor;
struct pipe_screen *screen = st->pipe->screen;
struct gl_perf_monitor_group *groups = NULL;
+ struct st_perf_monitor_group *stgroups = NULL;
int num_counters, num_groups;
int gid, cid;
@@ -304,26 +274,36 @@ st_init_perfmon(struct st_context *st)
if (!groups)
return false;
+ stgroups = CALLOC(num_groups, sizeof(*stgroups));
+ if (!stgroups)
+ goto fail_only_groups;
+
for (gid = 0; gid < num_groups; gid++) {
struct gl_perf_monitor_group *g = &groups[perfmon->NumGroups];
struct pipe_driver_query_group_info group_info;
struct gl_perf_monitor_counter *counters = NULL;
+ struct st_perf_monitor_counter *stcounters = NULL;
if (!screen->get_driver_query_group_info(screen, gid, &group_info))
continue;
g->Name = group_info.name;
g->MaxActiveCounters = group_info.max_active_queries;
- g->NumCounters = 0;
- g->Counters = NULL;
if (group_info.num_queries)
counters = CALLOC(group_info.num_queries, sizeof(*counters));
if (!counters)
goto fail;
+ g->Counters = counters;
+
+ stcounters = CALLOC(group_info.num_queries, sizeof(*stcounters));
+ if (!stcounters)
+ goto fail;
+ stgroups[perfmon->NumGroups].counters = stcounters;
for (cid = 0; cid < num_counters; cid++) {
struct gl_perf_monitor_counter *c = &counters[g->NumCounters];
+ struct st_perf_monitor_counter *stc = &stcounters[g->NumCounters];
struct pipe_driver_query_info info;
if (!screen->get_driver_query_info(screen, cid, &info))
@@ -359,18 +339,25 @@ st_init_perfmon(struct st_context *st)
default:
unreachable("Invalid driver query type!");
}
+
+ stc->query_type = info.query_type;
+
g->NumCounters++;
}
- g->Counters = counters;
perfmon->NumGroups++;
}
perfmon->Groups = groups;
+ st->perfmon = stgroups;
return true;
fail:
- for (gid = 0; gid < num_groups; gid++)
+ for (gid = 0; gid < num_groups; gid++) {
+ FREE(stgroups[gid].counters);
FREE((void *)groups[gid].Counters);
+ }
+ FREE(stgroups);
+fail_only_groups:
FREE(groups);
return false;
}
@@ -381,8 +368,11 @@ st_destroy_perfmon(struct st_context *st)
struct gl_perf_monitor_state *perfmon = &st->ctx->PerfMonitor;
int gid;
- for (gid = 0; gid < perfmon->NumGroups; gid++)
+ for (gid = 0; gid < perfmon->NumGroups; gid++) {
+ FREE(st->perfmon[gid].counters);
FREE((void *)perfmon->Groups[gid].Counters);
+ }
+ FREE(st->perfmon);
FREE((void *)perfmon->Groups);
}
diff --git a/src/mesa/state_tracker/st_cb_perfmon.h b/src/mesa/state_tracker/st_cb_perfmon.h
index 0b195de47fe..9864b0a15d2 100644
--- a/src/mesa/state_tracker/st_cb_perfmon.h
+++ b/src/mesa/state_tracker/st_cb_perfmon.h
@@ -44,6 +44,20 @@ struct st_perf_counter_object
};
/**
+ * Extra data per counter, supplementing gl_perf_monitor_counter with
+ * driver-specific information.
+ */
+struct st_perf_monitor_counter
+{
+ unsigned query_type;
+};
+
+struct st_perf_monitor_group
+{
+ struct st_perf_monitor_counter *counters;
+};
+
+/**
* Cast wrapper
*/
static inline struct st_perf_monitor_object *
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index c243f5cd966..60a9a4bb0d5 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -46,6 +46,7 @@ struct draw_stage;
struct gen_mipmap_state;
struct st_context;
struct st_fragment_program;
+struct st_perf_monitor_group;
struct u_upload_mgr;
@@ -217,6 +218,8 @@ struct st_context
int32_t read_stamp;
struct st_config_options options;
+
+ struct st_perf_monitor_group *perfmon;
};