]> git.cworth.org Git - fips/blob - glwrap.c
Sort the output and print the percentage.
[fips] / glwrap.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 "dlwrap.h"
23
24 /* The prototypes for some OpenGL functions changed at one point from:
25  *
26  *      const void* *indices
27  * to:
28  *      const void* const coist *indices
29  *
30  * This makes it difficult for us to provide an implementation of
31  * these functions that is consistent with the locally-available gl.h
32  * since we don't know if the extra const will be present or not.
33  *
34  * To workaround this problem, we simply #define away const altogether
35  * before including gl.h.
36  *
37  * Kudos to Keith Packard for suggesting this kludge.
38  */
39 #define const
40
41 #define GL_GLEXT_PROTOTYPES
42 #include <GL/gl.h>
43
44 #include "fips.h"
45
46 #include "glwrap.h"
47
48 #include "metrics.h"
49
50 static int inside_new_list = 0;
51
52 static void *gl_handle;
53
54 void
55 glwrap_set_gl_handle (void *handle)
56 {
57         if (gl_handle == NULL)
58                 gl_handle = handle;
59 }
60
61 void *
62 glwrap_lookup (char *name)
63 {
64         void *ret;
65
66         /* We don't call dlopen here to find the library in which to
67          * perform a dlsym lookup. That's because the application may
68          * be loading libGL.so or libGLESv2.so for its OpenGL symbols.
69          *
70          * So we instead watch for one of those filenames to go by in
71          * our dlopen wrapper, which will then call
72          * glwrap_set_gl_handle to give us the handle to use here.
73          *
74          * If the application hasn't called dlopen on a "libGL"
75          * library, then presumably the application is linked directly
76          * to an OpenGL implementation. In this case, we can use
77          * RTLD_NEXT to find the symbol.
78          *
79          * But just in case, we also let the user override that by
80          * specifying the FIPS_LIBGL environment variable to the path
81          * of the real libGL.so library that fips should dlopen here.
82          */
83         if (gl_handle == NULL) {
84                 const char *path;
85
86                 path = getenv ("FIPS_LIBGL");
87                 if (path) {
88                         gl_handle = dlopen (path, RTLD_LAZY);
89
90                         if (gl_handle == NULL) {
91                                 fprintf (stderr, "Failed to dlopen FIPS_LIBGL: "
92                                          "%s\n", path);
93                                 exit (1);
94                         }
95                 } else {
96                         gl_handle = RTLD_NEXT;
97                 }
98         }
99
100         ret = dlwrap_real_dlsym (gl_handle, name);
101
102         if (ret == NULL) {
103                 fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n",
104                          name);
105                 exit (1);
106         }
107
108         return ret;
109 }
110
111 /* Execute an OpenGL call and time it with a GPU metrics counter. */
112 #define TIMED_DEFER(function,...) do {                                  \
113         if (! inside_new_list) {                                        \
114                 unsigned counter;                                       \
115                 counter = metrics_counter_new ();                       \
116                 metrics_counter_start (counter);                        \
117         }                                                               \
118         GLWRAP_DEFER(function, __VA_ARGS__);                            \
119         if (! inside_new_list) {                                        \
120                 metrics_counter_stop ();                                \
121         }                                                               \
122 } while (0);
123
124 /* Thanks to apitrace source code for the list of OpenGL draw calls. */
125 void
126 glDrawArrays (GLenum mode, GLint first, GLsizei count)
127 {
128         TIMED_DEFER (glDrawArrays, mode, first, count);
129 }
130
131 void
132 glDrawArraysEXT (GLenum mode, GLint first, GLsizei count)
133 {
134         TIMED_DEFER (glDrawArraysEXT, mode, first, count);
135 }
136
137 void
138 glDrawArraysIndirect (GLenum mode, const GLvoid *indirect)
139 {
140         TIMED_DEFER (glDrawArraysIndirect, mode, indirect);
141 }
142
143 void
144 glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count,
145                        GLsizei primcount)
146 {
147         TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount);
148 }
149
150 void
151 glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count,
152                           GLsizei primcount)
153 {
154         TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount);
155 }
156
157 void
158 glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count,
159                           GLsizei primcount)
160 {
161         TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount);
162 }
163
164 void
165 glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count,
166                                    GLsizei primcount, GLuint baseinstance)
167 {
168         TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode,
169                      first, count, primcount, baseinstance);
170 }
171
172 void
173 glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width)
174 {
175         TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width);
176 }
177
178 void
179 glMultiDrawArrays (GLenum mode, const GLint *first,
180                    const GLsizei *count, GLsizei primcount)
181 {
182         TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount);
183 }
184
185 void
186 glMultiDrawArraysEXT (GLenum mode, const GLint *first,
187                       const GLsizei *count, GLsizei primcount)
188 {
189         TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount);
190 }
191
192 void
193 glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first,
194                           const GLsizei *count, GLsizei primcount,
195                           GLint modestride)
196 {
197         TIMED_DEFER (glMultiModeDrawArraysIBM, mode,
198                      first, count, primcount, modestride);
199 }
200
201 void
202 glMultiDrawArraysIndirect (GLenum mode, const void *indirect,
203                            GLsizei drawcount, GLsizei stride)
204 {
205         TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride);
206 }
207
208 void
209 glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect,
210                               GLsizei primcount, GLsizei stride)
211 {
212         TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode,
213                      indirect, primcount, stride);
214 }
215
216 void
217 glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
218 {
219         TIMED_DEFER (glDrawElements, mode, count, type, indices);
220 }
221
222 void
223 glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type,
224                           const GLvoid *indices, GLint basevertex)
225 {
226         TIMED_DEFER (glDrawElementsBaseVertex, mode, count,
227                      type, indices, basevertex);
228 }
229
230 void
231 glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect)
232 {
233         TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect);
234 }
235
236 void
237 glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type,
238                          const GLvoid *indices, GLsizei primcount)
239 {
240         TIMED_DEFER (glDrawElementsInstanced, mode, count,
241                      type, indices, primcount);
242 }
243
244 void
245 glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type,
246                             const GLvoid *indices, GLsizei primcount)
247 {
248         TIMED_DEFER (glDrawElementsInstancedARB, mode, count,
249                      type, indices, primcount);
250 }
251
252 void
253 glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type,
254                             const GLvoid *indices, GLsizei primcount)
255 {
256         TIMED_DEFER (glDrawElementsInstancedEXT, mode, count,
257                      type, indices, primcount);
258 }
259
260 void
261 glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type,
262                                    const GLvoid *indices, GLsizei primcount,
263                                    GLint basevertex)
264 {
265         TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count,
266                      type, indices, primcount, basevertex);
267 }
268
269 void
270 glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type,
271                                      const void *indices, GLsizei primcount,
272                                      GLuint baseinstance)
273 {
274         TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type,
275                      indices, primcount, baseinstance);
276 }
277
278 void
279 glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count,
280                       GLenum type, const void *indices, GLsizei primcount,
281                       GLint basevertex, GLuint baseinstance)
282 {
283         TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode,
284                      count, type, indices, primcount, basevertex, baseinstance);
285 }
286
287 void
288 glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
289                      GLenum type, const GLvoid *indices)
290 {
291         TIMED_DEFER (glDrawRangeElements, mode, start, end,
292                      count, type, indices);
293 }
294
295 void
296 glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count,
297                         GLenum type, const GLvoid *indices)
298 {
299         TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end,
300                      count, type, indices);
301 }
302
303 void
304 glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end,
305                                GLsizei count, GLenum type,
306                                const GLvoid *indices, GLint basevertex)
307 {
308         TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end,
309                      count, type, indices, basevertex);
310 }
311
312 void
313 glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type,
314                      const GLvoid* *indices, GLsizei primcount)
315 {
316         TIMED_DEFER (glMultiDrawElements, mode, count, type,
317                      indices, primcount);
318 }
319
320 void
321 glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count,
322                                GLenum type, const GLvoid* *indices,
323                                GLsizei primcount, const GLint *basevertex)
324 {
325         TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count,
326                      type, indices, primcount, basevertex);
327 }
328
329 void
330 glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type,
331                         const GLvoid* *indices, GLsizei primcount)
332 {
333         TIMED_DEFER (glMultiDrawElementsEXT, mode, count,
334                      type, indices, primcount);
335 }
336
337 void
338 glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count,
339                             GLenum type, const GLvoid* const *indices,
340                             GLsizei primcount, GLint modestride)
341 {
342         TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count,
343                      type, indices, primcount, modestride);
344 }
345
346 void
347 glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect,
348                              GLsizei drawcount, GLsizei stride)
349 {
350         TIMED_DEFER (glMultiDrawElementsIndirect, mode, type,
351                      indirect, drawcount, stride);
352 }
353
354 void
355 glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type,
356                                 const GLvoid *indirect,
357                                 GLsizei primcount, GLsizei stride)
358 {
359         TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type,
360                      indirect, primcount, stride);
361 }
362
363 void
364 glCallList (GLuint list)
365 {
366         TIMED_DEFER (glCallList, list);
367 }
368
369 void
370 glCallLists (GLsizei n, GLenum type, const GLvoid *lists)
371 {
372         TIMED_DEFER (glCallLists, n, type, lists);
373 }
374
375 void
376 glClear (GLbitfield mask)
377 {
378         TIMED_DEFER (glClear, mask);
379 }
380
381 /* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics
382  * counter must be started before glBegin and stopped after glEnd,
383  * (that is, everything from glBegin to glEnd is counted as a single
384  * operation). */
385 void
386 glBegin (GLenum mode)
387 {
388         if (! inside_new_list)
389         {
390                 unsigned counter;
391                 counter = metrics_counter_new ();
392                 metrics_counter_start (counter);
393         }
394
395         GLWRAP_DEFER (glBegin, mode);
396 }
397
398 void
399 glEnd (void)
400 {
401         GLWRAP_DEFER (glEnd);
402
403         if (! inside_new_list) {
404                 metrics_counter_stop ();
405         }
406 }
407
408 /* And we need to track display lists to avoid inserting queries
409  * inside the list while it's being constructed. */
410 void
411 glNewList (GLuint list, GLenum mode)
412 {
413         inside_new_list = 1;
414         GLWRAP_DEFER (glNewList, list, mode);
415 }
416
417 void
418 glEndList (void)
419 {
420         GLWRAP_DEFER (glEndList);
421         inside_new_list = 0;
422 }
423
424 void
425 glDrawPixels (GLsizei width, GLsizei height, GLenum format,
426               GLenum type, const GLvoid *pixels)
427 {
428         TIMED_DEFER (glDrawPixels, width, height, format, type, pixels);
429 }
430
431 void
432 glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
433                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
434                    GLbitfield mask, GLenum filter)
435 {
436         TIMED_DEFER (glBlitFramebuffer,
437                      srcX0, srcY0, srcX1, srcY1,
438                      dstX0, dstY0, dstX1, dstY1,
439                      mask, filter);
440 }
441
442 void
443 glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
444                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
445                       GLbitfield mask, GLenum filter)
446 {
447         TIMED_DEFER (glBlitFramebufferEXT,
448                      srcX0, srcY0, srcX1, srcY1,
449                      dstX0, dstY0, dstX1, dstY1,
450                      mask, filter);
451 }
452
453 void
454 glUseProgram (GLuint program)
455 {
456         metrics_set_current_program (program);
457
458         GLWRAP_DEFER(glUseProgram, program);
459 }
460
461 void
462 glUseProgramObjectARB (GLhandleARB programObj)
463 {
464         metrics_set_current_program (programObj);
465
466         GLWRAP_DEFER(glUseProgramObjectARB, programObj);
467 }