Add backend support for AMD performance counters.

This commit is contained in:
Matthäus G. Chajdas
2017-06-12 16:06:10 +02:00
committed by baldurk
parent e0104e8fe0
commit b7f893b559
30 changed files with 2146 additions and 7 deletions
+2
View File
@@ -84,6 +84,8 @@ The following libraries and components are incorporated into RenderDoc, listed h
Used to display message boxes cross-platform from the non-UI core code.
* `AMD GPUPerfAPI <https://github.com/GPUOpen-Tools/GPA>`_ - Copyright (c) 2016 Advanced Micro Devices, Inc., distributed under the MIT license.
Thanks
------
+14
View File
@@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderdoc", "renderdoc\rend
{F1E59A05-60D4-4927-9E57-DD191EAE90EF} = {F1E59A05-60D4-4927-9E57-DD191EAE90EF}
{EC847717-119A-2391-0477-212E1140082C} = {EC847717-119A-2391-0477-212E1140082C}
{B7399F39-300F-450E-F471-9490F959D2A7} = {B7399F39-300F-450E-F471-9490F959D2A7}
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A} = {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}
{2A793574-BD3C-46D4-9788-C339D9550CE1} = {2A793574-BD3C-46D4-9788-C339D9550CE1}
{EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7} = {EA1242CF-BB42-B1AC-9B6A-A508D96D1CB7}
EndProjectSection
@@ -52,6 +53,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "drivers", "drivers", "{864A
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d11", "renderdoc\driver\d3d11\renderdoc_d3d11.vcxproj", "{F1E59A05-60D4-4927-9E57-DD191EAE90EF}"
ProjectSection(ProjectDependencies) = postProject
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A} = {5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}
{2A793574-BD3C-46D4-9788-C339D9550CE1} = {2A793574-BD3C-46D4-9788-C339D9550CE1}
EndProjectSection
EndProject
@@ -71,6 +73,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d12", "renderdoc\driver\d
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d9", "renderdoc\driver\d3d9\renderdoc_d3d9.vcxproj", "{44044776-9469-4079-B587-ABFFF6574AA4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AMD", "renderdoc\driver\ihv\amd\AMD.vcxproj", "{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Development|x64 = Development|x64
@@ -207,6 +211,15 @@ Global
{44044776-9469-4079-B587-ABFFF6574AA4}.Release|x64.Build.0 = Release|x64
{44044776-9469-4079-B587-ABFFF6574AA4}.Release|x86.ActiveCfg = Release|Win32
{44044776-9469-4079-B587-ABFFF6574AA4}.Release|x86.Build.0 = Release|Win32
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x64.ActiveCfg = Development|x64
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x64.Build.0 = Development|x64
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x86.ActiveCfg = Development|Win32
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x86.Build.0 = Development|Win32
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Development|x86.Deploy.0 = Development|Win32
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x64.ActiveCfg = Release|x64
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x64.Build.0 = Release|x64
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x86.ActiveCfg = Release|Win32
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -232,5 +245,6 @@ Global
{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F} = {864A44B0-5612-451A-857F-41E3EF785EF6}
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4} = {864A44B0-5612-451A-857F-41E3EF785EF6}
{44044776-9469-4079-B587-ABFFF6574AA4} = {864A44B0-5612-451A-857F-41E3EF785EF6}
{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A} = {864A44B0-5612-451A-857F-41E3EF785EF6}
EndGlobalSection
EndGlobal
+15
View File
@@ -2918,12 +2918,27 @@ DOCUMENT(R"(The unit that GPU counter data is returned in.
.. data:: Percentage
The value is a floating point percentage value between 0.0 and 1.0.
.. data:: Ratio
The value describes a ratio between two separate GPU units or counters.
.. data:: Bytes
The value is in bytes.
.. data:: Cycles
The value is a duration in clock cycles.
)");
enum class CounterUnit : uint32_t
{
Absolute,
Seconds,
Percentage,
Ratio,
Bytes,
Cycles,
};
DOCUMENT(R"(How supported a given API is on a particular replay instance.
+194 -5
View File
@@ -22,7 +22,10 @@
* THE SOFTWARE.
******************************************************************************/
#include <algorithm>
#include <iterator>
#include "common/common.h"
#include "driver/ihv/amd/amd_counters.h"
#include "d3d11_context.h"
#include "d3d11_debug.h"
#include "d3d11_device.h"
@@ -61,6 +64,14 @@ vector<GPUCounter> D3D11DebugManager::EnumerateCounters()
ret.push_back(GPUCounter::PSInvocations);
ret.push_back(GPUCounter::CSInvocations);
if(m_pAMDCounters)
{
for(uint32_t i = 0; i < m_pAMDCounters->GetNumCounters(); i++)
{
ret.push_back(static_cast<GPUCounter>(static_cast<uint32_t>(GPUCounter::FirstAMD) + i));
}
}
return ret;
}
@@ -68,6 +79,17 @@ void D3D11DebugManager::DescribeCounter(GPUCounter counterID, CounterDescription
{
desc.counterID = counterID;
/////AMD//////
if(counterID >= GPUCounter::FirstAMD && counterID < GPUCounter::FirstIntel)
{
if(m_pAMDCounters)
{
desc = m_pAMDCounters->GetCounterDescription(counterID);
return;
}
}
switch(counterID)
{
case GPUCounter::EventGPUDuration:
@@ -257,6 +279,157 @@ void D3D11DebugManager::FillTimers(D3D11CounterContext &ctx, const DrawcallTreeN
}
}
void D3D11DebugManager::FillTimersAMD(uint32_t &eventStartID, uint32_t &sampleIndex,
vector<uint32_t> &eventIDs, const DrawcallTreeNode &drawnode)
{
if(drawnode.children.empty())
return;
for(size_t i = 0; i < drawnode.children.size(); i++)
{
const DrawcallDescription &d = drawnode.children[i].draw;
FillTimersAMD(eventStartID, sampleIndex, eventIDs, drawnode.children[i]);
if(d.events.count == 0)
continue;
eventIDs.push_back(d.eventID);
m_WrappedDevice->ReplayLog(eventStartID, d.eventID, eReplay_WithoutDraw);
m_pImmediateContext->Flush();
m_pAMDCounters->BeginSample(sampleIndex);
m_WrappedDevice->ReplayLog(eventStartID, d.eventID, eReplay_OnlyDraw);
m_pAMDCounters->EndSample();
eventStartID = d.eventID + 1;
sampleIndex++;
}
}
vector<CounterResult> D3D11DebugManager::FetchCountersAMD(const vector<GPUCounter> &counters)
{
vector<CounterResult> ret;
m_pAMDCounters->DisableAllCounters();
// enable counters it needs
for(size_t i = 0; i < counters.size(); i++)
{
// This function is only called internally, and violating this assertion means our
// caller has invoked this method incorrectly
RDCASSERT((counters[i] >= (GPUCounter::FirstAMD)) && (counters[i] < (GPUCounter::FirstIntel)));
m_pAMDCounters->EnableCounter(counters[i]);
}
uint32_t sessionID = m_pAMDCounters->BeginSession();
uint32_t passCount = m_pAMDCounters->GetPassCount();
uint32_t sampleIndex = 0;
vector<uint32_t> eventIDs;
for(uint32_t p = 0; p < passCount; p++)
{
m_pAMDCounters->BeginPass();
uint32_t eventStartID = 0;
sampleIndex = 0;
eventIDs.clear();
FillTimersAMD(eventStartID, sampleIndex, eventIDs, m_WrappedContext->GetRootDraw());
m_pAMDCounters->EndPass();
}
m_pAMDCounters->EndSesssion();
bool isReady = false;
do
{
isReady = m_pAMDCounters->IsSessionReady(sessionID);
} while(!isReady);
for(uint32_t s = 0; s < sampleIndex; s++)
{
for(size_t c = 0; c < counters.size(); c++)
{
const CounterDescription desc = m_pAMDCounters->GetCounterDescription(counters[c]);
switch(desc.resultType)
{
case CompType::UInt:
{
if(desc.resultByteWidth == sizeof(uint32_t))
{
uint32_t value = m_pAMDCounters->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 = m_pAMDCounters->GetSampleUint64(sessionID, s, counters[c]);
if(desc.unit == CounterUnit::Percentage)
{
value = RDCCLAMP(value, 0ULL, 100ULL);
}
ret.push_back(
CounterResult(eventIDs[s], counters[c], value));
}
else
{
RDCERR("Unexpected byte width %u", desc.resultByteWidth);
}
}
break;
case CompType::Float:
{
float value = m_pAMDCounters->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 = m_pAMDCounters->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;
}
vector<CounterResult> D3D11DebugManager::FetchCounters(const vector<GPUCounter> &counters)
{
vector<CounterResult> ret;
@@ -269,6 +442,21 @@ vector<CounterResult> D3D11DebugManager::FetchCounters(const vector<GPUCounter>
SCOPED_TIMER("Fetch Counters, counters to fetch %u", counters.size());
vector<GPUCounter> d3dCounters;
std::copy_if(counters.begin(), counters.end(), std::back_inserter(d3dCounters),
[](const GPUCounter &c) { return c <= GPUCounter::FirstAMD; });
if(m_pAMDCounters)
{
// Filter out the AMD counters
vector<GPUCounter> amdCounters;
std::copy_if(
counters.begin(), counters.end(), std::back_inserter(amdCounters),
[](const GPUCounter &c) { return c >= GPUCounter::FirstAMD && c < GPUCounter::FirstIntel; });
ret = FetchCountersAMD(amdCounters);
}
D3D11_QUERY_DESC disjointdesc = {D3D11_QUERY_TIMESTAMP_DISJOINT, 0};
ID3D11Query *disjoint = NULL;
@@ -349,9 +537,9 @@ vector<CounterResult> D3D11DebugManager::FetchCounters(const vector<GPUCounter>
hr = m_pImmediateContext->GetData(ctx.timers[i].occlusion, &occlusion, sizeof(UINT64), 0);
RDCASSERTEQUAL(hr, S_OK);
for(size_t c = 0; c < counters.size(); c++)
for(size_t c = 0; c < d3dCounters.size(); c++)
{
switch(counters[c])
switch(d3dCounters[c])
{
case GPUCounter::EventGPUDuration:
ret.push_back(
@@ -410,9 +598,9 @@ vector<CounterResult> D3D11DebugManager::FetchCounters(const vector<GPUCounter>
}
else
{
for(size_t c = 0; c < counters.size(); c++)
for(size_t c = 0; c < d3dCounters.size(); c++)
{
switch(counters[c])
switch(d3dCounters[c])
{
case GPUCounter::EventGPUDuration:
ret.push_back(
@@ -430,7 +618,8 @@ vector<CounterResult> D3D11DebugManager::FetchCounters(const vector<GPUCounter>
case GPUCounter::PSInvocations:
case GPUCounter::CSInvocations:
case GPUCounter::SamplesWritten:
ret.push_back(CounterResult(ctx.timers[i].eventID, counters[c], 0xFFFFFFFFFFFFFFFF));
ret.push_back(
CounterResult(ctx.timers[i].eventID, d3dCounters[c], 0xFFFFFFFFFFFFFFFF));
break;
}
}
+14
View File
@@ -28,6 +28,7 @@
#include "data/resource.h"
#include "driver/d3d11/d3d11_resources.h"
#include "driver/dx/official/d3dcompiler.h"
#include "driver/ihv/amd/amd_counters.h"
#include "driver/shaders/dxbc/dxbc_debug.h"
#include "maths/camera.h"
#include "maths/formatpacking.h"
@@ -156,10 +157,23 @@ D3D11DebugManager::D3D11DebugManager(WrappedID3D11Device *wrapper)
PostDeviceInitCounters();
RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f);
AMDCounters *counters = new AMDCounters();
if(counters->Init((void *)m_pDevice))
{
m_pAMDCounters = counters;
}
else
{
delete counters;
m_pAMDCounters = NULL;
}
}
D3D11DebugManager::~D3D11DebugManager()
{
SAFE_DELETE(m_pAMDCounters);
PreDeviceShutdownCounters();
if(m_ShaderCacheDirty)
+8
View File
@@ -43,6 +43,8 @@ class Vec3f;
class WrappedID3D11Device;
class WrappedID3D11DeviceContext;
class AMDCounters;
struct DrawcallTreeNode;
struct D3D11CounterContext;
@@ -158,6 +160,7 @@ public:
vector<GPUCounter> EnumerateCounters();
void DescribeCounter(GPUCounter counterID, CounterDescription &desc);
vector<CounterResult> FetchCounters(const vector<GPUCounter> &counters);
vector<CounterResult> FetchCountersAMD(const vector<GPUCounter> &counters);
void RenderText(float x, float y, const char *textfmt, ...);
void RenderMesh(uint32_t eventID, const vector<MeshFormat> &secondaryDraws, const MeshDisplay &cfg);
@@ -260,6 +263,8 @@ public:
TextureShaderDetails GetShaderDetails(ResourceId id, CompType typeHint, bool rawOutput);
AMDCounters *m_pAMDCounters;
private:
struct CacheElem
{
@@ -581,5 +586,8 @@ private:
void FillTimers(D3D11CounterContext &ctx, const DrawcallTreeNode &drawnode);
void FillTimersAMD(uint32_t &eventStartID, uint32_t &sampleIndex, vector<uint32_t> &eventIDs,
const DrawcallTreeNode &drawnode);
void FillCBuffer(ID3D11Buffer *buf, const void *data, size_t size);
};
+1 -1
View File
@@ -24,8 +24,8 @@
******************************************************************************/
#include "driver/d3d11/d3d11_device.h"
#include "driver/dx/official/amd/AmdDxExtApi.h"
#include "driver/dxgi/dxgi_wrapped.h"
#include "driver/ihv/amd/official/DXExt/AmdDxExtApi.h"
#include "hooks/hooks.h"
#define DLL_NAME "d3d11.dll"
@@ -59,7 +59,7 @@
<PreprocessorDefinitions>RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -144,6 +144,9 @@
<ClInclude Include="precompiled.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ihv\amd\AMD.vcxproj">
<Project>{5de5a561-548a-4dd7-90f0-06a2b39eae9a}</Project>
</ProjectReference>
<ProjectReference Include="..\shaders\dxbc\renderdoc_dxbc.vcxproj">
<Project>{c43ff27e-a155-4852-88ec-5ce9334c07a8}</Project>
<Private>false</Private>
+104
View File
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Development|Win32">
<Configuration>Development</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Development|x64">
<Configuration>Development</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{5DE5A561-548A-4DD7-90F0-06A2B39EAE9A}</ProjectGuid>
<RootNamespace>AMD</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
<IncludePath>$(SolutionDir)\breakpad;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<ExcludePath>$(ExcludePath)</ExcludePath>
<TargetName>driver_$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
<ClCompile>
<PreprocessorDefinitions>WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>RELEASE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level4</WarningLevel>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Development'">
<ClCompile>
<Optimization>Disabled</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="amd_counters.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="amd_counters.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="amd_counters.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="amd_counters.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+419
View File
@@ -0,0 +1,419 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015-2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "amd_counters.h"
#include <Windows.h>
#include "common/common.h"
#include "official/GPUPerfAPI/Include/GPUPerfAPI.h"
#include "official/GPUPerfAPI/Include/GPUPerfAPIFunctionTypes.h"
typedef GPA_Status(__stdcall *PFN_GPA_INITIALIZE)();
typedef GPA_Status(__stdcall *PFN_GPA_OPENCONTEXT)(void *pContext);
typedef GPA_Status(__stdcall *PFN_GPA_GET_NUM_COUNTERS)(gpa_uint32 *pCount);
typedef GPA_Status(__stdcall *PFN_GPA_GET_COUNTER_NAME)(gpa_uint32 index, const char **ppName);
typedef GPA_Status(__stdcall *PFN_GPA_GET_COUNTER_INDEX)(const char *pCounter, gpa_uint32 *pIndex);
typedef GPA_Status(__stdcall *PFN_GPA_GET_COUNTER_DESCRIPTION)(gpa_uint32 index,
const char **ppDescription);
typedef GPA_Status(__stdcall *PFN_GPA_GET_COUNTER_DATA_TYPE)(gpa_uint32 index, GPA_Type *pDataType);
typedef GPA_Status(__stdcall *PFN_GPA_GET_COUNTER_USAGE_TYPE)(gpa_uint32 index,
GPA_Usage_Type *usageType);
typedef GPA_Status(__stdcall *PFN_GPA_ENABLE_COUNTER)(gpa_uint32 index);
typedef GPA_Status(__stdcall *PFN_GPA_ENABLE_COUNTER_STR)(const char *pCounter);
typedef GPA_Status(__stdcall *PFN_GPA_ENABLE_ALL_COUNTERS)();
typedef GPA_Status(__stdcall *PFN_GPA_DISABLE_COUNTER)(gpa_uint32 index);
typedef GPA_Status(__stdcall *PFN_GPA_DISABLE_COUNTER_STR)(const char *pCounter);
typedef GPA_Status(__stdcall *PFN_GPA_DISABLE_ALL_COUNTERS)();
typedef GPA_Status(__stdcall *PFN_GPA_GET_PASS_COUNT)(gpa_uint32 *pNumPasses);
typedef GPA_Status(__stdcall *PFN_GPA_BEGIN_SESSION)(gpa_uint32 *pSessionID);
typedef GPA_Status(__stdcall *PFN_GPA_END_SESSION)();
typedef GPA_Status(__stdcall *PFN_GPA_BEGIN_PASS)();
typedef GPA_Status(__stdcall *PFN_GPA_END_PASS)();
typedef GPA_Status(__stdcall *PFN_GPA_BEGIN_SAMPLE)(gpa_uint32 sampleID);
typedef GPA_Status(__stdcall *PFN_GPA_END_SAMPLE)();
typedef GPA_Status(__stdcall *PFN_GPA_IS_SESSION_READY)(bool *pReadyResult, gpa_uint32 sessionID);
typedef GPA_Status(__stdcall *PFN_GPA_IS_SAMPLE_READY)(bool *pReadyResult, gpa_uint32 sessionID,
gpa_uint32 sampleID);
typedef GPA_Status(__stdcall *PFN_GPA_GET_SAMPLE_UINT32)(gpa_uint32 sessionID, gpa_uint32 sampleID,
gpa_uint32 counterID, gpa_uint32 *pResult);
typedef GPA_Status(__stdcall *PFN_GPA_GET_SAMPLE_UINT64)(gpa_uint32 sessionID, gpa_uint32 sampleID,
gpa_uint32 counterID, gpa_uint64 *pResult);
typedef GPA_Status(__stdcall *PFN_GPA_GET_SAMPLE_FLOAT32)(gpa_uint32 sessionID, gpa_uint32 sampleID,
gpa_uint32 counterID, gpa_float32 *pResult);
typedef GPA_Status(__stdcall *PFN_GPA_GET_SAMPLE_FLOAT64)(gpa_uint32 sessionID, gpa_uint32 sampleID,
gpa_uint32 counterID, gpa_float64 *pResult);
typedef GPA_Status(__stdcall *PFN_GPA_CLOSE_CONTEXT)();
typedef GPA_Status(__stdcall *PFN_GPA_DESTROY)();
class GPUPerfAPI
{
public:
PFN_GPA_INITIALIZE init;
PFN_GPA_OPENCONTEXT openContext;
PFN_GPA_GET_NUM_COUNTERS getNumCounters;
PFN_GPA_GET_COUNTER_NAME getCounterName;
PFN_GPA_GET_COUNTER_INDEX getCounterIndex;
PFN_GPA_GET_COUNTER_DESCRIPTION getCounterDescription;
PFN_GPA_GET_COUNTER_DATA_TYPE getCounterDataType;
PFN_GPA_GET_COUNTER_USAGE_TYPE getCounterUsageType;
PFN_GPA_ENABLE_COUNTER enableCounter;
PFN_GPA_ENABLE_COUNTER_STR enableCounterStr;
PFN_GPA_ENABLE_ALL_COUNTERS enableAllCounters;
PFN_GPA_DISABLE_COUNTER disableCounter;
PFN_GPA_DISABLE_COUNTER_STR disableCounterStr;
PFN_GPA_DISABLE_ALL_COUNTERS disableAllCounters;
PFN_GPA_GET_PASS_COUNT getPassCount;
PFN_GPA_BEGIN_SESSION beginSession;
PFN_GPA_END_SESSION endSession;
PFN_GPA_BEGIN_PASS beginPass;
PFN_GPA_END_PASS endPass;
PFN_GPA_BEGIN_SAMPLE beginSample;
PFN_GPA_END_SAMPLE endSample;
PFN_GPA_IS_SESSION_READY isSessionReady;
PFN_GPA_IS_SAMPLE_READY isSampleReady;
PFN_GPA_GET_SAMPLE_UINT32 getSampleUInt32;
PFN_GPA_GET_SAMPLE_UINT64 getSampleUInt64;
PFN_GPA_GET_SAMPLE_FLOAT32 getSampleFloat32;
PFN_GPA_GET_SAMPLE_FLOAT64 getSampleFloat64;
PFN_GPA_CLOSE_CONTEXT closeContext;
PFN_GPA_DESTROY destroy;
};
AMDCounters::AMDCounters() : m_pGPUPerfAPI(NULL)
{
}
bool AMDCounters::Init(void *pContext)
{
HMODULE module = LoadLibraryA("GPUPerfAPIDX11-x64.dll");
if(module == 0)
{
RDCERR(
"AMD GPU performance counters could not be initialized successfully. "
"Are you missing the DLLs?");
return false;
}
m_pGPUPerfAPI = new GPUPerfAPI();
m_pGPUPerfAPI->init = (PFN_GPA_INITIALIZE)GetProcAddress(module, "GPA_Initialize");
m_pGPUPerfAPI->openContext = (PFN_GPA_OPENCONTEXT)GetProcAddress(module, "GPA_OpenContext");
m_pGPUPerfAPI->getNumCounters =
(PFN_GPA_GET_NUM_COUNTERS)GetProcAddress(module, "GPA_GetNumCounters");
m_pGPUPerfAPI->getCounterName =
(PFN_GPA_GET_COUNTER_NAME)GetProcAddress(module, "GPA_GetCounterName");
m_pGPUPerfAPI->getCounterIndex =
(PFN_GPA_GET_COUNTER_INDEX)GetProcAddress(module, "GPA_GetCounterIndex");
m_pGPUPerfAPI->getCounterDescription =
(PFN_GPA_GET_COUNTER_DESCRIPTION)GetProcAddress(module, "GPA_GetCounterDescription");
m_pGPUPerfAPI->getCounterDataType =
(PFN_GPA_GET_COUNTER_DATA_TYPE)GetProcAddress(module, "GPA_GetCounterDataType");
m_pGPUPerfAPI->getCounterUsageType =
(PFN_GPA_GET_COUNTER_USAGE_TYPE)GetProcAddress(module, "GPA_GetCounterUsageType");
m_pGPUPerfAPI->enableCounter =
(PFN_GPA_ENABLE_COUNTER)GetProcAddress(module, "GPA_EnableCounter");
m_pGPUPerfAPI->enableCounterStr =
(PFN_GPA_ENABLE_COUNTER_STR)GetProcAddress(module, "GPA_EnableCounterStr");
m_pGPUPerfAPI->enableAllCounters =
(PFN_GPA_ENABLE_ALL_COUNTERS)GetProcAddress(module, "GPA_EnableAllCounters");
m_pGPUPerfAPI->disableCounter =
(PFN_GPA_DISABLE_COUNTER)GetProcAddress(module, "GPA_DisableCounter");
m_pGPUPerfAPI->disableCounterStr =
(PFN_GPA_DISABLE_COUNTER_STR)GetProcAddress(module, "GPA_DisableCounterStr");
m_pGPUPerfAPI->disableAllCounters =
(PFN_GPA_DISABLE_ALL_COUNTERS)GetProcAddress(module, "GPA_DisableAllCounters");
m_pGPUPerfAPI->getPassCount = (PFN_GPA_GET_PASS_COUNT)GetProcAddress(module, "GPA_GetPassCount");
m_pGPUPerfAPI->beginSession = (PFN_GPA_BEGIN_SESSION)GetProcAddress(module, "GPA_BeginSession");
m_pGPUPerfAPI->endSession = (PFN_GPA_END_SESSION)GetProcAddress(module, "GPA_EndSession");
m_pGPUPerfAPI->beginPass = (PFN_GPA_BEGIN_PASS)GetProcAddress(module, "GPA_BeginPass");
m_pGPUPerfAPI->endPass = (PFN_GPA_END_PASS)GetProcAddress(module, "GPA_EndPass");
m_pGPUPerfAPI->beginSample = (PFN_GPA_BEGIN_SAMPLE)GetProcAddress(module, "GPA_BeginSample");
m_pGPUPerfAPI->endSample = (PFN_GPA_END_SAMPLE)GetProcAddress(module, "GPA_EndSample");
m_pGPUPerfAPI->isSessionReady =
(PFN_GPA_IS_SESSION_READY)GetProcAddress(module, "GPA_IsSessionReady");
m_pGPUPerfAPI->isSampleReady =
(PFN_GPA_IS_SAMPLE_READY)GetProcAddress(module, "GPA_IsSampleReady");
m_pGPUPerfAPI->getSampleUInt32 =
(PFN_GPA_GET_SAMPLE_UINT32)GetProcAddress(module, "GPA_GetSampleUInt32");
m_pGPUPerfAPI->getSampleUInt64 =
(PFN_GPA_GET_SAMPLE_UINT64)GetProcAddress(module, "GPA_GetSampleUInt64");
m_pGPUPerfAPI->getSampleFloat32 =
(PFN_GPA_GET_SAMPLE_FLOAT32)GetProcAddress(module, "GPA_GetSampleFloat32");
m_pGPUPerfAPI->getSampleFloat64 =
(PFN_GPA_GET_SAMPLE_FLOAT64)GetProcAddress(module, "GPA_GetSampleFloat64");
m_pGPUPerfAPI->closeContext = (PFN_GPA_CLOSE_CONTEXT)GetProcAddress(module, "GPA_CloseContext");
m_pGPUPerfAPI->destroy = (PFN_GPA_DESTROY)GetProcAddress(module, "GPA_Destroy");
if(m_pGPUPerfAPI->init() != GPA_STATUS_OK)
{
delete m_pGPUPerfAPI;
m_pGPUPerfAPI = NULL;
return false;
}
if(m_pGPUPerfAPI->openContext(pContext) != GPA_STATUS_OK)
{
m_pGPUPerfAPI->destroy();
delete m_pGPUPerfAPI;
m_pGPUPerfAPI = NULL;
return false;
}
m_Counters = EnumerateCounters();
return true;
}
AMDCounters::~AMDCounters()
{
if(m_pGPUPerfAPI)
{
GPA_Status status = GPA_STATUS_OK;
status = m_pGPUPerfAPI->closeContext();
status = m_pGPUPerfAPI->destroy();
delete m_pGPUPerfAPI;
}
}
vector<AMDCounters::InternalCounterDescription> AMDCounters::EnumerateCounters()
{
gpa_uint32 num;
m_pGPUPerfAPI->getNumCounters(&num);
vector<InternalCounterDescription> counters;
for(uint32_t i = 0; i < num; ++i)
{
InternalCounterDescription internalDesc;
internalDesc.desc = InternalGetCounterDescription(i);
// We ignore any D3D11 counters, as those are handled elsewhere
if(strncmp(internalDesc.desc.description, "#D3D11#", 7) == 0)
{
continue;
}
internalDesc.internalIndex = i;
counters.push_back(internalDesc);
}
return counters;
}
uint32_t AMDCounters::GetNumCounters()
{
return (uint32_t)m_Counters.size();
}
CounterDescription AMDCounters::GetCounterDescription(GPUCounter counter)
{
return m_Counters[GPUCounterToCounterIndex(counter)].desc;
}
CounterDescription AMDCounters::InternalGetCounterDescription(uint32_t internalIndex)
{
CounterDescription desc = {};
const char *tmp = NULL;
m_pGPUPerfAPI->getCounterName(internalIndex, &tmp);
desc.name = tmp;
m_pGPUPerfAPI->getCounterDescription(internalIndex, &tmp);
desc.description = tmp;
GPA_Usage_Type usageType;
m_pGPUPerfAPI->getCounterUsageType(internalIndex, &usageType);
switch(usageType)
{
case GPA_USAGE_TYPE_RATIO: ///< Result is a ratio of two different values or types
desc.unit = CounterUnit::Ratio;
break;
case GPA_USAGE_TYPE_PERCENTAGE: ///< Result is a percentage, typically within [0,100] range,
/// but may be higher for certain counters
desc.unit = CounterUnit::Percentage;
break;
case GPA_USAGE_TYPE_CYCLES: ///< Result is in clock cycles
desc.unit = CounterUnit::Cycles;
break;
case GPA_USAGE_TYPE_MILLISECONDS: ///< Result is in milliseconds
desc.unit = CounterUnit::Seconds;
break;
case GPA_USAGE_TYPE_KILOBYTES: ///< Result is in kilobytes
case GPA_USAGE_TYPE_BYTES: ///< Result is in bytes
desc.unit = CounterUnit::Bytes;
break;
case GPA_USAGE_TYPE_ITEMS: ///< Result is a count of items or objects (ie, vertices,
/// triangles, threads, pixels, texels, etc)
desc.unit = CounterUnit::Absolute;
break;
default: desc.unit = CounterUnit::Absolute;
}
GPA_Type type;
m_pGPUPerfAPI->getCounterDataType(internalIndex, &type);
// results should either be float32/64 or uint32/64 as the GetSample functions only support those
switch(type)
{
case GPA_TYPE_FLOAT32: ///< Result will be a 32-bit float
desc.resultType = CompType::Float;
desc.resultByteWidth = sizeof(float);
break;
case GPA_TYPE_FLOAT64: ///< Result will be a 64-bit float
desc.resultType = CompType::Double;
desc.resultByteWidth = sizeof(double);
break;
case GPA_TYPE_UINT32: ///< Result will be a 32-bit unsigned int
desc.resultType = CompType::UInt;
desc.resultByteWidth = sizeof(uint32_t);
break;
case GPA_TYPE_UINT64: ///< Result will be a 64-bit unsigned int
desc.resultType = CompType::UInt;
desc.resultByteWidth = sizeof(uint64_t);
break;
case GPA_TYPE_INT32: ///< Result will be a 32-bit int
desc.resultType = CompType::SInt;
desc.resultByteWidth = sizeof(int32_t);
break;
case GPA_TYPE_INT64: ///< Result will be a 64-bit int
desc.resultType = CompType::SInt;
desc.resultByteWidth = sizeof(int64_t);
break;
default: desc.resultType = CompType::UInt; desc.resultByteWidth = sizeof(uint32_t);
}
return desc;
}
void AMDCounters::EnableCounter(GPUCounter counter)
{
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
m_pGPUPerfAPI->enableCounter(internalIndex);
}
void AMDCounters::EnableAllCounters()
{
m_pGPUPerfAPI->enableAllCounters();
}
void AMDCounters::DisableAllCounters()
{
m_pGPUPerfAPI->disableAllCounters();
}
uint32_t AMDCounters::GetPassCount()
{
gpa_uint32 numRequiredPasses;
m_pGPUPerfAPI->getPassCount(&numRequiredPasses);
return (uint32_t)numRequiredPasses;
}
uint32_t AMDCounters::BeginSession()
{
gpa_uint32 sessionID;
m_pGPUPerfAPI->beginSession(&sessionID);
return (uint32_t)sessionID;
}
void AMDCounters::EndSesssion()
{
m_pGPUPerfAPI->endSession();
}
bool AMDCounters::IsSessionReady(uint32_t sessionIndex)
{
bool readyResult = false;
GPA_Status status = m_pGPUPerfAPI->isSessionReady(&readyResult, sessionIndex);
return readyResult && status == GPA_STATUS_OK;
}
void AMDCounters::BeginPass()
{
m_pGPUPerfAPI->beginPass();
}
void AMDCounters::EndPass()
{
m_pGPUPerfAPI->endPass();
}
void AMDCounters::BeginSample(uint32_t index)
{
m_pGPUPerfAPI->beginSample(index);
}
void AMDCounters::EndSample()
{
m_pGPUPerfAPI->endSample();
}
uint32_t AMDCounters::GetSampleUint32(uint32_t session, uint32_t sample, GPUCounter counter)
{
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
uint32_t value;
m_pGPUPerfAPI->getSampleUInt32(session, sample, internalIndex, &value);
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;
m_pGPUPerfAPI->getSampleUInt64(session, sample, internalIndex, &value);
return value;
}
float AMDCounters::GetSampleFloat32(uint32_t session, uint32_t sample, GPUCounter counter)
{
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
float value;
m_pGPUPerfAPI->getSampleFloat32(session, sample, internalIndex, &value);
return value;
}
double AMDCounters::GetSampleFloat64(uint32_t session, uint32_t sample, GPUCounter counter)
{
const uint32_t internalIndex = m_Counters[GPUCounterToCounterIndex(counter)].internalIndex;
double value;
m_pGPUPerfAPI->getSampleFloat64(session, sample, internalIndex, &value);
return value;
}
+85
View File
@@ -0,0 +1,85 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2015-2017 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#pragma once
#include <vector>
#include "api/replay/renderdoc_replay.h"
class GPUPerfAPI;
class AMDCounters
{
public:
AMDCounters();
bool Init(void *pContext);
~AMDCounters();
uint32_t GetNumCounters();
CounterDescription GetCounterDescription(GPUCounter index);
void EnableCounter(GPUCounter index);
void EnableAllCounters();
void DisableAllCounters();
uint32_t GetPassCount();
uint32_t BeginSession();
void EndSesssion();
void BeginPass();
void EndPass();
void BeginSample(uint32_t index);
void EndSample();
bool IsSessionReady(uint32_t sessionIndex);
uint32_t GetSampleUint32(uint32_t session, uint32_t sample, GPUCounter counter);
uint64_t GetSampleUint64(uint32_t session, uint32_t sample, GPUCounter counter);
float GetSampleFloat32(uint32_t session, uint32_t sample, GPUCounter counter);
double GetSampleFloat64(uint32_t session, uint32_t sample, GPUCounter counter);
private:
GPUPerfAPI *m_pGPUPerfAPI;
static uint32_t GPUCounterToCounterIndex(GPUCounter counter)
{
return (uint32_t)(counter) - (uint32_t)(GPUCounter::FirstAMD);
}
CounterDescription InternalGetCounterDescription(uint32_t index);
struct InternalCounterDescription
{
CounterDescription desc;
uint32_t internalIndex;
};
std::vector<InternalCounterDescription> EnumerateCounters();
std::vector<InternalCounterDescription> m_Counters;
};
@@ -0,0 +1,32 @@
//==============================================================================
// Copyright (c) 2012-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief GPUPerfAPI Counter Generator function
//==============================================================================
#ifndef _GPA_COUNTER_GENERATOR_H_
#define _GPA_COUNTER_GENERATOR_H_
#include "GPAICounterAccessor.h"
#include "GPAICounterScheduler.h"
#include "GPUPerfAPITypes.h"
#include "GPUPerfAPITypes-Private.h"
// Internal function. We don't want this exposed by the internal DLLs though, so it doesn't use GPALIB_DECL
/// Generates a counter accessor object that can be used to obtain the counters to expose
/// \param[in] desiredAPI The API to generate counters for
/// \param[in] vendorId The vendor id to generate counters for
/// \param[in] deviceId The device id to generate counters for
/// \param[in] revisionId The revision id to generate counters for
/// \param[inout] ppCounterAccessorOut Address of a GPA_ICounterAccessor pointer which will be set to the necessary counter accessor
/// \param[inout] ppCounterSchedulerOut Address of a GPA_ICounterScheduler pointer which will be set to the necessary counter scheduler
/// \return GPA_STATUS_ERROR_NULL_POINTER if ppCounterAccessorOut or ppCounterSchedulerOut is nullptr
/// \return GPA_STATUS_ERROR_NOT_FOUND if the desired API is not supported
/// \return GPA_STATUS_ERROR_NOT_ENABLED if the desired API is not allowing any counters to be exposed
/// \return GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED if the desired generation is not supported
/// \return GPA_STATUS_OK if the desired API and generation are supported
GPA_Status GenerateCounters(GPA_API_Type desiredAPI, gpa_uint32 vendorId, gpa_uint32 deviceId, gpa_uint32 revisionId, GPA_ICounterAccessor** ppCounterAccessorOut, GPA_ICounterScheduler** ppCounterSchedulerOut);
#endif // _GPA_COUNTER_GENERATOR_H_
@@ -0,0 +1,81 @@
//==============================================================================
// Copyright (c) 2014-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief GPA required public function declarations wrapped in a macro
//==============================================================================
#ifndef GPA_FUNCTION_PREFIX
#define GPA_FUNCTION_PREFIX( f ) ///< placeholder macro in case it's not defined before including this file
#define NEED_TO_UNDEFINE_GPA_FUNCTION_PREFIX ///< used a a flag to indicate whether or not the macro needs to be undefined later
#endif
GPA_FUNCTION_PREFIX(GPA_RegisterLoggingCallback)
#ifdef AMDT_INTERNAL
GPA_FUNCTION_PREFIX(GPA_RegisterLoggingDebugCallback)
#endif // AMDT_INTERNAL
GPA_FUNCTION_PREFIX(GPA_Initialize)
GPA_FUNCTION_PREFIX(GPA_Destroy)
// Context
GPA_FUNCTION_PREFIX(GPA_OpenContext)
GPA_FUNCTION_PREFIX(GPA_CloseContext)
GPA_FUNCTION_PREFIX(GPA_SelectContext)
// Counter Interrogation
GPA_FUNCTION_PREFIX(GPA_GetNumCounters)
GPA_FUNCTION_PREFIX(GPA_GetCounterName)
GPA_FUNCTION_PREFIX(GPA_GetCounterDescription)
GPA_FUNCTION_PREFIX(GPA_GetCounterDataType)
GPA_FUNCTION_PREFIX(GPA_GetCounterUsageType)
GPA_FUNCTION_PREFIX(GPA_GetDataTypeAsStr)
GPA_FUNCTION_PREFIX(GPA_GetUsageTypeAsStr)
GPA_FUNCTION_PREFIX(GPA_GetStatusAsStr)
GPA_FUNCTION_PREFIX(GPA_EnableCounter)
GPA_FUNCTION_PREFIX(GPA_DisableCounter)
GPA_FUNCTION_PREFIX(GPA_GetEnabledCount)
GPA_FUNCTION_PREFIX(GPA_GetEnabledIndex)
GPA_FUNCTION_PREFIX(GPA_IsCounterEnabled)
GPA_FUNCTION_PREFIX(GPA_EnableCounterStr)
GPA_FUNCTION_PREFIX(GPA_DisableCounterStr)
GPA_FUNCTION_PREFIX(GPA_EnableAllCounters)
GPA_FUNCTION_PREFIX(GPA_DisableAllCounters)
GPA_FUNCTION_PREFIX(GPA_GetCounterIndex)
GPA_FUNCTION_PREFIX(GPA_GetPassCount)
GPA_FUNCTION_PREFIX(GPA_BeginSession)
GPA_FUNCTION_PREFIX(GPA_EndSession)
GPA_FUNCTION_PREFIX(GPA_BeginPass)
GPA_FUNCTION_PREFIX(GPA_EndPass)
GPA_FUNCTION_PREFIX(GPA_BeginSample)
GPA_FUNCTION_PREFIX(GPA_EndSample)
GPA_FUNCTION_PREFIX(GPA_GetSampleCount)
GPA_FUNCTION_PREFIX(GPA_IsSampleReady)
GPA_FUNCTION_PREFIX(GPA_IsSessionReady)
GPA_FUNCTION_PREFIX(GPA_GetSampleUInt64)
GPA_FUNCTION_PREFIX(GPA_GetSampleUInt32)
GPA_FUNCTION_PREFIX(GPA_GetSampleFloat64)
GPA_FUNCTION_PREFIX(GPA_GetSampleFloat32)
GPA_FUNCTION_PREFIX(GPA_GetDeviceID)
GPA_FUNCTION_PREFIX(GPA_GetDeviceDesc)
#ifdef AMDT_INTERNAL
GPA_FUNCTION_PREFIX(GPA_InternalSetDrawCallCounts)
#endif
#ifdef NEED_TO_UNDEFINE_GPA_FUNCTION_PREFIX
#undef GPA_FUNCTION_PREFIX
#undef NEED_TO_UNDEFINE_GPA_FUNCTION_PREFIX
#endif
@@ -0,0 +1,106 @@
//==============================================================================
// Copyright (c) 2012-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief An accessor interface for the GPA_CounterGeneratorBase class
//==============================================================================
#ifndef _GPA_I_COUNTER_ACCESSOR_H_
#define _GPA_I_COUNTER_ACCESSOR_H_
#include <vector>
#include "GPUPerfAPITypes.h"
struct GPA_HardwareCounterDescExt;
class GPA_HWInfo;
class GPA_PublicCounter;
class GPA_CounterResultLocation;
/// Types of counter
enum GPACounterType { PUBLIC_COUNTER, HARDWARE_COUNTER, SOFTWARE_COUNTER, UNKNOWN_COUNTER };
/// Stores the type of counter and its local index into that family of counters
struct GPACounterTypeInfo
{
gpa_uint32 m_localIndex; ///< the local index of the counter
GPACounterType m_counterType; ///< the type of the counter
/// Sets the data for
/// \param localIndex the local index to set
/// \param type the type to set
void Set(gpa_uint32 localIndex, GPACounterType type)
{
m_localIndex = localIndex;
m_counterType = type;
}
};
/// An accessor interface for the GPA_CounterGeneratorBase class
class GPA_ICounterAccessor
{
public:
/// Get the number of available counters
/// \return the number of available counters
virtual gpa_uint32 GetNumCounters() = 0;
/// Gets a counter's name
/// \param index The index of a counter, must be between 0 and the value returned from GetNumPublicCounters()
/// \return The counter name
virtual const char* GetCounterName(gpa_uint32 index) = 0;
/// Gets a counter's description
/// \param index The index of a counter, must be between 0 and the value returned from GetNumPublicCounters()
/// \return The counter description
virtual const char* GetCounterDescription(gpa_uint32 index) = 0;
/// Gets the data type of a public counter
/// \param index The index of a counter
/// \return The data type of the the desired counter
virtual GPA_Type GetCounterDataType(gpa_uint32 index) = 0;
/// Gets the usage type of a public counter
/// \param index The index of a counter
/// \return The usage of the the desired counter
virtual GPA_Usage_Type GetCounterUsageType(gpa_uint32 index) = 0;
/// Gets a public counter
/// \param index The index of the public counter to return
/// \return A public counter
virtual const GPA_PublicCounter* GetPublicCounter(gpa_uint32 index) = 0;
/// Gets a hardware counter
/// \param index The index of a hardware counter to return
/// \return A hardware counter
virtual GPA_HardwareCounterDescExt* GetHardwareCounterExt(gpa_uint32 index) = 0;
/// Gets the number of public counters available
/// \return The number of public counters
virtual gpa_uint32 GetNumPublicCounters() = 0;
/// Gets the internal counters required for the specified public counter index
/// \param index The index of a public counter
/// \return A vector of internal counter indices
virtual std::vector<gpa_uint32> GetInternalCountersRequired(gpa_uint32 index) = 0;
/// Computes a public counter value pased on supplied results and hardware info
/// \param[in] counterIndex The public counter index to calculate
/// \param[in] results A vector of hardware counter results
/// \param[in] internalCounterTypes A vector of counter types
/// \param[inout] pResult The computed counter result
/// \param[in] pHwInfo Information about the hardware on which the result was generated
virtual void ComputePublicCounterValue(gpa_uint32 counterIndex, std::vector<char*>& results, std::vector<GPA_Type>& internalCounterTypes, void* pResult, GPA_HWInfo* pHwInfo) = 0;
/// Gets the counter type information based on the global counter index
/// \param globalIndex The index into the main list of counters
/// \return The info about the counter
virtual GPACounterTypeInfo GetCounterTypeInfo(gpa_uint32 globalIndex) = 0;
/// Gets a counter's index
/// \param pName The name of a counter
/// \param[out] pIndex The index of the counter
/// \return true if the counter is found, false otherwise
virtual bool GetCounterIndex(const char* pName, gpa_uint32* pIndex) = 0;
};
#endif //_GPA_I_COUNTER_ACCESSOR_H_
@@ -0,0 +1,102 @@
//==============================================================================
// Copyright (c) 2012-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief An interface for scheduling counters in terms of enabling, disabling, and
/// obtaining the number of necessary passes.
//==============================================================================
#ifndef _GPA_I_COUNTER_SCHEDULER_H_
#define _GPA_I_COUNTER_SCHEDULER_H_
#include "GPAICounterAccessor.h"
#include "GPUPerfAPITypes.h"
#include <vector>
#include <map>
typedef std::map<unsigned int, GPA_CounterResultLocation> CounterResultLocationMap; ///< typedef for map of Counter Result Locations
/// An interface for enabling and disabling counters and getting the resulting number of necessary passes
class GPA_ICounterScheduler
{
public:
/// Reset the counter scheduler
virtual void Reset() = 0;
/// Set the counter accessor that should be used when scheduling counters
/// \param pCounterAccessor The counter accessor
/// \param vendorId the vendor id of the GPU hardware
/// \param deviceId the device id of the GPU hardware
/// \param revisionId the revision id of the GPU hardware
/// \return GPA_STATUS_ERROR_NULL_POINTER If pCounterAccessor is nullptr
/// \return GPA_STATUS_OK
virtual GPA_Status SetCounterAccessor(GPA_ICounterAccessor* pCounterAccessor, gpa_uint32 vendorId, gpa_uint32 deviceId, gpa_uint32 revisionId) = 0;
/// Enables a counter
/// \param index The index of a counter to enable
/// \return GPA_STATUS_OK on success
virtual GPA_Status EnableCounter(gpa_uint32 index) = 0;
/// Disables a counter
/// \param index The index of a counter to disable
/// \return GPA_STATUS_OK on success
virtual GPA_Status DisableCounter(gpa_uint32 index) = 0;
/// Disables all counters
virtual void DisableAllCounters() = 0;
/// Get the number of enabled counters
virtual gpa_uint32 GetNumEnabledCounters() = 0;
/// Gets the counter index of the specified enabled counter
/// \param enabledIndex the enabled counter whose counter index is needed
/// \param[out] pCounterAtIndex the counter index of the specified enabled counter
/// \return GPA_STATUS_OK on success
virtual GPA_Status GetEnabledIndex(gpa_uint32 enabledIndex, gpa_uint32* pCounterAtIndex) = 0;
/// Checks if the specified counter is enabled
/// \param counterIndex the index of the counter to check
/// \return GPA_STATUS_OK if the counter is enabled
virtual GPA_Status IsCounterEnabled(gpa_uint32 counterIndex) = 0;
/// Obtains the number of passes required to collect the enabled counters
/// \param[inout] pNumRequiredPassesOut Will contain the number of passes needed to collect the set of enabled counters
/// \return GPA_STATUS_OK on success
virtual GPA_Status GetNumRequiredPasses(gpa_uint32* pNumRequiredPassesOut) = 0;
/// Get a flag indicating if the counter selection has changed
/// \return true if the counter selection has changed, false otherwise
virtual bool GetCounterSelectionChanged() = 0;
/// Begin profiling -- sets pass index to zero
/// \return GPA_STATUS_OK on success
virtual GPA_Status BeginProfile() = 0;
/// Begin a pass -- increments the pass index
virtual void BeginPass() = 0;
/// Gets the counters for the specified pass
/// \param passIndex the pass whose counters are needed
/// \return a list of counters for the specified pass
virtual std::vector<unsigned int>* GetCountersForPass(gpa_uint32 passIndex) = 0;
/// End a pass
virtual void EndPass() = 0;
/// End profiling
/// \return GPA_STATUS_OK on success
virtual GPA_Status EndProfile() = 0;
/// Gets the counter result locations for the specified public counter
/// \param publicCounterIndex the counter index whose result locations are needed
/// \return a map of counter result locations
virtual CounterResultLocationMap* GetCounterResultLocations(unsigned int publicCounterIndex) = 0;
/// Set draw call counts (internal support)
/// \param iCounts the count of draw calls
virtual void SetDrawCallCounts(const int iCounts) = 0;
};
#endif //_GPA_I_COUNTER_SCHEDULER_H_
@@ -0,0 +1,46 @@
//==============================================================================
// Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief This file can be included by an application that wishes to use the HSA
/// version of GPUPerfAPI. It defines a structure that can be passed to the
/// GPA_OpenContext call when using GPUPerfAPI with HSA.
//==============================================================================
#ifndef _GPUPERFAPI_HSA_H_
#define _GPUPERFAPI_HSA_H_
#include "GPUPerfAPITypes.h"
#include "GPUPerfAPI.h"
#include "hsa.h"
// NOTE: When using the HSA version of GPUPerfAPI, you can initialize and call
// GPUPerfAPI in one of two ways:
// 1) You must call GPA_Initialize prior to the application initializing
// the HSA runtime with a call to hsa_init. You can then simply pass
// in a hsa_queue_t* instance when calling GPA_OpenContext. When doing
// this, GPUPerfAPI will set up the HSA runtime correctly to use the
// AQL-emulation mode and the pre/post-dispatch callbacks.
// 2) You can perform all initialization yourself to ensure that AQL-emulation
// mode is used and the pre/post-dispatch callbacks are used. In that case,
// you can then call GPA_OpenContext with an instance of the below structure
// (whose members you would initialize with data provided by the pre-dispatch
// callback). Note: this second method is currently used by the CodeXL GPU
// Profiler, though in the future, it may be modified to use the first method.
//
// It is recommended to use the first method above when using GPUPerfAPI directly
// from an HSA application.
/// an instance of this structure can be passed to GPA_OpenContext for the HSA
/// version of GPUPerfAPI.
typedef struct
{
const hsa_agent_t* m_pAgent; ///< the agent
const hsa_queue_t* m_pQueue; ///< the queue
void* m_pAqlTranslationHandle; ///< the AQL translation handle (an opaque pointer) supplied by the pre-dispatch callback
} GPA_HSA_Context;
#endif // _GPUPERFAPI_HSA_H_
@@ -0,0 +1,49 @@
//==============================================================================
// Copyright (c) 2009-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief Include this file rather than GPUPerfAPI.h for our internal usage.
//==============================================================================
#ifndef _GPUPERFAPI_PRIVATE_H_
#define _GPUPERFAPI_PRIVATE_H_
#include "GPUPerfAPIOS.h"
#include "GPUPerfAPI.h"
#include "GPUPerfAPITypes-Private.h"
#include "GPUPerfAPIFunctionTypes-Private.h"
// For internal use only
// *INDENT-OFF*
#ifdef AMDT_INTERNAL
/// \brief Register a debug callback function to receive debug log messages.
///
/// Only one debug callback function can be registered, so the implementation should be able
/// to handle the different types of messages. A parameter to the callback function will
/// indicate the message type being received.
/// \param loggingType Identifies the type of messages to receive callbacks for.
/// \param callbackFuncPtr Pointer to the callback function
/// \return GPA_STATUS_OK, unless the callbackFuncPtr is nullptr and the loggingType is not
/// GPA_LOGGING_NONE, in which case GPA_STATUS_ERROR_NULL_POINTER is returned.
GPALIB_DECL GPA_Status GPA_RegisterLoggingDebugCallback(GPA_Log_Debug_Type loggingType, GPA_LoggingDebugCallbackPtrType callbackFuncPtr);
/// \brief Internal function. Pass draw call counts to GPA for internal purposes.
/// \param iCounts[in] the draw counts for the current frame
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_InternalSetDrawCallCounts(const int iCounts);
#endif // AMDT_INTERNAL
// *INDENT-ON*
/// \brief Internal function. Unsupported and may be removed from the API at any time.
///
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_InternalProfileStart();
/// \brief Internal function. Unsupported and may be removed from the API at any time.
///
/// \param pFilename the name of the file to write profile results
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_InternalProfileStop(const char* pFilename);
#endif // _GPUPERFAPI_PRIVATE_H_
@@ -0,0 +1,389 @@
//==============================================================================
// Copyright (c) 2010-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief This file is the only header that must be included by an application that
/// wishes to use GPUPerfAPI. It defines all the available entrypoints.
//==============================================================================
#ifndef _GPUPERFAPI_H_
#define _GPUPERFAPI_H_
#ifndef GPALIB_DECL
/// macro for exporting an API function
#ifdef _WIN32
#ifdef __cplusplus
#define GPALIB_DECL extern "C" __declspec( dllimport )
#else
#define GPALIB_DECL __declspec( dllimport )
#endif
#else //__linux__
#ifdef __cplusplus
#define GPALIB_DECL extern "C"
#else
#define GPALIB_DECL extern
#endif
#endif
#endif
#include <assert.h>
#include "GPUPerfAPITypes.h"
#include "GPUPerfAPIFunctionTypes.h"
/// \brief Register a callback function to receive log messages.
///
/// Only one callback function can be registered, so the implementation should be able
/// to handle the different types of messages. A parameter to the callback function will
/// indicate the message type being received. Messages will not contain a newline character
/// at the end of the message.
/// \param loggingType Identifies the type of messages to receive callbacks for.
/// \param pCallbackFuncPtr Pointer to the callback function
/// \return GPA_STATUS_OK, unless the callbackFuncPtr is nullptr and the loggingType is not
/// GPA_LOGGING_NONE, in which case GPA_STATUS_ERROR_NULL_POINTER is returned.
GPALIB_DECL GPA_Status GPA_RegisterLoggingCallback(GPA_Logging_Type loggingType, GPA_LoggingCallbackPtrType pCallbackFuncPtr);
// Init / destroy GPA
/// \brief Initializes the driver so that counters are exposed.
///
/// This function must be called before the rendering context or device is created.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_Initialize();
/// \brief Undo any initialization to ensure proper behavior in applications that are not being profiled.
///
/// This function must be called after the rendering context or device is released / destroyed.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_Destroy();
// Context Startup / Finish
/// \brief Opens the counters in the specified context for reading.
///
/// This function must be called before any other GPA functions.
/// \param pContext The context to open counters for. Typically a device pointer. Refer to GPA API specific documentation for further details.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_OpenContext(void* pContext);
/// \brief Closes the counters in the currently active context.
///
/// GPA functions should not be called again until the counters are reopened with GPA_OpenContext.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_CloseContext();
/// \brief Select another context to be the currently active context.
///
/// The selected context must have previously been opened with a call to GPA_OpenContext.
/// If the call is successful, all GPA functions will act on the currently selected context.
/// \param pContext The context to select. The same value that was passed to GPA_OpenContext.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_SelectContext(void* pContext);
// Counter Interrogation
/// \brief Get the number of counters available.
///
/// \param pCount The value which will hold the count upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetNumCounters(gpa_uint32* pCount);
/// \brief Get the name of a specific counter.
///
/// \param index The index of the counter name to query. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \param ppName The value which will hold the name upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetCounterName(gpa_uint32 index, const char** ppName);
/// \brief Get description of the specified counter.
///
/// \param index The index of the counter to query. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \param ppDescription The value which will hold the description upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetCounterDescription(gpa_uint32 index, const char** ppDescription);
/// \brief Get the counter data type of the specified counter.
///
/// \param index The index of the counter. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \param pCounterDataType The value which will hold the description upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetCounterDataType(gpa_uint32 index, GPA_Type* pCounterDataType);
/// \brief Get the counter usage type of the specified counter.
///
/// \param index The index of the counter. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \param pCounterUsageType The value which will hold the description upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetCounterUsageType(gpa_uint32 index, GPA_Usage_Type* pCounterUsageType);
/// \brief Get a string with the name of the specified counter data type.
///
/// Typically used to display counter types along with their name.
/// E.g. counterDataType of GPA_TYPE_UINT64 would return "gpa_uint64".
/// \param counterDataType The type to get the string for.
/// \param ppTypeStr The value that will be set to contain a reference to the name of the counter data type.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetDataTypeAsStr(GPA_Type counterDataType, const char** ppTypeStr);
/// \brief Get a string with the name of the specified counter usage type.
///
/// Converts the counter usage type to a string representation.
/// E.g. counterUsageType of GPA_USAGE_TYPE_PERCENTAGE would return "percentage".
/// \param counterUsageType The type to get the string for.
/// \param ppUsageTypeStr The value that will be set to contain a reference to the name of the counter usage type.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetUsageTypeAsStr(GPA_Usage_Type counterUsageType, const char** ppUsageTypeStr);
/// \brief Enable a specified counter.
///
/// Subsequent sampling sessions will provide values for any enabled counters.
/// Initially all counters are disabled, and must explicitly be enabled by calling this function.
/// \param index The index of the counter to enable. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EnableCounter(gpa_uint32 index);
/// \brief Disable a specified counter.
///
/// Subsequent sampling sessions will not provide values for any disabled counters.
/// Initially all counters are disabled, and must explicitly be enabled.
/// \param index The index of the counter to enable. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_DisableCounter(gpa_uint32 index);
/// \brief Get the number of enabled counters.
///
/// \param pCount The value that will be set to the number of counters that are currently enabled.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetEnabledCount(gpa_uint32* pCount);
/// \brief Get the counter index for an enabled counter.
///
/// For example, if GPA_GetEnabledIndex returns 3, and I wanted the counter index of the first enabled counter,
/// I would call this function with enabledNumber equal to 0.
/// \param enabledNumber The number of the enabled counter to get the counter index for. Must lie between 0 and (GPA_GetEnabledIndex result - 1).
/// \param pEnabledCounterIndex The value that will contain the index of the counter.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetEnabledIndex(gpa_uint32 enabledNumber, gpa_uint32* pEnabledCounterIndex);
/// \brief Check that a counter is enabled.
///
/// \param counterIndex The index of the counter. Must lie between 0 and (GPA_GetNumCounters result - 1).
/// \return GPA_STATUS_OK is returned if the counter is enabled, GPA_STATUS_ERROR_NOT_FOUND otherwise.
GPALIB_DECL GPA_Status GPA_IsCounterEnabled(gpa_uint32 counterIndex);
/// \brief Enable a specified counter using the counter name (case insensitive).
///
/// Subsequent sampling sessions will provide values for any enabled counters.
/// Initially all counters are disabled, and must explicitly be enabled by calling this function.
/// \param pCounter The name of the counter to enable.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EnableCounterStr(const char* pCounter);
/// \brief Disable a specified counter using the counter name (case insensitive).
///
/// Subsequent sampling sessions will not provide values for any disabled counters.
/// Initially all counters are disabled, and must explicitly be enabled.
/// \param pCounter The name of the counter to disable.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_DisableCounterStr(const char* pCounter);
/// \brief Enable all counters.
///
/// Subsequent sampling sessions will provide values for all counters.
/// Initially all counters are disabled, and must explicitly be enabled by calling a function which enables them.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EnableAllCounters();
/// \brief Disable all counters.
///
/// Subsequent sampling sessions will not provide values for any disabled counters.
/// Initially all counters are disabled, and must explicitly be enabled.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_DisableAllCounters();
/// \brief Get index of a counter given its name (case insensitive).
///
/// \param pCounter The name of the counter to get the index for.
/// \param pIndex The index of the requested counter.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetCounterIndex(const char* pCounter, gpa_uint32* pIndex);
/// \brief Get the number of passes required for the currently enabled set of counters.
///
/// This represents the number of times the same sequence must be repeated to capture the counter data.
/// On each pass a different (compatible) set of counters will be measured.
/// \param pNumPasses The value of the number of passes.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetPassCount(gpa_uint32* pNumPasses);
/// \brief Begin sampling with the currently enabled set of counters.
///
/// This must be called to begin the counter sampling process.
/// A unique sessionID will be returned which is later used to retrieve the counter values.
/// Session Identifiers are integers and always start from 1 on a newly opened context, upwards in sequence.
/// The set of enabled counters cannot be changed inside a BeginSession/EndSession sequence.
/// \param pSessionID The value that will be set to the session identifier.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_BeginSession(gpa_uint32* pSessionID);
/// \brief End sampling with the currently enabled set of counters.
///
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EndSession();
/// \brief Begin sampling pass.
///
/// Between BeginPass and EndPass calls it is expected that a sequence of repeatable operations exist.
/// If this is not the case only counters which execute in a single pass should be activated.
/// The number of required passes can be determined by enabling a set of counters and then calling GPA_GetPassCount.
/// The operations inside the BeginPass/EndPass calls should be looped over GPA_GetPassCount result number of times.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_BeginPass();
/// \brief End sampling pass.
///
/// Between BeginPass and EndPass calls it is expected that a sequence of repeatable operations exist.
/// If this is not the case only counters which execute in a single pass should be activated.
/// The number of required passes can be determined by enabling a set of counters and then calling GPA_GetPassCount.
/// The operations inside the BeginPass/EndPass calls should be looped over GPA_GetPassCount result number of times.
/// This is necessary to capture all counter values, since sometimes counter combinations cannot be captured simultaneously.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EndPass();
/// \brief Begin a sample using the enabled counters.
///
/// Multiple samples can be performed inside a BeginSession/EndSession sequence.
/// Each sample computes the values of the counters between BeginSample and EndSample.
/// To identify each sample the user must provide a unique sampleID as a parameter to this function.
/// The number need only be unique within the same BeginSession/EndSession sequence.
/// BeginSample must be followed by a call to EndSample before BeginSample is called again.
/// \param sampleID Any integer, unique within the BeginSession/EndSession sequence, used to retrieve the sample results.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_BeginSample(gpa_uint32 sampleID);
/// \brief End sampling using the enabled counters.
///
/// BeginSample must be followed by a call to EndSample before BeginSample is called again.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_EndSample();
/// \brief Get the number of samples a specified session contains.
///
/// This is useful if samples are conditionally created and a count is not kept.
/// \param sessionID The session to get the number of samples for.
/// \param pSamples The value that will be set to the number of samples contained within the session.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetSampleCount(gpa_uint32 sessionID, gpa_uint32* pSamples);
/// \brief Determine if an individual sample result is available.
///
/// After a sampling session results may be available immediately or take a certain amount of time to become available.
/// This function allows you to determine when a sample can be read.
/// The function does not block, permitting periodic polling.
/// To block until a sample is ready use a GetSample* function instead of this.
/// It can be more efficient to determine if a whole session's worth of data is available using GPA_IsSessionReady.
/// \param pReadyResult The value that will contain the result of the sample being ready. True if ready.
/// \param sessionID The session containing the sample to determine availability.
/// \param sampleID The sample identifier of the sample to query availability for.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_IsSampleReady(bool* pReadyResult, gpa_uint32 sessionID, gpa_uint32 sampleID);
/// \brief Determine if all samples within a session are available.
///
/// After a sampling session results may be available immediately or take a certain amount of time to become available.
/// This function allows you to determine when the results of a session can be read.
/// The function does not block, permitting periodic polling.
/// To block until a sample is ready use a GetSample* function instead of this.
/// \param pReadyResult The value that will contain the result of the session being ready. True if ready.
/// \param sessionID The session to determine availability for.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_IsSessionReady(bool* pReadyResult, gpa_uint32 sessionID);
/// \brief Get a sample of type 64-bit unsigned integer.
///
/// This function will block until the value is available.
/// Use GPA_IsSampleReady if you do not wish to block.
/// \param sessionID The session identifier with the sample you wish to retrieve the result of.
/// \param sampleID The identifier of the sample to get the result for.
/// \param counterID The counter index to get the result for.
/// \param pResult The value which will contain the counter result upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetSampleUInt64(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterID, gpa_uint64* pResult);
/// \brief Get a sample of type 32-bit unsigned integer.
///
/// This function will block until the value is available.
/// Use GPA_IsSampleReady if you do not wish to block.
/// \param sessionID The session identifier with the sample you wish to retrieve the result of.
/// \param sampleID The identifier of the sample to get the result for.
/// \param counterIndex The counter index to get the result for.
/// \param pResult The value which will contain the counter result upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetSampleUInt32(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_uint32* pResult);
/// \brief Get a sample of type 64-bit float.
///
/// This function will block until the value is available.
/// Use GPA_IsSampleReady if you do not wish to block.
/// \param sessionID The session identifier with the sample you wish to retrieve the result of.
/// \param sampleID The identifier of the sample to get the result for.
/// \param counterIndex The counter index to get the result for.
/// \param pResult The value which will contain the counter result upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetSampleFloat64(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float64* pResult);
/// \brief Get a sample of type 32-bit float.
///
/// This function will block until the value is available.
/// Use GPA_IsSampleReady if you do not wish to block.
/// \param sessionID The session identifier with the sample you wish to retrieve the result of.
/// \param sampleID The identifier of the sample to get the result for.
/// \param counterIndex The counter index to get the result for.
/// \param pResult The value which will contain the counter result upon successful execution.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetSampleFloat32(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float32* pResult);
/// \brief Get a string translation of a GPA status value.
///
/// Provides a simple method to convert a status enum value into a string which can be used to display log messages.
/// \param status The status to convert into a string.
/// \return A string which describes the supplied status.
GPALIB_DECL const char* GPA_GetStatusAsStr(GPA_Status status);
/// \brief Get the GPU device id associated with the current context
///
/// \param deviceID The value that will be set to the device id.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetDeviceID(gpa_uint32* deviceID);
/// \brief Get the GPU device description associated with the current context
///
/// \param ppDesc The value that will be set to the device description.
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPALIB_DECL GPA_Status GPA_GetDeviceDesc(const char** ppDesc);
#endif // _GPUPERFAPI_H_
@@ -0,0 +1,45 @@
//==============================================================================
// Copyright (c) 2012-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief Implements a library that allows access to the available counters in GPUPerfAPI.
//==============================================================================
#ifndef _GPUPERFAPI_COUNTERS_H_
#define _GPUPERFAPI_COUNTERS_H_
#include "GPUPerfAPITypes-Private.h"
#include "GPAICounterAccessor.h"
#include "GPAICounterScheduler.h"
/// macro to export public API functions
#ifndef GPUPERFAPI_COUNTERS_DECL
#ifdef _WIN32
#ifdef __cplusplus
#define GPUPERFAPI_COUNTERS_DECL extern "C" __declspec( dllimport )
#else
#define GPUPERFAPI_COUNTERS_DECL __declspec( dllimport )
#endif
#else //_LINUX
#define GPUPERFAPI_COUNTERS_DECL extern
#endif
#endif
/// Entrypoint to get the available counters
/// \param api the api whose available counters are requested
/// \param vendorId the vendor id of the device whose available counters are requested
/// \param deviceId the device id of the device whose available counters are requested
/// \param revisionId the revision id of the device whose available counters are requested
/// \param[out] ppCounterAccessorOut the accessor that will provide the counters
/// \param[out] ppCounterSchedulerOut the scheduler that will provide the counters
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPUPERFAPI_COUNTERS_DECL GPA_Status GPA_GetAvailableCounters(GPA_API_Type api, gpa_uint32 vendorId, gpa_uint32 deviceId, gpa_uint32 revisionId, GPA_ICounterAccessor** ppCounterAccessorOut, GPA_ICounterScheduler** ppCounterSchedulerOut);
/// Entrypoint to get the available counters by hardware generation
/// \param api the api whose available counters are requested
/// \param generation the hardware generation whose available counters are requested
/// \param[out] ppCounterAccessorOut the accessor that will provide the counters
/// \return The GPA result status of the operation. GPA_STATUS_OK is returned if the operation is successful.
GPUPERFAPI_COUNTERS_DECL GPA_Status GPA_GetAvailableCountersByGeneration(GPA_API_Type api, GPA_HW_GENERATION generation, GPA_ICounterAccessor** ppCounterAccessorOut);
#endif // _GPUPERFAPI_COUNTERS_H_
@@ -0,0 +1,33 @@
//==============================================================================
// Copyright (c) 2010-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief This file is for internal use to define the function types.
//==============================================================================
#ifndef _GPUPERFAPI_FUNCTION_TYPES_INTERNAL_H_
#define _GPUPERFAPI_FUNCTION_TYPES_INTERNAL_H_
#include "GPUPerfAPIFunctionTypes.h"
/// Typedef for a function pointer for a function to enable counters from a file
typedef GPA_Status(*GPA_EnableCountersFromFilePtrType)(const char* pFile, gpa_uint32* pCountersRead);
/// Typedef for a function pointer for a debug logging callback
typedef void(*GPA_LoggingDebugCallbackPtrType)(GPA_Log_Debug_Type messageType, const char* pMessage);
/// Typedef for a function pointer for a function to register a debug logging callback
typedef GPA_Status(*GPA_RegisterLoggingDebugCallbackPtrType)(GPA_Log_Debug_Type loggingType, GPA_LoggingDebugCallbackPtrType pCallbackFuncPtr);
/// Typedef for a function pointer for a function to start profiling a GPA function
typedef GPA_Status(*GPA_InternalProfileStartPtrType)();
/// Typedef for a function pointer for a function to stop profiling a GPA function
typedef GPA_Status(*GPA_InternalProfileStopPtrType)(const char* pFilename);
/// Typedef for a function pointer for a function to set the number of draw calls in a frame
/// For internal purposes only -- not needed for normal operation of GPUPerfAPI
typedef GPA_Status(*GPA_InternalSetDrawCallCountsPtrType)(const int iCounts);
#endif // _GPUPERFAPI_FUNCTION_TYPES_INTERNAL_H_
@@ -0,0 +1,76 @@
//==============================================================================
// Copyright (c) 2010-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief This file defines function types to make it easier to dynamically load
/// different GPUPerfAPI DLLs into an application that supports multiple APIs.
/// Applications which statically link to GPUPerfAPI do not need to include
/// this file.
//==============================================================================
#ifndef _GPUPERFAPI_FUNCTION_TYPES_H_
#define _GPUPERFAPI_FUNCTION_TYPES_H_
#include "GPUPerfAPITypes.h"
typedef void(*GPA_LoggingCallbackPtrType)(GPA_Logging_Type messageType, const char* pMessage); ///< Typedef for a function pointer for a logging callback function
typedef GPA_Status(*GPA_RegisterLoggingCallbackPtrType)(GPA_Logging_Type loggingType, GPA_LoggingCallbackPtrType pCallbackFuncPtr); ///< Typedef for a function pointer for GPA_RegisterLoggingCallback
// Startup / exit
typedef GPA_Status(*GPA_InitializePtrType)(); ///< Typedef for a function pointer for GPA_Initialize
typedef GPA_Status(*GPA_DestroyPtrType)(); ///< Typedef for a function pointer for GPA_Destroy
// Context
typedef GPA_Status(*GPA_OpenContextPtrType)(void* pContext); ///< Typedef for a function pointer for GPA_OpenContext
typedef GPA_Status(*GPA_CloseContextPtrType)(); ///< Typedef for a function pointer for GPA_CloseContext
typedef GPA_Status(*GPA_SelectContextPtrType)(void* pCcontext); ///< Typedef for a function pointer for GPA_SelectContext
// Counter Interrogation
typedef GPA_Status(*GPA_GetNumCountersPtrType)(gpa_uint32* pCount); ///< Typedef for a function pointer for GPA_GetNumCounters
typedef GPA_Status(*GPA_GetCounterNamePtrType)(gpa_uint32 index, const char** ppName); ///< Typedef for a function pointer for GPA_GetCounterName
typedef GPA_Status(*GPA_GetCounterDescriptionPtrType)(gpa_uint32 index, const char** ppDescription); ///< Typedef for a function pointer for GPA_GetCounterDescription
typedef GPA_Status(*GPA_GetCounterDataTypePtrType)(gpa_uint32 index, GPA_Type* pCounterDataType); ///< Typedef for a function pointer for GPA_GetCounterDataType
typedef GPA_Status(*GPA_GetCounterUsageTypePtrType)(gpa_uint32 index, GPA_Usage_Type* pCounterUsageType); ///< Typedef for a function pointer for GPA_GetCounterUsageType
typedef GPA_Status(*GPA_GetDataTypeAsStrPtrType)(GPA_Type counterDataType, const char** ppTypeStr); ///< Typedef for a function pointer for GPA_GetDataTypeAsStr
typedef GPA_Status(*GPA_GetUsageTypeAsStrPtrType)(GPA_Usage_Type counterUsageType, const char** ppTypeStr); ///< Typedef for a function pointer for GPA_GetUsageTypeAsStr
typedef const char* (*GPA_GetStatusAsStrPtrType)(GPA_Status status); ///< Typedef for a function pointer for GPA_GetStatusAsStr
typedef GPA_Status(*GPA_EnableCounterPtrType)(gpa_uint32 index); ///< Typedef for a function pointer for GPA_EnableCounter
typedef GPA_Status(*GPA_DisableCounterPtrType)(gpa_uint32 index); ///< Typedef for a function pointer for GPA_DisableCounter
typedef GPA_Status(*GPA_GetEnabledCountPtrType)(gpa_uint32* pCount); ///< Typedef for a function pointer for GPA_GetEnabledCount
typedef GPA_Status(*GPA_GetEnabledIndexPtrType)(gpa_uint32 enabledNumber, gpa_uint32* pEnabledCounterIndex); ///< Typedef for a function pointer for GPA_GetEnabledIndex
typedef GPA_Status(*GPA_IsCounterEnabledPtrType)(gpa_uint32 counterIndex); ///< Typedef for a function pointer for GPA_IsCounterEnabled
typedef GPA_Status(*GPA_EnableCounterStrPtrType)(const char* pCounter); ///< Typedef for a function pointer for GPA_EnableCounterStr
typedef GPA_Status(*GPA_DisableCounterStrPtrType)(const char* pCounter); ///< Typedef for a function pointer for GPA_DisableCounterStr
typedef GPA_Status(*GPA_EnableAllCountersPtrType)(); ///< Typedef for a function pointer for GPA_EnableAllCounters
typedef GPA_Status(*GPA_DisableAllCountersPtrType)(); ///< Typedef for a function pointer for GPA_DisableAllCounters
typedef GPA_Status(*GPA_GetCounterIndexPtrType)(const char* pCounter, gpa_uint32* pIndex); ///< Typedef for a function pointer for GPA_GetCounterIndex
typedef GPA_Status(*GPA_GetPassCountPtrType)(gpa_uint32* pNumPasses); ///< Typedef for a function pointer for GPA_GetPassCount
typedef GPA_Status(*GPA_BeginSessionPtrType)(gpa_uint32* pSessionID); ///< Typedef for a function pointer for GPA_BeginSession
typedef GPA_Status(*GPA_EndSessionPtrType)(); ///< Typedef for a function pointer for GPA_EndSession
typedef GPA_Status(*GPA_BeginPassPtrType)(); ///< Typedef for a function pointer for GPA_BeginPass
typedef GPA_Status(*GPA_EndPassPtrType)(); ///< Typedef for a function pointer for GPA_EndPass
typedef GPA_Status(*GPA_BeginSamplePtrType)(gpa_uint32 sampleID); ///< Typedef for a function pointer for GPA_BeginSample
typedef GPA_Status(*GPA_EndSamplePtrType)(); ///< Typedef for a function pointer for GPA_EndSample
typedef GPA_Status(*GPA_GetSampleCountPtrType)(gpa_uint32 sessionID, gpa_uint32* pSamples); ///< Typedef for a function pointer for GPA_GetSampleCount
typedef GPA_Status(*GPA_IsSampleReadyPtrType)(bool* pReadyResult, gpa_uint32 sessionID, gpa_uint32 sampleID); ///< Typedef for a function pointer for GPA_IsSampleReady
typedef GPA_Status(*GPA_IsSessionReadyPtrType)(bool* pReadyResult, gpa_uint32 sessionID); ///< Typedef for a function pointer for GPA_IsSessionReady
typedef GPA_Status(*GPA_GetSampleUInt64PtrType)(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterID, gpa_uint64* pResult); ///< Typedef for a function pointer for GPA_GetSampleUInt64
typedef GPA_Status(*GPA_GetSampleUInt32PtrType)(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_uint32* pResult); ///< Typedef for a function pointer for GPA_GetSampleUInt32
typedef GPA_Status(*GPA_GetSampleFloat32PtrType)(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float32* pResult); ///< Typedef for a function pointer for GPA_GetSampleFloat32
typedef GPA_Status(*GPA_GetSampleFloat64PtrType)(gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float64* pResult); ///< Typedef for a function pointer for GPA_GetSampleFloat64
typedef GPA_Status(*GPA_GetDeviceIDPtrType)(gpa_uint32* pDeviceID); ///< Typedef for a function pointer for GPA_GetDeviceID
typedef GPA_Status(*GPA_GetDeviceDescPtrType)(const char** ppDesc); ///< Typedef for a function pointer for GPA_GetDeviceDesc
#endif // _GPUPERFAPI_FUNCTION_TYPES_H_
@@ -0,0 +1,61 @@
//==============================================================================
// Copyright (c) 2010-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief This file is for internal use to define the function types.
//==============================================================================
#ifndef _GPUPERFAPI_TYPES_INTERNAL_H_
#define _GPUPERFAPI_TYPES_INTERNAL_H_
#include "GPUPerfAPITypes.h"
// For internal use only
/// Counter type definitions
typedef enum
{
GPA_COUNTER_TYPE_DYNAMIC, ///< hardware per sample counter type
GPA_COUNTER_TYPE_SESSION, ///< hardware per session counter type
GPA_COUNTER_TYPE_API_DYNAMIC, ///< api per sample counter type
GPA_COUNTER_TYPE_API_SESSION, ///< api per session counter
GPA_COUNTER_TYPE__LAST ///< Marker indicating last element
} GPA_CounterType;
/// Private Logging types that adds messages defined in Debug Builds only
enum GPA_Log_Debug_Type
{
// these must match the public GPA_Logging_type enum (but note we change LOGGING to LOG)
GPA_LOG_NONE = 0,
GPA_LOG_ERROR = 1,
GPA_LOG_MESSAGE = 2,
GPA_LOG_ERROR_AND_MESSAGE = 3,
GPA_LOG_TRACE = 4,
GPA_LOG_ERROR_AND_TRACE = 5,
GPA_LOG_MESSAGE_AND_TRACE = 6,
GPA_LOG_ERROR_MESSAGE_AND_TRACE = 7,
GPA_LOG_ALL = 0xFF,
#ifdef AMDT_INTERNAL
// these are private types that are only defined in internal builds
GPA_LOG_DEBUG_ERROR = 0x0100,
GPA_LOG_DEBUG_MESSAGE = 0x0200,
GPA_LOG_DEBUG_TRACE = 0x0400,
GPA_LOG_DEBUG_COUNTERDEFS = 0x0800,
GPA_LOG_DEBUG_ALL = 0xFF00
#endif // AMDT_INTERNAL
};
/// this enum needs to be kept up to date with GDT_HW_GENERATION in DeviceInfo.h
enum GPA_HW_GENERATION
{
GPA_HW_GENERATION_NONE, ///< undefined hw generation
GPA_HW_GENERATION_NVIDIA, ///< Used for nvidia cards by GPA
GPA_HW_GENERATION_INTEL, ///< Used for Intel cards by GPA
GPA_HW_GENERATION_SOUTHERNISLAND, ///< GFX IP 6
GPA_HW_GENERATION_SEAISLAND, ///< GFX IP 7
GPA_HW_GENERATION_VOLCANICISLAND, ///< GFX IP 8
GPA_HW_GENERATION_LAST
};
#endif // _GPUPERFAPI_TYPES_INTERNAL_H_
@@ -0,0 +1,177 @@
//==============================================================================
// Copyright (c) 2010-2016 Advanced Micro Devices, Inc. All rights reserved.
/// \author AMD Developer Tools Team
/// \file
/// \brief Defines the data types and enumerations used by GPUPerfAPI.
/// This file does not need to be directly included by an application
/// that uses GPUPerfAPI.
//==============================================================================
#ifndef _GPUPERFAPI_TYPES_H_
#define _GPUPERFAPI_TYPES_H_
#include <limits.h>
// Type definitions
#ifdef _WIN32
typedef char gpa_int8;
typedef short gpa_int16;
typedef int gpa_int32;
typedef __int64 gpa_int64;
typedef float gpa_float32;
typedef double gpa_float64;
typedef unsigned char gpa_uint8;
typedef unsigned short gpa_uint16;
typedef unsigned int gpa_uint32;
typedef unsigned __int64 gpa_uint64;
#ifndef __cplusplus
typedef gpa_uint8 bool;
#endif
#endif // _WIN32
#ifdef __linux__
#ifdef GPALIB_DECL
#else
#ifdef __cplusplus
#define GPALIB_DECL extern "C"
#else
#define GPALIB_DECL
#endif // _cplusplus
#endif
typedef char gpa_int8;
typedef short gpa_int16;
typedef int gpa_int32;
typedef long long gpa_int64;
typedef unsigned int UINT;
typedef float gpa_float32;
typedef double gpa_float64;
typedef unsigned char gpa_uint8;
typedef unsigned short gpa_uint16;
typedef unsigned int gpa_uint32;
typedef unsigned long long gpa_uint64;
#ifndef __cplusplus
typedef gpa_uint8 bool;
#endif
#define UNREFERENCED_PARAMETER(x)
#define UNREFERECED_VAR(x)
#define _strcmpi(a, b) strcasecmp(a, b)
// for now, just use non secure version for Linux
#define strcpy_s(dst, ndst, src) strcpy(dst, src)
#define strtok_s(a, b, c) strtok(a, b)
#endif // __linux__
// Limit definitions
/// macro for max int8
#define GPA_INT8_MAX SCHAR_MAX
/// macro for max int16
#define GPA_INT16_MAX SHRT_MAX
/// macro for max int32
#define GPA_INT32_MAX INT_MAX
/// macro for max int64
#define GPA_INT64_MAX LLONG_MAX
/// macro for max uint8
#define GPA_UINT8_MAX UCHAR_MAX
/// macro for max uint16
#define GPA_UINT16_MAX USHRT_MAX
/// macro for max uint32
#define GPA_UINT32_MAX UINT_MAX
/// macro for max uint64
#define GPA_UINT64_MAX ULLONG_MAX
/// Status enumerations
typedef enum
{
GPA_STATUS_OK = 0,
GPA_STATUS_ERROR_NULL_POINTER,
GPA_STATUS_ERROR_COUNTERS_NOT_OPEN,
GPA_STATUS_ERROR_COUNTERS_ALREADY_OPEN,
GPA_STATUS_ERROR_INDEX_OUT_OF_RANGE,
GPA_STATUS_ERROR_NOT_FOUND,
GPA_STATUS_ERROR_ALREADY_ENABLED,
GPA_STATUS_ERROR_NO_COUNTERS_ENABLED,
GPA_STATUS_ERROR_NOT_ENABLED,
GPA_STATUS_ERROR_SAMPLING_NOT_STARTED,
GPA_STATUS_ERROR_SAMPLING_ALREADY_STARTED,
GPA_STATUS_ERROR_SAMPLING_NOT_ENDED,
GPA_STATUS_ERROR_NOT_ENOUGH_PASSES,
GPA_STATUS_ERROR_PASS_NOT_ENDED,
GPA_STATUS_ERROR_PASS_NOT_STARTED,
GPA_STATUS_ERROR_PASS_ALREADY_STARTED,
GPA_STATUS_ERROR_SAMPLE_NOT_STARTED,
GPA_STATUS_ERROR_SAMPLE_ALREADY_STARTED,
GPA_STATUS_ERROR_SAMPLE_NOT_ENDED,
GPA_STATUS_ERROR_CANNOT_CHANGE_COUNTERS_WHEN_SAMPLING,
GPA_STATUS_ERROR_SESSION_NOT_FOUND,
GPA_STATUS_ERROR_SAMPLE_NOT_FOUND,
GPA_STATUS_ERROR_SAMPLE_NOT_FOUND_IN_ALL_PASSES,
GPA_STATUS_ERROR_COUNTER_NOT_OF_SPECIFIED_TYPE,
GPA_STATUS_ERROR_READING_COUNTER_RESULT,
GPA_STATUS_ERROR_VARIABLE_NUMBER_OF_SAMPLES_IN_PASSES,
GPA_STATUS_ERROR_FAILED,
GPA_STATUS_ERROR_HARDWARE_NOT_SUPPORTED,
GPA_STATUS_ERROR_DRIVER_NOT_SUPPORTED,
// following are status codes used internally within GPUPerfAPI
GPA_STATUS_INTERNAL = 256,
GPA_STATUS_OK_HANDLED = GPA_STATUS_INTERNAL,
} GPA_Status;
/// Value type definitions
typedef enum
{
GPA_TYPE_FLOAT32, ///< Result will be a 32-bit float
GPA_TYPE_FLOAT64, ///< Result will be a 64-bit float
GPA_TYPE_UINT32, ///< Result will be a 32-bit unsigned int
GPA_TYPE_UINT64, ///< Result will be a 64-bit unsigned int
GPA_TYPE_INT32, ///< Result will be a 32-bit int
GPA_TYPE_INT64, ///< Result will be a 64-bit int
GPA_TYPE__LAST ///< Marker indicating last element
} GPA_Type;
/// Result usage type definitions
typedef enum
{
GPA_USAGE_TYPE_RATIO, ///< Result is a ratio of two different values or types
GPA_USAGE_TYPE_PERCENTAGE, ///< Result is a percentage, typically within [0,100] range, but may be higher for certain counters
GPA_USAGE_TYPE_CYCLES, ///< Result is in clock cycles
GPA_USAGE_TYPE_MILLISECONDS, ///< Result is in milliseconds
GPA_USAGE_TYPE_BYTES, ///< Result is in bytes
GPA_USAGE_TYPE_ITEMS, ///< Result is a count of items or objects (ie, vertices, triangles, threads, pixels, texels, etc)
GPA_USAGE_TYPE_KILOBYTES, ///< Result is in kilobytes
GPA_USAGE_TYPE__LAST ///< Marker indicating last element
} GPA_Usage_Type;
/// Logging type definitions
typedef enum
{
GPA_LOGGING_NONE = 0,
GPA_LOGGING_ERROR = 1,
GPA_LOGGING_MESSAGE = 2,
GPA_LOGGING_ERROR_AND_MESSAGE = 3,
GPA_LOGGING_TRACE = 4,
GPA_LOGGING_ERROR_AND_TRACE = 5,
GPA_LOGGING_MESSAGE_AND_TRACE = 6,
GPA_LOGGING_ERROR_MESSAGE_AND_TRACE = 7,
GPA_LOGGING_ALL = 0xFF
} GPA_Logging_Type;
/// APIs Supported (either publicly or internally) by GPUPerfAPI
typedef enum
{
GPA_API_DIRECTX_11,
GPA_API_DIRECTX_12,
GPA_API_OPENGL,
GPA_API_OPENGLES,
GPA_API_OPENCL,
GPA_API_HSA,
GPA_API__LAST
} GPA_API_Type;
#endif // _GPUPERFAPI_TYPES_H_
@@ -0,0 +1,19 @@
Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,42 @@
Third-party licenses, acknowledgements
======================================
GPUPerfAPI uses the following third-party software:
OpenCL
------
Copyright (c) 2008-2012 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and/or associated documentation files (the "Materials"), to deal in the Materials without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Materials, and to permit persons to whom the Materials are furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
OpenGLES (3 entries from 3 different header files)
--------
Copyright (c) 2013-2014 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and/or associated documentation files (the "Materials"), to deal in the Materials without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Materials, and to permit persons to whom the Materials are furnished to do so, subject tothe following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Materials.
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
--------
This document is licensed under the SGI Free Software B License Version 2.0. For details, see http://oss.sgi.com/projects/FreeB/
--------
License Applicability. Except to the extent portions of this file are made subject to an alternative license as permitted in the SGI Free Software License B, Version 1.0 (the "License"), the contents of this file are subject only to the provisions of the License. You may not use this file except in compliance with the License. You may obtain a copy of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
http://oss.sgi.com/projects/FreeB
Note that, as provided in the License, the Software is distributed on an "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
Original Code. The Original Code is: OpenGL Sample Implementation, Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. Copyright in any portions created by third parties is as indicated elsewhere herein. All Rights Reserved.
Additional Notice Provisions: The application programming interfaces established by SGI in conjunction with the Original Code are The OpenGL(R) Graphics System: A Specification (Version 1.2.1), released April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version1.3), released November 4, 1998; and OpenGL(R) Graphics with the XWindow System(R) (Version 1.3), released October 19, 1998. This software was created using the OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has not been independently verified as being compliant with the OpenGL(R) version 1.2.1 Specification.
@@ -0,0 +1 @@
Release: GPUPerfAPI 2.22.1