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 _______________________________________________ apitrace mailing list apitrace@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/apitrace