X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Ftrace_profiler.cpp;h=0f90ee2766318c54f790fc110efd772b8126f309;hb=77373c35010d89e5ab3f030e4c60f8f6e3fdbe82;hp=6fc00395cd1d3de808d8ae999f05f9540f10a86a;hpb=6d92327e88d2bb4c03a1b84663e50497f99fc24f;p=apitrace diff --git a/common/trace_profiler.cpp b/common/trace_profiler.cpp index 6fc0039..0f90ee2 100644 --- a/common/trace_profiler.cpp +++ b/common/trace_profiler.cpp @@ -24,13 +24,16 @@ **************************************************************************/ #include "trace_profiler.hpp" +#include "os_time.hpp" #include +#include +#include namespace trace { Profiler::Profiler() - : lastProgram(0), - baseGpuTime(0), + : baseGpuTime(0), baseCpuTime(0), + minCpuTime(1000), cpuTimes(false), gpuTimes(true), pixelsDrawn(false) @@ -47,109 +50,151 @@ void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_) gpuTimes = gpuTimes_; pixelsDrawn = pixelsDrawn_; - std::cout << "# frame begin " << std::endl; - std::cout << "# frame end " << std::endl; - std::cout << "# call " << std::endl; - std::cout << "# use shader program " << std::endl; + std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl; } -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 Profiler::getBaseCpuTime() { - if (baseGpuTime == 0) - baseGpuTime = gpuStart; - - if (baseCpuTime == 0) - baseCpuTime = cpuStart; - - if (program != lastProgram) { - std::cout << "use shader program " << program << std::endl; - lastProgram = program; - } - - std::cout << "call " << no; - - if (gpuTimes) { - std::cout << " " - << (gpuStart - baseGpuTime) << " " - << gpuDuration; - } else { - std::cout << " _ _"; - } - - if (cpuTimes) { - std::cout << " " - << (cpuStart - baseCpuTime) << " " - << cpuDuration; - } else { - std::cout << " _ _"; - } + return baseCpuTime; +} - if (pixelsDrawn) { - std::cout << " " << pixels; - } else { - std::cout << " _"; - } +int64_t Profiler::getBaseGpuTime() +{ + return baseGpuTime; +} - std::cout << " " << name << std::endl; +void Profiler::setBaseCpuTime(int64_t cpuStart) +{ + baseCpuTime = cpuStart; } -void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart) +void Profiler::setBaseGpuTime(int64_t gpuStart) { - if (baseGpuTime == 0) - baseGpuTime = gpuStart; + baseGpuTime = gpuStart; +} - if (baseCpuTime == 0) - baseCpuTime = cpuStart; +bool Profiler::hasBaseTimes() +{ + return baseCpuTime != 0 || baseGpuTime != 0; +} - lastFrame.no = no; - lastFrame.gpuStart = gpuStart - baseGpuTime; +void Profiler::addCall(unsigned no, + const char *name, + unsigned program, + int64_t pixels, + int64_t gpuStart, int64_t gpuDuration, + int64_t cpuStart, int64_t cpuDuration) +{ + if (gpuTimes && gpuStart) { + gpuStart -= baseGpuTime; + } else { + gpuStart = 0; + gpuDuration = 0; + } - std::cout << "frame begin " << lastFrame.no; + if (cpuTimes && cpuStart) { + double cpuTimeScale = 1.0E9 / os::timeFrequency; + cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale; + cpuDuration = cpuDuration * cpuTimeScale; - if (gpuTimes) { - std::cout << " " << lastFrame.gpuStart; + if (cpuDuration < minCpuTime) { + return; + } } else { - std::cout << " _"; + cpuStart = 0; + cpuDuration = 0; } - if (gpuTimes) { - std::cout << " " << lastFrame.cpuStart; - } else { - std::cout << " _"; + if (!pixelsDrawn) { + pixels = 0; } - std::cout << std::endl; + std::cout << "call" + << " " << no + << " " << gpuStart + << " " << gpuDuration + << " " << cpuStart + << " " << cpuDuration + << " " << pixels + << " " << program + << " " << name + << std::endl; } -void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd) +void Profiler::addFrameEnd() { - if (baseGpuTime == 0) - baseGpuTime = gpuEnd; - - if (baseCpuTime == 0) - baseCpuTime = cpuEnd; + std::cout << "frame_end" << std::endl; +} - lastFrame.gpuEnd = gpuEnd - baseGpuTime; +void Profiler::parseLine(const char* in, Profile* profile) +{ + std::stringstream line(in, std::ios_base::in); + std::string type; + static int64_t lastGpuTime; + static int64_t lastCpuTime; - std::cout << "frame end " << lastFrame.no; + if (in[0] == '#' || strlen(in) < 4) + return; - if (gpuTimes) { - std::cout << " " << lastFrame.gpuEnd << " " << (lastFrame.gpuEnd - lastFrame.gpuStart); - } else { - std::cout << " _ _"; + if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) { + lastGpuTime = 0; + lastCpuTime = 0; } - if (cpuTimes) { - std::cout << " " << lastFrame.cpuEnd << " " << (lastFrame.cpuEnd - lastFrame.cpuStart); - } else { - std::cout << " _ _"; + line >> type; + + if (type.compare("call") == 0) { + Profile::Call call; + + line >> call.no + >> call.gpuStart + >> call.gpuDuration + >> call.cpuStart + >> call.cpuDuration + >> call.pixels + >> call.program + >> call.name; + + if (lastGpuTime < call.gpuStart + call.gpuDuration) { + lastGpuTime = call.gpuStart + call.gpuDuration; + } + + if (lastCpuTime < call.cpuStart + call.cpuDuration) { + lastCpuTime = call.cpuStart + call.cpuDuration; + } + + profile->calls.push_back(call); + + if (call.pixels >= 0) { + if (profile->programs.size() <= call.program) { + profile->programs.resize(call.program + 1); + } + + Profile::Program& program = profile->programs[call.program]; + program.cpuTotal += call.cpuDuration; + program.gpuTotal += call.gpuDuration; + program.pixelTotal += call.pixels; + program.calls.push_back(profile->calls.size() - 1); + } + } else if (type.compare("frame_end") == 0) { + Profile::Frame frame; + frame.no = profile->frames.size(); + + if (frame.no == 0) { + frame.gpuStart = 0; + frame.cpuStart = 0; + frame.calls.begin = 0; + } else { + frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration; + frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration; + frame.calls.begin = profile->frames.back().calls.end + 1; + } + + frame.gpuDuration = lastGpuTime - frame.gpuStart; + frame.cpuDuration = lastCpuTime - frame.cpuStart; + frame.calls.end = profile->calls.size() - 1; + + profile->frames.push_back(frame); } - - std::cout << std::endl; } }