]> git.cworth.org Git - fips/blob - metrics.c
configure: Test whether compiler can create both 32 and 64-bit binaries
[fips] / metrics.c
1 /* Copyright © 2013, Intel Corporation
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include <sys/time.h>
26
27 #define GL_GLEXT_PROTOTYPES
28 #include <GL/gl.h>
29
30 #include "metrics.h"
31
32 typedef struct counter
33 {
34         unsigned id;
35         unsigned program;
36         struct counter *next;
37 } counter_t;
38
39 typedef struct program_metrics
40 {
41         unsigned id;
42         double ticks;
43 } program_metrics_t;
44
45 typedef struct context
46 {
47         unsigned int program;
48
49         counter_t *counter_head;
50         counter_t *counter_tail;
51
52         unsigned num_program_metrics;
53         program_metrics_t *program_metrics;
54 } context_t;
55
56 /* FIXME: Need a map from integers to context objects and track the
57  * current context with glXMakeContextCurrent, eglMakeCurrent, etc. */
58
59 context_t current_context;
60
61 unsigned
62 metrics_add_counter (void)
63 {
64         counter_t *counter;
65
66         counter = malloc (sizeof(counter_t));
67         if (counter == NULL) {
68                 fprintf (stderr, "Out of memory\n");
69                 exit (1);
70         }
71
72         glGenQueries (1, &counter->id);
73
74         counter->program = current_context.program;
75         counter->next = NULL;
76
77         if (current_context.counter_tail) {
78                 current_context.counter_tail->next = counter;
79                 current_context.counter_tail = counter;
80         } else {
81                 current_context.counter_tail = counter;
82                 current_context.counter_head = counter;
83         }
84
85         return counter->id;
86 }
87
88 void
89 metrics_set_current_program (unsigned program)
90 {
91         current_context.program = program;
92 }
93
94 static void
95 accumulate_program_ticks (unsigned program_id, unsigned ticks)
96 {
97         context_t *ctx = &current_context;
98         unsigned i;
99
100         if (program_id >= ctx->num_program_metrics) {
101                 ctx->program_metrics = realloc (ctx->program_metrics,
102                                                 (program_id + 1) * sizeof (program_metrics_t));
103                 for (i = ctx->num_program_metrics; i < program_id + 1; i++) {
104                         ctx->program_metrics[i].id = i;
105                         ctx->program_metrics[i].ticks = 0.0;
106                 }
107
108                 ctx->num_program_metrics = program_id + 1;
109         }
110
111         ctx->program_metrics[program_id].ticks += ticks;
112 }
113
114 /* FIXME: Should sort the metrics, print out percentages, etc. */
115 static void
116 print_program_metrics (void)
117 {
118         context_t *ctx = &current_context;
119         unsigned i;
120
121         for (i = 0; i < ctx->num_program_metrics; i++) {
122                 if (ctx->program_metrics[i].ticks == 0.0)
123                         continue;
124                 printf ("Program %d:\t%7.2f mega-ticks\n",
125                         i, ctx->program_metrics[i].ticks / 1e6);
126         }
127 }
128
129 void
130 metrics_end_frame (void)
131 {
132         static int initialized = 0;
133         static int frames;
134         static struct timeval tv_start, tv_now;
135
136         if (! initialized) {
137                 frames = 0;
138                 gettimeofday (&tv_start, NULL);
139                 initialized = 1;
140         }
141
142
143         frames++;
144         gettimeofday (&tv_now, NULL);
145
146         /* Consume all counters that are ready. */
147         counter_t *counter = current_context.counter_head;
148
149         while (counter) {
150                 GLuint available, elapsed;
151
152                 glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT_AVAILABLE,
153                                      &available);
154                 if (! available)
155                         break;
156
157                 glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed);
158
159                 accumulate_program_ticks (counter->program, elapsed);
160
161                 current_context.counter_head = counter->next;
162                 if (current_context.counter_head == NULL)
163                         current_context.counter_tail = NULL;
164
165                 glDeleteQueries (1, &counter->id);
166
167                 free (counter);
168                 counter = current_context.counter_head;
169         }
170
171         if (frames % 60 == 0) {
172                 double fps;
173
174                 fps = (double) frames / (tv_now.tv_sec - tv_start.tv_sec +
175                                          (tv_now.tv_usec - tv_start.tv_usec) / 1.0e6);
176
177                 printf("FPS: %.3f\n", fps);
178
179                 print_program_metrics ();
180         }
181 }