port from perforce
This commit is contained in:
168
hgplus/bliss/Engine/profiler.h
Normal file
168
hgplus/bliss/Engine/profiler.h
Normal file
@@ -0,0 +1,168 @@
|
||||
#ifdef _DEBUG
|
||||
|
||||
class Profiler
|
||||
{
|
||||
public:
|
||||
static Profiler GlobalProfiler;
|
||||
bool EnableProfiling;
|
||||
|
||||
void Initialize(ID3D11Device* device, ID3D11DeviceContext* immContext)
|
||||
{
|
||||
this->device = device;
|
||||
this->context = immContext;
|
||||
this->currentFrame = 0;
|
||||
this->EnableProfiling = false;
|
||||
}
|
||||
|
||||
void StartFrame()
|
||||
{
|
||||
currentFrame++;
|
||||
profileCount = 0;
|
||||
|
||||
if (!EnableProfiling)
|
||||
return;
|
||||
|
||||
startFrame = currentFrame;
|
||||
}
|
||||
|
||||
int StartProfile(char* name)
|
||||
{
|
||||
if (!EnableProfiling)
|
||||
return -1;
|
||||
|
||||
int index = profileCount++;
|
||||
ProfileData& profileData = profiles[index];
|
||||
profileData.Name = name;
|
||||
|
||||
// Create the queries
|
||||
D3D11_QUERY_DESC desc;
|
||||
desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;
|
||||
desc.MiscFlags = 0;
|
||||
device->CreateQuery(&desc, &profileData.DisjointQuery);
|
||||
|
||||
desc.Query = D3D11_QUERY_TIMESTAMP;
|
||||
device->CreateQuery(&desc, &profileData.TimestampStartQuery);
|
||||
device->CreateQuery(&desc, &profileData.TimestampEndQuery);
|
||||
|
||||
// Start a disjoint query first
|
||||
context->Begin(profileData.DisjointQuery);
|
||||
|
||||
// Insert the start timestamp
|
||||
context->End(profileData.TimestampStartQuery);
|
||||
|
||||
profileData.QueryStarted = TRUE;
|
||||
profileData.QueryFinished = FALSE;
|
||||
return index;
|
||||
}
|
||||
|
||||
void EndProfile(int index)
|
||||
{
|
||||
if (!EnableProfiling)
|
||||
return;
|
||||
|
||||
ProfileData& profileData = profiles[index];
|
||||
|
||||
if (profileData.QueryFinished)
|
||||
throw;
|
||||
|
||||
// Insert the end timestamp
|
||||
context->End(profileData.TimestampEndQuery);
|
||||
|
||||
// End the disjoint query
|
||||
context->End(profileData.DisjointQuery);
|
||||
|
||||
profileData.QueryStarted = FALSE;
|
||||
profileData.QueryFinished = TRUE;
|
||||
}
|
||||
|
||||
void EndFrame()
|
||||
{
|
||||
if (currentFrame < startFrame + queryLatency)
|
||||
return;
|
||||
|
||||
if (!EnableProfiling)
|
||||
return;
|
||||
|
||||
deviceContext->Flush();
|
||||
EnableProfiling = false;
|
||||
float queryTime = 0.0f;
|
||||
|
||||
// Iterate over all of the profiles
|
||||
for (int i = 0; i < profileCount; ++i)
|
||||
{
|
||||
ProfileData& profile = profiles[i];
|
||||
if (profile.QueryFinished == FALSE)
|
||||
continue;
|
||||
|
||||
profile.QueryFinished = FALSE;
|
||||
|
||||
// Get the query data
|
||||
UINT64 startTime = 0;
|
||||
while (context->GetData(profile.TimestampStartQuery, &startTime, sizeof(startTime), 0) != S_OK);
|
||||
|
||||
UINT64 endTime = 0;
|
||||
while (context->GetData(profile.TimestampEndQuery, &endTime, sizeof(endTime), 0) != S_OK);
|
||||
|
||||
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData;
|
||||
while (context->GetData(profile.DisjointQuery, &disjointData, sizeof(disjointData), 0) != S_OK);
|
||||
|
||||
float time = 9.0f;
|
||||
if (disjointData.Disjoint == FALSE)
|
||||
{
|
||||
UINT64 delta = endTime - startTime;
|
||||
float frequency = static_cast<float>(disjointData.Frequency);
|
||||
time = (delta * 1000.0f) / frequency;
|
||||
}
|
||||
|
||||
char message[256] = { 0 };
|
||||
sprintf_s(message, 256, "%s: %.8f ms\n", profile.Name, time);
|
||||
printf(message);
|
||||
OutputDebugStringA(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
struct ProfileData
|
||||
{
|
||||
ID3D11Query* DisjointQuery;
|
||||
ID3D11Query* TimestampStartQuery;
|
||||
ID3D11Query* TimestampEndQuery;
|
||||
BOOL QueryStarted;
|
||||
BOOL QueryFinished;
|
||||
char* Name;
|
||||
|
||||
ProfileData() : QueryStarted(FALSE), QueryFinished(FALSE) {}
|
||||
};
|
||||
|
||||
typedef ProfileData ProfileMap[64];
|
||||
|
||||
ProfileMap profiles;
|
||||
int profileCount;
|
||||
int startFrame;
|
||||
int currentFrame;
|
||||
const int queryLatency = 5;
|
||||
|
||||
ID3D11Device* device;
|
||||
ID3D11DeviceContext* context;
|
||||
};
|
||||
|
||||
struct ProfileBlock
|
||||
{
|
||||
public:
|
||||
|
||||
ProfileBlock(char* name)
|
||||
{
|
||||
this->index = Profiler::GlobalProfiler.StartProfile(name);
|
||||
}
|
||||
|
||||
~ProfileBlock()
|
||||
{
|
||||
Profiler::GlobalProfiler.EndProfile(this->index);
|
||||
}
|
||||
|
||||
protected:
|
||||
int index;
|
||||
};
|
||||
|
||||
Profiler Profiler::GlobalProfiler;
|
||||
#endif
|
||||
Reference in New Issue
Block a user