+ metrics_info->max_counters_per_group = 0;
+
+ metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (counter_group_info_t));
+
+ for (i = 0; i < metrics_info->num_groups; i++)
+ {
+ counter_group_info_t *group;
+
+ group = &metrics_info->groups[i];
+
+ group->id = group_ids[i];
+
+ glGetPerfMonitorCountersAMD (group->id, &group->num_counters,
+ &group->max_active_counters, 0, NULL);
+
+ group->counters = xmalloc (group->num_counters * sizeof (GLuint));
+
+ glGetPerfMonitorCountersAMD (group->id, NULL, NULL,
+ group->num_counters,
+ group->counters);
+
+ if (group->num_counters > metrics_info->max_counters_per_group)
+ metrics_info->max_counters_per_group = group->num_counters;
+ }
+
+ free (group_ids);
+}
+
+static const char *
+metrics_op_string (metrics_op_t op)
+{
+ if (op >= METRICS_OP_SHADER)
+ return "Shader program";
+
+ switch (op)
+ {
+ case METRICS_OP_ACCUM:
+ return "glAccum*(+)";
+ case METRICS_OP_BUFFER_DATA:
+ return "glBufferData(+)";
+ case METRICS_OP_BUFFER_SUB_DATA:
+ return "glCopyBufferSubData*";
+ case METRICS_OP_BITMAP:
+ return "glBitmap*";
+ case METRICS_OP_BLIT_FRAMEBUFFER:
+ return "glBlitFramebuffer*";
+ case METRICS_OP_CLEAR:
+ return "glClear(+)";
+ case METRICS_OP_CLEAR_BUFFER_DATA:
+ return "glCearBufferData(+)";
+ case METRICS_OP_CLEAR_TEX_IMAGE:
+ return "glClearTexImage(+)";
+ case METRICS_OP_COPY_PIXELS:
+ return "glCopyPixels";
+ case METRICS_OP_COPY_TEX_IMAGE:
+ return "glCopyTexImage(+)";
+ case METRICS_OP_DRAW_PIXELS:
+ return "glDrawPixels";
+ case METRICS_OP_GET_TEX_IMAGE:
+ return "glGetTexImage(+)";
+ case METRICS_OP_READ_PIXELS:
+ return "glReadPixels*";
+ case METRICS_OP_TEX_IMAGE:
+ return "glTexImage*(+)";
+ default:
+ fprintf (stderr, "fips: Internal error: "
+ "Unknown metrics op value: %d\n", op);
+ exit (1);