X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=metrics.c;h=39c90ad1145547846da59dac480a6e711e4a846c;hb=2ddfc599cf1f15f2eec12ddb24754fe768b38e03;hp=f4c0a2150f05b2092031a17907da231631b09bd4;hpb=c0c549440d852153d1777eca3fa962c1b70483b3;p=fips diff --git a/metrics.c b/metrics.c index f4c0a21..39c90ad 100644 --- a/metrics.c +++ b/metrics.c @@ -19,13 +19,14 @@ * THE SOFTWARE. */ +#define _GNU_SOURCE + #include #include #include -#define GL_GLEXT_PROTOTYPES -#include +#include "fips-dispatch-gl.h" #include "metrics.h" @@ -38,8 +39,11 @@ typedef struct counter typedef struct program_metrics { + /* This happens to also be the index into the + * ctx->program_metrics array currently + */ unsigned id; - double ticks; + double time_ns; } program_metrics_t; typedef struct context @@ -58,8 +62,11 @@ typedef struct context context_t current_context; -unsigned -metrics_add_counter (void) +int frames; +int verbose; + +void +metrics_counter_start (void) { counter_t *counter; @@ -82,7 +89,13 @@ metrics_add_counter (void) current_context.counter_head = counter; } - return counter->id; + glBeginQuery (GL_TIME_ELAPSED, counter->id); +} + +void +metrics_counter_stop (void) +{ + glEndQuery (GL_TIME_ELAPSED); } void @@ -92,7 +105,7 @@ metrics_set_current_program (unsigned program) } static void -accumulate_program_ticks (unsigned program_id, unsigned ticks) +accumulate_program_time (unsigned program_id, unsigned time_ns) { context_t *ctx = ¤t_context; unsigned i; @@ -102,73 +115,107 @@ accumulate_program_ticks (unsigned program_id, unsigned ticks) (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; + ctx->program_metrics[i].time_ns = 0.0; } ctx->num_program_metrics = program_id + 1; } - ctx->program_metrics[program_id].ticks += ticks; + ctx->program_metrics[program_id].time_ns += time_ns; +} + +static int +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; + + if (metrics[a].time_ns < metrics[b].time_ns) + return -1; + if (metrics[a].time_ns > metrics[b].time_ns) + return 1; + return 0; } -/* FIXME: Should sort the metrics, print out percentages, etc. */ static void print_program_metrics (void) { context_t *ctx = ¤t_context; unsigned i; + int *sorted; /* Sorted indices into the ctx->program_metrics */ + double total = 0; + /* Make a sorted list of the programs by time used, and figure + * out to total so we can print percentages. + */ + sorted = calloc(ctx->num_program_metrics, sizeof(*sorted)); for (i = 0; i < ctx->num_program_metrics; i++) { - if (ctx->program_metrics[i].ticks == 0.0) + sorted[i] = i; + total += ctx->program_metrics[i].time_ns; + } + qsort_r(sorted, ctx->num_program_metrics, sizeof(*sorted), + time_compare, ctx->program_metrics); + + for (i = 0; i < ctx->num_program_metrics; i++) { + struct program_metrics *metric = + &ctx->program_metrics[sorted[i]]; + + /* Since we sparsely fill the array based on program + * id, many "programs" have no time. + */ + if (metric->time_ns == 0.0) continue; - printf ("Program %d:\t%7.2f mega-ticks\n", - i, ctx->program_metrics[i].ticks / 1e6); + + printf ("Program %d:\t%7.2f ms (% 2.1f%%)\n", + metric->id, metric->time_ns / 1e6, + metric->time_ns / total * 100); } } +/* Called at program exit */ +static void +metrics_exit (void) +{ + if (verbose) + printf ("fips: terminating\n"); +} + + void metrics_end_frame (void) { static int initialized = 0; - static int frames; static struct timeval tv_start, tv_now; if (! initialized) { - frames = 0; gettimeofday (&tv_start, NULL); + atexit (metrics_exit); + if (getenv ("FIPS_VERBOSE")) + verbose = 1; initialized = 1; } + if (verbose) + printf ("fips: frame %d complete\n", frames); frames++; - - if (frames % 60 == 0) { - double fps; - gettimeofday (&tv_now, NULL); - - fps = (double) frames / (tv_now.tv_sec - tv_start.tv_sec + - (tv_now.tv_usec - tv_start.tv_usec) / 1.0e6); - - printf("FPS: %.3f\n", fps); - - print_program_metrics (); - } + gettimeofday (&tv_now, NULL); /* Consume all counters that are ready. */ counter_t *counter = current_context.counter_head; while (counter) { - GLint available; - GLuint elapsed; + GLuint available, elapsed; - glGetQueryObjectiv (counter->id, GL_QUERY_RESULT_AVAILABLE, - &available); + glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT_AVAILABLE, + &available); if (! available) break; glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed); - accumulate_program_ticks (counter->program, elapsed); + accumulate_program_time (counter->program, elapsed); current_context.counter_head = counter->next; if (current_context.counter_head == NULL) @@ -179,4 +226,15 @@ metrics_end_frame (void) free (counter); counter = current_context.counter_head; } + + if (frames % 60 == 0) { + double fps; + + fps = (double) frames / (tv_now.tv_sec - tv_start.tv_sec + + (tv_now.tv_usec - tv_start.tv_usec) / 1.0e6); + + printf("FPS: %.3f\n", fps); + + print_program_metrics (); + } }