X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glretrace_main.cpp;h=11f34ce8200ca16215780c0fbfce976f918ca414;hb=8c5ab641f8481289a9ea18eec621a3eacc1e1caf;hp=dc022762fc35d439eb358cbff18eed2b77cdc2cc;hpb=9a0ed9ce37a521e78fdfdfe3fa6042dcb6c08d39;p=apitrace diff --git a/glretrace_main.cpp b/glretrace_main.cpp index dc02276..11f34ce 100644 --- a/glretrace_main.cpp +++ b/glretrace_main.cpp @@ -26,8 +26,12 @@ #include +#include "os_binary.hpp" +#include "os_string.hpp" +#include "os_time.hpp" #include "image.hpp" #include "retrace.hpp" +#include "trace_callset.hpp" #include "glproc.hpp" #include "glstate.hpp" #include "glretrace.hpp" @@ -37,8 +41,9 @@ namespace glretrace { bool double_buffer = true; bool insideGlBeginEnd = false; -Trace::Parser parser; -glws::Visual *visual = NULL; +trace::Parser parser; +glws::Profile defaultProfile = glws::PROFILE_COMPAT; +glws::Visual *visual[glws::PROFILE_MAX]; glws::Drawable *drawable = NULL; glws::Context *context = NULL; @@ -47,14 +52,15 @@ long long startTime = 0; bool wait = false; bool benchmark = false; -const char *compare_prefix = NULL; -const char *snapshot_prefix = NULL; -enum frequency snapshot_frequency = FREQUENCY_NEVER; +static const char *compare_prefix = NULL; +static const char *snapshot_prefix = NULL; +static trace::CallSet snapshot_frequency; +static trace::CallSet compare_frequency; unsigned dump_state = ~0; void -checkGlError(Trace::Call &call) { +checkGlError(trace::Call &call) { GLenum error = glGetError(); if (error == GL_NO_ERROR) { return; @@ -110,8 +116,14 @@ updateDrawable(int width, int height) { return; } - if (width <= glretrace::drawable->width && - height <= glretrace::drawable->height) { + if (drawable->visible && + width <= drawable->width && + height <= drawable->height) { + return; + } + + // Ignore zero area viewports + if (width == 0 || height == 0) { return; } @@ -122,26 +134,26 @@ updateDrawable(int width, int height) { return; } - glretrace::drawable->resize(width, height); - if (!drawable->visible) { - drawable->show(); - } + drawable->resize(width, height); + drawable->show(); + glScissor(0, 0, width, height); } -void snapshot(unsigned call_no) { - if (!drawable || - (!snapshot_prefix && !compare_prefix)) { +static void +snapshot(unsigned call_no) { + assert(snapshot_prefix || compare_prefix); + + if (!drawable) { return; } - Image::Image *ref = NULL; + image::Image *ref = NULL; if (compare_prefix) { - char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s%010u.png", compare_prefix, call_no); - ref = Image::readPNG(filename); + os::String filename = os::String::format("%s%010u.png", compare_prefix, call_no); + ref = image::readPNG(filename); if (!ref) { return; } @@ -150,7 +162,7 @@ void snapshot(unsigned call_no) { } } - Image::Image *src = glstate::getDrawBufferImage(GL_RGBA); + image::Image *src = glstate::getDrawBufferImage(); if (!src) { return; } @@ -161,8 +173,7 @@ void snapshot(unsigned call_no) { snprintf(comment, sizeof comment, "%u", call_no); src->writePNM(std::cout, comment); } else { - char filename[PATH_MAX]; - snprintf(filename, sizeof filename, "%s%010u.png", snapshot_prefix, call_no); + os::String filename = os::String::format("%s%010u.png", snapshot_prefix, call_no); if (src->writePNG(filename) && retrace::verbosity >= 0) { std::cout << "Wrote " << filename << "\n"; } @@ -178,12 +189,15 @@ void snapshot(unsigned call_no) { } -void frame_complete(unsigned call_no) { +void frame_complete(trace::Call &call) { ++frame; - if (snapshot_frequency == FREQUENCY_FRAME || - snapshot_frequency == FREQUENCY_FRAMEBUFFER) { - snapshot(call_no); + if (!drawable) { + return; + } + + if (!drawable->visible) { + retrace::warning(call) << "could not infer drawable size (glViewport never called)\n"; } } @@ -195,13 +209,38 @@ static void display(void) { retracer.addCallbacks(glx_callbacks); retracer.addCallbacks(wgl_callbacks); retracer.addCallbacks(cgl_callbacks); + retracer.addCallbacks(egl_callbacks); - startTime = OS::GetTime(); - Trace::Call *call; + startTime = os::getTime(); + trace::Call *call; while ((call = parser.parse_call())) { + bool swapRenderTarget = call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET; + bool doSnapshot = + snapshot_frequency.contains(*call) || + compare_frequency.contains(*call) + ; + + // For calls which cause rendertargets to be swaped, we take the + // snapshot _before_ swapping the rendertargets. + if (doSnapshot && swapRenderTarget) { + if (call->flags & trace::CALL_FLAG_END_FRAME) { + // For swapbuffers/presents we still use this call number, + // spite not have been executed yet. + snapshot(call->no); + } else { + // Whereas for ordinate fbo/rendertarget changes we use the + // previous call's number. + snapshot(call->no - 1); + } + } + retracer.retrace(*call); + if (doSnapshot && !swapRenderTarget) { + snapshot(call->no); + } + if (!insideGlBeginEnd && drawable && context && call->no >= dump_state) { @@ -215,10 +254,10 @@ static void display(void) { // Reached the end of trace glFlush(); - long long endTime = OS::GetTime(); - float timeInterval = (endTime - startTime) * 1.0E-6; + long long endTime = os::getTime(); + float timeInterval = (endTime - startTime) * (1.0 / os::timeFrequency); - if (retrace::verbosity >= -1) { + if ((retrace::verbosity >= -1) || (retrace::profiling)) { std::cout << "Rendered " << frame << " frames" " in " << timeInterval << " secs," @@ -239,12 +278,15 @@ static void usage(void) { "Replay TRACE.\n" "\n" " -b benchmark mode (no error checking or warning messages)\n" + " -p profiling mode (run whole trace, dump profiling info)\n" " -c PREFIX compare against snapshots\n" + " -C CALLSET calls to compare (default is every frame)\n" + " -core use core profile\n" " -db use a double buffer visual (default)\n" " -sb use a single buffer visual\n" " -s PREFIX take snapshots; `-` for PNM stdout output\n" - " -S FREQUENCY snapshot frequency: frame (default), framebuffer, or draw\n" - " -v verbose output\n" + " -S CALLSET calls to snapshot (default is every frame)\n" + " -v increase output verbosity\n" " -D CALLNO dump state at specific call no\n" " -w wait on final frame\n"; } @@ -252,6 +294,8 @@ static void usage(void) { extern "C" int main(int argc, char **argv) { + assert(compare_frequency.empty()); + assert(snapshot_frequency.empty()); int i; for (i = 1; i < argc; ++i) { @@ -266,14 +310,26 @@ int main(int argc, char **argv) } else if (!strcmp(arg, "-b")) { benchmark = true; retrace::verbosity = -1; + glws::debug = false; + } else if (!strcmp(arg, "-p")) { + retrace::profiling = true; + retrace::verbosity = -1; + glws::debug = false; } else if (!strcmp(arg, "-c")) { compare_prefix = argv[++i]; - if (snapshot_frequency == FREQUENCY_NEVER) { - snapshot_frequency = FREQUENCY_FRAME; + if (compare_frequency.empty()) { + compare_frequency = trace::CallSet(trace::FREQUENCY_FRAME); + } + } else if (!strcmp(arg, "-C")) { + compare_frequency = trace::CallSet(argv[++i]); + if (compare_prefix == NULL) { + compare_prefix = ""; } } else if (!strcmp(arg, "-D")) { dump_state = atoi(argv[++i]); retrace::verbosity = -2; + } else if (!strcmp(arg, "-core")) { + defaultProfile = glws::PROFILE_CORE; } else if (!strcmp(arg, "-db")) { double_buffer = true; } else if (!strcmp(arg, "-sb")) { @@ -283,25 +339,15 @@ int main(int argc, char **argv) return 0; } else if (!strcmp(arg, "-s")) { snapshot_prefix = argv[++i]; - if (snapshot_frequency == FREQUENCY_NEVER) { - snapshot_frequency = FREQUENCY_FRAME; + if (snapshot_frequency.empty()) { + snapshot_frequency = trace::CallSet(trace::FREQUENCY_FRAME); } if (snapshot_prefix[0] == '-' && snapshot_prefix[1] == 0) { + os::setBinaryMode(stdout); retrace::verbosity = -2; } } else if (!strcmp(arg, "-S")) { - arg = argv[++i]; - if (!strcmp(arg, "frame")) { - snapshot_frequency = FREQUENCY_FRAME; - } else if (!strcmp(arg, "framebuffer")) { - snapshot_frequency = FREQUENCY_FRAMEBUFFER; - } else if (!strcmp(arg, "draw")) { - snapshot_frequency = FREQUENCY_DRAW; - } else { - std::cerr << "error: unknown frequency " << arg << "\n"; - usage(); - return 1; - } + snapshot_frequency = trace::CallSet(argv[++i]); if (snapshot_prefix == NULL) { snapshot_prefix = ""; } @@ -317,7 +363,10 @@ int main(int argc, char **argv) } glws::init(); - visual = glws::createVisual(double_buffer); + visual[glws::PROFILE_COMPAT] = glws::createVisual(double_buffer, glws::PROFILE_COMPAT); + visual[glws::PROFILE_CORE] = glws::createVisual(double_buffer, glws::PROFILE_CORE); + visual[glws::PROFILE_ES1] = glws::createVisual(double_buffer, glws::PROFILE_ES1); + visual[glws::PROFILE_ES2] = glws::createVisual(double_buffer, glws::PROFILE_ES2); for ( ; i < argc; ++i) { if (!parser.open(argv[i])) { @@ -329,8 +378,11 @@ int main(int argc, char **argv) parser.close(); } - - delete visual; + + for (int n = 0; n < glws::PROFILE_MAX; n++) { + delete visual[n]; + } + glws::cleanup(); return 0;