- if (program_id >= ctx->num_program_metrics) {
- ctx->program_metrics = realloc (ctx->program_metrics,
- (program_id + 1) * sizeof (program_metrics_t));
- for (i = ctx->num_program_metrics; i < program_id + 1; i++) {
- ctx->program_metrics[i].id = i;
- ctx->program_metrics[i].time_ns = 0.0;
+ metrics->op = op;
+ metrics->time_ns = 0.0;
+
+ metrics->num_counters = info->num_groups * info->max_counters_per_group;
+ metrics->counters = xmalloc (sizeof(double) * metrics->num_counters);
+
+ for (i = 0; i < metrics->num_counters; i++)
+ metrics->counters[i] = 0.0;
+}
+
+static op_metrics_t *
+ctx_get_op_metrics (context_t *ctx, metrics_op_t op)
+{
+ unsigned i;
+
+ if (op >= ctx->num_op_metrics)
+ {
+ ctx->op_metrics = realloc (ctx->op_metrics,
+ (op + 1) * sizeof (op_metrics_t));
+ for (i = ctx->num_op_metrics; i < op + 1; i++)
+ op_metrics_init (ctx, &ctx->op_metrics[i], i);
+
+ ctx->num_op_metrics = op + 1;
+ }
+
+ return &ctx->op_metrics[op];
+}
+
+static void
+accumulate_program_metrics (metrics_op_t op, GLuint *result, GLuint size)
+{
+#define CONSUME(var) \
+ if (p + sizeof(var) > ((unsigned char *) result) + size) \
+ { \
+ fprintf (stderr, "Unexpected end-of-buffer while " \
+ "parsing results\n"); \
+ break; \
+ } \
+ (var) = *((typeof(var) *) p); \
+ p += sizeof(var);
+
+ context_t *ctx = ¤t_context;
+ unsigned char *p = (unsigned char *) result;
+
+ while (p < ((unsigned char *) result) + size)
+ {
+ GLuint group_id, counter_id, counter_type;
+ uint32_t value;
+ unsigned i;
+
+ CONSUME (group_id);
+ CONSUME (counter_id);
+
+ glGetPerfMonitorCounterInfoAMD (group_id, counter_id,
+ GL_COUNTER_TYPE_AMD,
+ &counter_type);
+
+ /* We assume that all peformance counters are made
+ * available as uint32 values. This code can easily be
+ * extended as needed. */
+ if (counter_type != GL_UNSIGNED_INT) {
+ fprintf (stderr, "Warning: Non-uint counter value. Ignoring remainder of results\n");
+ break;