From 0aea83dc4ad8826648be7b400553083e0aeac004 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Thu, 12 Nov 2015 11:53:22 +0100 Subject: [PATCH] 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 Tested-by: Samuel Pitoiset --- src/mesa/state_tracker/st_cb_perfmon.c | 74 +++++++++++--------------- src/mesa/state_tracker/st_cb_perfmon.h | 14 +++++ src/mesa/state_tracker/st_context.h | 3 ++ 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 @@ -43,6 +43,20 @@ struct st_perf_counter_object int group_id; }; +/** + * 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 */ 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; }; -- 2.30.2