+
+ if (! info->initialized)
+ return;
+
+ for (timer = ctx->timer_head;
+ timer;
+ timer = timer_next)
+ {
+ timer_next = timer->next;
+ free (timer);
+ }
+
+ for (monitor = ctx->monitor_head;
+ monitor;
+ monitor = monitor_next)
+ {
+ monitor_next = monitor->next;
+ free (monitor);
+ }
+
+ for (i = 0; i < info->num_groups; i++) {
+ metrics_group_info_t *group = &info->groups[i];
+
+ for (j = 0; j < group->num_counters; i++)
+ free (group->counter_names[j]);
+
+ free (group->counter_types);
+ free (group->counter_names);
+ free (group->counter_ids);
+
+ free (group->name);
+ }
+
+ free (info->groups);
+
+ for (i = 0; i < info->num_shader_stages; i++)
+ free (info->stages[i].name);
+
+ free (info->stages);
+}
+
+void
+metrics_collect_available (void)
+{
+ context_t *ctx = context_get_current ();
+
+ /* Consume all timer queries that are ready. */
+ timer_query_t *timer = ctx->timer_head;
+
+ while (timer) {
+ GLuint available, elapsed;
+
+ glGetQueryObjectuiv (timer->id,
+ GL_QUERY_RESULT_AVAILABLE, &available);
+ if (! available)
+ break;
+
+ glGetQueryObjectuiv (timer->id,
+ GL_QUERY_RESULT, &elapsed);
+
+ accumulate_program_time (timer->op, elapsed);
+
+ ctx->timer_head = timer->next;
+ if (ctx->timer_head == NULL)
+ ctx->timer_tail = NULL;
+
+ glDeleteQueries (1, &timer->id);
+
+ free (timer);
+ timer = ctx->timer_head;
+ }
+
+ /* And similarly for all performance monitors that are ready. */
+ monitor_t *monitor = ctx->monitor_head;
+
+ while (monitor) {
+ GLuint available, result_size, *result;
+ GLint bytes_written;
+
+ glGetPerfMonitorCounterDataAMD (monitor->id,
+ GL_PERFMON_RESULT_AVAILABLE_AMD,
+ sizeof (available), &available,
+ NULL);
+ if (! available)
+ break;
+
+ glGetPerfMonitorCounterDataAMD (monitor->id,
+ GL_PERFMON_RESULT_SIZE_AMD,
+ sizeof (result_size),
+ &result_size, NULL);
+
+ result = xmalloc (result_size);
+
+ glGetPerfMonitorCounterDataAMD (monitor->id,
+ GL_PERFMON_RESULT_AMD,
+ result_size, result,
+ &bytes_written);
+
+ accumulate_program_metrics (monitor->op, result, result_size);
+
+ free (result);
+
+ ctx->monitor_head = monitor->next;
+ if (ctx->monitor_head == NULL)
+ ctx->monitor_tail = NULL;
+
+ glDeletePerfMonitorsAMD (1, &monitor->id);
+
+ free (monitor);
+
+ ctx->monitors_in_flight--;
+
+ monitor = ctx->monitor_head;
+ }