This isn't necessarily a very useful way to see the numbers. The
important part of the code here is that fips is now querying the names
so that it can do some useful interpretation of the values based on
the names.
metrics_op_t op;
double time_ns;
metrics_op_t op;
double time_ns;
- double *counters;
- unsigned num_counters;
-typedef struct counter_group_info
+typedef struct metrics_group_info
- GLint num_counters;
- GLint max_active_counters;
+ char *name;
+
+ GLuint num_counters;
+ GLuint max_active_counters;
+
+ char **counter_names;
+ GLuint *counter_types;
+
+} metrics_group_info_t;
typedef struct metrics_info
{
typedef struct metrics_info
{
- int num_groups;
- int max_counters_per_group;
- counter_group_info_t *groups;
+ unsigned num_groups;
+ metrics_group_info_t *groups;
} metrics_info_t;
typedef struct context
} metrics_info_t;
typedef struct context
-void
-metrics_info_init (void)
+static void
+metrics_group_info_init (metrics_group_info_t *group, GLuint id)
- int i;
- GLuint *group_ids;
- metrics_info_t *metrics_info = ¤t_context.metrics_info;
+ GLsizei length;
+ unsigned i;
- glGetPerfMonitorGroupsAMD (&metrics_info->num_groups, 0, NULL);
- group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint));
+ /* Get name */
+ glGetPerfMonitorGroupStringAMD (id, 0, &length, NULL);
- glGetPerfMonitorGroupsAMD (NULL, metrics_info->num_groups, group_ids);
+ group->name = xmalloc (length + 1);
- metrics_info->max_counters_per_group = 0;
+ glGetPerfMonitorGroupStringAMD (id, length + 1, NULL, group->name);
- metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (counter_group_info_t));
+ /* Get number of counters */
+ group->num_counters = 0;
+ group->max_active_counters = 0;
+ glGetPerfMonitorCountersAMD (group->id,
+ (int *) &group->num_counters,
+ (int *) &group->max_active_counters,
+ 0, NULL);
- for (i = 0; i < metrics_info->num_groups; i++)
- {
- counter_group_info_t *group;
+ /* Get counter numbers */
+ group->counters = xmalloc (group->num_counters * sizeof (GLuint));
+
+ glGetPerfMonitorCountersAMD (group->id, NULL, NULL,
+ group->num_counters,
+ group->counters);
- group = &metrics_info->groups[i];
+ /* Get counter names */
+ group->counter_names = xmalloc (group->num_counters * sizeof (char *));
+ group->counter_types = xmalloc (group->num_counters * sizeof (GLuint));
- group->id = group_ids[i];
+ for (i = 0; i < group->num_counters; i++) {
+ glGetPerfMonitorCounterInfoAMD (group->id,
+ group->counters[i],
+ GL_COUNTER_TYPE_AMD,
+ &group->counter_types[i]);
- glGetPerfMonitorCountersAMD (group->id, &group->num_counters,
- &group->max_active_counters, 0, NULL);
+ /* We assume that all peformance counters are made
+ * available as uint32 values. The code calling
+ * CONSUME in accumulate_program_metrics will need to
+ * be extended to accomodate other counter values. */
+ if (group->counter_types[i] != GL_UNSIGNED_INT) {
+ fprintf (stderr, "fips: Internal error: No support for non-uint counter values\n");
+ exit (1);
+ }
- group->counters = xmalloc (group->num_counters * sizeof (GLuint));
+ glGetPerfMonitorCounterStringAMD (group->id,
+ group->counters[i],
+ 0, &length, NULL);
- glGetPerfMonitorCountersAMD (group->id, NULL, NULL,
- group->num_counters,
- group->counters);
+ group->counter_names[i] = xmalloc (length + 1);
- if (group->num_counters > metrics_info->max_counters_per_group)
- metrics_info->max_counters_per_group = group->num_counters;
+ glGetPerfMonitorCounterStringAMD (group->id,
+ group->counters[i],
+ length + 1, NULL,
+ group->counter_names[i]);
+}
+
+void
+metrics_info_init (void)
+{
+ unsigned i;
+ GLuint *group_ids;
+ metrics_info_t *metrics_info = ¤t_context.metrics_info;
+
+ glGetPerfMonitorGroupsAMD ((int *) &metrics_info->num_groups, 0, NULL);
+
+ group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint));
+
+ glGetPerfMonitorGroupsAMD (NULL, metrics_info->num_groups, group_ids);
+
+ metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (metrics_group_info_t));
+
+ for (i = 0; i < metrics_info->num_groups; i++)
+ metrics_group_info_init (&metrics_info->groups[i], i);
context_t *ctx = ¤t_context;
timer_query_t *timer;
monitor_t *monitor;
context_t *ctx = ¤t_context;
timer_query_t *timer;
monitor_t *monitor;
/* Create new timer query, add to list */
timer = xmalloc (sizeof (timer_query_t));
/* Create new timer query, add to list */
timer = xmalloc (sizeof (timer_query_t));
for (i = 0; i < ctx->metrics_info.num_groups; i++)
{
for (i = 0; i < ctx->metrics_info.num_groups; i++)
{
- counter_group_info_t *group;
+ metrics_group_info_t *group;
int num_counters;
group = &ctx->metrics_info.groups[i];
int num_counters;
group = &ctx->metrics_info.groups[i];
op_metrics_init (context_t *ctx, op_metrics_t *metrics, metrics_op_t op)
{
metrics_info_t *info = &ctx->metrics_info;
op_metrics_init (context_t *ctx, op_metrics_t *metrics, metrics_op_t op)
{
metrics_info_t *info = &ctx->metrics_info;
metrics->op = op;
metrics->time_ns = 0.0;
metrics->op = op;
metrics->time_ns = 0.0;
- metrics->num_counters = info->num_groups * info->max_counters_per_group;
- metrics->counters = xmalloc (sizeof(double) * metrics->num_counters);
+ metrics->counters = xmalloc (sizeof(double *) * info->num_groups);
- for (i = 0; i < metrics->num_counters; i++)
- metrics->counters[i] = 0.0;
+ for (i = 0; i < info->num_groups; i++) {
+ metrics->counters[i] = xmalloc (sizeof (double) *
+ info->groups[i].num_counters);
+ for (j = 0; j < info->groups[i].num_counters; j++)
+ metrics->counters[i][j] = 0.0;
+ }
while (p < ((unsigned char *) result) + size)
{
while (p < ((unsigned char *) result) + size)
{
- GLuint group_id, counter_id, counter_type;
+ GLuint group_id, counter_id, counter_index;
+ metrics_group_info_t *group;
uint32_t value;
unsigned i;
CONSUME (group_id);
CONSUME (counter_id);
uint32_t value;
unsigned i;
CONSUME (group_id);
CONSUME (counter_id);
- glGetPerfMonitorCounterInfoAMD (group_id, counter_id,
- GL_COUNTER_TYPE_AMD,
- &counter_type);
+ assert (group_id < ctx->metrics_info.num_groups);
+ group = &ctx->metrics_info.groups[group_id];
- /* We assume that all peformance counters are made
- * available as uint32 values. This code can easily be
- * extended as needed. */
- if (counter_type != GL_UNSIGNED_INT) {
- fprintf (stderr, "Warning: Non-uint counter value. Ignoring remainder of results\n");
- break;
+ for (i = 0; i < group->num_counters; i++) {
+ if (group->counters[i] == counter_id)
+ break;
+ counter_index = i;
+ assert (counter_index < group->num_counters);
- CONSUME (value);
-
- i = (group_id * ctx->metrics_info.max_counters_per_group +
- counter_id);
-
- assert (i < ctx->op_metrics[op].num_counters);
-
- /* FIXME: While I'm still occasionally getting bogus
- * numbers from the performance counters, I'm simply
- * going to discard anything larger than half the
- * range, (something that looks like a negative signed
- * quantity).
- */
- if (((int32_t) value) < 0)
- fprintf (stderr, ".");
- else
- ctx->op_metrics[op].counters[i] += value;
+ ctx->op_metrics[op].counters[group_id][counter_index] += value;
-print_op_metrics (op_metrics_t *metric, double total)
+print_op_metrics (context_t *ctx, op_metrics_t *metric, double total)
+ metrics_info_t *info = &ctx->metrics_info;
+ metrics_group_info_t *group;
+ unsigned i, group_id, counter;
+ double value;
/* Since we sparsely fill the array based on program
* id, many "programs" have no time.
/* Since we sparsely fill the array based on program
* id, many "programs" have no time.
metric->time_ns / total * 100);
printf ("[");
metric->time_ns / total * 100);
printf ("[");
- for (i = 0; i < metric->num_counters; i++) {
- if (metric->counters[i] == 0.0)
- continue;
- printf ("%d: %.2f ms ", i, metric->counters[i] / 1e6);
+ for (group_id = 0; group_id < info->num_groups; group_id++) {
+ group = &info->groups[group_id];
+ for (counter = 0; counter < group->num_counters; counter++) {
+ value = metric->counters[group_id][counter];
+ if (value == 0.0)
+ continue;
+ printf ("%s: %.2f ", group->counter_names[counter],
+ value / 1e6);
+ }
time_compare, ctx->op_metrics);
for (i = 0; i < ctx->num_op_metrics; i++)
time_compare, ctx->op_metrics);
for (i = 0; i < ctx->num_op_metrics; i++)
- print_op_metrics (&ctx->op_metrics[sorted[i]], total);
+ print_op_metrics (ctx, &ctx->op_metrics[sorted[i]], total);
}
/* Called at program exit */
}
/* Called at program exit */