]> git.cworth.org Git - apitrace/blobdiff - retrace/retrace_main.cpp
replay: Add a --loop option to repeatedly loop over the final frame
[apitrace] / retrace / retrace_main.cpp
index ca03745c64d241ba836f718ca7aef041c2749cbc..0c358e185517a80e08973a23666a3ad89c62379c 100644 (file)
@@ -1,6 +1,8 @@
 /**************************************************************************
  *
  * Copyright 2011 Jose Fonseca
+ * Copyright (C) 2013 Intel Corporation. All rights reversed.
+ * Author: Shuang He <shuang.he@intel.com>
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
 
 
 static bool waitOnFinish = false;
+static bool loopOnFinish = false;
 
 static const char *comparePrefix = NULL;
 static const char *snapshotPrefix = NULL;
 static trace::CallSet snapshotFrequency;
 static trace::CallSet compareFrequency;
+static trace::ParseBookmark lastFrameStart;
 
 static unsigned dumpStateCallNo = ~0;
 
@@ -72,7 +76,9 @@ bool profiling = false;
 bool profilingGpuTimes = false;
 bool profilingCpuTimes = false;
 bool profilingPixelsDrawn = false;
+bool profilingMemoryUsage = false;
 bool useCallNos = true;
+bool singleThread = false;
 
 unsigned frameNo = 0;
 unsigned callNo = 0;
@@ -305,13 +311,34 @@ public:
      */
     void
     runLeg(trace::Call *call) {
+
         /* Consume successive calls for this thread. */
         do {
+            bool callEndsFrame = false;
+            static trace::ParseBookmark frameStart;
+
             assert(call);
             assert(call->thread_id == leg);
+
+            if (loopOnFinish && call->flags & trace::CALL_FLAG_END_FRAME) {
+                callEndsFrame = true;
+                parser.getBookmark(frameStart);
+            }
+
             retraceCall(call);
             delete call;
             call = parser.parse_call();
+
+            /* Restart last frame if looping is requested. */
+            if (loopOnFinish) {
+                if (!call) {
+                    parser.setBookmark(lastFrameStart);
+                    call = parser.parse_call();
+                } else if (callEndsFrame) {
+                    lastFrameStart = frameStart;
+                }
+            }
+
         } while (call && call->thread_id == leg);
 
         if (call) {
@@ -419,6 +446,14 @@ RelayRace::run(void) {
         return;
     }
 
+    /* If the user wants to loop we need to get a bookmark target. We
+     * usually get this after replaying a call that ends a frame, but
+     * for a trace that has only one frame we need to get it at the
+     * beginning. */
+    if (loopOnFinish) {
+        parser.getBookmark(lastFrameStart);
+    }
+
     RelayRunner *foreRunner = getForeRunner();
     if (call->thread_id == 0) {
         /* We are the forerunner thread, so no need to pass baton */
@@ -480,8 +515,17 @@ mainLoop() {
 
     startTime = os::getTime();
 
-    RelayRace race;
-    race.run();
+    if (singleThread) {
+        trace::Call *call;
+        while ((call = parser.parse_call())) {
+            retraceCall(call);
+            delete call;
+        };
+        flushRendering();
+    } else {
+        RelayRace race;
+        race.run();
+    }
 
     long long endTime = os::getTime();
     float timeInterval = (endTime - startTime) * (1.0 / os::timeFrequency);
@@ -514,6 +558,7 @@ usage(const char *argv0) {
         "      --pcpu              cpu profiling (cpu times per call)\n"
         "      --pgpu              gpu profiling (gpu times per draw call)\n"
         "      --ppd               pixels drawn profiling (pixels drawn per draw call)\n"
+        "      --pmem              memory usage profiling (vsize rss per call)\n"
         "  -c, --compare=PREFIX    compare against snapshots with given PREFIX\n"
         "  -C, --calls=CALLSET     calls to compare (default is every frame)\n"
         "      --call-nos[=BOOL]   use call numbers in snapshot filenames\n"
@@ -525,7 +570,9 @@ usage(const char *argv0) {
         "  -S, --snapshot=CALLSET  calls to snapshot (default is every frame)\n"
         "  -v, --verbose           increase output verbosity\n"
         "  -D, --dump-state=CALL   dump state at specific call no\n"
-        "  -w, --wait              waitOnFinish on final frame\n";
+        "  -w, --wait              waitOnFinish on final frame\n"
+        "      --loop              continuously loop, replaying final frame.\n"
+        "      --singlethread      use a single thread to replay command stream\n";
 }
 
 enum {
@@ -536,7 +583,10 @@ enum {
     PCPU_OPT,
     PGPU_OPT,
     PPD_OPT,
+    PMEM_OPT,
     SB_OPT,
+    LOOP_OPT,
+    SINGLETHREAD_OPT
 };
 
 const static char *
@@ -556,11 +606,14 @@ longOptions[] = {
     {"pcpu", no_argument, 0, PCPU_OPT},
     {"pgpu", no_argument, 0, PGPU_OPT},
     {"ppd", no_argument, 0, PPD_OPT},
+    {"pmem", no_argument, 0, PMEM_OPT},
     {"sb", no_argument, 0, SB_OPT},
     {"snapshot-prefix", required_argument, 0, 's'},
     {"snapshot", required_argument, 0, 'S'},
     {"verbose", no_argument, 0, 'v'},
     {"wait", no_argument, 0, 'w'},
+    {"loop", no_argument, 0, LOOP_OPT},
+    {"singlethread", no_argument, 0, SINGLETHREAD_OPT},
     {0, 0, 0, 0}
 };
 
@@ -633,6 +686,9 @@ int main(int argc, char **argv)
         case SB_OPT:
             retrace::doubleBuffer = false;
             break;
+        case SINGLETHREAD_OPT:
+            retrace::singleThread = true;
+            break;
         case 's':
             snapshotPrefix = optarg;
             if (snapshotFrequency.empty()) {
@@ -655,6 +711,9 @@ int main(int argc, char **argv)
         case 'w':
             waitOnFinish = true;
             break;
+        case LOOP_OPT:
+            loopOnFinish = true;
+            break;
         case PGPU_OPT:
             retrace::debug = false;
             retrace::profiling = true;
@@ -676,6 +735,13 @@ int main(int argc, char **argv)
 
             retrace::profilingPixelsDrawn = true;
             break;
+        case PMEM_OPT:
+            retrace::debug = false;
+            retrace::profiling = true;
+            retrace::verbosity = -1;
+
+            retrace::profilingMemoryUsage = true;
+            break;
         default:
             std::cerr << "error: unknown option " << opt << "\n";
             usage(argv[0]);
@@ -685,7 +751,7 @@ int main(int argc, char **argv)
 
     retrace::setUp();
     if (retrace::profiling) {
-        retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn);
+        retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn, retrace::profilingMemoryUsage);
     }
 
     os::setExceptionCallback(exceptionCallback);