[PATCH] Add profiling support to d3dretrace
Jeff Muizelaar
jmuizelaar at mozilla.com
Tue Dec 10 14:20:18 PST 2013
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();'
More information about the apitrace
mailing list