From c53c649fae47d25824e905e3a08d7a27585ffc3f Mon Sep 17 00:00:00 2001 From: James Benton Date: Mon, 13 Aug 2012 18:21:16 +0100 Subject: CPU Profiling now includes all OpenGL calls (was only draw calls). This only affects CPU profiling, not GPU or non-occluded pixels. --- common/trace_profiler.cpp | 27 +++++++++------ common/trace_profiler.hpp | 21 ++++++------ retrace/glretrace.hpp | 4 +-- retrace/glretrace.py | 17 ++++++---- retrace/glretrace_main.cpp | 85 +++++++++++++++++++++++++++++----------------- 5 files changed, 94 insertions(+), 60 deletions(-) diff --git a/common/trace_profiler.cpp b/common/trace_profiler.cpp index 2d126980..403c2609 100644 --- a/common/trace_profiler.cpp +++ b/common/trace_profiler.cpp @@ -55,27 +55,32 @@ void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_) std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl; } -void Profiler::setBaseTimes(uint64_t gpuStart, uint64_t cpuStart) +void Profiler::setBaseTimes(int64_t gpuStart, int64_t cpuStart) { baseCpuTime = cpuStart; baseGpuTime = gpuStart; } +bool Profiler::hasBaseTimes() +{ + return baseCpuTime != 0 || baseGpuTime != 0; +} + void Profiler::addCall(unsigned no, const char *name, unsigned program, - uint64_t pixels, - uint64_t gpuStart, uint64_t gpuDuration, - uint64_t cpuStart, uint64_t cpuDuration) + int64_t pixels, + int64_t gpuStart, int64_t gpuDuration, + int64_t cpuStart, int64_t cpuDuration) { - if (gpuTimes) { + if (gpuTimes && gpuStart) { gpuStart -= baseGpuTime; } else { gpuStart = 0; gpuDuration = 0; } - if (cpuTimes) { + if (cpuTimes && cpuStart) { double cpuTimeScale = 1.0E9 / os::timeFrequency; cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale; cpuDuration = cpuDuration * cpuTimeScale; @@ -100,7 +105,7 @@ void Profiler::addCall(unsigned no, << std::endl; } -void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart) +void Profiler::addFrameStart(unsigned no, int64_t gpuStart, int64_t cpuStart) { lastFrame.no = no; lastFrame.gpuStart = gpuStart; @@ -126,9 +131,9 @@ void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart) << std::endl; } -void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd) +void Profiler::addFrameEnd(int64_t gpuEnd, int64_t cpuEnd) { - uint64_t gpuDuration, cpuDuration; + int64_t gpuDuration, cpuDuration; if (gpuTimes) { gpuDuration = gpuEnd - lastFrame.gpuStart; @@ -179,7 +184,9 @@ void Profiler::parseLine(const char* in, Profile* profile) >> call.program >> call.name; - profile->frames.back().calls.push_back(call); + if (call.pixels >= 0) { + profile->frames.back().calls.push_back(call); + } } else if (type.compare("frame_begin") == 0) { Profile::Frame frame; frame.gpuDuration = 0; diff --git a/common/trace_profiler.hpp b/common/trace_profiler.hpp index 78783f5a..dc3c4be0 100644 --- a/common/trace_profiler.hpp +++ b/common/trace_profiler.hpp @@ -71,23 +71,24 @@ public: ~Profiler(); void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_); - void setBaseTimes(uint64_t gpuStart, uint64_t cpuStart); + void setBaseTimes(int64_t gpuStart, int64_t cpuStart); + bool hasBaseTimes(); - void addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart); - void addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd); + void addFrameStart(unsigned no, int64_t gpuStart, int64_t cpuStart); + void addFrameEnd(int64_t gpuEnd, int64_t cpuEnd); void addCall(unsigned no, const char* name, unsigned program, - uint64_t pixels, - uint64_t gpuStart, uint64_t gpuDuration, - uint64_t cpuStart, uint64_t cpuDuration); + int64_t pixels, + int64_t gpuStart, int64_t gpuDuration, + int64_t cpuStart, int64_t cpuDuration); static void parseLine(const char* line, Profile* profile); private: - uint64_t baseGpuTime; - uint64_t baseCpuTime; + int64_t baseGpuTime; + int64_t baseCpuTime; bool cpuTimes; bool gpuTimes; @@ -95,8 +96,8 @@ private: struct { unsigned no; - uint64_t gpuStart; - uint64_t cpuStart; + int64_t gpuStart; + int64_t cpuStart; } lastFrame; }; } diff --git a/retrace/glretrace.hpp b/retrace/glretrace.hpp index 27085d48..568049ec 100644 --- a/retrace/glretrace.hpp +++ b/retrace/glretrace.hpp @@ -90,8 +90,8 @@ void initContext(); void updateDrawable(int width, int height); void flushQueries(); -void beginProfile(trace::Call &call); -void endProfile(trace::Call &call); +void beginProfile(trace::Call &call, bool isDraw); +void endProfile(trace::Call &call, bool isDraw); } /* namespace glretrace */ diff --git a/retrace/glretrace.py b/retrace/glretrace.py index 987798fe..6c73e697 100644 --- a/retrace/glretrace.py +++ b/retrace/glretrace.py @@ -310,9 +310,12 @@ class GlRetracer(Retracer): if function.name == 'glEndList': print r' glretrace::insideList = false;' - if profileDraw and function.name != 'glEnd': + if function.name != 'glEnd': print r' if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {' - print r' glretrace::beginProfile(call);' + if profileDraw: + print r' glretrace::beginProfile(call, true);' + else: + print r' glretrace::beginProfile(call, false);' print r' }' if function.name == 'glCreateShaderProgramv': @@ -349,10 +352,12 @@ class GlRetracer(Retracer): if function.name == "glBegin": print ' glretrace::insideGlBeginEnd = true;' - if profileDraw or function.name == 'glEnd': - print r' if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {' - print r' glretrace::endProfile(call);' - print r' }' + print r' if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {' + if profileDraw: + print r' glretrace::endProfile(call, true);' + else: + print r' glretrace::endProfile(call, false);' + print r' }' # Error checking if function.name.startswith('gl'): diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp index 8bd52762..c01b67d2 100755 --- a/retrace/glretrace_main.cpp +++ b/retrace/glretrace_main.cpp @@ -49,8 +49,8 @@ struct CallQuery unsigned call; GLuint program; const trace::FunctionSig *sig; - uint64_t cpuStart; - uint64_t cpuEnd; + int64_t cpuStart; + int64_t cpuEnd; }; static bool supportsElapsed = true; @@ -109,22 +109,22 @@ checkGlError(trace::Call &call) { os << "\n"; } -static inline GLuint64 +static inline GLint64 getGpuTimestamp() { GLuint query = 0; - GLuint64 timestamp = 0; + GLint64 timestamp = 0; if (retrace::profilingGpuTimes && supportsTimestamp) { glGenQueries(1, &query); glQueryCounter(query, GL_TIMESTAMP); - glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT, ×tamp); + glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, ×tamp); glDeleteQueries(1, &query); } return timestamp; } -static inline GLuint64 +static inline GLint64 getCpuTimestamp() { if (retrace::profilingCpuTimes) { return os::getTime(); @@ -136,14 +136,14 @@ getCpuTimestamp() { static void completeCallQuery(CallQuery& query) { /* Get call start and duration */ - GLuint64 gpuStart = 0, gpuDuration = 0, cpuDuration = 0, samples = 0; + GLint64 gpuStart = 0, gpuDuration = 0, cpuDuration = 0, samples = 0; if (retrace::profilingGpuTimes) { if (supportsTimestamp) { - glGetQueryObjectui64vEXT(query.ids[0], GL_QUERY_RESULT, &gpuStart); + glGetQueryObjecti64vEXT(query.ids[0], GL_QUERY_RESULT, &gpuStart); } - glGetQueryObjectui64vEXT(query.ids[1], GL_QUERY_RESULT, &gpuDuration); + glGetQueryObjecti64vEXT(query.ids[1], GL_QUERY_RESULT, &gpuDuration); } if (retrace::profilingCpuTimes) { @@ -151,7 +151,7 @@ completeCallQuery(CallQuery& query) { } if (retrace::profilingPixelsDrawn) { - glGetQueryObjectui64vEXT(query.ids[2], GL_QUERY_RESULT, &samples); + glGetQueryObjecti64vEXT(query.ids[2], GL_QUERY_RESULT, &samples); } glDeleteQueries(3, query.ids); @@ -170,7 +170,7 @@ flushQueries() { } void -beginProfile(trace::Call &call) { +beginProfile(trace::Call &call, bool isDraw) { if (firstFrame) { frame_start(); } @@ -181,18 +181,20 @@ beginProfile(trace::Call &call) { query.sig = call.sig; query.program = glretrace::currentContext ? glretrace::currentContext->activeProgram : 0; - glGenQueries(3, query.ids); + if (isDraw) { + glGenQueries(3, query.ids); - if (retrace::profilingGpuTimes) { - if (supportsTimestamp) { - glQueryCounter(query.ids[0], GL_TIMESTAMP); - } + if (retrace::profilingGpuTimes) { + if (supportsTimestamp) { + glQueryCounter(query.ids[0], GL_TIMESTAMP); + } - glBeginQuery(GL_TIME_ELAPSED, query.ids[1]); - } + glBeginQuery(GL_TIME_ELAPSED, query.ids[1]); + } - if (retrace::profilingPixelsDrawn) { - glBeginQuery(GL_SAMPLES_PASSED, query.ids[2]); + if (retrace::profilingPixelsDrawn) { + glBeginQuery(GL_SAMPLES_PASSED, query.ids[2]); + } } if (retrace::profilingCpuTimes) { @@ -203,24 +205,31 @@ beginProfile(trace::Call &call) { } void -endProfile(trace::Call &call) { +endProfile(trace::Call &call, bool isDraw) { if (retrace::profilingCpuTimes) { CallQuery& query = callQueries.back(); query.cpuEnd = getCpuTimestamp(); - } - if (retrace::profilingGpuTimes) { - glEndQuery(GL_TIME_ELAPSED); + if (!isDraw) { + retrace::profiler.addCall(query.call, query.sig->name, query.program, -1, 0, 0, query.cpuStart, query.cpuEnd - query.cpuStart); + callQueries.pop_back(); + } } - if (retrace::profilingPixelsDrawn) { - glEndQuery(GL_SAMPLES_PASSED); + if (isDraw) { + if (retrace::profilingGpuTimes) { + glEndQuery(GL_TIME_ELAPSED); + } + + if (retrace::profilingPixelsDrawn) { + glEndQuery(GL_SAMPLES_PASSED); + } } } void initContext() { - GLuint64 gpuTime, cpuTime; + GLint64 gpuTime = 0, cpuTime = 0; const char* extensions; extensions = (const char*)glGetString(GL_EXTENSIONS); @@ -260,9 +269,17 @@ initContext() { } /* Sync the gpu and cpu start times */ - gpuTime = getGpuTimestamp(); - cpuTime = getCpuTimestamp(); - retrace::profiler.setBaseTimes(gpuTime, cpuTime); + if (!retrace::profiler.hasBaseTimes()) { + if (retrace::profilingGpuTimes) { + gpuTime = getGpuTimestamp(); + } + + if (retrace::profilingCpuTimes) { + cpuTime = getCpuTimestamp(); + } + + retrace::profiler.setBaseTimes(gpuTime, cpuTime); + } } void @@ -270,7 +287,9 @@ frame_start() { firstFrame = false; if (retrace::profiling) { - retrace::profiler.addFrameStart(retrace::frameNo, getGpuTimestamp(), getCpuTimestamp()); + int64_t gpuStart = getGpuTimestamp(); + int64_t cpuStart = getCpuTimestamp(); + retrace::profiler.addFrameStart(retrace::frameNo, gpuStart, cpuStart); } } @@ -281,7 +300,9 @@ frame_complete(trace::Call &call) { flushQueries(); /* Indicate end of current frame */ - retrace::profiler.addFrameEnd(getGpuTimestamp(), getCpuTimestamp()); + int64_t gpuEnd = getGpuTimestamp(); + int64_t cpuEnd = getCpuTimestamp(); + retrace::profiler.addFrameEnd(gpuEnd, cpuEnd); } retrace::frameComplete(call); -- cgit v1.2.3