[PATCH] glretrace: Use GL_TIMESTAMP (if available) for CPU profiling.

Carl Worth cworth at cworth.org
Thu Nov 15 10:51:01 PST 2012


The prior scheme of trying to continuously re-synchronize separate CPU
and GPU counters is doomed to always be unreliable. Instead, simply prefer
to use the GL_TIMESTAMP values for both GPU and for CPU profiling.
---
 retrace/glretrace_main.cpp |   42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
index 024a285..771eb27 100755
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -46,7 +46,7 @@ bool supportsARBShaderObjects = false;
 
 struct CallQuery
 {
-    GLuint ids[3];
+    GLuint ids[5];
     unsigned call;
     bool isDraw;
     GLuint program;
@@ -113,22 +113,30 @@ checkGlError(trace::Call &call) {
 static void
 getCurrentTimes(int64_t& cpuTime, int64_t& gpuTime) {
     GLuint query;
+    int64_t timestamp;
 
-    if (retrace::profilingGpuTimes && supportsTimestamp) {
+    if (supportsTimestamp) {
         glGenQueries(1, &query);
         glQueryCounter(query, GL_TIMESTAMP);
-        glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &gpuTime);
+        glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &timestamp);
+    }
+
+    if (retrace::profilingGpuTimes && supportsTimestamp) {
+        gpuTime = timestamp;
     } else {
         gpuTime = 0;
     }
 
     if (retrace::profilingCpuTimes) {
-        cpuTime = os::getTime();
+        if (supportsTimestamp)
+            cpuTime = timestamp;
+        else
+            cpuTime = os::getTime();
     } else {
         cpuTime = 0;
     }
 
-    if (retrace::profilingGpuTimes && supportsTimestamp) {
+    if (supportsTimestamp) {
         glDeleteQueries(1, &query);
     }
 }
@@ -151,15 +159,20 @@ completeCallQuery(CallQuery& query) {
             glGetQueryObjecti64vEXT(query.ids[2], GL_QUERY_RESULT, &pixels);
         }
 
-        glDeleteQueries(3, query.ids);
     } else {
         pixels = -1;
     }
 
     if (retrace::profilingCpuTimes) {
+        if (supportsTimestamp) {
+            query.cpuStart = gpuStart;
+            glGetQueryObjecti64vEXT(query.ids[3], GL_QUERY_RESULT, &query.cpuEnd);
+        }
         cpuDuration = query.cpuEnd - query.cpuStart;
     }
 
+    glDeleteQueries(4, query.ids);
+
     /* Add call to profile */
     retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration);
 }
@@ -182,10 +195,10 @@ beginProfile(trace::Call &call, bool isDraw) {
     query.sig = call.sig;
     query.program = glretrace::currentContext ? glretrace::currentContext->activeProgram : 0;
 
+    glGenQueries(4, query.ids);
+
     /* GPU profiling only for draw calls */
     if (isDraw) {
-        glGenQueries(3, query.ids);
-
         if (retrace::profilingGpuTimes) {
             if (supportsTimestamp) {
                 glQueryCounter(query.ids[0], GL_TIMESTAMP);
@@ -203,7 +216,11 @@ beginProfile(trace::Call &call, bool isDraw) {
 
     /* CPU profiling for all calls */
     if (retrace::profilingCpuTimes) {
-       callQueries.back().cpuStart = os::getTime();
+        CallQuery& query = callQueries.back();
+
+        if (! supportsTimestamp) {
+            query.cpuStart = os::getTime();
+        }
     }
 }
 
@@ -214,7 +231,12 @@ endProfile(trace::Call &call, bool isDraw) {
     /* CPU profiling for all calls */
     if (retrace::profilingCpuTimes) {
         CallQuery& query = callQueries.back();
-        query.cpuEnd = time;
+
+        if (supportsTimestamp) {
+            glQueryCounter(query.ids[3], GL_TIMESTAMP);
+        } else {
+            query.cpuEnd = time;
+        }
     }
 
     /* GPU profiling only for draw calls */
-- 
1.7.10



More information about the apitrace mailing list