Files
WickedEngine/WickedEngine/wiProfiler.cpp
T
turanszkij cda074370b refactor
2017-03-06 17:00:11 +01:00

180 lines
3.8 KiB
C++

#include "wiProfiler.h"
#include "wiGraphicsDevice.h"
#include "wiRenderer.h"
#include "wiFont.h"
using namespace wiGraphicsTypes;
void wiProfiler::BeginFrame()
{
if (!ENABLED)
return;
wiRenderer::GetDevice()->LOCK();
wiRenderer::GetDevice()->QueryBegin(&disjoint, GRAPHICSTHREAD_IMMEDIATE);
wiRenderer::GetDevice()->UNLOCK();
}
void wiProfiler::EndFrame()
{
if (!ENABLED)
return;
wiRenderer::GetDevice()->LOCK();
wiRenderer::GetDevice()->QueryEnd(&disjoint, GRAPHICSTHREAD_IMMEDIATE);
while(!wiRenderer::GetDevice()->QueryRead(&disjoint, GRAPHICSTHREAD_IMMEDIATE));
assert(rangeStack.empty() && "There was a range which was not ended!");
if (disjoint.result_disjoint == FALSE)
{
for (auto& x : ranges)
{
x.second->time = 0;
switch (x.second->domain)
{
case wiProfiler::DOMAIN_CPU:
x.second->time = (float)abs(x.second->cpuEnd.elapsed() - x.second->cpuBegin.elapsed());
break;
case wiProfiler::DOMAIN_GPU:
while (!wiRenderer::GetDevice()->QueryRead(&x.second->gpuBegin, GRAPHICSTHREAD_IMMEDIATE));
while (!wiRenderer::GetDevice()->QueryRead(&x.second->gpuEnd, GRAPHICSTHREAD_IMMEDIATE));
x.second->time = abs((float)(x.second->gpuEnd.result_timestamp - x.second->gpuBegin.result_timestamp) / disjoint.result_timestamp_frequency * 1000.0f);
break;
default:
assert(0);
break;
}
}
}
wiRenderer::GetDevice()->UNLOCK();
}
void wiProfiler::BeginRange(const std::string& name, PROFILER_DOMAIN domain, GRAPHICSTHREAD threadID)
{
if (!ENABLED)
return;
if (ranges.find(name) == ranges.end())
{
Range* range = new Range;
range->name = name;
range->domain = domain;
range->time = 0;
switch (domain)
{
case wiProfiler::DOMAIN_CPU:
range->cpuBegin.Start();
range->cpuEnd.Start();
break;
case wiProfiler::DOMAIN_GPU:
{
GPUQueryDesc desc;
desc.async_latency = 4;
desc.MiscFlags = 0;
desc.Type = GPU_QUERY_TYPE_TIMESTAMP;
wiRenderer::GetDevice()->CreateQuery(&desc, &range->gpuBegin);
wiRenderer::GetDevice()->CreateQuery(&desc, &range->gpuEnd);
}
break;
default:
assert(0);
break;
}
ranges.insert(make_pair(name, range));
}
switch (domain)
{
case wiProfiler::DOMAIN_CPU:
ranges[name]->cpuBegin.record();
break;
case wiProfiler::DOMAIN_GPU:
wiRenderer::GetDevice()->QueryEnd(&ranges[name]->gpuBegin, threadID);
break;
default:
assert(0);
break;
}
rangeStack.push(name);
}
void wiProfiler::EndRange(GRAPHICSTHREAD threadID)
{
if (!ENABLED)
return;
assert(!rangeStack.empty() && "There is no range to end!");
const string& top = rangeStack.top();
auto& it = ranges.find(top);
if (it != ranges.end())
{
switch (it->second->domain)
{
case wiProfiler::DOMAIN_CPU:
it->second->cpuEnd.record();
break;
case wiProfiler::DOMAIN_GPU:
wiRenderer::GetDevice()->QueryEnd(&it->second->gpuEnd, threadID);
break;
default:
assert(0);
break;
}
}
else
{
assert(0);
}
rangeStack.pop();
}
void wiProfiler::DrawData(int x, int y, GRAPHICSTHREAD threadID)
{
if (!ENABLED)
return;
stringstream ss("");
ss.precision(2);
ss << "Frame Profiler Ranges:" << endl << "----------------------------" << endl;
for (int domain = DOMAIN_CPU; domain < DOMAIN_COUNT; ++domain)
{
for (auto& x : ranges)
{
if (x.second->domain == domain)
{
ss << x.first << ": " << fixed << x.second->time << " ms" << endl;
}
}
ss << endl;
}
wiFont(ss.str(), wiFontProps(x, y, -1, WIFALIGN_LEFT, WIFALIGN_TOP, 2, 1, wiColor(255,255,255,255), wiColor(0,0,0,255))).Draw(threadID);
}
wiProfiler::wiProfiler()
{
ranges.reserve(100);
GPUQueryDesc desc;
desc.async_latency = 4;
desc.MiscFlags = 0;
desc.Type = GPU_QUERY_TYPE_TIMESTAMP_DISJOINT;
wiRenderer::GetDevice()->CreateQuery(&desc, &disjoint);
ENABLED = true;
}
wiProfiler::~wiProfiler()
{
for (auto& x : ranges)
{
SAFE_DELETE(x.second);
}
}