+ stage->stall_group_index = group_index;
+ stage->stall_counter_index = counter_index;
+ }
+
+ free (stage_name);
+}
+
+void
+metrics_info_init (void)
+{
+ unsigned i, j;
+ GLuint *group_ids;
+ metrics_info_t *info = ¤t_context.metrics_info;
+
+ glGetPerfMonitorGroupsAMD ((int *) &info->num_groups, 0, NULL);
+
+ group_ids = xmalloc (info->num_groups * sizeof (GLuint));
+
+ glGetPerfMonitorGroupsAMD (NULL, info->num_groups, group_ids);
+
+ info->groups = xmalloc (info->num_groups * sizeof (metrics_group_info_t));
+
+ for (i = 0; i < info->num_groups; i++)
+ metrics_group_info_init (&info->groups[i], group_ids[i]);
+
+ free (group_ids);
+
+ /* Identify each shader stage (by looking at
+ * performance-counter names for specific patterns) and
+ * initialize structures referring to the corresponding
+ * counter numbers for each stage. */
+ info->num_shader_stages = 0;
+ info->stages = NULL;
+
+ for (i = 0; i < info->num_groups; i++) {
+ metrics_group_info_t *group = &info->groups[i];
+ for (j = 0; j < group->num_counters; j++) {
+ char *name = group->counter_names[j];
+ if (strstr (name, "Shader Active Time")) {
+ _add_shader_stage (info, name, i, j,
+ SHADER_ACTIVE);
+ }
+ if (strstr (name, "Shader Stall Time")) {
+ _add_shader_stage (info, name, i, j,
+ SHADER_STALL);
+ }
+ }
+ }
+
+ info->initialized = 1;
+}
+
+void
+metrics_info_fini (void)
+{
+ metrics_info_t *info = ¤t_context.metrics_info;
+ unsigned i;
+ timer_query_t *timer, *timer_next;
+ monitor_t *monitor, *monitor_next;
+
+ if (! info->initialized)
+ return;
+
+ for (timer = current_context.timer_head;
+ timer;
+ timer = timer_next)
+ {
+ timer_next = timer->next;
+ free (timer);
+ }
+ current_context.timer_head = NULL;
+ current_context.timer_tail = NULL;
+
+ for (monitor = current_context.monitor_head;
+ monitor;
+ monitor = monitor_next)
+ {
+ monitor_next = monitor->next;
+ free (monitor);