[RFC] retrace: support for profiling on a tiler

Rob Clark robdclark at gmail.com
Sat Jul 23 17:36:56 UTC 2016


In most cases, timestamp query doesn't really tell you what you want to
know on a tiler.  For freedreno, it will tell you the time at the first
tile.  (It's a bit undefined, I think other drivers could give you the
value on the last tile.)  But time-elapsed query will give you the sum
over all the tiles (as it should.. this is what you actually want to
know).  The end result is that:

   drawA.gpuStart + drawA.gpuDuration != drawB.gpuStart

which confuses qapitrace.

Let's instead use the timestamp query for the first call in a frame, to
get an accurate starting position in time, and then emulate it for the
intermediate draws, calculating it from previous draw's start and
duration.
---
Obviously not ready to merge, without a better way to decide if the
gpu is a tiler or not.  Not sure if there is a better option than
having a table of vendor strings for known drivers for tiling gpus?

 retrace/glretrace_main.cpp | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
index a7688e8..d16f2a0 100755
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -78,6 +78,7 @@ struct CallQuery
 static bool supportsElapsed = true;
 static bool supportsTimestamp = true;
 static bool supportsOcclusion = true;
+static bool isTiler = true; // TODO guess based on vendor string??
 
 static std::list<CallQuery> callQueries;
 
@@ -213,7 +214,7 @@ getCurrentRss(int64_t& rss) {
 }
 
 static void
-completeCallQuery(CallQuery& query) {
+completeCallQuery(CallQuery& query, bool first, int64_t *lastGpuStart, int64_t *lastGpuDuration) {
     /* Get call start and duration */
     int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0;
 
@@ -221,7 +222,17 @@ completeCallQuery(CallQuery& query) {
         if (retrace::profilingGpuTimes) {
             if (supportsTimestamp) {
                 /* Use ARB queries in case EXT not present */
-                glGetQueryObjecti64v(query.ids[GPU_START], GL_QUERY_RESULT, &gpuStart);
+                if (isTiler && !first) {
+                    /* for tilers, timestamp query doesn't make much sense because
+                     * point in the "cmdstream" is executed for each tile.  We can
+                     * at least assume a sensible result for the first draw in a
+                     * frame.  But other than that, emulate gpuStart as last-start
+                     * plus last-duration.
+                     */
+                    gpuStart = *lastGpuStart + *lastGpuDuration;
+                } else {
+                    glGetQueryObjecti64v(query.ids[GPU_START], GL_QUERY_RESULT, &gpuStart);
+                }
                 glGetQueryObjecti64v(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration);
             } else {
                 glGetQueryObjecti64vEXT(query.ids[GPU_DURATION], GL_QUERY_RESULT, &gpuDuration);
@@ -240,6 +251,8 @@ completeCallQuery(CallQuery& query) {
             }
         }
 
+        *lastGpuStart = gpuStart;
+        *lastGpuDuration = gpuDuration;
     } else {
         pixels = -1;
     }
@@ -263,8 +276,12 @@ completeCallQuery(CallQuery& query) {
 
 void
 flushQueries() {
+    int64_t lastGpuStart = 0, lastGpuDuration = 0;
+    bool first = true;
     for (auto & callQuerie : callQueries) {
-        completeCallQuery(callQuerie);
+        completeCallQuery(callQuerie, first, &lastGpuStart, &lastGpuDuration);
+        if (callQuerie.isDraw)
+            first = false;
     }
 
     callQueries.clear();
-- 
2.7.4



More information about the apitrace mailing list