mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-13 02:01:08 +00:00
AMD GPUPerfAPI 3.0 Preview Integration.
Direct3D11, Direct3D12, OpenGL, and Vulkan supported. Fixes Direct3D11 counter command isolation.
This commit is contained in:
@@ -23,29 +23,84 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "amd_counters.h"
|
||||
#include <Windows.h>
|
||||
#include "common/common.h"
|
||||
#include "common/timing.h"
|
||||
#include "core/plugins.h"
|
||||
#include "official/GPUPerfAPI/Include/GPUPerfAPI.h"
|
||||
#include "official/GPUPerfAPI/Include/GPUPerfAPIFunctionTypes.h"
|
||||
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
inline bool AMD_FAILED(GPA_Status status)
|
||||
{
|
||||
return status != GPA_STATUS_OK;
|
||||
}
|
||||
|
||||
inline bool AMD_SUCCEEDED(GPA_Status status)
|
||||
{
|
||||
return status == GPA_STATUS_OK;
|
||||
}
|
||||
|
||||
static void GPA_LoggingCallback(GPA_Logging_Type messageType, const char *pMessage)
|
||||
{
|
||||
if(messageType == GPA_LOGGING_ERROR)
|
||||
{
|
||||
RDCWARN(pMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG(pMessage);
|
||||
}
|
||||
}
|
||||
|
||||
AMDCounters::AMDCounters() : m_pGPUPerfAPI(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
bool AMDCounters::Init(void *pContext)
|
||||
std::string AMDCounters::FormatErrMessage(const char *operation, uint32_t status)
|
||||
{
|
||||
const char *dllName = "GPUPerfAPIDX11-x64.dll";
|
||||
std::string err =
|
||||
StringFormat::Fmt("%s. %s", operation, m_pGPUPerfAPI->GPA_GetStatusAsStr((GPA_Status)status));
|
||||
return err;
|
||||
}
|
||||
|
||||
bool AMDCounters::Init(ApiType apiType, void *pContext)
|
||||
{
|
||||
#if DISABLED(RDOC_WIN32) && DISABLED(RDOC_LINUX)
|
||||
return false;
|
||||
#else
|
||||
|
||||
std::string dllName("GPUPerfAPI");
|
||||
|
||||
switch(apiType)
|
||||
{
|
||||
case ApiType::Dx11: dllName += "DX11"; break;
|
||||
case ApiType::Dx12: dllName += "DX12"; break;
|
||||
case ApiType::Ogl: dllName += "GL"; break;
|
||||
case ApiType::Vk: dllName += "VK"; break;
|
||||
default:
|
||||
RDCWARN(
|
||||
"AMD GPU performance counters could not be initialized successfully. "
|
||||
"Unsupported API type specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if ENABLED(RDOC_WIN32)
|
||||
#if ENABLED(RDOC_X64)
|
||||
dllName += "-x64";
|
||||
#endif
|
||||
dllName += ".dll";
|
||||
#else
|
||||
dllName = "lib" + dllName;
|
||||
dllName += ".so";
|
||||
#endif
|
||||
|
||||
// first try in the plugin location it will be in distributed builds
|
||||
HMODULE module = LoadLibraryA(LocatePluginFile("amd/counters", dllName).c_str());
|
||||
std::string dllPath = LocatePluginFile("amd/counters", dllName.c_str());
|
||||
|
||||
// if that failed then try checking for it just in the default search path
|
||||
void *module = Process::LoadModule(dllPath.c_str());
|
||||
if(module == NULL)
|
||||
{
|
||||
module = LoadLibraryA(dllName);
|
||||
module = Process::LoadModule(dllName.c_str());
|
||||
}
|
||||
|
||||
if(module == NULL)
|
||||
@@ -53,39 +108,52 @@ bool AMDCounters::Init(void *pContext)
|
||||
RDCWARN(
|
||||
"AMD GPU performance counters could not be initialized successfully. "
|
||||
"Are you missing the DLLs?");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pGPUPerfAPI = new GPAApi();
|
||||
GPA_GetFuncTablePtrType getFuncTable =
|
||||
(GPA_GetFuncTablePtrType)GetProcAddress(module, "GPA_GetFuncTable");
|
||||
(GPA_GetFuncTablePtrType)Process::GetFunctionAddress(module, "GPA_GetFuncTable");
|
||||
|
||||
m_pGPUPerfAPI = new GPAApi();
|
||||
if(getFuncTable)
|
||||
{
|
||||
getFuncTable((void **)&m_pGPUPerfAPI);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"GPA version is out of date, doesn't expose GPA_GetFuncTable. Make sure you have 3.0 or "
|
||||
"above.");
|
||||
delete m_pGPUPerfAPI;
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
"Failed to get GPA function table. Invalid dynamic library?");
|
||||
return false;
|
||||
}
|
||||
|
||||
GPA_Logging_Type loggingType = GPA_LOGGING_ERROR;
|
||||
#if ENABLED(RDOC_DEVEL)
|
||||
loggingType = GPA_LOGGING_ERROR_AND_MESSAGE;
|
||||
#endif
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_RegisterLoggingCallback(loggingType, GPA_LoggingCallback);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Failed to initialize logging", status).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
status = m_pGPUPerfAPI->GPA_Initialize();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Initialization failed", status).c_str());
|
||||
delete m_pGPUPerfAPI;
|
||||
m_pGPUPerfAPI = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_pGPUPerfAPI->GPA_Initialize() != GPA_STATUS_OK)
|
||||
{
|
||||
delete m_pGPUPerfAPI;
|
||||
m_pGPUPerfAPI = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_pGPUPerfAPI->GPA_OpenContext(pContext, GPA_OPENCONTEXT_HIDE_PUBLIC_COUNTERS_BIT |
|
||||
GPA_OPENCONTEXT_CLOCK_MODE_PEAK_BIT) !=
|
||||
GPA_STATUS_OK)
|
||||
status = m_pGPUPerfAPI->GPA_OpenContext(
|
||||
pContext, GPA_OPENCONTEXT_HIDE_SOFTWARE_COUNTERS_BIT | GPA_OPENCONTEXT_CLOCK_MODE_PEAK_BIT);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Open context for counters failed", status).c_str());
|
||||
m_pGPUPerfAPI->GPA_Destroy();
|
||||
delete m_pGPUPerfAPI;
|
||||
m_pGPUPerfAPI = NULL;
|
||||
@@ -95,66 +163,127 @@ bool AMDCounters::Init(void *pContext)
|
||||
m_Counters = EnumerateCounters();
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
AMDCounters::~AMDCounters()
|
||||
{
|
||||
if(m_pGPUPerfAPI)
|
||||
{
|
||||
GPA_Status status = GPA_STATUS_OK;
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_CloseContext();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Close context failed", status).c_str());
|
||||
}
|
||||
|
||||
status = m_pGPUPerfAPI->GPA_CloseContext();
|
||||
status = m_pGPUPerfAPI->GPA_Destroy();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Destroy failed", status).c_str());
|
||||
}
|
||||
|
||||
delete m_pGPUPerfAPI;
|
||||
}
|
||||
}
|
||||
|
||||
vector<AMDCounters::InternalCounterDescription> AMDCounters::EnumerateCounters()
|
||||
std::map<uint32_t, CounterDescription> AMDCounters::EnumerateCounters()
|
||||
{
|
||||
std::map<uint32_t, CounterDescription> counters;
|
||||
|
||||
gpa_uint32 num;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetNumCounters(&num);
|
||||
|
||||
vector<InternalCounterDescription> counters;
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetNumCounters(&num);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get number of counters", status).c_str());
|
||||
return counters;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < num; ++i)
|
||||
{
|
||||
InternalCounterDescription internalDesc;
|
||||
internalDesc.desc = InternalGetCounterDescription(i);
|
||||
GPA_Usage_Type usageType;
|
||||
|
||||
internalDesc.internalIndex = i;
|
||||
internalDesc.desc.counter = MakeAMDCounter(i);
|
||||
counters.push_back(internalDesc);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(i, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return counters;
|
||||
}
|
||||
|
||||
// Ignore percentage counters due to aggregate roll-up support
|
||||
if(usageType == GPA_USAGE_TYPE_PERCENTAGE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CounterDescription desc = InternalGetCounterDescription(i);
|
||||
|
||||
desc.counter = MakeAMDCounter(i);
|
||||
counters[i] = desc;
|
||||
|
||||
m_PublicToInternalCounter[desc.counter] = i;
|
||||
}
|
||||
|
||||
return counters;
|
||||
}
|
||||
|
||||
uint32_t AMDCounters::GetNumCounters()
|
||||
std::vector<GPUCounter> AMDCounters::GetPublicCounterIds() const
|
||||
{
|
||||
return (uint32_t)m_Counters.size();
|
||||
std::vector<GPUCounter> ret;
|
||||
|
||||
for(const std::pair<GPUCounter, uint32_t> &entry : m_PublicToInternalCounter)
|
||||
ret.push_back(entry.first);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CounterDescription AMDCounters::GetCounterDescription(GPUCounter counter)
|
||||
{
|
||||
return m_Counters[GPUCounterToCounterIndex(counter)].desc;
|
||||
return m_Counters[m_PublicToInternalCounter[counter]];
|
||||
}
|
||||
|
||||
CounterDescription AMDCounters::InternalGetCounterDescription(uint32_t internalIndex)
|
||||
{
|
||||
CounterDescription desc = {};
|
||||
const char *tmp = NULL;
|
||||
m_pGPUPerfAPI->GPA_GetCounterName(internalIndex, &tmp);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetCounterName(internalIndex, &tmp);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get counter name.", status).c_str());
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc.name = tmp;
|
||||
m_pGPUPerfAPI->GPA_GetCounterDescription(internalIndex, &tmp);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterDescription(internalIndex, &tmp);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter description.", status).c_str());
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc.description = tmp;
|
||||
m_pGPUPerfAPI->GPA_GetCounterCategory(internalIndex, &tmp);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterCategory(internalIndex, &tmp);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get counter category.", status).c_str());
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc.category = tmp;
|
||||
|
||||
GPA_Usage_Type usageType;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return desc;
|
||||
}
|
||||
|
||||
switch(usageType)
|
||||
{
|
||||
@@ -184,7 +313,13 @@ CounterDescription AMDCounters::InternalGetCounterDescription(uint32_t internalI
|
||||
|
||||
GPA_Type type;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetCounterDataType(internalIndex, &type);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterDataType(internalIndex, &type);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter data type.", status).c_str());
|
||||
return desc;
|
||||
}
|
||||
|
||||
// results should either be float32/64 or uint32/64 as the GetSample functions only support those
|
||||
switch(type)
|
||||
@@ -227,41 +362,164 @@ CounterDescription AMDCounters::InternalGetCounterDescription(uint32_t internalI
|
||||
|
||||
void AMDCounters::EnableCounter(GPUCounter counter)
|
||||
{
|
||||
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
|
||||
const uint32_t internalIndex = m_PublicToInternalCounter[counter];
|
||||
|
||||
m_pGPUPerfAPI->GPA_EnableCounter(internalIndex);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EnableCounter(internalIndex);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Enable counter.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::EnableAllCounters()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_EnableAllCounters();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EnableAllCounters();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Enable all counters.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::DisableAllCounters()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_DisableAllCounters();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_DisableAllCounters();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Disable all counters.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AMDCounters::GetPassCount()
|
||||
{
|
||||
gpa_uint32 numRequiredPasses;
|
||||
m_pGPUPerfAPI->GPA_GetPassCount(&numRequiredPasses);
|
||||
gpa_uint32 numRequiredPasses = 0;
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetPassCount(&numRequiredPasses);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get pass count.", status).c_str());
|
||||
}
|
||||
|
||||
return (uint32_t)numRequiredPasses;
|
||||
}
|
||||
|
||||
uint32_t AMDCounters::BeginSession()
|
||||
{
|
||||
gpa_uint32 sessionID;
|
||||
gpa_uint32 sessionID = 0;
|
||||
|
||||
m_pGPUPerfAPI->GPA_BeginSession(&sessionID);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_BeginSession(&sessionID);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Begin session.", status).c_str());
|
||||
}
|
||||
|
||||
return (uint32_t)sessionID;
|
||||
}
|
||||
|
||||
void AMDCounters::EndSesssion()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_EndSession();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EndSession();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("End session.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CounterResult> AMDCounters::GetCounterData(uint32_t sessionID, uint32_t maxSampleIndex,
|
||||
const std::vector<uint32_t> &eventIDs,
|
||||
const std::vector<GPUCounter> &counters)
|
||||
{
|
||||
std::vector<CounterResult> ret;
|
||||
|
||||
bool isReady = false;
|
||||
|
||||
const uint32_t timeoutPeriod = 10000; // ms
|
||||
|
||||
PerformanceTimer timeout;
|
||||
|
||||
do
|
||||
{
|
||||
isReady = IsSessionReady(sessionID);
|
||||
if(!isReady)
|
||||
{
|
||||
Threading::Sleep(0);
|
||||
|
||||
PerformanceTimer endTime;
|
||||
|
||||
if(timeout.GetMilliseconds() > timeoutPeriod)
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, "GetCounterData failed due to elapsed timeout.");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} while(!isReady);
|
||||
|
||||
for(uint32_t s = 0; s < maxSampleIndex; s++)
|
||||
{
|
||||
for(size_t c = 0; c < counters.size(); c++)
|
||||
{
|
||||
const CounterDescription desc = GetCounterDescription(counters[c]);
|
||||
|
||||
switch(desc.resultType)
|
||||
{
|
||||
case CompType::UInt:
|
||||
{
|
||||
if(desc.resultByteWidth == sizeof(uint32_t))
|
||||
{
|
||||
uint32_t value = GetSampleUint32(sessionID, s, counters[c]);
|
||||
|
||||
if(desc.unit == CounterUnit::Percentage)
|
||||
{
|
||||
value = RDCCLAMP(value, 0U, 100U);
|
||||
}
|
||||
|
||||
ret.push_back(CounterResult(eventIDs[s], counters[c], value));
|
||||
}
|
||||
else if(desc.resultByteWidth == sizeof(uint64_t))
|
||||
{
|
||||
uint64_t value = GetSampleUint64(sessionID, s, counters[c]);
|
||||
|
||||
if(desc.unit == CounterUnit::Percentage)
|
||||
{
|
||||
value = RDCCLAMP(value, (uint64_t)0, (uint64_t)100);
|
||||
}
|
||||
|
||||
ret.push_back(CounterResult(eventIDs[s], counters[c], value));
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected byte width %u", desc.resultByteWidth);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CompType::Float:
|
||||
{
|
||||
float value = GetSampleFloat32(sessionID, s, counters[c]);
|
||||
|
||||
if(desc.unit == CounterUnit::Percentage)
|
||||
{
|
||||
value = RDCCLAMP(value, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
ret.push_back(CounterResult(eventIDs[s], counters[c], value));
|
||||
}
|
||||
break;
|
||||
case CompType::Double:
|
||||
{
|
||||
double value = GetSampleFloat64(sessionID, s, counters[c]);
|
||||
|
||||
if(desc.unit == CounterUnit::Percentage)
|
||||
{
|
||||
value = RDCCLAMP(value, 0.0, 100.0);
|
||||
}
|
||||
|
||||
ret.push_back(CounterResult(eventIDs[s], counters[c], value));
|
||||
}
|
||||
break;
|
||||
default: RDCASSERT(0); break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AMDCounters::IsSessionReady(uint32_t sessionIndex)
|
||||
@@ -269,98 +527,212 @@ bool AMDCounters::IsSessionReady(uint32_t sessionIndex)
|
||||
gpa_uint8 readyResult = 0;
|
||||
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_IsSessionReady(&readyResult, sessionIndex);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Is session ready", status).c_str());
|
||||
}
|
||||
|
||||
return readyResult && status == GPA_STATUS_OK;
|
||||
}
|
||||
|
||||
void AMDCounters::BeginPass()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_BeginPass();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_BeginPass();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Begin pass.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::EndPass()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_EndPass();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EndPass();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("End pass.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::BeginSample(uint32_t index)
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_BeginSample(index);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_BeginSample(index);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Begin sample.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::EndSample()
|
||||
{
|
||||
m_pGPUPerfAPI->GPA_EndSample();
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EndSample();
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("End sample.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::BeginSampleList(void *pSampleList)
|
||||
{
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_BeginSampleList(pSampleList);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("BeginSampleList.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::EndSampleList(void *pSampleList)
|
||||
{
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EndSampleList(pSampleList);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("EndSampleList.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::BeginSampleInSampleList(uint32_t sampleID, void *pSampleList)
|
||||
{
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_BeginSampleInSampleList(sampleID, pSampleList);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("BeginSampleInSampleList.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void AMDCounters::EndSampleInSampleList(void *pSampleList)
|
||||
{
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_EndSampleInSampleList(pSampleList);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("EndSampleInSampleList.", status).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AMDCounters::GetSampleUint32(uint32_t session, uint32_t sample, GPUCounter counter)
|
||||
{
|
||||
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
|
||||
uint32_t value;
|
||||
const uint32_t internalIndex = m_PublicToInternalCounter[counter];
|
||||
uint32_t value = 0;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetSampleUInt32(session, sample, internalIndex, &value);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetSampleUInt32(session, sample, internalIndex, &value);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get sample uint32.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
// normalise units as expected
|
||||
GPA_Usage_Type usageType;
|
||||
m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
if(usageType == GPA_USAGE_TYPE_KILOBYTES)
|
||||
{
|
||||
value *= 1000;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t AMDCounters::GetSampleUint64(uint32_t session, uint32_t sample, GPUCounter counter)
|
||||
{
|
||||
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
|
||||
gpa_uint64 value;
|
||||
const uint32_t internalIndex = m_PublicToInternalCounter[counter];
|
||||
gpa_uint64 value = 0;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetSampleUInt64(session, sample, internalIndex, &value);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetSampleUInt64(session, sample, internalIndex, &value);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get sample uint64.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
// normalise units as expected
|
||||
GPA_Usage_Type usageType;
|
||||
m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
if(usageType == GPA_USAGE_TYPE_KILOBYTES)
|
||||
{
|
||||
value *= 1000;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float AMDCounters::GetSampleFloat32(uint32_t session, uint32_t sample, GPUCounter counter)
|
||||
{
|
||||
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
|
||||
float value;
|
||||
const uint32_t internalIndex = m_PublicToInternalCounter[counter];
|
||||
float value = 0;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetSampleFloat32(session, sample, internalIndex, &value);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetSampleFloat32(session, sample, internalIndex, &value);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get sample float32.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
// normalise units as expected
|
||||
GPA_Usage_Type usageType;
|
||||
m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
if(usageType == GPA_USAGE_TYPE_KILOBYTES)
|
||||
{
|
||||
value *= 1000.0f;
|
||||
}
|
||||
else if(usageType == GPA_USAGE_TYPE_MILLISECONDS)
|
||||
{
|
||||
value /= 1000.0f;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
double AMDCounters::GetSampleFloat64(uint32_t session, uint32_t sample, GPUCounter counter)
|
||||
{
|
||||
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
|
||||
const uint32_t internalIndex = m_PublicToInternalCounter[counter];
|
||||
double value;
|
||||
|
||||
m_pGPUPerfAPI->GPA_GetSampleFloat64(session, sample, internalIndex, &value);
|
||||
GPA_Status status = m_pGPUPerfAPI->GPA_GetSampleFloat64(session, sample, internalIndex, &value);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR, FormatErrMessage("Get sample float64.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
// normalise units as expected
|
||||
GPA_Usage_Type usageType;
|
||||
m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
status = m_pGPUPerfAPI->GPA_GetCounterUsageType(internalIndex, &usageType);
|
||||
if(AMD_FAILED(status))
|
||||
{
|
||||
GPA_LoggingCallback(GPA_LOGGING_ERROR,
|
||||
FormatErrMessage("Get counter usage type.", status).c_str());
|
||||
return value;
|
||||
}
|
||||
|
||||
if(usageType == GPA_USAGE_TYPE_KILOBYTES)
|
||||
{
|
||||
value *= 1000.0;
|
||||
}
|
||||
else if(usageType == GPA_USAGE_TYPE_MILLISECONDS)
|
||||
{
|
||||
value /= 1000.0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
Reference in New Issue
Block a user