[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