X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=retrace%2Fretrace_main.cpp;h=ca03745c64d241ba836f718ca7aef041c2749cbc;hb=93d51c3065260cdb088f33d3e6d5bdfb4707c1a9;hp=e3e74f84cf20d979928b6fd704593939f22305ba;hpb=b35ae0df401ff22e3b2dc9b6bfacf1e23baebde0;p=apitrace diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp index e3e74f8..ca03745 100644 --- a/retrace/retrace_main.cpp +++ b/retrace/retrace_main.cpp @@ -35,6 +35,7 @@ #include "image.hpp" #include "trace_callset.hpp" #include "trace_dump.hpp" +#include "trace_option.hpp" #include "retrace.hpp" @@ -61,6 +62,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 +72,7 @@ bool profiling = false; bool profilingGpuTimes = false; bool profilingCpuTimes = false; bool profilingPixelsDrawn = false; +bool useCallNos = true; unsigned frameNo = 0; unsigned callNo = 0; @@ -79,11 +84,18 @@ frameComplete(trace::Call &call) { } +static Dumper defaultDumper; + +Dumper *dumper = &defaultDumper; + + /** * Take/compare snapshots. */ static void takeSnapshot(unsigned call_no) { + static unsigned snapshot_no = 0; + assert(snapshotPrefix || comparePrefix); image::Image *ref = NULL; @@ -99,18 +111,22 @@ takeSnapshot(unsigned call_no) { } } - image::Image *src = getSnapshot(); + 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"; } @@ -124,6 +140,8 @@ takeSnapshot(unsigned call_no) { delete src; + snapshot_no++; + return; } @@ -162,7 +180,7 @@ retraceCall(trace::Call *call) { takeSnapshot(call->no); if (call->no >= dumpStateCallNo && - dumpState(std::cout)) { + dumper->dumpState(std::cout)) { exit(0); } } @@ -498,8 +516,10 @@ usage(const char *argv0) { " --ppd pixels drawn profiling (pixels drawn per draw 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" @@ -509,8 +529,10 @@ usage(const char *argv0) { } enum { - CORE_OPT = CHAR_MAX + 1, + CALL_NOS_OPT = CHAR_MAX + 1, + CORE_OPT, DB_OPT, + DRIVER_OPT, PCPU_OPT, PGPU_OPT, PPD_OPT, @@ -523,10 +545,12 @@ 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}, @@ -540,6 +564,13 @@ longOptions[] = { {0, 0, 0, 0} }; + +static void exceptionCallback(void) +{ + std::cerr << retrace::callNo << ": error: caught an unhandled exception\n"; +} + + extern "C" int main(int argc, char **argv) { @@ -559,6 +590,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()) { @@ -582,6 +616,20 @@ 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; @@ -640,9 +688,10 @@ int main(int argc, char **argv) retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn); } + os::setExceptionCallback(exceptionCallback); + for (i = optind; i < argc; ++i) { if (!retrace::parser.open(argv[i])) { - std::cerr << "error: failed to open " << argv[i] << "\n"; return 1; } @@ -650,6 +699,8 @@ int main(int argc, char **argv) retrace::parser.close(); } + + os::resetExceptionCallback(); // XXX: X often hangs on XCloseDisplay //retrace::cleanUp();