From a73706f5eae8f1be84a8cebd50f32b08cc66b16c Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 7 Oct 2013 15:57:34 -0700 Subject: [PATCH 01/16] metrics: Use a more meaningful field name. I had "ticks" here before I knew the units of the timer-query result. Since then, Eric dug up the documentation saying that this timer reports time in nanoseconds. So use a field name of "time_ns" rather than "ticks". --- metrics.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/metrics.c b/metrics.c index 74d6c56..e00bb63 100644 --- a/metrics.c +++ b/metrics.c @@ -43,7 +43,7 @@ typedef struct program_metrics * ctx->program_metrics array currently */ unsigned id; - double ticks; + double time_ns; } program_metrics_t; typedef struct context @@ -111,7 +111,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; @@ -121,13 +121,13 @@ 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 @@ -137,9 +137,9 @@ time_compare(const void *in_a, const void *in_b, void *arg) int b = *(const int *)in_b; struct program_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; } @@ -158,7 +158,7 @@ print_program_metrics (void) sorted = calloc(ctx->num_program_metrics, sizeof(*sorted)); for (i = 0; i < ctx->num_program_metrics; i++) { sorted[i] = i; - total += ctx->program_metrics[i].ticks; + total += ctx->program_metrics[i].time_ns; } qsort_r(sorted, ctx->num_program_metrics, sizeof(*sorted), time_compare, ctx->program_metrics); @@ -170,12 +170,12 @@ print_program_metrics (void) /* 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); + metric->id, metric->time_ns / 1e6, + metric->time_ns / total * 100); } } @@ -221,7 +221,7 @@ metrics_end_frame (void) 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) -- 2.43.0 From 2ddfc599cf1f15f2eec12ddb24754fe768b38e03 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 15 Oct 2013 13:20:33 -0700 Subject: [PATCH 02/16] Simplify metrics interface by dropping metrics_counter_new None of the callers of this function were doing anything with the returned value other than passing it directly to metrics_counter_start. So it's simpler to just fold the contents of the metrics_counter_new function into the body of metrics_counter_start itself. --- glwrap.c | 13 +++---------- metrics.c | 12 +++--------- metrics.h | 13 +++---------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/glwrap.c b/glwrap.c index 3c751cc..ebe7e54 100644 --- a/glwrap.c +++ b/glwrap.c @@ -111,9 +111,7 @@ glwrap_lookup (char *name) /* Execute an OpenGL call and time it with a GPU metrics counter. */ #define TIMED_DEFER(function,...) do { \ if (! inside_new_list) { \ - unsigned counter; \ - counter = metrics_counter_new (); \ - metrics_counter_start (counter); \ + metrics_counter_start (); \ } \ GLWRAP_DEFER(function, __VA_ARGS__); \ if (! inside_new_list) { \ @@ -386,11 +384,7 @@ void glBegin (GLenum mode) { if (! inside_new_list) - { - unsigned counter; - counter = metrics_counter_new (); - metrics_counter_start (counter); - } + metrics_counter_start (); GLWRAP_DEFER (glBegin, mode); } @@ -400,9 +394,8 @@ glEnd (void) { GLWRAP_DEFER (glEnd); - if (! inside_new_list) { + if (! inside_new_list) metrics_counter_stop (); - } } /* And we need to track display lists to avoid inserting queries diff --git a/metrics.c b/metrics.c index e00bb63..39c90ad 100644 --- a/metrics.c +++ b/metrics.c @@ -65,8 +65,8 @@ context_t current_context; int frames; int verbose; -unsigned -metrics_counter_new (void) +void +metrics_counter_start (void) { counter_t *counter; @@ -89,13 +89,7 @@ metrics_counter_new (void) current_context.counter_head = counter; } - return counter->id; -} - -void -metrics_counter_start (unsigned counter) -{ - glBeginQuery (GL_TIME_ELAPSED, counter); + glBeginQuery (GL_TIME_ELAPSED, counter->id); } void diff --git a/metrics.h b/metrics.h index 2d93d90..8b68867 100644 --- a/metrics.h +++ b/metrics.h @@ -22,20 +22,13 @@ #ifndef METRICS_H #define METRICS_H -/* Add a new counter to the metrics tracking state. +/* Start accumulating GPU time. * - * The value accumulated in this counter be accounted against the + * The time accumulated will be accounted against the * current program (as set with metrics_set_current_program). - * - * Returns: A counter ID suitable for use with metrics_counter_start - * and metrics_counter_stop. */ -unsigned -metrics_counter_new (void); - -/* Start accumulating GPU time spent into the given counter. */ void -metrics_counter_start (unsigned counter); +metrics_counter_start (void); /* Stop accumulating GPU time (stops the most-recently started counter) */ void -- 2.43.0 From 8dc8bcb282b0948605e4b526b9787f51c56301d6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 15 Oct 2013 13:45:06 -0700 Subject: [PATCH 03/16] Rework timer queries to run continuously. Previously, we ran timer queries only around gl calls that we determined were "drawing operations". This had the following drawbacks: 1. Lots of timer queries, so more overhead than desired 2. Misses accumulating time from non "drawing operations" 3. Misses accumulating time from drawing operations we failed to identify. Here, instead, we keep the timer running continuously, solving all three of the above problems. We first start timer at make-current time (glxMakeCurrent, glxMakeContextCurrent, or eglMakeCurrent), and only stop it, (and immediately restart it), in one of the following circumstances: 1. Current program changed (glUseProgram or glUseProgramObjectARB) 2. At each frame end (glxSwapBuffers or eglSwapBuffers) --- eglwrap.c | 7 ++ glwrap.c | 347 ++---------------------------------------------------- glxwrap.c | 8 ++ 3 files changed, 25 insertions(+), 337 deletions(-) diff --git a/eglwrap.c b/eglwrap.c index 198b4f0..f74ae40 100644 --- a/eglwrap.c +++ b/eglwrap.c @@ -77,8 +77,13 @@ eglSwapBuffers (EGLDisplay dpy, EGLSurface surface) EGLBoolean ret; EGLWRAP_DEFER_WITH_RETURN (ret, eglSwapBuffers, dpy, surface); + + metrics_counter_stop (); + metrics_end_frame (); + metrics_counter_start (); + return ret; } @@ -107,5 +112,7 @@ eglMakeCurrent (EGLDisplay display, EGLSurface draw, EGLSurface read, EGLWRAP_DEFER_WITH_RETURN (ret, eglMakeCurrent, display, draw, read, context); + metrics_counter_start (); + return ret; } diff --git a/glwrap.c b/glwrap.c index ebe7e54..ec03ce7 100644 --- a/glwrap.c +++ b/glwrap.c @@ -47,8 +47,6 @@ #include "metrics.h" -static int inside_new_list = 0; - static void *gl_handle; void @@ -108,353 +106,28 @@ glwrap_lookup (char *name) return ret; } -/* Execute an OpenGL call and time it with a GPU metrics counter. */ -#define TIMED_DEFER(function,...) do { \ - if (! inside_new_list) { \ - metrics_counter_start (); \ - } \ - GLWRAP_DEFER(function, __VA_ARGS__); \ - if (! inside_new_list) { \ - metrics_counter_stop (); \ - } \ -} while (0); - -/* Thanks to apitrace source code for the list of OpenGL draw calls. */ -void -glDrawArrays (GLenum mode, GLint first, GLsizei count) -{ - TIMED_DEFER (glDrawArrays, mode, first, count); -} - -void -glDrawArraysEXT (GLenum mode, GLint first, GLsizei count) -{ - TIMED_DEFER (glDrawArraysEXT, mode, first, count); -} - -void -glDrawArraysIndirect (GLenum mode, const GLvoid *indirect) -{ - TIMED_DEFER (glDrawArraysIndirect, mode, indirect); -} - -void -glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, - GLsizei primcount) -{ - TIMED_DEFER (glDrawArraysInstanced, mode, first, count, primcount); -} - -void -glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, - GLsizei primcount) -{ - TIMED_DEFER (glDrawArraysInstancedARB, mode, first, count, primcount); -} - -void -glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, - GLsizei primcount) -{ - TIMED_DEFER (glDrawArraysInstancedEXT, mode, start, count, primcount); -} - -void -glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, - GLsizei primcount, GLuint baseinstance) -{ - TIMED_DEFER (glDrawArraysInstancedBaseInstance, mode, - first, count, primcount, baseinstance); -} - -void -glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width) -{ - TIMED_DEFER (glDrawMeshArraysSUN, mode, first, count, width); -} - -void -glMultiDrawArrays (GLenum mode, const GLint *first, - const GLsizei *count, GLsizei primcount) -{ - TIMED_DEFER (glMultiDrawArrays, mode, first, count, primcount); -} - -void -glMultiDrawArraysEXT (GLenum mode, const GLint *first, - const GLsizei *count, GLsizei primcount) -{ - TIMED_DEFER (glMultiDrawArraysEXT, mode, first, count, primcount); -} - -void -glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, - const GLsizei *count, GLsizei primcount, - GLint modestride) -{ - TIMED_DEFER (glMultiModeDrawArraysIBM, mode, - first, count, primcount, modestride); -} - -void -glMultiDrawArraysIndirect (GLenum mode, const void *indirect, - GLsizei drawcount, GLsizei stride) -{ - TIMED_DEFER (glMultiDrawArraysIndirect, mode, indirect, drawcount, stride); -} - -void -glMultiDrawArraysIndirectAMD (GLenum mode, const GLvoid *indirect, - GLsizei primcount, GLsizei stride) -{ - TIMED_DEFER (glMultiDrawArraysIndirectAMD, mode, - indirect, primcount, stride); -} - -void -glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -{ - TIMED_DEFER (glDrawElements, mode, count, type, indices); -} - -void -glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - TIMED_DEFER (glDrawElementsBaseVertex, mode, count, - type, indices, basevertex); -} - -void -glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect) -{ - TIMED_DEFER (glDrawElementsIndirect, mode, type, indirect); -} - -void -glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount) -{ - TIMED_DEFER (glDrawElementsInstanced, mode, count, - type, indices, primcount); -} - -void -glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount) -{ - TIMED_DEFER (glDrawElementsInstancedARB, mode, count, - type, indices, primcount); -} - -void -glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount) -{ - TIMED_DEFER (glDrawElementsInstancedEXT, mode, count, - type, indices, primcount); -} - -void -glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei primcount, - GLint basevertex) -{ - TIMED_DEFER (glDrawElementsInstancedBaseVertex, mode, count, - type, indices, primcount, basevertex); -} - -void -glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, - const void *indices, GLsizei primcount, - GLuint baseinstance) -{ - TIMED_DEFER (glDrawElementsInstancedBaseInstance, mode, count, type, - indices, primcount, baseinstance); -} - -void -glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, - GLenum type, const void *indices, GLsizei primcount, - GLint basevertex, GLuint baseinstance) -{ - TIMED_DEFER (glDrawElementsInstancedBaseVertexBaseInstance, mode, - count, type, indices, primcount, basevertex, baseinstance); -} - -void -glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices) -{ - TIMED_DEFER (glDrawRangeElements, mode, start, end, - count, type, indices); -} - -void -glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices) -{ - TIMED_DEFER (glDrawRangeElementsEXT, mode, start, end, - count, type, indices); -} - -void -glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) -{ - TIMED_DEFER (glDrawRangeElementsBaseVertex, mode, start, end, - count, type, indices, basevertex); -} - -void -glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, - const GLvoid* *indices, GLsizei primcount) -{ - TIMED_DEFER (glMultiDrawElements, mode, count, type, - indices, primcount); -} - -void -glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, - GLenum type, const GLvoid* *indices, - GLsizei primcount, const GLint *basevertex) -{ - TIMED_DEFER (glMultiDrawElementsBaseVertex, mode, count, - type, indices, primcount, basevertex); -} - -void -glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, - const GLvoid* *indices, GLsizei primcount) -{ - TIMED_DEFER (glMultiDrawElementsEXT, mode, count, - type, indices, primcount); -} - -void -glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, - GLenum type, const GLvoid* const *indices, - GLsizei primcount, GLint modestride) -{ - TIMED_DEFER (glMultiModeDrawElementsIBM, mode, count, - type, indices, primcount, modestride); -} - -void -glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, - GLsizei drawcount, GLsizei stride) -{ - TIMED_DEFER (glMultiDrawElementsIndirect, mode, type, - indirect, drawcount, stride); -} - -void -glMultiDrawElementsIndirectAMD (GLenum mode, GLenum type, - const GLvoid *indirect, - GLsizei primcount, GLsizei stride) -{ - TIMED_DEFER (glMultiDrawElementsIndirectAMD, mode, type, - indirect, primcount, stride); -} - -void -glCallList (GLuint list) -{ - TIMED_DEFER (glCallList, list); -} - -void -glCallLists (GLsizei n, GLenum type, const GLvoid *lists) -{ - TIMED_DEFER (glCallLists, n, type, lists); -} - -void -glClear (GLbitfield mask) -{ - TIMED_DEFER (glClear, mask); -} - -/* We can't just use TIMED_DEFER for glBegin/glEnd since the metrics - * counter must be started before glBegin and stopped after glEnd, - * (that is, everything from glBegin to glEnd is counted as a single - * operation). */ -void -glBegin (GLenum mode) -{ - if (! inside_new_list) - metrics_counter_start (); - - GLWRAP_DEFER (glBegin, mode); -} - -void -glEnd (void) -{ - GLWRAP_DEFER (glEnd); - - if (! inside_new_list) - metrics_counter_stop (); -} - -/* And we need to track display lists to avoid inserting queries - * inside the list while it's being constructed. */ -void -glNewList (GLuint list, GLenum mode) -{ - inside_new_list = 1; - GLWRAP_DEFER (glNewList, list, mode); -} - -void -glEndList (void) -{ - GLWRAP_DEFER (glEndList); - inside_new_list = 0; -} - -void -glDrawPixels (GLsizei width, GLsizei height, GLenum format, - GLenum type, const GLvoid *pixels) -{ - TIMED_DEFER (glDrawPixels, width, height, format, type, pixels); -} - -void -glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - TIMED_DEFER (glBlitFramebuffer, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); -} - -void -glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) -{ - TIMED_DEFER (glBlitFramebufferEXT, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); -} - +/* With a program change, we stop the counter, update the + * active program, then start the counter up again. */ void glUseProgram (GLuint program) { + metrics_counter_stop (); + metrics_set_current_program (program); + metrics_counter_start (); + GLWRAP_DEFER(glUseProgram, program); } void glUseProgramObjectARB (GLhandleARB programObj) { + metrics_counter_stop (); + metrics_set_current_program (programObj); + metrics_counter_start (); + GLWRAP_DEFER(glUseProgramObjectARB, programObj); } diff --git a/glxwrap.c b/glxwrap.c index 59d3e8e..a57c557 100644 --- a/glxwrap.c +++ b/glxwrap.c @@ -36,7 +36,11 @@ glXSwapBuffers (Display *dpy, GLXDrawable drawable) { GLWRAP_DEFER (glXSwapBuffers, dpy, drawable); + metrics_counter_stop (); + metrics_end_frame (); + + metrics_counter_start (); } /* glXGetProcAddressARB is a function which accepts a string and @@ -84,6 +88,8 @@ glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx) GLWRAP_DEFER_WITH_RETURN (ret, glXMakeCurrent, dpy, drawable, ctx); + metrics_counter_start (); + return ret; } @@ -96,5 +102,7 @@ glXMakeContextCurrent (Display *dpy, GLXDrawable drawable, GLXDrawable read, GLX GLWRAP_DEFER_WITH_RETURN (ret, glXMakeContextCurrent, dpy, drawable, read, ctx); + metrics_counter_start (); + return ret; } -- 2.43.0 From 61b4545d541527ca2bd76811195b964595db7ed1 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 15 Oct 2013 20:23:08 -0700 Subject: [PATCH 04/16] Aggregate non-shader GPU operations into their own operations These operations are named after representative functions, (glClear, glReadPixels, etc.). Aggregate time spent in any of these operations is sorted together with the existing reports for time spent in particular shader programs. The shader program times should now be more accurate since time spent in operations such as glClear will now no longer be accumulated into the most recently-used shader. --- eglwrap.c | 1 + glwrap.c | 1231 ++++++++++++++++++++++++++++++++++++++++++++++++++++- glxwrap.c | 2 + metrics.c | 128 ++++-- metrics.h | 44 +- 5 files changed, 1356 insertions(+), 50 deletions(-) diff --git a/eglwrap.c b/eglwrap.c index f74ae40..9e58389 100644 --- a/eglwrap.c +++ b/eglwrap.c @@ -112,6 +112,7 @@ eglMakeCurrent (EGLDisplay display, EGLSurface draw, EGLSurface read, EGLWRAP_DEFER_WITH_RETURN (ret, eglMakeCurrent, display, draw, read, context); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); return ret; diff --git a/glwrap.c b/glwrap.c index ec03ce7..80c5e36 100644 --- a/glwrap.c +++ b/glwrap.c @@ -49,6 +49,11 @@ static void *gl_handle; +#define SWITCH_METRICS_OP(op) \ + metrics_counter_stop (); \ + metrics_set_current_op (op); \ + metrics_counter_start (); + void glwrap_set_gl_handle (void *handle) { @@ -111,11 +116,7 @@ glwrap_lookup (char *name) void glUseProgram (GLuint program) { - metrics_counter_stop (); - - metrics_set_current_program (program); - - metrics_counter_start (); + SWITCH_METRICS_OP (METRICS_OP_SHADER + program); GLWRAP_DEFER(glUseProgram, program); } @@ -123,11 +124,1223 @@ glUseProgram (GLuint program) void glUseProgramObjectARB (GLhandleARB programObj) { - metrics_counter_stop (); + SWITCH_METRICS_OP (METRICS_OP_SHADER + programObj); - metrics_set_current_program (programObj); + GLWRAP_DEFER(glUseProgramObjectARB, programObj); +} - metrics_counter_start (); +/* METRICS_OP_ACCUM */ +void +glAccum (GLenum op, GLfloat value) +{ + SWITCH_METRICS_OP (METRICS_OP_ACCUM); - GLWRAP_DEFER(glUseProgramObjectARB, programObj); + GLWRAP_DEFER (glAccum, op, value); +} + +void +glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + SWITCH_METRICS_OP (METRICS_OP_ACCUM); + + GLWRAP_DEFER (glClearAccum, red, green, blue, alpha); +} + +void +glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +{ + SWITCH_METRICS_OP (METRICS_OP_ACCUM); + + GLWRAP_DEFER (glClearAccumxOES, red, green, blue, alpha); +} + +/* METRICS_OP_BUFFER_DATA */ +void +glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glBufferData, target, size, data, usage); +} + +void +glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, + GLenum usage) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glNamedBufferDataEXT, buffer, size, data, usage); +} + +void +glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glBufferSubData, target, offset, size, data); +} + +void +glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glNamedBufferSubDataEXT, buffer, offset, size, data); +} + +void * +glMapBuffer (GLenum target, GLenum access) +{ + void *ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glMapBuffer, target, access); + + return ret; +} + +void * +glMapBufferARB (GLenum target, GLenum access) +{ + void *ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glMapBufferARB, target, access); + + return ret; +} + +void * +glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, + GLbitfield access) +{ + void *ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glMapBufferRange, target, offset, + length, access); + + return ret; +} + +GLboolean +glUnmapBuffer (GLenum target) +{ + GLboolean ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glUnmapBuffer, target); + + return ret; +} + +GLboolean +glUnmapNamedBufferEXT (GLuint buffer) +{ + GLboolean ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glUnmapNamedBufferEXT, buffer); + + return ret; +} + +GLboolean +glUnmapBufferARB (GLenum target) +{ + GLboolean ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glUnmapBufferARB, target); + + return ret; +} + +void +glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glFlushMappedBufferRange, target, offset, length); +} + +void +glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glFlushMappedBufferRangeAPPLE, target, offset, size); +} + +void +glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, + GLsizeiptr length) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER (glFlushMappedNamedBufferRangeEXT, buffer, offset, length); +} + +void * +glMapNamedBufferEXT (GLuint buffer, GLenum access) +{ + void *ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glMapNamedBufferEXT, buffer, access); + + return ret; +} + +void * +glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access) +{ + void *ret; + + SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + + GLWRAP_DEFER_WITH_RETURN (ret, glMapNamedBufferRangeEXT, buffer, + offset, length, access); + + return ret; +} + +/* METRICS_OP_BUFFER_SUB_DATA */ +void +glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); + + GLWRAP_DEFER (glCopyBufferSubData, readTarget, writeTarget, + readOffset, writeOffset, size); +} + +void +glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) +{ + SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); + + GLWRAP_DEFER (glNamedCopyBufferSubDataEXT, readBuffer, + writeBuffer, readOffset, writeOffset, size); +} + +/* METRICS_OP_BITMAP */ +void +glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) +{ + SWITCH_METRICS_OP (METRICS_OP_BITMAP); + + GLWRAP_DEFER (glBitmap, width, height, xorig, yorig, + xmove, ymove, bitmap); +} + +void +glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, + GLfixed xmove, GLfixed ymove, const GLubyte *bitmap) +{ + SWITCH_METRICS_OP (METRICS_OP_BITMAP); + + GLWRAP_DEFER (glBitmapxOES, width, height, xorig, yorig, + xmove, ymove, bitmap); +} + +/* METRICS_OP_BLIT_FRAMEBUFFER */ +void +glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); + + GLWRAP_DEFER (glBlitFramebuffer, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +void +glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); + + GLWRAP_DEFER (glBlitFramebufferEXT, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); +} + +/* METRICS_OP_CLEAR */ +void +glClear (GLbitfield mask) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR); + + GLWRAP_DEFER (glClear, mask); +} + +void +glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR); + + GLWRAP_DEFER (glClearBufferfi, buffer, drawbuffer, depth, stencil); +} + +void +glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR); + + GLWRAP_DEFER (glClearBufferfv, buffer, drawbuffer, value); +} + +void +glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR); + + GLWRAP_DEFER (glClearBufferiv, buffer, drawbuffer, value); +} + +void +glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR); + + GLWRAP_DEFER (glClearBufferuiv, buffer, drawbuffer, value); +} + +/* METRICS_OP_CLEAR_BUFFER_DATA */ + +void +glClearBufferData (GLenum target, GLenum internalformat, GLenum format, + GLenum type, const void *data) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + + GLWRAP_DEFER (glClearBufferData, target, internalformat, format, + type, data); +} + +void +glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, + GLsizeiptr size, GLenum format, GLenum type, + const void *data) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + + GLWRAP_DEFER (glClearBufferSubData, target, internalformat, + offset, size, format, type, data); +} + +void +glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, + GLenum type, const void *data) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + + GLWRAP_DEFER (glClearNamedBufferDataEXT, buffer, internalformat, + format, type, data); +} + +void +glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, + GLenum format, GLenum type, GLsizeiptr offset, + GLsizeiptr size, const void *data) +{ + SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + + GLWRAP_DEFER (glClearNamedBufferSubDataEXT, buffer, + internalformat, format, type, offset, size, data); +} + +/* METRICS_OP_CLEAR_TEX_IMAGE */ + + +/* METRICS_OP_COPY_PIXELS */ +void +glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_PIXELS); + + GLWRAP_DEFER (glCopyPixels, x, y, width, height, type); +} + +/* METRICS_OP_COPY_TEX_IMAGE */ +void +glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexImage1D, target, level, internalformat, + x, y, width, border); +} + +void +glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexImage1DEXT, target, level, internalformat, + x, y, width, border); +} + +void +glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexImage2D, target, level, internalformat, + x, y, width, height, border); +} + +void +glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexImage2DEXT, target, level, internalformat, + x, y, width, height, border); +} + +void +glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage1D, target, level, xoffset, + x, y, width); +} + +void +glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage1DEXT, target, level, xoffset, + x, y, width); +} + +void +glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage2D, target, level, xoffset, yoffset, + x, y, width, height); +} + +void +glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage2DEXT, target, level, xoffset, yoffset, + x, y, width, height); +} + +void +glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage3D, target, level, xoffset, yoffset, + zoffset, x, y, width, height); +} + +void +glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTexSubImage3DEXT, target, level, xoffset, yoffset, + zoffset, x, y, width, height); +} + +void +glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTextureImage1DEXT, texture, target, level, + internalformat, x, y, width, border); +} + +void +glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTextureImage2DEXT, texture, target, + level, internalformat, x, y, width, height, border); +} + +void +glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTextureSubImage1DEXT, texture, target, level, + xoffset, x, y, width); +} + +void +glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTextureSubImage2DEXT, texture, target, level, + xoffset, yoffset, x, y, width, height); +} + +void +glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyTextureSubImage3DEXT, texture, target, level, + xoffset, yoffset, zoffset, x, y, width, height); +} + +void +glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyMultiTexImage1DEXT, texunit, target, level, + internalformat, x, y, width, border); +} + +void +glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyMultiTexImage2DEXT, texunit, target, level, + internalformat, x, y, width, height, border); +} + +void +glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyMultiTexSubImage1DEXT, texunit, target, level, + xoffset, x, y, width); +} + +void +glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyMultiTexSubImage2DEXT, texunit, target, level, + xoffset, yoffset, x, y, width, height); +} + +void +glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + + GLWRAP_DEFER (glCopyMultiTexSubImage3DEXT, texunit, target, level, + xoffset, yoffset, zoffset, x, y, width, height); +} + +/* METRICS_OP_DRAW_PIXELS */ +void +glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_DRAW_PIXELS); + + GLWRAP_DEFER (glDrawPixels, width, height, format, type, pixels); +} + +/* METRICS_OP_GET_TEX_IMAGE */ + +void +glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, + GLint lod, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetCompressedMultiTexImageEXT, texunit, + target, lod, img); +} + +void +glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetCompressedTexImage, target, level, img); +} + +void +glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetCompressedTexImageARB, target, level, img); +} + +void +glGetCompressedTextureImageEXT (GLuint texture, GLenum target, + GLint lod, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetCompressedTextureImageEXT, texture, + target, lod, img); +} + +void +glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetMultiTexImageEXT, texunit, + target, level, format, type, pixels); +} + +void +glGetnCompressedTexImageARB (GLenum target, GLint lod, + GLsizei bufSize, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetnCompressedTexImageARB, target, lod, bufSize, img); +} + +void +glGetnTexImageARB (GLenum target, GLint level, GLenum format, + GLenum type, GLsizei bufSize, GLvoid *img) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetnTexImageARB, target, level, + format, type, bufSize, img); +} + +void +glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, + GLvoid *pixels ) +{ + SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + + GLWRAP_DEFER (glGetTexImage, target, level, format, type, pixels); +} + +/* METRICS_OP_READ_PIXELS */ +void +glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels ) +{ + SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); + + GLWRAP_DEFER (glReadPixels, x, y, width, height, format, type, pixels); +} + +void +glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); + + GLWRAP_DEFER (glReadnPixelsARB, x, y, width, height, + format, type, bufSize, data); +} + +/* METRICS_OP_TEX_IMAGE */ +void +glTexImage1D (GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLint border, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage1D, target, level, internalFormat, width, + border, format, type, pixels); +} + +void +glTexImage2D (GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, GLenum format, + GLenum type, const GLvoid *pixels ) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage2D, target, level, internalFormat, + width, height, border, format, type, pixels); +} + + +void +glTexImage2DMultisample (GLenum target, GLsizei samples, + GLint internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage2DMultisample, target, samples, + internalformat, width, height, fixedsamplelocations); +} + +void +glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, + GLsizei colorSamples, GLint internalFormat, + GLsizei width, GLsizei height, + GLboolean fixedSampleLocations) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage2DMultisampleCoverageNV, target, + coverageSamples, colorSamples, internalFormat, + width, height, fixedSampleLocations); +} + +void +glTexImage3D (GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage3D, target, level, internalformat, + width, height, depth, border, format, type, pixels); +} + +void +glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage3DEXT, target, level, internalformat, + width, height, depth, border, format, type, pixels); +} + +void +glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage3DMultisample, target, samples, + internalformat, width, height, depth, + fixedsamplelocations); +} + +void +glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, + GLsizei colorSamples, GLint internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLboolean fixedSampleLocations) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage3DMultisampleCoverageNV, target, + coverageSamples, colorSamples, internalFormat, + width, height, depth, fixedSampleLocations); +} + +void +glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLsizei size4d, GLint border, GLenum format, + GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexImage4DSGIS, target, level, + internalformat, width, height, depth, + size4d, border, format, type, pixels); +} + +void +glTexSubImage1D (GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage1D, target, level, xoffset, + width, format, type, pixels); +} + +void +glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage1DEXT, target, level, xoffset, + width, format, type, pixels); +} + +void +glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage2D, target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + +void +glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage2DEXT, target, level, xoffset, yoffset, + width, height, format, type, pixels); +} + +void +glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage3D, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, pixels); +} + +void +glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage3DEXT, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, pixels); +} + +void +glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLint woffset, GLsizei width, + GLsizei height, GLsizei depth, GLsizei size4d, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glTexSubImage4DSGIS, target, level, xoffset, + yoffset, zoffset, woffset, width, height, + depth, size4d, format, type, pixels); +} + +void +glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexImage1DEXT, texunit, target, + level, internalformat, width, border, imageSize, bits); +} + +void +glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexImage2DEXT, texunit, target, level, + internalformat, width, height, border, imageSize, bits); +} + +void +glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexImage3DEXT, texunit, target, + level, internalformat, width, height, depth, + border, imageSize, bits); +} + +void +glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexSubImage1DEXT, texunit, target, + level, xoffset, width, format, imageSize, bits); +} + +void +glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexSubImage2DEXT, texunit, target, level, + xoffset, yoffset, width, height, format, imageSize, bits); +} + +void +glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedMultiTexSubImage3DEXT, texunit, target, + level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, bits); +} + +void +glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLint border, GLsizei imageSize, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage1D, target, level, + internalformat, width, border, imageSize, data); +} + +void +glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLint border, GLsizei imageSize, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage1DARB, target, level, internalformat, + width, border, imageSize, data); +} + +void +glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage2D, target, level, internalformat, + width, height, border, imageSize, data); +} + +void +glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage2DARB, target, level, internalformat, + width, height, border, imageSize, data); +} + +void +glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage3D, target, level, internalformat, + width, height, depth, border, imageSize, data); +} + +void +glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexImage3DARB, target, level, internalformat, + width, height, depth, border, imageSize, data); +} + +void +glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage1D, target, level, xoffset, + width, format, imageSize, data); +} + +void +glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage1DARB, target, level, xoffset, + width, format, imageSize, data); +} + +void +glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage2D, target, level, xoffset, + yoffset, width, height, format, imageSize, data); +} + +void +glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage2DARB, target, level, xoffset, + yoffset, width, height, format, imageSize, data); +} + +void +glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage3D, target, level, xoffset, + yoffset, zoffset, width, height, depth, format, + imageSize, data); +} + +void +glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTexSubImage3DARB, target, level, xoffset, + yoffset, zoffset, width, height, depth, format, + imageSize, data); +} + +void +glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureImage1DEXT, texture, target, level, + internalformat, width, border, imageSize, bits); +} + +void +glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureImage2DEXT, texture, target, level, + internalformat, width, height, border, imageSize, bits); +} + +void +glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureImage3DEXT, texture, target, + level, internalformat, width, height, depth, + border, imageSize, bits); +} + +void +glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureSubImage1DEXT, texture, target, + level, xoffset, width, format, imageSize, bits); +} + +void +glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureSubImage2DEXT, texture, target, level, + xoffset, yoffset, width, height, format, imageSize, bits); +} + +void +glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const GLvoid *bits) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glCompressedTextureSubImage3DEXT, texture, target, + level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, bits); +} + +void +glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexImage1DEXT, texunit, target, level, + internalformat, width, border, format, type, pixels); +} + +void +glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexImage2DEXT, texunit, target, level, + internalformat, width, height, border, format, + type, pixels); +} + +void +glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, + GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexImage3DEXT, texunit, target, level, + internalformat, width, height, depth, border, + format, type, pixels); +} + +void +glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexSubImage1DEXT, texunit, target, level, + xoffset, width, format, type, pixels); +} + +void +glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexSubImage2DEXT, texunit, target, level, xoffset, + yoffset, width, height, format, type, pixels); +} + +void +glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + + GLWRAP_DEFER (glMultiTexSubImage3DEXT, texunit, target, level, + xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); } diff --git a/glxwrap.c b/glxwrap.c index a57c557..eda3583 100644 --- a/glxwrap.c +++ b/glxwrap.c @@ -88,6 +88,7 @@ glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx) GLWRAP_DEFER_WITH_RETURN (ret, glXMakeCurrent, dpy, drawable, ctx); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); return ret; @@ -102,6 +103,7 @@ glXMakeContextCurrent (Display *dpy, GLXDrawable drawable, GLXDrawable read, GLX GLWRAP_DEFER_WITH_RETURN (ret, glXMakeContextCurrent, dpy, drawable, read, ctx); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); return ret; diff --git a/metrics.c b/metrics.c index 39c90ad..327c270 100644 --- a/metrics.c +++ b/metrics.c @@ -33,28 +33,29 @@ 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; + metrics_op_t op; double time_ns; -} program_metrics_t; +} 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,6 +66,51 @@ context_t current_context; int frames; int verbose; +static const char * +metrics_op_string (metrics_op_t op) +{ + 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) { @@ -78,7 +124,7 @@ metrics_counter_start (void) glGenQueries (1, &counter->id); - counter->program = current_context.program; + counter->op = current_context.op; counter->next = NULL; if (current_context.counter_tail) { @@ -99,29 +145,29 @@ metrics_counter_stop (void) } void -metrics_set_current_program (unsigned program) +metrics_set_current_op (metrics_op_t op) { - current_context.program = program; + current_context.op = op; } static void -accumulate_program_time (unsigned program_id, unsigned time_ns) +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].time_ns = 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].time_ns += time_ns; + ctx->op_metrics[op].time_ns += time_ns; } static int @@ -129,7 +175,7 @@ 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].time_ns < metrics[b].time_ns) return -1; @@ -142,24 +188,24 @@ 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].time_ns; + 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. @@ -167,8 +213,18 @@ print_program_metrics (void) if (metric->time_ns == 0.0) continue; - printf ("Program %d:\t%7.2f ms (% 2.1f%%)\n", - metric->id, metric->time_ns / 1e6, + 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); } } @@ -215,7 +271,7 @@ metrics_end_frame (void) glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed); - accumulate_program_time (counter->program, elapsed); + accumulate_program_time (counter->op, elapsed); current_context.counter_head = counter->next; if (current_context.counter_head == NULL) diff --git a/metrics.h b/metrics.h index 8b68867..b5f9859 100644 --- a/metrics.h +++ b/metrics.h @@ -22,6 +22,34 @@ #ifndef METRICS_H #define METRICS_H +typedef enum +{ + METRICS_OP_ACCUM, + METRICS_OP_BUFFER_DATA, + METRICS_OP_BUFFER_SUB_DATA, + METRICS_OP_BITMAP, + METRICS_OP_BLIT_FRAMEBUFFER, + METRICS_OP_CLEAR, + METRICS_OP_CLEAR_BUFFER_DATA, + METRICS_OP_CLEAR_TEX_IMAGE, + METRICS_OP_COPY_PIXELS, + METRICS_OP_COPY_TEX_IMAGE, + METRICS_OP_DRAW_PIXELS, + METRICS_OP_GET_TEX_IMAGE, + METRICS_OP_READ_PIXELS, + METRICS_OP_TEX_IMAGE, + + /* METRICS_OP_SHADER must be last. + * + * All larger values for metrics_op_t are interpreted as: + * + * METRICS_OP_SHADER + shader_program_number + * + * to indicate a specific shader program. + */ + METRICS_OP_SHADER +} metrics_op_t; + /* Start accumulating GPU time. * * The time accumulated will be accounted against the @@ -34,14 +62,20 @@ metrics_counter_start (void); void metrics_counter_stop (void); -/* Set the ID of the currently executing shader program. +/* Set a metrics_op_t value to indicate what kind of operation is + * being performed. + * + * The metrics-tracking code will account for timings by accumulating + * measured counter values into a separate counter for each + * metrics_op_t value, (so that the report can describe which + * operations are the most expensive). * - * The metrics-tracking code will account for per-shader-program - * timings by accumulating counter values measured while each porogram - * is active (see metrics_add_counter). + * In addition, for the value METRICS_OP_SHADER, each specific shader + * program can be distinguished. To accomplish this, pass a value of + * METRICS_OP_SHADER + shader_program_number to this function. */ void -metrics_set_current_program (unsigned program); +metrics_set_current_op (metrics_op_t op); /* Should be called at the end of every function wrapper for a * function that ends a frame, (glXSwapBuffers and similar). -- 2.43.0 From 7980e4108be1dff9b074aa91b97c8d787df41d83 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 16 Oct 2013 13:03:15 -0700 Subject: [PATCH 05/16] Restore metrics op after temporarily changing for non-shader operation This fixes the bug where an operation such as glClear would incorrectly accrue all subsequent time until the next call to glUseProgram would change the op away from glClear. Now, each non-shader operation that changes the metrics operation restores it to its previous value immediately afterward. --- glwrap.c | 454 +++++++++++++++++++++++++++++++++++++++++------------- metrics.c | 6 + metrics.h | 6 + 3 files changed, 355 insertions(+), 111 deletions(-) diff --git a/glwrap.c b/glwrap.c index 80c5e36..94966f5 100644 --- a/glwrap.c +++ b/glwrap.c @@ -49,11 +49,21 @@ static void *gl_handle; +/* Switch metrics operation persistently, (until next SWITCH) */ #define SWITCH_METRICS_OP(op) \ metrics_counter_stop (); \ metrics_set_current_op (op); \ metrics_counter_start (); +/* Switch metrics operation temporarily, see RESTORE_METRICS_OP */ +#define SAVE_THEN_SWITCH_METRICS_OP(op) \ + metrics_op_t save = metrics_get_current_op (); \ + SWITCH_METRICS_OP (op); + +/* Switch back to metrics operation saved by SAVE_THEN_SWITCH_METRICS_OP */ +#define RESTORE_METRICS_OP(op) \ + SWITCH_METRICS_OP (save); + void glwrap_set_gl_handle (void *handle) { @@ -133,61 +143,75 @@ glUseProgramObjectARB (GLhandleARB programObj) void glAccum (GLenum op, GLfloat value) { - SWITCH_METRICS_OP (METRICS_OP_ACCUM); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_ACCUM); GLWRAP_DEFER (glAccum, op, value); + + RESTORE_METRICS_OP (); } void glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - SWITCH_METRICS_OP (METRICS_OP_ACCUM); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_ACCUM); GLWRAP_DEFER (glClearAccum, red, green, blue, alpha); + + RESTORE_METRICS_OP (); } void glClearAccumxOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) { - SWITCH_METRICS_OP (METRICS_OP_ACCUM); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_ACCUM); GLWRAP_DEFER (glClearAccumxOES, red, green, blue, alpha); + + RESTORE_METRICS_OP (); } /* METRICS_OP_BUFFER_DATA */ void glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glBufferData, target, size, data, usage); + + RESTORE_METRICS_OP (); } void glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glNamedBufferDataEXT, buffer, size, data, usage); + + RESTORE_METRICS_OP (); } void glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glBufferSubData, target, offset, size, data); + + RESTORE_METRICS_OP (); } void glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glNamedBufferSubDataEXT, buffer, offset, size, data); + + RESTORE_METRICS_OP (); } void * @@ -195,10 +219,12 @@ glMapBuffer (GLenum target, GLenum access) { void *ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glMapBuffer, target, access); + RESTORE_METRICS_OP (); + return ret; } @@ -207,10 +233,12 @@ glMapBufferARB (GLenum target, GLenum access) { void *ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glMapBufferARB, target, access); + RESTORE_METRICS_OP (); + return ret; } @@ -220,11 +248,13 @@ glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, { void *ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glMapBufferRange, target, offset, length, access); + RESTORE_METRICS_OP (); + return ret; } @@ -233,10 +263,12 @@ glUnmapBuffer (GLenum target) { GLboolean ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glUnmapBuffer, target); + RESTORE_METRICS_OP (); + return ret; } @@ -245,10 +277,12 @@ glUnmapNamedBufferEXT (GLuint buffer) { GLboolean ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glUnmapNamedBufferEXT, buffer); + RESTORE_METRICS_OP (); + return ret; } @@ -257,36 +291,44 @@ glUnmapBufferARB (GLenum target) { GLboolean ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glUnmapBufferARB, target); + RESTORE_METRICS_OP (); + return ret; } void glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glFlushMappedBufferRange, target, offset, length); + + RESTORE_METRICS_OP (); } void glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glFlushMappedBufferRangeAPPLE, target, offset, size); + + RESTORE_METRICS_OP (); } void glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER (glFlushMappedNamedBufferRangeEXT, buffer, offset, length); + + RESTORE_METRICS_OP (); } void * @@ -294,10 +336,12 @@ glMapNamedBufferEXT (GLuint buffer, GLenum access) { void *ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glMapNamedBufferEXT, buffer, access); + RESTORE_METRICS_OP (); + return ret; } @@ -307,11 +351,13 @@ glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, { void *ret; - SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_DATA); GLWRAP_DEFER_WITH_RETURN (ret, glMapNamedBufferRangeEXT, buffer, offset, length, access); + RESTORE_METRICS_OP (); + return ret; } @@ -321,10 +367,12 @@ glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); GLWRAP_DEFER (glCopyBufferSubData, readTarget, writeTarget, readOffset, writeOffset, size); + + RESTORE_METRICS_OP (); } void @@ -332,10 +380,12 @@ glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { - SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BUFFER_SUB_DATA); GLWRAP_DEFER (glNamedCopyBufferSubDataEXT, readBuffer, writeBuffer, readOffset, writeOffset, size); + + RESTORE_METRICS_OP (); } /* METRICS_OP_BITMAP */ @@ -343,20 +393,24 @@ void glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { - SWITCH_METRICS_OP (METRICS_OP_BITMAP); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BITMAP); GLWRAP_DEFER (glBitmap, width, height, xorig, yorig, xmove, ymove, bitmap); + + RESTORE_METRICS_OP (); } void glBitmapxOES (GLsizei width, GLsizei height, GLfixed xorig, GLfixed yorig, GLfixed xmove, GLfixed ymove, const GLubyte *bitmap) { - SWITCH_METRICS_OP (METRICS_OP_BITMAP); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BITMAP); GLWRAP_DEFER (glBitmapxOES, width, height, xorig, yorig, xmove, ymove, bitmap); + + RESTORE_METRICS_OP (); } /* METRICS_OP_BLIT_FRAMEBUFFER */ @@ -365,10 +419,12 @@ glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); GLWRAP_DEFER (glBlitFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + RESTORE_METRICS_OP (); } void @@ -376,51 +432,63 @@ glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_BLIT_FRAMEBUFFER); GLWRAP_DEFER (glBlitFramebufferEXT, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + RESTORE_METRICS_OP (); } /* METRICS_OP_CLEAR */ void glClear (GLbitfield mask) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR); GLWRAP_DEFER (glClear, mask); + + RESTORE_METRICS_OP (); } void glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR); GLWRAP_DEFER (glClearBufferfi, buffer, drawbuffer, depth, stencil); + + RESTORE_METRICS_OP (); } void glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR); GLWRAP_DEFER (glClearBufferfv, buffer, drawbuffer, value); + + RESTORE_METRICS_OP (); } void glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR); GLWRAP_DEFER (glClearBufferiv, buffer, drawbuffer, value); + + RESTORE_METRICS_OP (); } void glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR); GLWRAP_DEFER (glClearBufferuiv, buffer, drawbuffer, value); + + RESTORE_METRICS_OP (); } /* METRICS_OP_CLEAR_BUFFER_DATA */ @@ -429,10 +497,12 @@ void glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); GLWRAP_DEFER (glClearBufferData, target, internalformat, format, type, data); + + RESTORE_METRICS_OP (); } void @@ -440,20 +510,24 @@ glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); GLWRAP_DEFER (glClearBufferSubData, target, internalformat, offset, size, format, type, data); + + RESTORE_METRICS_OP (); } void glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); GLWRAP_DEFER (glClearNamedBufferDataEXT, buffer, internalformat, format, type, data); + + RESTORE_METRICS_OP (); } void @@ -461,10 +535,12 @@ glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data) { - SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_CLEAR_BUFFER_DATA); GLWRAP_DEFER (glClearNamedBufferSubDataEXT, buffer, internalformat, format, type, offset, size, data); + + RESTORE_METRICS_OP (); } /* METRICS_OP_CLEAR_TEX_IMAGE */ @@ -474,9 +550,11 @@ glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, void glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ) { - SWITCH_METRICS_OP (METRICS_OP_COPY_PIXELS); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_PIXELS); GLWRAP_DEFER (glCopyPixels, x, y, width, height, type); + + RESTORE_METRICS_OP (); } /* METRICS_OP_COPY_TEX_IMAGE */ @@ -484,20 +562,24 @@ void glCopyTexImage1D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexImage1D, target, level, internalformat, x, y, width, border); + + RESTORE_METRICS_OP (); } void glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexImage1DEXT, target, level, internalformat, x, y, width, border); + + RESTORE_METRICS_OP (); } void @@ -505,10 +587,12 @@ glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexImage2D, target, level, internalformat, x, y, width, height, border); + + RESTORE_METRICS_OP (); } void @@ -516,30 +600,36 @@ glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexImage2DEXT, target, level, internalformat, x, y, width, height, border); + + RESTORE_METRICS_OP (); } void glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage1D, target, level, xoffset, x, y, width); + + RESTORE_METRICS_OP (); } void glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage1DEXT, target, level, xoffset, x, y, width); + + RESTORE_METRICS_OP (); } void @@ -547,10 +637,12 @@ glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -558,10 +650,12 @@ glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage2DEXT, target, level, xoffset, yoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -569,10 +663,12 @@ glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage3D, target, level, xoffset, yoffset, zoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -580,10 +676,12 @@ glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTexSubImage3DEXT, target, level, xoffset, yoffset, zoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -591,10 +689,12 @@ glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTextureImage1DEXT, texture, target, level, internalformat, x, y, width, border); + + RESTORE_METRICS_OP (); } void @@ -602,20 +702,24 @@ glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTextureImage2DEXT, texture, target, level, internalformat, x, y, width, height, border); + + RESTORE_METRICS_OP (); } void glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTextureSubImage1DEXT, texture, target, level, xoffset, x, y, width); + + RESTORE_METRICS_OP (); } void @@ -623,10 +727,12 @@ glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTextureSubImage2DEXT, texture, target, level, xoffset, yoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -634,10 +740,12 @@ glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyTextureSubImage3DEXT, texture, target, level, xoffset, yoffset, zoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -645,10 +753,12 @@ glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyMultiTexImage1DEXT, texunit, target, level, internalformat, x, y, width, border); + + RESTORE_METRICS_OP (); } void @@ -656,20 +766,24 @@ glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyMultiTexImage2DEXT, texunit, target, level, internalformat, x, y, width, height, border); + + RESTORE_METRICS_OP (); } void glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyMultiTexSubImage1DEXT, texunit, target, level, xoffset, x, y, width); + + RESTORE_METRICS_OP (); } void @@ -677,10 +791,12 @@ glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyMultiTexSubImage2DEXT, texunit, target, level, xoffset, yoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } void @@ -688,10 +804,12 @@ glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_COPY_TEX_IMAGE); GLWRAP_DEFER (glCopyMultiTexSubImage3DEXT, texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height); + + RESTORE_METRICS_OP (); } /* METRICS_OP_DRAW_PIXELS */ @@ -699,9 +817,11 @@ void glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_DRAW_PIXELS); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_DRAW_PIXELS); GLWRAP_DEFER (glDrawPixels, width, height, format, type, pixels); + + RESTORE_METRICS_OP (); } /* METRICS_OP_GET_TEX_IMAGE */ @@ -710,74 +830,90 @@ void glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetCompressedMultiTexImageEXT, texunit, target, lod, img); + + RESTORE_METRICS_OP (); } void glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetCompressedTexImage, target, level, img); + + RESTORE_METRICS_OP (); } void glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetCompressedTexImageARB, target, level, img); + + RESTORE_METRICS_OP (); } void glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetCompressedTextureImageEXT, texture, target, lod, img); + + RESTORE_METRICS_OP (); } void glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetMultiTexImageEXT, texunit, target, level, format, type, pixels); + + RESTORE_METRICS_OP (); } void glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetnCompressedTexImageARB, target, lod, bufSize, img); + + RESTORE_METRICS_OP (); } void glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetnTexImageARB, target, level, format, type, bufSize, img); + + RESTORE_METRICS_OP (); } void glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ) { - SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_GET_TEX_IMAGE); GLWRAP_DEFER (glGetTexImage, target, level, format, type, pixels); + + RESTORE_METRICS_OP (); } /* METRICS_OP_READ_PIXELS */ @@ -785,19 +921,23 @@ void glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) { - SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); GLWRAP_DEFER (glReadPixels, x, y, width, height, format, type, pixels); + + RESTORE_METRICS_OP (); } void glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_READ_PIXELS); GLWRAP_DEFER (glReadnPixelsARB, x, y, width, height, format, type, bufSize, data); + + RESTORE_METRICS_OP (); } /* METRICS_OP_TEX_IMAGE */ @@ -806,10 +946,12 @@ glTexImage1D (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage1D, target, level, internalFormat, width, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -817,10 +959,12 @@ glTexImage2D (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage2D, target, level, internalFormat, width, height, border, format, type, pixels); + + RESTORE_METRICS_OP (); } @@ -829,10 +973,12 @@ glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage2DMultisample, target, samples, internalformat, width, height, fixedsamplelocations); + + RESTORE_METRICS_OP (); } void @@ -841,11 +987,13 @@ glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage2DMultisampleCoverageNV, target, coverageSamples, colorSamples, internalFormat, width, height, fixedSampleLocations); + + RESTORE_METRICS_OP (); } void @@ -853,10 +1001,12 @@ glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage3D, target, level, internalformat, width, height, depth, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -864,10 +1014,12 @@ glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage3DEXT, target, level, internalformat, width, height, depth, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -875,11 +1027,13 @@ glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage3DMultisample, target, samples, internalformat, width, height, depth, fixedsamplelocations); + + RESTORE_METRICS_OP (); } void @@ -888,11 +1042,13 @@ glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage3DMultisampleCoverageNV, target, coverageSamples, colorSamples, internalFormat, width, height, depth, fixedSampleLocations); + + RESTORE_METRICS_OP (); } void @@ -901,11 +1057,13 @@ glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexImage4DSGIS, target, level, internalformat, width, height, depth, size4d, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -913,10 +1071,12 @@ glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage1D, target, level, xoffset, width, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -924,10 +1084,12 @@ glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage1DEXT, target, level, xoffset, width, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -935,10 +1097,12 @@ glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -946,10 +1110,12 @@ glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage2DEXT, target, level, xoffset, yoffset, width, height, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -957,10 +1123,12 @@ glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage3D, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -968,10 +1136,12 @@ glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage3DEXT, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -980,11 +1150,13 @@ glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glTexSubImage4DSGIS, target, level, xoffset, yoffset, zoffset, woffset, width, height, depth, size4d, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -993,10 +1165,12 @@ glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexImage1DEXT, texunit, target, level, internalformat, width, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1005,10 +1179,12 @@ glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexImage2DEXT, texunit, target, level, internalformat, width, height, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1017,11 +1193,13 @@ glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexImage3DEXT, texunit, target, level, internalformat, width, height, depth, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1029,10 +1207,12 @@ glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexSubImage1DEXT, texunit, target, level, xoffset, width, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1041,10 +1221,12 @@ glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexSubImage2DEXT, texunit, target, level, xoffset, yoffset, width, height, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1054,11 +1236,13 @@ glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedMultiTexSubImage3DEXT, texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1066,10 +1250,12 @@ glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage1D, target, level, internalformat, width, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1077,10 +1263,12 @@ glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage1DARB, target, level, internalformat, width, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1088,10 +1276,12 @@ glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1099,10 +1289,12 @@ glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage2DARB, target, level, internalformat, width, height, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1110,10 +1302,12 @@ glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage3D, target, level, internalformat, width, height, depth, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1121,10 +1315,12 @@ glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexImage3DARB, target, level, internalformat, width, height, depth, border, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1132,10 +1328,12 @@ glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage1D, target, level, xoffset, width, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1143,10 +1341,12 @@ glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage1DARB, target, level, xoffset, width, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1154,10 +1354,12 @@ glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1166,10 +1368,12 @@ glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage2DARB, target, level, xoffset, yoffset, width, height, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1178,11 +1382,13 @@ glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage3D, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1191,11 +1397,13 @@ glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTexSubImage3DARB, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + + RESTORE_METRICS_OP (); } void @@ -1204,10 +1412,12 @@ glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureImage1DEXT, texture, target, level, internalformat, width, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1216,10 +1426,12 @@ glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureImage2DEXT, texture, target, level, internalformat, width, height, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1228,11 +1440,13 @@ glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureImage3DEXT, texture, target, level, internalformat, width, height, depth, border, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1240,10 +1454,12 @@ glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureSubImage1DEXT, texture, target, level, xoffset, width, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1252,10 +1468,12 @@ glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureSubImage2DEXT, texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1265,11 +1483,13 @@ glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLsizei imageSize, const GLvoid *bits) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glCompressedTextureSubImage3DEXT, texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits); + + RESTORE_METRICS_OP (); } void @@ -1277,10 +1497,12 @@ glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexImage1DEXT, texunit, target, level, internalformat, width, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -1289,11 +1511,13 @@ glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexImage2DEXT, texunit, target, level, internalformat, width, height, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -1302,11 +1526,13 @@ glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexImage3DEXT, texunit, target, level, internalformat, width, height, depth, border, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -1314,10 +1540,12 @@ glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexSubImage1DEXT, texunit, target, level, xoffset, width, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -1326,10 +1554,12 @@ glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexSubImage2DEXT, texunit, target, level, xoffset, yoffset, width, height, format, type, pixels); + + RESTORE_METRICS_OP (); } void @@ -1338,9 +1568,11 @@ glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { - SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); + SAVE_THEN_SWITCH_METRICS_OP (METRICS_OP_TEX_IMAGE); GLWRAP_DEFER (glMultiTexSubImage3DEXT, texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + RESTORE_METRICS_OP (); } diff --git a/metrics.c b/metrics.c index 327c270..77d7321 100644 --- a/metrics.c +++ b/metrics.c @@ -150,6 +150,12 @@ metrics_set_current_op (metrics_op_t op) current_context.op = op; } +metrics_op_t +metrics_get_current_op (void) +{ + return current_context.op; +} + static void accumulate_program_time (metrics_op_t op, unsigned time_ns) { diff --git a/metrics.h b/metrics.h index b5f9859..45fef33 100644 --- a/metrics.h +++ b/metrics.h @@ -77,6 +77,12 @@ metrics_counter_stop (void); void metrics_set_current_op (metrics_op_t op); +/* Return the current metrics_op_t value, (the value most-recently-set + * with a call to metrics_set_current_op). + */ +metrics_op_t +metrics_get_current_op (void); + /* Should be called at the end of every function wrapper for a * function that ends a frame, (glXSwapBuffers and similar). * -- 2.43.0 From da0ee5e7efab316635f59d212028844f848fa6ce Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 10:26:22 -0700 Subject: [PATCH 06/16] Add xmalloc function To simplify the code by abstracting away repeated checks for malloc failure and exit. --- Makefile.local | 6 ++++-- execute.c | 7 ++----- metrics.c | 7 ++----- xmalloc.c | 39 +++++++++++++++++++++++++++++++++++++++ xmalloc.h | 28 ++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 xmalloc.c create mode 100644 xmalloc.h diff --git a/Makefile.local b/Makefile.local index 8d2475b..4ace9aa 100644 --- a/Makefile.local +++ b/Makefile.local @@ -76,7 +76,8 @@ distclean: clean fips_srcs = \ execute.c \ - fips.c + fips.c \ + xmalloc.c fips_modules = $(fips_srcs:.c=.o) @@ -94,7 +95,8 @@ libfips_srcs = \ fips-dispatch-gl.c \ glwrap.c \ glxwrap.c \ - metrics.c + metrics.c \ + xmalloc.c ifeq ($(HAVE_EGL),Yes) libfips_srcs += eglwrap.c diff --git a/execute.c b/execute.c index cc01c43..07fd30f 100644 --- a/execute.c +++ b/execute.c @@ -36,6 +36,7 @@ #include #include "execute.h" +#include "xmalloc.h" /* Terminate a string representing a filename at the final '/' to * eliminate the final filename component, (leaving only the directory @@ -294,11 +295,7 @@ execute_with_fips_preload (int argc, char * const argv[]) char **execvp_args; int i; - execvp_args = malloc((argc + 1) * sizeof(char *)); - if (execvp_args == NULL) { - fprintf (stderr, "Out of memory,\n"); - return 1; - } + execvp_args = xmalloc((argc + 1) * sizeof(char *)); for (i = 0; i < argc; i++) { execvp_args[i] = argv[i]; diff --git a/metrics.c b/metrics.c index 77d7321..09083e6 100644 --- a/metrics.c +++ b/metrics.c @@ -29,6 +29,7 @@ #include "fips-dispatch-gl.h" #include "metrics.h" +#include "xmalloc.h" typedef struct counter { @@ -116,11 +117,7 @@ metrics_counter_start (void) { counter_t *counter; - counter = malloc (sizeof(counter_t)); - if (counter == NULL) { - fprintf (stderr, "Out of memory\n"); - exit (1); - } + counter = xmalloc (sizeof(counter_t)); glGenQueries (1, &counter->id); diff --git a/xmalloc.c b/xmalloc.c new file mode 100644 index 0000000..22eb7cf --- /dev/null +++ b/xmalloc.c @@ -0,0 +1,39 @@ +/* Copyright © 2013, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "xmalloc.h" + +void * +xmalloc (size_t size) +{ + void *ret; + + ret = malloc (size); + if (ret == NULL) { + fprintf (stderr, "Out of memory\n"); + exit (1); + } + + return ret; +} diff --git a/xmalloc.h b/xmalloc.h new file mode 100644 index 0000000..b36c900 --- /dev/null +++ b/xmalloc.h @@ -0,0 +1,28 @@ +/* Copyright © 2013, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef XMALLOC_H +#define XMALLOC_H + +void * +xmalloc (size_t size); + +#endif -- 2.43.0 From 01c9b8f64fa861a8102fd82ecd7c714e82420180 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 10:41:16 -0700 Subject: [PATCH 07/16] fips-dispatch: Simplify dispatch code by abstracting resolve functions All of the resolve functions were structured identically, so rather than repating the function bodies over and over, we can use a simple "resolve" macro to implement this code. This gives a net reduction in source code for better readability and maintainability. --- fips-dispatch-gl.c | 84 ++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 62 deletions(-) diff --git a/fips-dispatch-gl.c b/fips-dispatch-gl.c index cd9e35e..8b02b6a 100644 --- a/fips-dispatch-gl.c +++ b/fips-dispatch-gl.c @@ -41,109 +41,69 @@ unsupported (const char *name) exit (1); } -static void -resolve_glGenQueries (void) -{ - fips_dispatch_glGenQueries = fips_dispatch_lookup ("glGenQueries"); - - if (! fips_dispatch_glGenQueries) - fips_dispatch_glGenQueries = fips_dispatch_lookup ("glGenQueriesARB"); - - if (! fips_dispatch_glGenQueries) - unsupported ("GenQueries"); -} +#define resolve(dispatch, name) \ + dispatch = fips_dispatch_lookup (name); \ + if (! dispatch) \ + unsupported (name); + +#define resolve2(dispatch, name_a, name_b) \ + dispatch = fips_dispatch_lookup (name_a); \ + if (! dispatch) \ + dispatch = fips_dispatch_lookup (name_b); \ + if (! dispatch) \ + unsupported (name_a); static void stub_glGenQueries (GLsizei n, GLuint *ids) { check_initialized (); - resolve_glGenQueries (); + resolve2 (fips_dispatch_glGenQueries, + "glGenQueries", "glGenQueriesARB") fips_dispatch_glGenQueries (n, ids); } PFNGLGENQUERIESPROC fips_dispatch_glGenQueries = stub_glGenQueries; -static void -resolve_glDeleteQueries (void) -{ - fips_dispatch_glDeleteQueries = fips_dispatch_lookup ("glDeleteQueries"); - - if (! fips_dispatch_glDeleteQueries) - fips_dispatch_glDeleteQueries = fips_dispatch_lookup ("glDeleteQueriesARB"); - - if (! fips_dispatch_glDeleteQueries) - unsupported ("DeleteQueries"); -} - static void stub_glDeleteQueries (GLsizei n, const GLuint * ids) { check_initialized (); - resolve_glDeleteQueries (); + resolve2 (fips_dispatch_glDeleteQueries, + "glDeleteQueries", "glDeleteQueriesARB"); fips_dispatch_glDeleteQueries (n, ids); } PFNGLDELETEQUERIESPROC fips_dispatch_glDeleteQueries = stub_glDeleteQueries; -static void -resolve_glBeginQuery (void) -{ - fips_dispatch_glBeginQuery = fips_dispatch_lookup ("glBeginQuery"); - - if (! fips_dispatch_glBeginQuery) - fips_dispatch_glBeginQuery = fips_dispatch_lookup ("glBeginQueryARB"); - - if (! fips_dispatch_glBeginQuery) - unsupported ("BeginQuery"); -} - static void stub_glBeginQuery (GLenum target, GLuint id) { check_initialized (); - resolve_glBeginQuery (); + resolve2 (fips_dispatch_glBeginQuery, + "glBeginQuery", "glBeginQueryARB"); fips_dispatch_glBeginQuery (target, id); } PFNGLBEGINQUERYPROC fips_dispatch_glBeginQuery = stub_glBeginQuery; -static void -resolve_glEndQuery (void) -{ - fips_dispatch_glEndQuery = fips_dispatch_lookup ("glEndQuery"); - - if (! fips_dispatch_glEndQuery) - fips_dispatch_glEndQuery = fips_dispatch_lookup ("glEndQueryARB"); - - if (! fips_dispatch_glEndQuery) - unsupported ("EndQuery"); -} - static void stub_glEndQuery (GLenum target) { check_initialized (); - resolve_glEndQuery (); + resolve2 (fips_dispatch_glEndQuery, "glEndQuery", "glEndQueryARB"); fips_dispatch_glEndQuery (target); } PFNGLENDQUERYPROC fips_dispatch_glEndQuery = stub_glEndQuery; -static void -resolve_glGetQueryObjectuiv (void) -{ - fips_dispatch_glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) fips_dispatch_lookup ("glGetQueryObjectuivARB"); - - if (! fips_dispatch_glGetQueryObjectuiv) - unsupported ("GetQueryObjectuiv"); -} - static void stub_glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint * params) { check_initialized (); - resolve_glGetQueryObjectuiv (); + resolve2 (fips_dispatch_glGetQueryObjectuiv, + "glGetQueryObjectuiv", "glGetQueryObjectuivARB"); fips_dispatch_glGetQueryObjectuiv (id, pname, params); } -PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv = stub_glGetQueryObjectuiv; +PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv = + stub_glGetQueryObjectuiv; -- 2.43.0 From 917ee542ec53e422b189023c681478780761af81 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 10:46:04 -0700 Subject: [PATCH 08/16] fips-dispatch: Add support for AMD_performance_monitor extension Soon, fips will be using this extension internally, so the dispatch layer needs this support to be able to resolve these functions appropriately. --- fips-dispatch-gl.c | 150 +++++++++++++++++++++++++++++++++++++++++++++ fips-dispatch-gl.h | 74 ++++++++++++++++++++++ 2 files changed, 224 insertions(+) diff --git a/fips-dispatch-gl.c b/fips-dispatch-gl.c index 8b02b6a..192b2bc 100644 --- a/fips-dispatch-gl.c +++ b/fips-dispatch-gl.c @@ -107,3 +107,153 @@ stub_glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint * params) PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv = stub_glGetQueryObjectuiv; + +static void +stub_glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, + GLuint *groups) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorGroupsAMD, + "glGetPerfMonitorGroupsAMD"); + fips_dispatch_glGetPerfMonitorGroupsAMD (numGroups, groupsSize, groups); +} + +PFNGLGETPERFMONITORGROUPSAMDPROC fips_dispatch_glGetPerfMonitorGroupsAMD = + stub_glGetPerfMonitorGroupsAMD; + +static void +stub_glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, + GLint *maxActiveCounters, + GLsizei counterSize, GLuint *counters) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorCountersAMD, + "glGetPerfMonitorCountersAMD"); + fips_dispatch_glGetPerfMonitorCountersAMD (group, numCounters, + maxActiveCounters, + counterSize, counters); +} + +PFNGLGETPERFMONITORCOUNTERSAMDPROC fips_dispatch_glGetPerfMonitorCountersAMD = + stub_glGetPerfMonitorCountersAMD; + +static void +stub_glGetPerfMonitorGroupsStringAMD (GLuint group, GLsizei bufSize, + GLsizei *length, GLchar *groupString) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorGroupsStringAMD, + "glGetPerfMonitorGroupsStringAMD"); + fips_dispatch_glGetPerfMonitorGroupsStringAMD (group, bufSize, length, + groupString); +} + +PFNGLGETPERFMONITORGROUPSTRINGAMDPROC +fips_dispatch_glGetPerfMonitorGroupsStringAMD = + stub_glGetPerfMonitorGroupsStringAMD; + +static void +stub_glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, + GLsizei bufSize, GLsizei *length, + GLchar *counterString) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorCounterStringAMD, + "glGetPerfMonitorCounterStringAMD"); + fips_dispatch_glGetPerfMonitorCounterStringAMD (group, counter, + bufSize, length, + counterString); +} + +PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC +fips_dispatch_glGetPerfMonitorCounterStringAMD = + stub_glGetPerfMonitorCounterStringAMD; + +static void +stub_glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorCounterInfoAMD, + "glGetPerfMonitorCounterInfoAMD"); + fips_dispatch_glGetPerfMonitorCounterInfoAMD (group, counter, + pname, data); +} + +PFNGLGETPERFMONITORCOUNTERINFOAMDPROC +fips_dispatch_glGetPerfMonitorCounterInfoAMD = + stub_glGetPerfMonitorCounterInfoAMD; + +static void +stub_glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors) +{ + check_initialized (); + resolve (fips_dispatch_glGenPerfMonitorsAMD, "glGenPerfMonitorsAMD"); + fips_dispatch_glGenPerfMonitorsAMD (n, monitors); +} + +PFNGLGENPERFMONITORSAMDPROC fips_dispatch_glGenPerfMonitorsAMD = + stub_glGenPerfMonitorsAMD; + +static void +stub_glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors) +{ + check_initialized (); + resolve (fips_dispatch_glDeletePerfMonitorsAMD, + "glDeletePerfMonitorsAMD"); + fips_dispatch_glDeletePerfMonitorsAMD (n, monitors); +} + +PFNGLDELETEPERFMONITORSAMDPROC fips_dispatch_glDeletePerfMonitorsAMD = + stub_glDeletePerfMonitorsAMD; + +static void +stub_glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, + GLuint group, GLint numCounters, + GLuint *counterList) +{ + check_initialized (); + resolve (fips_dispatch_glSelectPerfMonitorCountersAMD, + "glSelectPerfMonitorCountersAMD"); + fips_dispatch_glSelectPerfMonitorCountersAMD (monitor, enable, group, + numCounters, counterList); +} + +PFNGLSELECTPERFMONITORCOUNTERSAMDPROC +fips_dispatch_glSelectPerfMonitorCountersAMD = + stub_glSelectPerfMonitorCountersAMD; + +static void +stub_glBeginPerfMonitorAMD (GLuint monitor) +{ + check_initialized (); + resolve (fips_dispatch_glBeginPerfMonitorAMD, "glBeginPerfMonitorAMD"); + fips_dispatch_glBeginPerfMonitorAMD (monitor); +} + +PFNGLBEGINPERFMONITORAMDPROC fips_dispatch_glBeginPerfMonitorAMD = + stub_glBeginPerfMonitorAMD; + +static void +stub_glEndPerfMonitorAMD (GLuint monitor) +{ + check_initialized (); + resolve (fips_dispatch_glEndPerfMonitorAMD, "glEndPerfMonitorAMD"); + fips_dispatch_glEndPerfMonitorAMD (monitor); +} + +PFNGLENDPERFMONITORAMDPROC fips_dispatch_glEndPerfMonitorAMD = + stub_glEndPerfMonitorAMD; + +static void +stub_glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) +{ + check_initialized (); + resolve (fips_dispatch_glGetPerfMonitorCounterDataAMD, + "glGetPerfMonitorCounterDataAMD"); + fips_dispatch_glGetPerfMonitorCounterDataAMD (monitor, pname, dataSize, + data, bytesWritten); +} + +PFNGLGETPERFMONITORCOUNTERDATAAMDPROC +fips_dispatch_glGetPerfMonitorCounterDataAMD = + stub_glGetPerfMonitorCounterDataAMD; diff --git a/fips-dispatch-gl.h b/fips-dispatch-gl.h index f70f4b8..eaa23d6 100644 --- a/fips-dispatch-gl.h +++ b/fips-dispatch-gl.h @@ -35,6 +35,21 @@ #include #include +#define GL_FALSE 0 +#define GL_TRUE 1 + +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 +#define GL_DOUBLE 0x140A + typedef unsigned int GLenum; typedef unsigned int GLbitfield; typedef unsigned int GLuint; @@ -69,6 +84,24 @@ typedef void (*PFNGLBEGINQUERYPROC)(GLenum, GLuint); typedef void (*PFNGLENDQUERYPROC)(GLenum); typedef void (*PFNGLGETQUERYOBJECTUIVPROC)(GLuint, GLenum, GLuint *); +typedef void (*PFNGLGETPERFMONITORGROUPSAMDPROC)(GLint *, GLsizei, GLuint *); +typedef void (*PFNGLGETPERFMONITORCOUNTERSAMDPROC)(GLuint, GLint *, GLint *, + GLsizei, GLuint *); +typedef void (*PFNGLGETPERFMONITORGROUPSTRINGAMDPROC)(GLuint, GLsizei, + GLsizei *, GLchar *); +typedef void (*PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC)(GLuint, GLuint, + GLsizei, GLsizei *, GLchar *); +typedef void (*PFNGLGETPERFMONITORCOUNTERINFOAMDPROC)(GLuint, GLuint, + GLenum, GLvoid *); +typedef void (*PFNGLGENPERFMONITORSAMDPROC)(GLsizei, GLuint *); +typedef void (*PFNGLDELETEPERFMONITORSAMDPROC)(GLsizei, GLuint *); +typedef void (*PFNGLSELECTPERFMONITORCOUNTERSAMDPROC)(GLuint, GLboolean, + GLuint, GLint, GLuint *); +typedef void (*PFNGLBEGINPERFMONITORAMDPROC)(GLuint); +typedef void (*PFNGLENDPERFMONITORAMDPROC)(GLuint); +typedef void (*PFNGLGETPERFMONITORCOUNTERDATAAMDPROC)(GLuint, GLenum, + GLsizei, GLuint *, GLint *); + #define GL_QUERY_RESULT 0x8866 #define GL_QUERY_RESULT_AVAILABLE 0x8867 #define GL_TIME_ELAPSED 0x88BF @@ -88,4 +121,45 @@ extern PFNGLENDQUERYPROC fips_dispatch_glEndQuery; extern PFNGLGETQUERYOBJECTUIVPROC fips_dispatch_glGetQueryObjectuiv; #define glGetQueryObjectuiv fips_dispatch_glGetQueryObjectuiv +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 + +extern PFNGLGETPERFMONITORGROUPSAMDPROC fips_dispatch_glGetPerfMonitorGroupsAMD; +#define glGetPerfMonitorGroupsAMD fips_dispatch_glGetPerfMonitorGroupsAMD + +extern PFNGLGETPERFMONITORCOUNTERSAMDPROC fips_dispatch_glGetPerfMonitorCountersAMD; +#define glGetPerfMonitorCountersAMD fips_dispatch_glGetPerfMonitorCountersAMD + +extern PFNGLGETPERFMONITORGROUPSTRINGAMDPROC fips_dispatch_glGetPerfMonitorGroupsStringAMD; +#define glGetPerfMonitorGroupsStringAMD fips_dispatch_glGetPerfMonitorGroupsStringAMD + +extern PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC fips_dispatch_glGetPerfMonitorCounterStringAMD; +#define glGetPerfMonitorCounterStringAMD fips_dispatch_glGetPerfMonitorCounterStringAMD + +extern PFNGLGETPERFMONITORCOUNTERINFOAMDPROC fips_dispatch_glGetPerfMonitorCounterInfoAMD; +#define glGetPerfMonitorCounterInfoAMD fips_dispatch_glGetPerfMonitorCounterInfoAMD + +extern PFNGLGENPERFMONITORSAMDPROC fips_dispatch_glGenPerfMonitorsAMD; +#define glGenPerfMonitorsAMD fips_dispatch_glGenPerfMonitorsAMD + +extern PFNGLDELETEPERFMONITORSAMDPROC fips_dispatch_glDeletePerfMonitorsAMD; +#define glDeletePerfMonitorsAMD fips_dispatch_glDeletePerfMonitorsAMD + +extern PFNGLSELECTPERFMONITORCOUNTERSAMDPROC fips_dispatch_glSelectPerfMonitorCountersAMD; +#define glSelectPerfMonitorCountersAMD fips_dispatch_glSelectPerfMonitorCountersAMD + +extern PFNGLBEGINPERFMONITORAMDPROC fips_dispatch_glBeginPerfMonitorAMD; +#define glBeginPerfMonitorAMD fips_dispatch_glBeginPerfMonitorAMD + +extern PFNGLENDPERFMONITORAMDPROC fips_dispatch_glEndPerfMonitorAMD; +#define glEndPerfMonitorAMD fips_dispatch_glEndPerfMonitorAMD + +extern PFNGLGETPERFMONITORCOUNTERDATAAMDPROC fips_dispatch_glGetPerfMonitorCounterDataAMD; +#define glGetPerfMonitorCounterDataAMD fips_dispatch_glGetPerfMonitorCounterDataAMD + #endif /* FIPS_DISPATCH_GL_H */ -- 2.43.0 From 2760598732e9c373f3331d7d125b580a224bbbe3 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 11:04:25 -0700 Subject: [PATCH 09/16] Add collection of (AMD_performance_monitor) performance counters to fips The implementation involves a linked-list of outstanding performance-monitor queries next to the existing list of outstanding timer queries. The results from the performance counters are stored (without any interpretation in an array of values next to the existing time values within each op_metrics_t value for each operation. The numbers are currently printed with simple counter numbers (no names and no units) and with the values divided by 1e6. Counters with values of zero are not printed. Next steps from here that will make things useful: 1. Use relative number of cycels in each stage to apportion measured shader time among the various stages, (so that per-stage time numbers are sorted in the final report). 2. Print percentage active, (by looking at per-stage active and stall times) 3. Print names for counters (other than per-stage active and stall which will be used in the above two calculations). 4. Fix to silently ignore performance counters if the AMD_performance_monitor extension is not available. --- eglwrap.c | 2 + glxwrap.c | 4 + metrics.c | 330 +++++++++++++++++++++++++++++++++++++++++++++++------- metrics.h | 9 ++ 4 files changed, 305 insertions(+), 40 deletions(-) diff --git a/eglwrap.c b/eglwrap.c index 9e58389..497779c 100644 --- a/eglwrap.c +++ b/eglwrap.c @@ -112,6 +112,8 @@ eglMakeCurrent (EGLDisplay display, EGLSurface draw, EGLSurface read, EGLWRAP_DEFER_WITH_RETURN (ret, eglMakeCurrent, display, draw, read, context); + metrics_info_init (); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); diff --git a/glxwrap.c b/glxwrap.c index eda3583..9a28d7d 100644 --- a/glxwrap.c +++ b/glxwrap.c @@ -88,6 +88,8 @@ glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx) GLWRAP_DEFER_WITH_RETURN (ret, glXMakeCurrent, dpy, drawable, ctx); + metrics_info_init (); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); @@ -103,6 +105,8 @@ glXMakeContextCurrent (Display *dpy, GLXDrawable drawable, GLXDrawable read, GLX GLWRAP_DEFER_WITH_RETURN (ret, glXMakeContextCurrent, dpy, drawable, read, ctx); + metrics_info_init (); + metrics_set_current_op (METRICS_OP_SHADER + 0); metrics_counter_start (); diff --git a/metrics.c b/metrics.c index 09083e6..0c776e7 100644 --- a/metrics.c +++ b/metrics.c @@ -23,7 +23,7 @@ #include #include - +#include #include #include "fips-dispatch-gl.h" @@ -31,13 +31,24 @@ #include "metrics.h" #include "xmalloc.h" -typedef struct counter +/* Timer query */ +typedef struct timer_query { unsigned id; metrics_op_t op; - struct counter *next; -} counter_t; + struct timer_query *next; +} timer_query_t; + +/* Performance-monitor query */ +typedef struct monitor +{ + unsigned id; + + metrics_op_t op; + struct monitor *next; +} monitor_t; + typedef struct op_metrics { @@ -46,14 +57,37 @@ typedef struct op_metrics */ metrics_op_t op; double time_ns; + + double *counters; + unsigned num_counters; } op_metrics_t; +typedef struct counter_group_info +{ + GLuint id; + GLint num_counters; + GLint max_active_counters; + GLuint *counters; +} counter_group_info_t; + +typedef struct metrics_info +{ + int num_groups; + int max_counters_per_group; + counter_group_info_t *groups; +} metrics_info_t; + typedef struct context { + metrics_info_t metrics_info; + metrics_op_t op; - counter_t *counter_head; - counter_t *counter_tail; + timer_query_t *timer_head; + timer_query_t *timer_tail; + + monitor_t *monitor_head; + monitor_t *monitor_tail; unsigned num_op_metrics; op_metrics_t *op_metrics; @@ -67,6 +101,47 @@ context_t current_context; int frames; int verbose; +void +metrics_info_init (void) +{ + int i; + GLuint *group_ids; + metrics_info_t *metrics_info = ¤t_context.metrics_info; + + glGetPerfMonitorGroupsAMD (&metrics_info->num_groups, 0, NULL); + + group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint)); + + glGetPerfMonitorGroupsAMD (NULL, metrics_info->num_groups, group_ids); + + metrics_info->max_counters_per_group = 0; + + metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (counter_group_info_t)); + + for (i = 0; i < metrics_info->num_groups; i++) + { + counter_group_info_t *group; + + group = &metrics_info->groups[i]; + + group->id = group_ids[i]; + + glGetPerfMonitorCountersAMD (group->id, &group->num_counters, + &group->max_active_counters, 0, NULL); + + group->counters = xmalloc (group->num_counters * sizeof (GLuint)); + + glGetPerfMonitorCountersAMD (group->id, NULL, NULL, + group->num_counters, + group->counters); + + if (group->num_counters > metrics_info->max_counters_per_group) + metrics_info->max_counters_per_group = group->num_counters; + } + + free (group_ids); +} + static const char * metrics_op_string (metrics_op_t op) { @@ -115,30 +190,78 @@ metrics_op_string (metrics_op_t op) void metrics_counter_start (void) { - counter_t *counter; + context_t *ctx = ¤t_context; + timer_query_t *timer; + monitor_t *monitor; + int i; + + /* Create new timer query, add to list */ + timer = xmalloc (sizeof (timer_query_t)); - counter = xmalloc (sizeof(counter_t)); + timer->op = ctx->op; + timer->next = NULL; + + if (ctx->timer_tail) { + ctx->timer_tail->next = timer; + ctx->timer_tail = timer; + } else { + ctx->timer_tail = timer; + ctx->timer_head = timer; + } - glGenQueries (1, &counter->id); + /* Create a new performance-monitor query */ + monitor = xmalloc (sizeof (monitor_t)); - counter->op = current_context.op; - counter->next = NULL; + monitor->op = ctx->op; + monitor->next = NULL; - if (current_context.counter_tail) { - current_context.counter_tail->next = counter; - current_context.counter_tail = counter; + if (ctx->monitor_tail) { + ctx->monitor_tail->next = monitor; + ctx->monitor_tail = monitor; } else { - current_context.counter_tail = counter; - current_context.counter_head = counter; + ctx->monitor_tail = monitor; + ctx->monitor_head = monitor; } - glBeginQuery (GL_TIME_ELAPSED, counter->id); + /* Initialize the timer_query and monitor objects */ + glGenQueries (1, &timer->id); + + glGenPerfMonitorsAMD (1, &monitor->id); + + for (i = 0; i < ctx->metrics_info.num_groups; i++) + { + counter_group_info_t *group; + int num_counters; + + group = &ctx->metrics_info.groups[i]; + + num_counters = group->num_counters; + if (group->max_active_counters < group->num_counters) + { + fprintf (stderr, "Warning: Only monitoring %d/%d counters from group %d\n", + group->max_active_counters, + group->num_counters, i); + num_counters = group->max_active_counters; + + } + + glSelectPerfMonitorCountersAMD(monitor->id, + GL_TRUE, group->id, + num_counters, + group->counters); + } + + /* Start the queries */ + glBeginQuery (GL_TIME_ELAPSED, timer->id); + + glBeginPerfMonitorAMD (monitor->id); } void metrics_counter_stop (void) { glEndQuery (GL_TIME_ELAPSED); + glEndPerfMonitorAMD (current_context.monitor_tail->id); } void @@ -154,23 +277,104 @@ metrics_get_current_op (void) } static void -accumulate_program_time (metrics_op_t op, unsigned time_ns) +op_metrics_init (context_t *ctx, op_metrics_t *metrics, metrics_op_t op) { - context_t *ctx = ¤t_context; + metrics_info_t *info = &ctx->metrics_info; unsigned i; - if (op >= ctx->num_op_metrics) { + 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++) { - ctx->op_metrics[i].op = i; - ctx->op_metrics[i].time_ns = 0.0; - } + 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; } - ctx->op_metrics[op].time_ns += time_ns; + 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; + } + + CONSUME (value); + + i = (group_id * ctx->metrics_info.max_counters_per_group + + counter_id); + + assert (i < ctx->op_metrics[op].num_counters); + + /* FIXME: While I'm still occasionally getting bogus + * numbers from the performance counters, I'm simply + * going to discard anything larger than half the + * range, (something that looks like a negative signed + * quantity). + */ + if (((int32_t) value) < 0) + fprintf (stderr, "."); + else + ctx->op_metrics[op].counters[i] += value; + } +} + +static void +accumulate_program_time (metrics_op_t op, unsigned time_ns) +{ + op_metrics_t *metrics; + + metrics = ctx_get_op_metrics (¤t_context, op); + + metrics->time_ns += time_ns; } static int @@ -191,9 +395,9 @@ static void print_program_metrics (void) { context_t *ctx = ¤t_context; - unsigned i, j; int *sorted; /* Sorted indices into the ctx->op_metrics */ double total = 0; + unsigned i, j; /* Make a sorted list of the operations by time used, and figure * out the total so we can print percentages. @@ -226,9 +430,16 @@ print_program_metrics (void) for (j = strlen (op_string); j < 20; j++) printf (" "); } - printf ("\t%7.2f ms (% 2.1f%%)\n", + printf ("\t%7.2f ms (% 2.1f%%)", metric->time_ns / 1e6, metric->time_ns / total * 100); + printf ("["); + for (j = 0; j < metric->num_counters; j++) { + if (metric->counters[j] == 0.0) + continue; + printf ("%d: %.2f ms ", j, metric->counters[j] / 1e6); + } + printf ("]\n"); } } @@ -261,29 +472,68 @@ metrics_end_frame (void) frames++; gettimeofday (&tv_now, NULL); - /* Consume all counters that are ready. */ - counter_t *counter = current_context.counter_head; + /* Consume all timer queries that are ready. */ + timer_query_t *timer = current_context.timer_head; - while (counter) { + while (timer) { GLuint available, elapsed; - glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT_AVAILABLE, - &available); + glGetQueryObjectuiv (timer->id, + GL_QUERY_RESULT_AVAILABLE, &available); + if (! available) + break; + + glGetQueryObjectuiv (timer->id, + GL_QUERY_RESULT, &elapsed); + + accumulate_program_time (timer->op, elapsed); + + current_context.timer_head = timer->next; + if (current_context.timer_head == NULL) + current_context.timer_tail = NULL; + + glDeleteQueries (1, &timer->id); + + free (timer); + timer = current_context.timer_head; + } + + /* And similarly for all performance monitors that are ready. */ + monitor_t *monitor = current_context.monitor_head; + + while (monitor) { + GLuint available, result_size, *result; + GLint bytes_written; + + glGetPerfMonitorCounterDataAMD (monitor->id, + GL_PERFMON_RESULT_AVAILABLE_AMD, + sizeof (available), &available, + NULL); if (! available) break; - glGetQueryObjectuiv (counter->id, GL_QUERY_RESULT, &elapsed); + glGetPerfMonitorCounterDataAMD (monitor->id, + GL_PERFMON_RESULT_SIZE_AMD, + sizeof (result_size), + &result_size, NULL); + + result = xmalloc (result_size); + + glGetPerfMonitorCounterDataAMD (monitor->id, + GL_PERFMON_RESULT_AMD, + result_size, result, + &bytes_written); - accumulate_program_time (counter->op, elapsed); + accumulate_program_metrics (monitor->op, result, result_size); - current_context.counter_head = counter->next; - if (current_context.counter_head == NULL) - current_context.counter_tail = NULL; + current_context.monitor_head = monitor->next; + if (current_context.monitor_head == NULL) + current_context.monitor_tail = NULL; - glDeleteQueries (1, &counter->id); + glDeletePerfMonitorsAMD (1, &monitor->id); - free (counter); - counter = current_context.counter_head; + free (monitor); + monitor = current_context.monitor_head; } if (frames % 60 == 0) { diff --git a/metrics.h b/metrics.h index 45fef33..accafe5 100644 --- a/metrics.h +++ b/metrics.h @@ -50,6 +50,15 @@ typedef enum METRICS_OP_SHADER } metrics_op_t; +/* Initialize metrics info + * + * This queries the names and ranges for all available performance counters. + * + * This should be called once before any other metrics functions. + */ +void +metrics_info_init (void); + /* Start accumulating GPU time. * * The time accumulated will be accounted against the -- 2.43.0 From 89d08b1a163772b49a52e5a1142363d9d0de7c60 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 12:18:23 -0700 Subject: [PATCH 10/16] Ensure that the name "fips" appears in all error messages. With the number of wrappers potentially involved, (fips, glaze, apitrace, etc.), sometimes it can be ambiguous which error messages belong to which wrappers. Ensure that fips, at least, always advertises its own name in its error messages. --- execute.c | 14 +++++++------- fips.c | 2 +- glwrap.c | 2 +- metrics.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/execute.c b/execute.c index 07fd30f..eaedbb4 100644 --- a/execute.c +++ b/execute.c @@ -86,7 +86,7 @@ get_bin_name (void *ctx) name_len = readlink (link, name, name_len - 1); if (name_len < 0) { - fprintf (stderr, "Failed to readlink %s: %s\n", link, + fprintf (stderr, "fips: Error: Failed to readlink %s: %s\n", link, strerror (errno)); exit (1); } @@ -176,31 +176,31 @@ elf_bits (const char *program) fd = open (absolute_program, O_RDONLY, 0); if (fd < 0) { - fprintf (stderr, "Failed to open %s: %s\n", absolute_program, + fprintf (stderr, "fips: Failed to open %s: %s\n", absolute_program, strerror (errno)); exit (1); } if (elf_version (EV_CURRENT ) == EV_NONE) { - fprintf (stderr, "Failed to initialize elf library: %s\n", + fprintf (stderr, "fips: Failed to initialize elf library: %s\n", elf_errmsg (-1)); exit (1); } elf = elf_begin (fd, ELF_C_READ, NULL); if (elf == NULL) { - fprintf (stderr, "Call to elf_begin on %s failed: %s\n", + fprintf (stderr, "fips: Call to elf_begin on %s failed: %s\n", absolute_program, elf_errmsg(-1)); exit (1); } if (elf_kind (elf) != ELF_K_ELF) { - fprintf (stderr, "Not an ELF object: %s\n", absolute_program); + fprintf (stderr, "fips: Not an ELF object: %s\n", absolute_program); exit (1); } if (gelf_getehdr (elf, &ehdr) == NULL) { - fprintf (stderr, "getehdr on %s failed: %s\n", + fprintf (stderr, "fips: getehdr on %s failed: %s\n", absolute_program, elf_errmsg (-1)); exit (1); } @@ -208,7 +208,7 @@ elf_bits (const char *program) class = gelf_getclass (elf); if (class == ELFCLASSNONE) { - fprintf (stderr, "getclass on %s failed: %s\n", + fprintf (stderr, "fips: getclass on %s failed: %s\n", absolute_program, elf_errmsg (-1)); exit (1); } diff --git a/fips.c b/fips.c index 5aeb8c3..7276ce9 100644 --- a/fips.c +++ b/fips.c @@ -77,7 +77,7 @@ main (int argc, char *argv[]) case '?': break; default: - fprintf(stderr, "Internal error: " + fprintf(stderr, "fips: Internal error: " "unexpected getopt value: %d\n", opt); exit (1); } diff --git a/glwrap.c b/glwrap.c index 94966f5..f5b4f84 100644 --- a/glwrap.c +++ b/glwrap.c @@ -113,7 +113,7 @@ glwrap_lookup (char *name) ret = dlwrap_real_dlsym (gl_handle, name); if (ret == NULL) { - fprintf (stderr, "Error: glwrap_lookup failed to dlsym %s\n", + fprintf (stderr, "fips: Error: glwrap_lookup failed to dlsym %s\n", name); exit (1); } diff --git a/metrics.c b/metrics.c index 0c776e7..1e2e018 100644 --- a/metrics.c +++ b/metrics.c @@ -179,7 +179,7 @@ metrics_op_string (metrics_op_t op) case METRICS_OP_TEX_IMAGE: return "glTexImage*(+)"; default: - fprintf (stderr, "Internal error: " + fprintf (stderr, "fips: Internal error: " "Unknown metrics op value: %d\n", op); exit (1); } -- 2.43.0 From a19c938ab14709674bcadfcc9d6ccdee136d45bb Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 12:19:37 -0700 Subject: [PATCH 11/16] Respect GLAZE_LIBGL environment variable (if FIPS_LIBGL is unset) Since the LD_PRELOAD mechanism of fips may not work with some programs, users may want to run fips within glaze instead, (which uses LD_LIBRARY_PATH instead of LD_PRELOAD). In order to make this convenient, fips can recognize that glaze has identified the appropriate libGL.so library by examining the GLAZE_LIBGL environment variable. So, if the user has not specifically set the FIPS_LIBGL variable, and the GLAZE_LIBGL variable is set, use it to find the libGL.so to load. --- glwrap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/glwrap.c b/glwrap.c index f5b4f84..aa56038 100644 --- a/glwrap.c +++ b/glwrap.c @@ -97,6 +97,8 @@ glwrap_lookup (char *name) const char *path; path = getenv ("FIPS_LIBGL"); + if (! path) + path = getenv ("GLAZE_LIBGL"); if (path) { gl_handle = dlopen (path, RTLD_LAZY); -- 2.43.0 From 4fba48e967e0ab9d3af0bc230d1a0390250a5758 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 16:29:15 -0700 Subject: [PATCH 12/16] fips-dispatch: Fix misspelled glGetPerfMonitorGroupStringAMD There was an extra 's' in here before (GroupsString instead of GroupString), preventing these functions from being used correctly. Fix this, (since fips will soon be using this function). --- fips-dispatch-gl.c | 16 ++++++++-------- fips-dispatch-gl.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fips-dispatch-gl.c b/fips-dispatch-gl.c index 192b2bc..1154058 100644 --- a/fips-dispatch-gl.c +++ b/fips-dispatch-gl.c @@ -138,19 +138,19 @@ PFNGLGETPERFMONITORCOUNTERSAMDPROC fips_dispatch_glGetPerfMonitorCountersAMD = stub_glGetPerfMonitorCountersAMD; static void -stub_glGetPerfMonitorGroupsStringAMD (GLuint group, GLsizei bufSize, - GLsizei *length, GLchar *groupString) +stub_glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, + GLsizei *length, GLchar *groupString) { check_initialized (); - resolve (fips_dispatch_glGetPerfMonitorGroupsStringAMD, - "glGetPerfMonitorGroupsStringAMD"); - fips_dispatch_glGetPerfMonitorGroupsStringAMD (group, bufSize, length, - groupString); + resolve (fips_dispatch_glGetPerfMonitorGroupStringAMD, + "glGetPerfMonitorGroupStringAMD"); + fips_dispatch_glGetPerfMonitorGroupStringAMD (group, bufSize, length, + groupString); } PFNGLGETPERFMONITORGROUPSTRINGAMDPROC -fips_dispatch_glGetPerfMonitorGroupsStringAMD = - stub_glGetPerfMonitorGroupsStringAMD; +fips_dispatch_glGetPerfMonitorGroupStringAMD = + stub_glGetPerfMonitorGroupStringAMD; static void stub_glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, diff --git a/fips-dispatch-gl.h b/fips-dispatch-gl.h index eaa23d6..494d8e1 100644 --- a/fips-dispatch-gl.h +++ b/fips-dispatch-gl.h @@ -135,8 +135,8 @@ extern PFNGLGETPERFMONITORGROUPSAMDPROC fips_dispatch_glGetPerfMonitorGroupsAMD; extern PFNGLGETPERFMONITORCOUNTERSAMDPROC fips_dispatch_glGetPerfMonitorCountersAMD; #define glGetPerfMonitorCountersAMD fips_dispatch_glGetPerfMonitorCountersAMD -extern PFNGLGETPERFMONITORGROUPSTRINGAMDPROC fips_dispatch_glGetPerfMonitorGroupsStringAMD; -#define glGetPerfMonitorGroupsStringAMD fips_dispatch_glGetPerfMonitorGroupsStringAMD +extern PFNGLGETPERFMONITORGROUPSTRINGAMDPROC fips_dispatch_glGetPerfMonitorGroupStringAMD; +#define glGetPerfMonitorGroupStringAMD fips_dispatch_glGetPerfMonitorGroupStringAMD extern PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC fips_dispatch_glGetPerfMonitorCounterStringAMD; #define glGetPerfMonitorCounterStringAMD fips_dispatch_glGetPerfMonitorCounterStringAMD -- 2.43.0 From 2926b5a9207c28986f449a322761e4103f4c28e7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 16:30:34 -0700 Subject: [PATCH 13/16] Un-nest an inner loop while printing program metrics Before we add more code to complicate the way we print performance counters, it helps to have this code in its own function, (where we can safely use 'i' instead of 'j' for loop-control variable, etc.). --- metrics.c | 71 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/metrics.c b/metrics.c index 1e2e018..64f1dcc 100644 --- a/metrics.c +++ b/metrics.c @@ -391,13 +391,49 @@ time_compare(const void *in_a, const void *in_b, void *arg) return 0; } +static void +print_op_metrics (op_metrics_t *metric, double total) +{ + const char *op_string; + unsigned i; + + /* Since we sparsely fill the array based on program + * id, many "programs" have no time. + */ + if (metric->time_ns == 0.0) + return; + + 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 (i = strlen (op_string); i < 20; i++) + printf (" "); + } + + printf ("\t%7.2f ms (% 2.1f%%)", + metric->time_ns / 1e6, + metric->time_ns / total * 100); + + printf ("["); + for (i = 0; i < metric->num_counters; i++) { + if (metric->counters[i] == 0.0) + continue; + printf ("%d: %.2f ms ", i, metric->counters[i] / 1e6); + } + printf ("]\n"); +} + static void print_program_metrics (void) { context_t *ctx = ¤t_context; int *sorted; /* Sorted indices into the ctx->op_metrics */ double total = 0; - unsigned i, j; + unsigned i; /* Make a sorted list of the operations by time used, and figure * out the total so we can print percentages. @@ -410,37 +446,8 @@ print_program_metrics (void) qsort_r(sorted, ctx->num_op_metrics, sizeof(*sorted), time_compare, ctx->op_metrics); - 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->time_ns == 0.0) - continue; - - 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%%)", - metric->time_ns / 1e6, - metric->time_ns / total * 100); - printf ("["); - for (j = 0; j < metric->num_counters; j++) { - if (metric->counters[j] == 0.0) - continue; - printf ("%d: %.2f ms ", j, metric->counters[j] / 1e6); - } - printf ("]\n"); - } + for (i = 0; i < ctx->num_op_metrics; i++) + print_op_metrics (&ctx->op_metrics[sorted[i]], total); } /* Called at program exit */ -- 2.43.0 From 6256917740cf81e158aa06bf89f495c4ab74af16 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 17:23:46 -0700 Subject: [PATCH 14/16] Print performance-counter names in report This isn't necessarily a very useful way to see the numbers. The important part of the code here is that fips is now querying the names so that it can do some useful interpretation of the values based on the names. --- metrics.c | 187 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 114 insertions(+), 73 deletions(-) diff --git a/metrics.c b/metrics.c index 64f1dcc..f1f4428 100644 --- a/metrics.c +++ b/metrics.c @@ -58,23 +58,27 @@ typedef struct op_metrics metrics_op_t op; double time_ns; - double *counters; - unsigned num_counters; + double **counters; } op_metrics_t; -typedef struct counter_group_info +typedef struct metrics_group_info { GLuint id; - GLint num_counters; - GLint max_active_counters; + char *name; + + GLuint num_counters; + GLuint max_active_counters; + GLuint *counters; -} counter_group_info_t; + char **counter_names; + GLuint *counter_types; + +} metrics_group_info_t; typedef struct metrics_info { - int num_groups; - int max_counters_per_group; - counter_group_info_t *groups; + unsigned num_groups; + metrics_group_info_t *groups; } metrics_info_t; typedef struct context @@ -101,43 +105,85 @@ context_t current_context; int frames; int verbose; -void -metrics_info_init (void) +static void +metrics_group_info_init (metrics_group_info_t *group, GLuint id) { - int i; - GLuint *group_ids; - metrics_info_t *metrics_info = ¤t_context.metrics_info; + GLsizei length; + unsigned i; - glGetPerfMonitorGroupsAMD (&metrics_info->num_groups, 0, NULL); + group->id = id; - group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint)); + /* Get name */ + glGetPerfMonitorGroupStringAMD (id, 0, &length, NULL); - glGetPerfMonitorGroupsAMD (NULL, metrics_info->num_groups, group_ids); + group->name = xmalloc (length + 1); - metrics_info->max_counters_per_group = 0; + glGetPerfMonitorGroupStringAMD (id, length + 1, NULL, group->name); - metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (counter_group_info_t)); + /* Get number of counters */ + group->num_counters = 0; + group->max_active_counters = 0; + glGetPerfMonitorCountersAMD (group->id, + (int *) &group->num_counters, + (int *) &group->max_active_counters, + 0, NULL); - for (i = 0; i < metrics_info->num_groups; i++) - { - counter_group_info_t *group; + /* Get counter numbers */ + group->counters = xmalloc (group->num_counters * sizeof (GLuint)); + + glGetPerfMonitorCountersAMD (group->id, NULL, NULL, + group->num_counters, + group->counters); - group = &metrics_info->groups[i]; + /* Get counter names */ + group->counter_names = xmalloc (group->num_counters * sizeof (char *)); + group->counter_types = xmalloc (group->num_counters * sizeof (GLuint)); - group->id = group_ids[i]; + for (i = 0; i < group->num_counters; i++) { + glGetPerfMonitorCounterInfoAMD (group->id, + group->counters[i], + GL_COUNTER_TYPE_AMD, + &group->counter_types[i]); - glGetPerfMonitorCountersAMD (group->id, &group->num_counters, - &group->max_active_counters, 0, NULL); + /* We assume that all peformance counters are made + * available as uint32 values. The code calling + * CONSUME in accumulate_program_metrics will need to + * be extended to accomodate other counter values. */ + if (group->counter_types[i] != GL_UNSIGNED_INT) { + fprintf (stderr, "fips: Internal error: No support for non-uint counter values\n"); + exit (1); + } - group->counters = xmalloc (group->num_counters * sizeof (GLuint)); + glGetPerfMonitorCounterStringAMD (group->id, + group->counters[i], + 0, &length, NULL); - glGetPerfMonitorCountersAMD (group->id, NULL, NULL, - group->num_counters, - group->counters); + group->counter_names[i] = xmalloc (length + 1); - if (group->num_counters > metrics_info->max_counters_per_group) - metrics_info->max_counters_per_group = group->num_counters; + glGetPerfMonitorCounterStringAMD (group->id, + group->counters[i], + length + 1, NULL, + group->counter_names[i]); } +} + +void +metrics_info_init (void) +{ + unsigned i; + GLuint *group_ids; + metrics_info_t *metrics_info = ¤t_context.metrics_info; + + glGetPerfMonitorGroupsAMD ((int *) &metrics_info->num_groups, 0, NULL); + + group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint)); + + glGetPerfMonitorGroupsAMD (NULL, metrics_info->num_groups, group_ids); + + metrics_info->groups = xmalloc (metrics_info->num_groups * sizeof (metrics_group_info_t)); + + for (i = 0; i < metrics_info->num_groups; i++) + metrics_group_info_init (&metrics_info->groups[i], i); free (group_ids); } @@ -193,7 +239,7 @@ metrics_counter_start (void) context_t *ctx = ¤t_context; timer_query_t *timer; monitor_t *monitor; - int i; + unsigned i; /* Create new timer query, add to list */ timer = xmalloc (sizeof (timer_query_t)); @@ -230,7 +276,7 @@ metrics_counter_start (void) for (i = 0; i < ctx->metrics_info.num_groups; i++) { - counter_group_info_t *group; + metrics_group_info_t *group; int num_counters; group = &ctx->metrics_info.groups[i]; @@ -280,16 +326,19 @@ static void op_metrics_init (context_t *ctx, op_metrics_t *metrics, metrics_op_t op) { metrics_info_t *info = &ctx->metrics_info; - unsigned i; + unsigned i, j; 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); + metrics->counters = xmalloc (sizeof(double *) * info->num_groups); - for (i = 0; i < metrics->num_counters; i++) - metrics->counters[i] = 0.0; + for (i = 0; i < info->num_groups; i++) { + metrics->counters[i] = xmalloc (sizeof (double) * + info->groups[i].num_counters); + for (j = 0; j < info->groups[i].num_counters; j++) + metrics->counters[i][j] = 0.0; + } } static op_metrics_t * @@ -328,42 +377,26 @@ accumulate_program_metrics (metrics_op_t op, GLuint *result, GLuint size) while (p < ((unsigned char *) result) + size) { - GLuint group_id, counter_id, counter_type; + GLuint group_id, counter_id, counter_index; + metrics_group_info_t *group; uint32_t value; unsigned i; CONSUME (group_id); CONSUME (counter_id); + CONSUME (value); - glGetPerfMonitorCounterInfoAMD (group_id, counter_id, - GL_COUNTER_TYPE_AMD, - &counter_type); + assert (group_id < ctx->metrics_info.num_groups); + group = &ctx->metrics_info.groups[group_id]; - /* 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; + for (i = 0; i < group->num_counters; i++) { + if (group->counters[i] == counter_id) + break; } + counter_index = i; + assert (counter_index < group->num_counters); - CONSUME (value); - - i = (group_id * ctx->metrics_info.max_counters_per_group + - counter_id); - - assert (i < ctx->op_metrics[op].num_counters); - - /* FIXME: While I'm still occasionally getting bogus - * numbers from the performance counters, I'm simply - * going to discard anything larger than half the - * range, (something that looks like a negative signed - * quantity). - */ - if (((int32_t) value) < 0) - fprintf (stderr, "."); - else - ctx->op_metrics[op].counters[i] += value; + ctx->op_metrics[op].counters[group_id][counter_index] += value; } } @@ -392,10 +425,13 @@ time_compare(const void *in_a, const void *in_b, void *arg) } static void -print_op_metrics (op_metrics_t *metric, double total) +print_op_metrics (context_t *ctx, op_metrics_t *metric, double total) { + metrics_info_t *info = &ctx->metrics_info; + metrics_group_info_t *group; const char *op_string; - unsigned i; + unsigned i, group_id, counter; + double value; /* Since we sparsely fill the array based on program * id, many "programs" have no time. @@ -419,10 +455,15 @@ print_op_metrics (op_metrics_t *metric, double total) metric->time_ns / total * 100); printf ("["); - for (i = 0; i < metric->num_counters; i++) { - if (metric->counters[i] == 0.0) - continue; - printf ("%d: %.2f ms ", i, metric->counters[i] / 1e6); + for (group_id = 0; group_id < info->num_groups; group_id++) { + group = &info->groups[group_id]; + for (counter = 0; counter < group->num_counters; counter++) { + value = metric->counters[group_id][counter]; + if (value == 0.0) + continue; + printf ("%s: %.2f ", group->counter_names[counter], + value / 1e6); + } } printf ("]\n"); } @@ -447,7 +488,7 @@ print_program_metrics (void) time_compare, ctx->op_metrics); for (i = 0; i < ctx->num_op_metrics; i++) - print_op_metrics (&ctx->op_metrics[sorted[i]], total); + print_op_metrics (ctx, &ctx->op_metrics[sorted[i]], total); } /* Called at program exit */ -- 2.43.0 From cff9de18eebbbbc9b88e51483f5e471afbafaac1 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 17:43:31 -0700 Subject: [PATCH 15/16] Close two memory leaks in fips metrics reporting. Thanks to valgrind for pointing these out. --- metrics.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/metrics.c b/metrics.c index f1f4428..38e9e95 100644 --- a/metrics.c +++ b/metrics.c @@ -489,6 +489,8 @@ print_program_metrics (void) for (i = 0; i < ctx->num_op_metrics; i++) print_op_metrics (ctx, &ctx->op_metrics[sorted[i]], total); + + free (sorted); } /* Called at program exit */ @@ -574,6 +576,8 @@ metrics_end_frame (void) accumulate_program_metrics (monitor->op, result, result_size); + free (result); + current_context.monitor_head = monitor->next; if (current_context.monitor_head == NULL) current_context.monitor_tail = NULL; -- 2.43.0 From cc60267c8ddfcc6681106193294da2d8221160cf Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 22 Oct 2013 17:44:04 -0700 Subject: [PATCH 16/16] Free all fip-allocated data when the program exits This isn't strictly necessary since the operating system is about to reclaim all of this data anyway. The only real advantage of doing this is that it enables us to see in a valgrind report that there aren't any memory leaks due to direct allocation by code within fips. --- metrics.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/metrics.c b/metrics.c index 38e9e95..5c5cd1b 100644 --- a/metrics.c +++ b/metrics.c @@ -77,6 +77,8 @@ typedef struct metrics_group_info typedef struct metrics_info { + int initialized; + unsigned num_groups; metrics_group_info_t *groups; } metrics_info_t; @@ -167,6 +169,24 @@ metrics_group_info_init (metrics_group_info_t *group, GLuint id) } } +static void +metrics_group_info_fini (metrics_group_info_t *group) +{ + unsigned i; + + for (i = 0; i < group->num_counters; i++) + free (group->counter_names[i]); + + free (group->counter_types); + free (group->counter_names); + free (group->counters); + + free (group->name); +} + +static void +metrics_info_fini (metrics_info_t *info); + void metrics_info_init (void) { @@ -174,6 +194,9 @@ metrics_info_init (void) GLuint *group_ids; metrics_info_t *metrics_info = ¤t_context.metrics_info; + if (metrics_info->initialized) + metrics_info_fini (metrics_info); + glGetPerfMonitorGroupsAMD ((int *) &metrics_info->num_groups, 0, NULL); group_ids = xmalloc (metrics_info->num_groups * sizeof (GLuint)); @@ -186,6 +209,19 @@ metrics_info_init (void) metrics_group_info_init (&metrics_info->groups[i], i); free (group_ids); + + metrics_info->initialized = 1; +} + +static void +metrics_info_fini (metrics_info_t *info) +{ + unsigned i; + + for (i = 0; i < info->num_groups; i++) + metrics_group_info_fini (&info->groups[i]); + + free (info->groups); } static const char * @@ -499,6 +535,8 @@ metrics_exit (void) { if (verbose) printf ("fips: terminating\n"); + + metrics_info_fini (¤t_context.metrics_info); } -- 2.43.0