X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=metrics.c;h=09083e639ab966d6e80c36845c8da3c76f447059;hb=da0ee5e7efab316635f59d212028844f848fa6ce;hp=74d6c567d9e92cf46cde1b5110498a54605c0ef9;hpb=7c716eca3492764413e63bbd5386b7ec18d2efa7;p=fips diff --git a/metrics.c b/metrics.c index 74d6c56..09083e6 100644 --- a/metrics.c +++ b/metrics.c @@ -29,32 +29,34 @@ #include "fips-dispatch-gl.h" #include "metrics.h" +#include "xmalloc.h" typedef struct counter { unsigned id; - unsigned program; + + metrics_op_t op; struct counter *next; } counter_t; -typedef struct program_metrics +typedef struct op_metrics { /* This happens to also be the index into the - * ctx->program_metrics array currently + * ctx->op_metrics array currently */ - unsigned id; - double ticks; -} program_metrics_t; + metrics_op_t op; + double time_ns; +} op_metrics_t; typedef struct context { - unsigned int program; + metrics_op_t op; counter_t *counter_head; counter_t *counter_tail; - unsigned num_program_metrics; - program_metrics_t *program_metrics; + unsigned num_op_metrics; + op_metrics_t *op_metrics; } context_t; /* FIXME: Need a map from integers to context objects and track the @@ -65,20 +67,61 @@ context_t current_context; int frames; int verbose; -unsigned -metrics_counter_new (void) +static const char * +metrics_op_string (metrics_op_t op) { - counter_t *counter; - - counter = malloc (sizeof(counter_t)); - if (counter == NULL) { - fprintf (stderr, "Out of memory\n"); + 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, "Internal error: " + "Unknown metrics op value: %d\n", op); exit (1); } + return ""; +} + +void +metrics_counter_start (void) +{ + counter_t *counter; + + counter = xmalloc (sizeof(counter_t)); + glGenQueries (1, &counter->id); - counter->program = current_context.program; + counter->op = current_context.op; counter->next = NULL; if (current_context.counter_tail) { @@ -89,45 +132,45 @@ metrics_counter_new (void) current_context.counter_head = counter; } - return counter->id; + glBeginQuery (GL_TIME_ELAPSED, counter->id); } void -metrics_counter_start (unsigned counter) +metrics_counter_stop (void) { - glBeginQuery (GL_TIME_ELAPSED, counter); + glEndQuery (GL_TIME_ELAPSED); } void -metrics_counter_stop (void) +metrics_set_current_op (metrics_op_t op) { - glEndQuery (GL_TIME_ELAPSED); + current_context.op = op; } -void -metrics_set_current_program (unsigned program) +metrics_op_t +metrics_get_current_op (void) { - current_context.program = program; + return current_context.op; } static void -accumulate_program_ticks (unsigned program_id, unsigned ticks) +accumulate_program_time (metrics_op_t op, unsigned time_ns) { context_t *ctx = ¤t_context; unsigned i; - 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].ticks = 0.0; + 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++) { + ctx->op_metrics[i].op = i; + ctx->op_metrics[i].time_ns = 0.0; } - ctx->num_program_metrics = program_id + 1; + ctx->num_op_metrics = op + 1; } - ctx->program_metrics[program_id].ticks += ticks; + ctx->op_metrics[op].time_ns += time_ns; } static int @@ -135,11 +178,11 @@ time_compare(const void *in_a, const void *in_b, void *arg) { int a = *(const int *)in_a; int b = *(const int *)in_b; - struct program_metrics *metrics = arg; + struct op_metrics *metrics = arg; - if (metrics[a].ticks < metrics[b].ticks) + if (metrics[a].time_ns < metrics[b].time_ns) return -1; - if (metrics[a].ticks > metrics[b].ticks) + if (metrics[a].time_ns > metrics[b].time_ns) return 1; return 0; } @@ -148,34 +191,44 @@ static void print_program_metrics (void) { context_t *ctx = ¤t_context; - unsigned i; - int *sorted; /* Sorted indices into the ctx->program_metrics */ + unsigned i, j; + int *sorted; /* Sorted indices into the ctx->op_metrics */ double total = 0; - /* Make a sorted list of the programs by time used, and figure - * out to total so we can print percentages. + /* Make a sorted list of the operations by time used, and figure + * out the total so we can print percentages. */ - sorted = calloc(ctx->num_program_metrics, sizeof(*sorted)); - for (i = 0; i < ctx->num_program_metrics; i++) { + sorted = calloc(ctx->num_op_metrics, sizeof(*sorted)); + for (i = 0; i < ctx->num_op_metrics; i++) { sorted[i] = i; - total += ctx->program_metrics[i].ticks; + total += ctx->op_metrics[i].time_ns; } - qsort_r(sorted, ctx->num_program_metrics, sizeof(*sorted), - time_compare, ctx->program_metrics); + qsort_r(sorted, ctx->num_op_metrics, sizeof(*sorted), + time_compare, ctx->op_metrics); - for (i = 0; i < ctx->num_program_metrics; i++) { - struct program_metrics *metric = - &ctx->program_metrics[sorted[i]]; + for (i = 0; i < ctx->num_op_metrics; i++) { + const char *op_string; + op_metrics_t *metric =&ctx->op_metrics[sorted[i]]; /* Since we sparsely fill the array based on program * id, many "programs" have no time. */ - if (metric->ticks == 0.0) + if (metric->time_ns == 0.0) continue; - printf ("Program %d:\t%7.2f ms (% 2.1f%%)\n", - metric->id, metric->ticks / 1e6, - metric->ticks / total * 100); + op_string = metrics_op_string (metric->op); + + printf ("%s", op_string); + if (metric->op >= METRICS_OP_SHADER) { + printf (" %d:", metric->op - METRICS_OP_SHADER); + } else { + printf (":"); + for (j = strlen (op_string); j < 20; j++) + printf (" "); + } + printf ("\t%7.2f ms (% 2.1f%%)\n", + metric->time_ns / 1e6, + metric->time_ns / total * 100); } } @@ -221,7 +274,7 @@ metrics_end_frame (void) glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed); - accumulate_program_ticks (counter->program, elapsed); + accumulate_program_time (counter->op, elapsed); current_context.counter_head = counter->next; if (current_context.counter_head == NULL)