X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fretrace_main.cpp;h=0c358e185517a80e08973a23666a3ad89c62379c;hb=448a82a8d4070b8911f6db667d55693d1dc8f99f;hp=a59ee9ae81f3f4aecbdd8b6501a77eaf3f05bffb;hpb=00611a483a0a531272ba5810b77fb5d293db1723;p=apitrace diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp index a59ee9a..0c358e1 100644 --- a/retrace/retrace_main.cpp +++ b/retrace/retrace_main.cpp @@ -1,6 +1,8 @@ /************************************************************************** * * Copyright 2011 Jose Fonseca + * Copyright (C) 2013 Intel Corporation. All rights reversed. + * Author: Shuang He * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -35,15 +37,18 @@ #include "image.hpp" #include "trace_callset.hpp" #include "trace_dump.hpp" +#include "trace_option.hpp" #include "retrace.hpp" 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; @@ -61,6 +66,9 @@ int verbosity = 0; bool debug = true; bool dumpingState = false; +Driver driver = DRIVER_DEFAULT; +const char *driverModule = NULL; + bool doubleBuffer = true; bool coreProfile = false; @@ -68,6 +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; @@ -89,6 +100,8 @@ Dumper *dumper = &defaultDumper; */ static void takeSnapshot(unsigned call_no) { + static unsigned snapshot_no = 0; + assert(snapshotPrefix || comparePrefix); image::Image *ref = NULL; @@ -106,16 +119,20 @@ takeSnapshot(unsigned call_no) { image::Image *src = dumper->getSnapshot(); if (!src) { + std::cout << "Failed to get snapshot\n"; return; } if (snapshotPrefix) { if (snapshotPrefix[0] == '-' && snapshotPrefix[1] == 0) { char comment[21]; - snprintf(comment, sizeof comment, "%u", call_no); + snprintf(comment, sizeof comment, "%u", + useCallNos ? call_no : snapshot_no); src->writePNM(std::cout, comment); } else { - os::String filename = os::String::format("%s%010u.png", snapshotPrefix, call_no); + os::String filename = os::String::format("%s%010u.png", + snapshotPrefix, + useCallNos ? call_no : snapshot_no); if (src->writePNG(filename) && retrace::verbosity >= 0) { std::cout << "Wrote " << filename << "\n"; } @@ -129,6 +146,8 @@ takeSnapshot(unsigned call_no) { delete src; + snapshot_no++; + return; } @@ -292,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) { @@ -406,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 */ @@ -467,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); @@ -501,25 +558,35 @@ 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" " --core use core profile\n" " --db use a double buffer visual (default)\n" + " --driver=DRIVER force driver type (`hw`, `sw`, `ref`, `null`, or driver module name)\n" " --sb use a single buffer visual\n" " -s, --snapshot-prefix=PREFIX take snapshots; `-` for PNM stdout output\n" " -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 { - CORE_OPT = CHAR_MAX + 1, + CALL_NOS_OPT = CHAR_MAX + 1, + CORE_OPT, DB_OPT, + DRIVER_OPT, PCPU_OPT, PGPU_OPT, PPD_OPT, + PMEM_OPT, SB_OPT, + LOOP_OPT, + SINGLETHREAD_OPT }; const static char * @@ -528,20 +595,25 @@ shortOptions = "bc:C:D:hs:S:vw"; const static struct option longOptions[] = { {"benchmark", no_argument, 0, 'b'}, + {"call-nos", optional_argument, 0, CALL_NOS_OPT }, {"calls", required_argument, 0, 'C'}, {"compare", required_argument, 0, 'c'}, {"core", no_argument, 0, CORE_OPT}, {"db", no_argument, 0, DB_OPT}, + {"driver", required_argument, 0, DRIVER_OPT}, {"dump-state", required_argument, 0, 'D'}, {"help", no_argument, 0, 'h'}, {"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} }; @@ -571,6 +643,9 @@ int main(int argc, char **argv) retrace::debug = false; retrace::verbosity = -1; break; + case CALL_NOS_OPT: + useCallNos = trace::boolOption(optarg); + break; case 'c': comparePrefix = optarg; if (compareFrequency.empty()) { @@ -594,9 +669,26 @@ int main(int argc, char **argv) case DB_OPT: retrace::doubleBuffer = true; break; + case DRIVER_OPT: + if (strcasecmp(optarg, "hw") == 0) { + driver = DRIVER_HARDWARE; + } else if (strcasecmp(optarg, "sw") == 0) { + driver = DRIVER_SOFTWARE; + } else if (strcasecmp(optarg, "ref") == 0) { + driver = DRIVER_REFERENCE; + } else if (strcasecmp(optarg, "null") == 0) { + driver = DRIVER_NULL; + } else { + driver = DRIVER_MODULE; + driverModule = optarg; + } + break; case SB_OPT: retrace::doubleBuffer = false; break; + case SINGLETHREAD_OPT: + retrace::singleThread = true; + break; case 's': snapshotPrefix = optarg; if (snapshotFrequency.empty()) { @@ -619,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; @@ -640,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]); @@ -649,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);