+ 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);
+ }
+
+ return "";
+}
+
+void
+metrics_counter_start (void)
+{
+ context_t *ctx = ¤t_context;
+ timer_query_t *timer;
+ monitor_t *monitor;
+ unsigned i;
+
+ /* Create new timer query, add to list */
+ timer = xmalloc (sizeof (timer_query_t));
+
+ timer->op = ctx->op;
+ timer->next = NULL;
+
+ if (ctx->timer_tail) {
+ ctx->timer_tail->next = timer;
+ ctx->timer_tail = timer;
+ } else {
+ ctx->timer_tail = timer;
+ ctx->timer_head = timer;
+ }
+
+ /* Create a new performance-monitor query */
+ monitor = xmalloc (sizeof (monitor_t));
+
+ monitor->op = ctx->op;
+ monitor->next = NULL;
+
+ if (ctx->monitor_tail) {
+ ctx->monitor_tail->next = monitor;
+ ctx->monitor_tail = monitor;
+ } else {
+ ctx->monitor_tail = monitor;
+ ctx->monitor_head = monitor;
+ }
+
+ /* Initialize the timer_query and monitor objects */
+ glGenQueries (1, &timer->id);
+
+ glGenPerfMonitorsAMD (1, &monitor->id);
+
+ for (i = 0; i < ctx->metrics_info.num_groups; i++)
+ {
+ metrics_group_info_t *group;
+ int num_counters;
+
+ group = &ctx->metrics_info.groups[i];
+
+ num_counters = group->num_counters;
+ if (group->max_active_counters < group->num_counters)
+ {
+ fprintf (stderr, "Warning: Only monitoring %d/%d counters from group %d\n",
+ group->max_active_counters,
+ group->num_counters, i);
+ num_counters = group->max_active_counters;
+
+ }
+
+ glSelectPerfMonitorCountersAMD(monitor->id,
+ GL_TRUE, group->id,
+ num_counters,
+ group->counter_ids);
+ }
+
+ /* Start the queries */
+ glBeginQuery (GL_TIME_ELAPSED, timer->id);
+
+ glBeginPerfMonitorAMD (monitor->id);