[Mesa-dev] [PATCH 6/9] st/mesa: maintain active perfmon counters in an array
Samuel Pitoiset
samuel.pitoiset at gmail.com
Fri Nov 13 09:34:47 PST 2015
On 11/13/2015 04:57 PM, Nicolai Hähnle wrote:
> It is easy enough to pre-determine the required size, and arrays are
> generally better behaved especially when they get large.
> ---
> src/mesa/state_tracker/st_cb_perfmon.c | 78 ++++++++++++++++++++--------------
> src/mesa/state_tracker/st_cb_perfmon.h | 18 ++++----
> 2 files changed, 55 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..6c71a13 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,29 @@ init_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m)
> return false;
> }
>
> + num_active_counters += m->ActiveGroups[gid];
> + }
> +
> + stm->active_counters = CALLOC(num_active_counters,
> + sizeof(*stm->active_counters));
> + if (!stm->active_counters)
> + return false;
Previously, this function returned true when there was no active
counters, and you changed the behaviour. Are you sure this is not going
to break what the spec says about BeginPerfMonitor ? Did you make sure
by running amd_performance_monitor piglit tests?
> +
> + /* 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 +92,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 +128,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 +138,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 +156,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 +186,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 +213,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 +223,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;
> };
>
> /**
>
--
-Samuel
More information about the mesa-dev
mailing list