diff options
author | Emma Anholt <emma@anholt.net> | 2023-01-09 12:45:18 -0800 |
---|---|---|
committer | Emma Anholt <emma@anholt.net> | 2023-01-09 13:04:06 -0800 |
commit | 6904cf16f809fd9fc7813a932477b162d9b6f281 (patch) | |
tree | 8a8b614afedae6f27d950c21e8a1ff8143e1c500 | |
parent | e36325ffa9be874467a703bb85e907540f0cac38 (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.hpp | 2 | ||||
-rw-r--r-- | lib/trace/trace_parser_loop.cpp | 41 | ||||
-rw-r--r-- | retrace/retrace_main.cpp | 10 |
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])) { |