summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmma Anholt <emma@anholt.net>2023-01-09 12:45:18 -0800
committerEmma Anholt <emma@anholt.net>2023-01-09 13:04:06 -0800
commit6904cf16f809fd9fc7813a932477b162d9b6f281 (patch)
tree8a8b614afedae6f27d950c21e8a1ff8143e1c500
parente36325ffa9be874467a703bb85e907540f0cac38 (diff)
retrace: Add --loopsecs argument.loopsecs
The traces-db traces are all trimmed to be one giant setup frame and one frame of rendering. If you want to do performance work on that, you really just care about measuring the rendering frame, not the setup frame. People have suggested ranking "--loop=" up high enough, but it turns out that there's not really a useful value of "high enough" if the setup time might be also changing (such as when evaluating zink vs native GL). Sample output: eglretrace ~/src/traces-db/valve/portal-2-v2.trace --loopsecs=5 warning: --loop blindly repeats the last frame calls, therefore frames might not necessarily render correctly (https://github.com/apitrace/apitrace/issues/800) [...] Rendered the last frame 2305 times in 5.00101 secs, average of 460.907 fps Rendered 2308 frames in 7.15039 secs, average of 322.78 fps
-rw-r--r--lib/trace/trace_parser.hpp2
-rw-r--r--lib/trace/trace_parser_loop.cpp41
-rw-r--r--retrace/retrace_main.cpp10
3 files changed, 45 insertions, 8 deletions
diff --git a/lib/trace/trace_parser.hpp b/lib/trace/trace_parser.hpp
index 72bbded3..5223c42a 100644
--- a/lib/trace/trace_parser.hpp
+++ b/lib/trace/trace_parser.hpp
@@ -272,7 +272,7 @@ protected:
AbstractParser *
-lastFrameLoopParser(AbstractParser *parser, int loopCount);
+lastFrameLoopParser(AbstractParser *parser, int loopCount, int loopSecs);
} /* namespace trace */
diff --git a/lib/trace/trace_parser_loop.cpp b/lib/trace/trace_parser_loop.cpp
index 23c92c8d..b213d28f 100644
--- a/lib/trace/trace_parser_loop.cpp
+++ b/lib/trace/trace_parser_loop.cpp
@@ -25,6 +25,7 @@
#include "trace_parser.hpp"
+#include "os_time.hpp"
namespace trace {
@@ -33,10 +34,13 @@ namespace trace {
// Decorator for parser which loops
class LastFrameLoopParser : public AbstractParser {
public:
- LastFrameLoopParser(AbstractParser *p, int c) {
+ LastFrameLoopParser(AbstractParser *p, int c, int s) {
parser = p;
loopCount = c;
+ loopSecs = s;
starts_new_frame = true;
+ startTime = 0;
+ lastFrameCount = 0;
}
~LastFrameLoopParser() {
@@ -57,6 +61,11 @@ public:
const Properties & getProperties(void) const override { return parser->getProperties(); }
private:
int loopCount;
+
+ int loopSecs;
+ long long startTime;
+ int lastFrameCount;
+
bool starts_new_frame;
AbstractParser *parser;
std::vector<Call *> lastFrameCalls;
@@ -99,9 +108,29 @@ LastFrameLoopParser::parse_call(void)
call = *lastFrameIterator;
++lastFrameIterator;
if (lastFrameIterator == lastFrameCalls.end()) {
- /* repeat the frame */
- lastFrameIterator = lastFrameCalls.begin();
- --loopCount;
+ if (loopSecs) {
+ if (startTime == 0) {
+ /* First loop, start measuring. */
+ startTime = os::getTime();
+ } else {
+ long long endTime = os::getTime();
+ float timeInterval = (endTime - startTime) * (1.0 / os::timeFrequency);
+ if (timeInterval >= loopSecs) {
+ std::cout <<
+ "Rendered the last frame " << lastFrameCount << " times"
+ " in " << timeInterval << " secs,"
+ " average of " << (lastFrameCount/timeInterval) << " fps\n";
+ loopCount = 0;
+ }
+ }
+ }
+
+ if (loopCount) {
+ /* repeat the frame */
+ lastFrameIterator = lastFrameCalls.begin();
+ --loopCount;
+ lastFrameCount++;
+ }
}
}
@@ -110,9 +139,9 @@ LastFrameLoopParser::parse_call(void)
AbstractParser *
-lastFrameLoopParser(AbstractParser *parser, int loopCount)
+lastFrameLoopParser(AbstractParser *parser, int loopCount, int loop_secs)
{
- return new LastFrameLoopParser(parser, loopCount);
+ return new LastFrameLoopParser(parser, loopCount, loop_secs);
}
diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index 1ed5dd50..29d41818 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -812,6 +812,7 @@ usage(const char *argv0) {
" --per-frame-delay=MICROSECONDS add extra delay after each frame (in addition to min-frame-duration)\n"
" -w, --wait waitOnFinish on final frame\n"
" --loop[=N] loop N times (N<0 continuously) replaying final frame.\n"
+ " --loopsecs[=N] loop N seconds replaying final frame.\n"
" --watchdog invokes abort() if retrace of a single api call will take more than " << retrace::RetraceWatchdog::TimeoutInSec << " seconds\n"
" --singlethread use a single thread to replay command stream\n"
" --ignore-retvals ignore return values in wglMakeCurrent, etc\n"
@@ -846,6 +847,7 @@ enum {
MIN_FRAME_DURATION_OPT,
PER_FRAME_DELAY_OPT,
LOOP_OPT,
+ LOOP_SECS_OPT,
SINGLETHREAD_OPT,
IGNORE_RETVALS_OPT,
NO_CONTEXT_CHECK,
@@ -908,6 +910,7 @@ longOptions[] = {
{"min-frame-duration", required_argument, 0, MIN_FRAME_DURATION_OPT},
{"per-frame-delay", required_argument, 0, PER_FRAME_DELAY_OPT},
{"loop", optional_argument, 0, LOOP_OPT},
+ {"loopsecs", optional_argument, 0, LOOP_SECS_OPT},
{"singlethread", no_argument, 0, SINGLETHREAD_OPT},
{"ignore-retvals", no_argument, 0, IGNORE_RETVALS_OPT},
{"no-context-check", no_argument, 0, NO_CONTEXT_CHECK},
@@ -1121,6 +1124,7 @@ int main(int argc, char **argv)
{
using namespace retrace;
int loopCount = 0;
+ int loopSecs = 0;
int i;
bool snapshotThreaded = false;
@@ -1298,6 +1302,10 @@ int main(int argc, char **argv)
case LOOP_OPT:
loopCount = trace::intOption(optarg, -1);
break;
+ case LOOP_SECS_OPT:
+ loopSecs = trace::intOption(optarg, -1);
+ loopCount = -1;
+ break;
case PFRAMETIMES_OPT:
retrace::debug = 0;
retrace::profiling = true;
@@ -1444,7 +1452,7 @@ int main(int argc, char **argv)
for (i = optind; i < argc; ++i) {
parser = new trace::Parser;
if (loopCount) {
- parser = lastFrameLoopParser(parser, loopCount);
+ parser = lastFrameLoopParser(parser, loopCount, loopSecs);
}
if (!parser->open(argv[i])) {