This works the same way as in glretrace. diff --git a/retrace/d3dretrace.hpp b/retrace/d3dretrace.hpp index 41cc1c5..aea8c03 100644 --- a/retrace/d3dretrace.hpp +++ b/retrace/d3dretrace.hpp @@ -91,6 +91,9 @@ resizeWindow(HWND hWnd, int width, int height); bool processEvents(void); +void frame_complete(trace::Call &call); +void beginProfile(trace::Call &call); +void endProfile(trace::Call &call); } /* namespace d3dretrace */ diff --git a/retrace/d3dretrace_main.cpp b/retrace/d3dretrace_main.cpp index 33fb835..df6d8bc 100644 --- a/retrace/d3dretrace_main.cpp +++ b/retrace/d3dretrace_main.cpp @@ -27,11 +27,108 @@ #include <string.h> #include "os_string.hpp" +#include "os_time.hpp" #include "d3dstate.hpp" #include "retrace.hpp" #include "d3dretrace.hpp" +namespace d3dretrace { + +struct CallQuery +{ + unsigned call; + bool isDraw; + const trace::FunctionSig *sig; + int64_t cpuStart; + int64_t cpuEnd; + int64_t vsizeStart; + int64_t vsizeEnd; + int64_t rssStart; + int64_t rssEnd; +}; +static std::list<CallQuery> callQueries; + + +static inline int64_t +getTimeFrequency(void) { + return os::timeFrequency; +} + +static inline int64_t +getCurrentTime(void) { + return os::getTime(); +} + + +static void +completeCallQuery(CallQuery& query) { + /* Get call start and duration */ + int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0; + + pixels = -1; + + if (retrace::profilingCpuTimes) { + double cpuTimeScale = 1.0E9 / getTimeFrequency(); + cpuDuration = (query.cpuEnd - query.cpuStart) * cpuTimeScale; + query.cpuStart *= cpuTimeScale; + } + + /* Add call to profile */ + retrace::profiler.addCall(query.call, query.sig->name, 0, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration, query.vsizeStart, vsizeDuration, query.rssStart, rssDuration); +} + +void +flushQueries() { + for (std::list<CallQuery>::iterator itr = callQueries.begin(); itr != callQueries.end(); ++itr) { + completeCallQuery(*itr); + } + + callQueries.clear(); +} + +void +beginProfile(trace::Call &call) { + + /* Create call query */ + CallQuery query; + query.isDraw = false; + query.call = call.no; + query.sig = call.sig; + + callQueries.push_back(query); + + /* CPU profiling for all calls */ + if (retrace::profilingCpuTimes) { + CallQuery& query = callQueries.back(); + query.cpuStart = getCurrentTime(); + } + +} + +void +endProfile(trace::Call &call) { + /* CPU profiling for all calls */ + if (retrace::profilingCpuTimes) { + CallQuery& query = callQueries.back(); + query.cpuEnd = getCurrentTime(); + } +} + +void +frame_complete(trace::Call &call) { + if (retrace::profiling) { + /* Complete any remaining queries */ + flushQueries(); + + /* Indicate end of current frame */ + retrace::profiler.addFrameEnd(); + } + + retrace::frameComplete(call); +} + +}; void retrace::setFeatureLevel(const char *featureLevel) { diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py index f363858..7cd706a 100755 --- a/retrace/dxgiretrace.py +++ b/retrace/dxgiretrace.py @@ -218,9 +218,7 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { if method.name == 'CreateSwapChain': print r' createWindow(pDesc);' - # notify frame has been completed - if method.name == 'Present': - print r' retrace::frameComplete(call);' + print r' d3dretrace::beginProfile(call);' if 'pSharedResource' in method.argNames(): print r' if (pSharedResource) {' @@ -298,6 +296,11 @@ createWindow(DXGI_SWAP_CHAIN_DESC *pSwapChainDesc) { Retracer.invokeInterfaceMethod(self, interface, method) + print r' d3dretrace::endProfile(call);' + # notify frame has been completed + if method.name == 'Present': + print r' d3dretrace::frame_complete(call);' + # process events after presents if method.name == 'Present': print r' d3dretrace::processEvents();'
_______________________________________________ apitrace mailing list apitrace@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/apitrace