[Mesa-dev] [PATCH 4/9] st/mesa: store mapping from perfmon counter to query type
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Nov 13 09:34:41 PST 2015
On 11/13/2015 04:57 PM, Nicolai Hähnle wrote:
> 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.
When I wrote this code one year ago for the nvc0 driver, this wasn't a
real issue because it didn't expose lots of queries.
Anyway, this looks like a good improvement. Thanks!
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
> 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 dedb8f5..80ff170 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 0b195de..9864b0a 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 c243f5c..60a9a4b 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;
> };
>
>
>
--
-Samuel
More information about the mesa-dev
mailing list