[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