+typedef struct per_stage_metrics
+{
+ op_metrics_t *metrics;
+ shader_stage_info_t *stage;
+ double time_ns;
+ double active;
+} per_stage_metrics_t;
+
+static int
+_is_shader_stage_counter (metrics_info_t *info,
+ unsigned group_index,
+ unsigned counter_index)
+{
+ shader_stage_info_t *stage;
+ unsigned i;
+
+ for (i = 0; i < info->num_shader_stages; i++) {
+ stage = &info->stages[i];
+
+ if (stage->active_group_index == group_index &&
+ stage->active_counter_index == counter_index)
+ {
+ return 1;
+ }
+
+ if (stage->stall_group_index == group_index &&
+ stage->stall_counter_index == counter_index)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+print_per_stage_metrics (context_t *ctx,
+ per_stage_metrics_t *per_stage,
+ double total)
+{
+ metrics_info_t *info = &ctx->metrics_info;
+ op_metrics_t *metric = per_stage->metrics;
+ metrics_group_info_t *group;
+ const char *op_string;
+ unsigned group_index, counter;
+ double value;
+
+ /* Don't print anything for stages with no alloted time. */
+ if (per_stage->time_ns == 0.0)
+ return;
+
+ op_string = metrics_op_string (metric->op);
+
+ printf ("%21s", op_string);
+
+ if (metric->op >= METRICS_OP_SHADER) {
+ printf (" %3d", metric->op - METRICS_OP_SHADER);
+ } else {
+ printf (" ");
+
+ }
+
+ if (per_stage->stage)
+ printf (" %cS:", per_stage->stage->name[0]);
+ else
+ printf (" :");
+
+ printf ("\t%7.2f ms (%4.1f%%)",
+ per_stage->time_ns / 1e6,
+ per_stage->time_ns / total * 100);
+
+ if (per_stage->active)
+ printf (", %4.1f%% active", per_stage->active * 100);
+
+ printf ("\n");
+
+ /* I'm not seeing a lot of value printing the rest of these
+ * performance counters by default yet. Use --verbose to get
+ * them for now. */
+ if (! verbose)
+ return;
+
+ printf ("[");
+ for (group_index = 0; group_index < info->num_groups; group_index++) {
+ group = &info->groups[group_index];
+ for (counter = 0; counter < group->num_counters; counter++) {
+
+ /* Don't print this counter value if it's a
+ * per-stage cycle counter, (which we have
+ * already accounted for). */
+ if (_is_shader_stage_counter (info, group_index, counter))
+ continue;
+
+ value = metric->counters[group_index][counter];
+ if (value == 0.0)
+ continue;
+ printf ("%s: %.2f ", group->counter_names[counter],
+ value / 1e6);
+ }
+ }
+ printf ("]\n");
+}
+