From 8dc8bcb282b0948605e4b526b9787f51c56301d6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 15 Oct 2013 13:45:06 -0700 Subject: [PATCH] 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