]> git.cworth.org Git - apitrace/blobdiff - common/trace_profiler.cpp
Synchronise gpuStart and cpuStart for profiling.
[apitrace] / common / trace_profiler.cpp
index fdc0fd4a2f748c170c464bbd7af12e6852d4f68b..2d12698083a5082d0ed13d94f68e59759a19a708 100644 (file)
 
 #include "trace_profiler.hpp"
 #include <iostream>
+#include <string.h>
+#include <assert.h>
+#include <sstream>
+#include "os_time.hpp"
 
 namespace trace {
 Profiler::Profiler()
-    : baseTime(0)
+    : baseGpuTime(0),
+      baseCpuTime(0),
+      cpuTimes(false),
+      gpuTimes(true),
+      pixelsDrawn(false)
 {
 }
 
@@ -36,26 +44,162 @@ Profiler::~Profiler()
 {
 }
 
-void Profiler::addCall(const Call& call)
+void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
 {
-    if (baseTime == 0)
-        baseTime = call.gpu.start;
+    cpuTimes = cpuTimes_;
+    gpuTimes = gpuTimes_;
+    pixelsDrawn = pixelsDrawn_;
 
-    std::cout << "call "
-              << call.no << " "
-              << (call.gpu.start - baseTime) << " "
-              << call.gpu.duration << " "
-              << call.name << std::endl;
+    std::cout << "# frame_begin no gpu_start cpu_start" << std::endl;
+    std::cout << "# frame_end no gpu_end gpu_dura cpu_end cpu_dura" << std::endl;
+    std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
 }
 
-void Profiler::addFrame(const Frame& frame)
+void Profiler::setBaseTimes(uint64_t gpuStart, uint64_t cpuStart)
 {
-    if (baseTime == 0)
-        baseTime = frame.gpu.start;
+    baseCpuTime = cpuStart;
+    baseGpuTime = gpuStart;
+}
+
+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)
+{
+    if (gpuTimes) {
+        gpuStart -= baseGpuTime;
+    } else {
+        gpuStart = 0;
+        gpuDuration = 0;
+    }
+
+    if (cpuTimes) {
+        double cpuTimeScale = 1.0E9 / os::timeFrequency;
+        cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
+        cpuDuration = cpuDuration * cpuTimeScale;
+    } else {
+        cpuStart = 0;
+        cpuDuration = 0;
+    }
+
+    if (!pixelsDrawn) {
+        pixels = 0;
+    }
+
+    std::cout << "call"
+              << " " << no
+              << " " << gpuStart
+              << " " << gpuDuration
+              << " " << cpuStart
+              << " " << cpuDuration
+              << " " << pixels
+              << " " << program
+              << " " << name
+              << std::endl;
+}
+
+void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart)
+{
+    lastFrame.no = no;
+    lastFrame.gpuStart = gpuStart;
+    lastFrame.cpuStart = cpuStart;
+
+    if (gpuTimes) {
+        gpuStart = gpuStart - baseGpuTime;
+    } else {
+        gpuStart = 0;
+    }
+
+    if (cpuTimes) {
+        double cpuTimeScale = 1.0E9 / os::timeFrequency;
+        cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
+    } else {
+        cpuStart = 0;
+    }
+
+    std::cout << "frame_begin"
+              << " " << no
+              << " " << gpuStart
+              << " " << cpuStart
+              << std::endl;
+}
+
+void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd)
+{
+    uint64_t gpuDuration, cpuDuration;
+
+    if (gpuTimes) {
+        gpuDuration = gpuEnd - lastFrame.gpuStart;
+        gpuEnd = gpuEnd - baseGpuTime;
+    } else {
+        gpuEnd = 0;
+        gpuDuration = 0;
+    }
+
+    if (cpuTimes) {
+        double cpuTimeScale = 1.0E9 / os::timeFrequency;
+        cpuDuration = (cpuEnd - lastFrame.cpuStart) * cpuTimeScale;
+        cpuEnd = (cpuEnd - baseCpuTime) * cpuTimeScale;
+    } else {
+        cpuEnd = 0;
+        cpuDuration = 0;
+    }
+
+    std::cout << "frame_end"
+              << " " << lastFrame.no
+              << " " << gpuEnd
+              << " " << gpuDuration
+              << " " << cpuEnd
+              << " " << cpuDuration
+              << std::endl;
+}
+
+void Profiler::parseLine(const char* in, Profile* profile)
+{
+    std::stringstream line(in, std::ios_base::in);
+    std::string type;
+
+    if (in[0] == '#' || strlen(in) < 12)
+        return;
+
+    line >> type;
+
+    if (type.compare("call") == 0) {
+        assert(profile->frames.size());
+        Profile::Call call;
+
+        line >> call.no
+             >> call.gpuStart
+             >> call.gpuDuration
+             >> call.cpuStart
+             >> call.cpuDuration
+             >> call.pixels
+             >> call.program
+             >> call.name;
+
+        profile->frames.back().calls.push_back(call);
+    } else if (type.compare("frame_begin") == 0) {
+        Profile::Frame frame;
+        frame.gpuDuration = 0;
+        frame.cpuDuration = 0;
+
+        line >> frame.no
+             >> frame.gpuStart
+             >> frame.cpuStart;
+
+        profile->frames.push_back(frame);
+    } else if (type.compare("frame_end") == 0) {
+        assert(profile->frames.size());
+        Profile::Frame& frame = profile->frames.back();
+        int64_t skipi64;
 
-    std::cout << "frame "
-              << frame.no << " "
-              << (frame.gpu.start - baseTime) << " "
-              << frame.gpu.duration << std::endl;
+        line >> frame.no
+             >> skipi64
+             >> frame.gpuDuration
+             >> skipi64
+             >> frame.cpuDuration;
+    }
 }
 }