Commits

Anonymous committed b83d329

Initial commit.

Comments (0)

Files changed (6)

+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(AmdPerfLibrary)
+
+SET(SOURCES
+	PerfLib.cpp
+)
+
+SET(HEADERS
+	PerfLib.h
+
+	GPUPerfAPI.h
+	GPUPerfAPIFunctionTypes.h
+	GPUPerfAPITypes.h
+)
+
+IF(MSVC)
+	ADD_DEFINITIONS(/wd4127)
+ENDIF(MSVC)
+
+IF(NIVEN_OS_WINDOWS)
+	ADD_DEFINITIONS(-DAMD_PERF_API_WINDOWS=1)
+ELSEIF(NIVEN_OS_LINUX)
+	ADD_DEFINITIONS(-DAMD_PERF_API_LINUX=1 -D_LINUX)
+ENDIF()
+
+ADD_LIBRARY(AmdPerfLibrary STATIC ${SOURCES} ${HEADERS})
+
+NIVEN_SETUP_PROJECT(AmdPerfLibrary
+	FOLDER "extern")
+//=============================================================================
+//
+// Author: GPU Developer Tools
+//         AMD, Inc.
+//
+// This file is the only header that must be included by an application that
+// wishes to use GPUPerfAPI. It defines all the available entrypoints.
+//=============================================================================
+// Copyright (c) 2010 Advanced Micro Devices, Inc.  All rights reserved.
+//=============================================================================
+
+#ifndef _GPUPERFAPI_H_
+#define _GPUPERFAPI_H_
+
+#ifndef GPALIB_DECL
+   #ifdef _WIN32
+      #ifdef __cplusplus
+         #define GPALIB_DECL extern "C" __declspec( dllimport )
+      #else
+         #define GPALIB_DECL __declspec( dllimport )
+      #endif
+   #else //_LINUX
+      #define GPALIB_DECL extern
+   #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 callbackFuncPtr Pointer to the callback function
+/// \return GPA_STATUS_OK, unless the callbackFuncPtr is NULL 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 callbackFuncPtr );
+
+// 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 context 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* context );
+
+/// \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 context 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* context );
+
+
+// Counter Interrogation
+
+/// \brief Get the number of counters available.
+///
+/// \param count 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* count );
+
+/// \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 name 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** name );
+
+/// \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 description 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** description );
+
+/// \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 counterDataType 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* counterDataType );
+
+/// \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 counterUsageType 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* counterUsageType );
+
+/// \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 typeStr 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** typeStr );
+
+/// \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 usageTypeStr 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** usageTypeStr );
+
+/// \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 count 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* count );
+
+
+/// \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 enabledCounterIndex 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* enabledCounterIndex );
+
+
+/// \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 counter 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* counter );
+
+
+/// \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 counter 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* counter );
+
+
+/// \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 counter The name of the counter to get the index for.
+/// \param index 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* counter, gpa_uint32* index );
+
+
+/// \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 numPasses 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* numPasses );
+
+
+/// \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 sessionID 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* sessionID );
+
+
+/// \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 samples 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* samples );
+
+
+/// \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 readyResult 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* readyResult, 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 readyResult 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* readyResult, 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 result 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* result );
+
+
+/// \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 result 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* result );
+
+
+/// \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 result 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* result );
+
+
+/// \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 result 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* result );
+
+
+/// \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 );
+
+#endif // _GPUPERFAPI_H_

GPUPerfAPIFunctionTypes.h

+//=============================================================================
+//
+// Author: GPU Developer Tools
+//         AMD, Inc.
+//
+// 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.
+//=============================================================================
+// Copyright (c) 2010 Advanced Micro Devices, Inc.  All rights reserved.
+//=============================================================================
+
+#ifndef _GPUPERFAPI_FUNCTION_TYPES_H_
+#define _GPUPERFAPI_FUNCTION_TYPES_H_
+
+#include "GPUPerfAPITypes.h"
+
+typedef void( *GPA_LoggingCallbackPtrType ) ( GPA_Logging_Type messageType, const char* message );
+
+typedef GPA_Status( *GPA_RegisterLoggingCallbackPtrType ) ( GPA_Logging_Type loggingType, GPA_LoggingCallbackPtrType callbackFuncPtr );
+
+// Startup / exit
+typedef GPA_Status( *GPA_InitializePtrType )();
+typedef GPA_Status( *GPA_DestroyPtrType )();
+
+// Context
+typedef GPA_Status( *GPA_OpenContextPtrType )( void* context );
+typedef GPA_Status( *GPA_CloseContextPtrType )();
+typedef GPA_Status( *GPA_SelectContextPtrType )( void* context );
+
+// Counter Interrogation
+typedef GPA_Status( *GPA_GetNumCountersPtrType )( gpa_uint32* count );
+typedef GPA_Status( *GPA_GetCounterNamePtrType )( gpa_uint32 index, const char** name );
+typedef GPA_Status( *GPA_GetCounterDescriptionPtrType )( gpa_uint32 index, const char** description );
+typedef GPA_Status( *GPA_GetCounterDataTypePtrType )( gpa_uint32 index, GPA_Type* counterDataType );
+typedef GPA_Status( *GPA_GetCounterUsageTypePtrType ) ( gpa_uint32 index, GPA_Usage_Type* counterUsageType );
+typedef GPA_Status( *GPA_GetDataTypeAsStrPtrType )( GPA_Type counterDataType, const char** typeStr );
+typedef GPA_Status( *GPA_GetUsageTypeAsStrPtrType )( GPA_Usage_Type counterUsageType, const char** typeStr );
+typedef const char*( *GPA_GetStatusAsStrPtrType ) ( GPA_Status status );
+
+typedef GPA_Status( *GPA_EnableCounterPtrType )( gpa_uint32 index );
+typedef GPA_Status( *GPA_DisableCounterPtrType )( gpa_uint32 index );
+typedef GPA_Status( *GPA_GetEnabledCountPtrType )( gpa_uint32* count );
+typedef GPA_Status( *GPA_GetEnabledIndexPtrType )( gpa_uint32 enabledNumber, gpa_uint32* enabledCounterIndex );
+
+typedef GPA_Status( *GPA_IsCounterEnabledPtrType)( gpa_uint32 counterIndex );
+
+typedef GPA_Status( *GPA_EnableCounterStrPtrType )( const char* counter );
+typedef GPA_Status( *GPA_DisableCounterStrPtrType )( const char* counter );
+
+typedef GPA_Status( *GPA_EnableAllCountersPtrType )();
+typedef GPA_Status( *GPA_DisableAllCountersPtrType )();
+typedef GPA_Status( *GPA_GetCounterIndexPtrType )( const char* counter, gpa_uint32* index );
+
+typedef GPA_Status( *GPA_GetPassCountPtrType )( gpa_uint32* numPasses );
+
+typedef GPA_Status( *GPA_BeginSessionPtrType )( gpa_uint32* sessionID );
+typedef GPA_Status( *GPA_EndSessionPtrType )();
+
+typedef GPA_Status( *GPA_BeginPassPtrType )();
+typedef GPA_Status( *GPA_EndPassPtrType )();
+
+typedef GPA_Status( *GPA_BeginSamplePtrType )( gpa_uint32 sampleID );
+typedef GPA_Status( *GPA_EndSamplePtrType )();
+
+typedef GPA_Status( *GPA_GetSampleCountPtrType ) ( gpa_uint32 sessionID, gpa_uint32 *samples );
+
+typedef GPA_Status( *GPA_IsSampleReadyPtrType )( bool* readyResult, gpa_uint32 sessionID, gpa_uint32 sampleID );
+typedef GPA_Status( *GPA_IsSessionReadyPtrType )( bool* readyResult, gpa_uint32 sessionID );
+typedef GPA_Status( *GPA_GetSampleUInt64PtrType )( gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterID, gpa_uint64* result );
+typedef GPA_Status( *GPA_GetSampleUInt32PtrType )( gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_uint32* result );
+typedef GPA_Status( *GPA_GetSampleFloat32PtrType )( gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float32* result );
+typedef GPA_Status( *GPA_GetSampleFloat64PtrType )( gpa_uint32 sessionID, gpa_uint32 sampleID, gpa_uint32 counterIndex, gpa_float64* result );
+
+#endif // _GPUPERFAPI_FUNCTION_TYPES_H_

GPUPerfAPITypes.h

+//=============================================================================
+//
+// Author: GPU Developer Tools
+//         AMD, Inc.
+//
+// Defines the data types and enumerations used by GPUPerfAPI.
+// This file does not need to be directly included by an application
+// that uses GPUPerfAPI.
+//=============================================================================
+// Copyright (c) 2010 Advanced Micro Devices, Inc.  All rights reserved.
+//=============================================================================
+#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 int 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 int gpa_uint64;
+#ifndef __cplusplus
+typedef gpa_uint8 bool;
+#endif
+
+// Linux
+#define TRACE_FUNCTION(x)
+#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
+#define GPA_INT8_MAX SCHAR_MAX
+#define GPA_INT16_MAX SHRT_MAX
+#define GPA_INT32_MAX INT_MAX
+#define GPA_INT64_MAX LLONG_MAX
+
+#define GPA_UINT8_MAX UCHAR_MAX
+#define GPA_UINT16_MAX USHRT_MAX
+#define GPA_UINT32_MAX UINT_MAX
+#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,
+
+   // Bug FB 9349: This error code is for a work around to a gl driver bug where it crashes on SI h/w for 12.9 catalyst
+   GPA_STATUS_ERROR_CATALYST_VER_UNSUPPORTED_SI,
+} 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;
+
+#endif // _GPUPERFAPI_TYPES_H_
+#include "PerfLib.h"
+#include "GPUPerfAPI.h"
+
+#if AMD_PERF_API_LINUX
+	#include <dlfcn.h>	//dyopen, dlsym, dlclose
+	#include <stdlib.h>
+	#include <string.h>	//memeset
+	#include <unistd.h>	//sleep
+#elif AMD_PERF_API_WINDOWS
+	#include <windows.h>
+	#include <tchar.h>
+#endif
+
+#include <stdio.h>
+#include <cstdlib>
+#include <vector>
+
+#include <iostream>
+#include <stdexcept>
+
+#define NIV_SAFE_GPA(expr) do { const auto r = (expr); if (r != GPA_STATUS_OK) throw std::runtime_error ("GPA failure"); } while (0)
+
+namespace Amd {
+namespace {
+template <typename T>
+T function_pointer_cast (const void* p)
+{
+	static_assert (sizeof (T) == sizeof (void*), "Size of a plain function pointer "
+		"must be equal to size of a plain pointer.");
+	T result;
+	::memcpy (&result, &p, sizeof (void*));
+	return result;
+}
+
+struct LogCallback
+{
+	GPA_LoggingCallbackPtrType	;
+	std::function<void (int, const char*)>	callback;
+};
+}
+
+struct PerformanceLibrary::Impl
+{
+	Impl (const ProfileApi::Enum api)
+	{
+#if AMD_PERF_API_LINUX
+#elif AMD_PERF_API_WINDOWS
+		switch (api) {
+		case ProfileApi::Direct3D10: lib_	= LoadLibraryA ("GPUPerfAPICL-x64.dll"); break;
+		case ProfileApi::Direct3D11: lib_	= LoadLibraryA ("GPUPerfAPIDX11-x64.dll"); break;
+		case ProfileApi::OpenGL: lib_		= LoadLibraryA ("GPUPerfAPIGL-x64.dll"); break;
+		case ProfileApi::OpenCL: lib_		= LoadLibraryA ("GPUPerfAPICL-x64.dll"); break;
+		}
+#endif
+
+		InitFunctions ();
+
+		initialize_ ();
+	}
+
+	~Impl ()
+	{
+		destroy_ ();
+
+#if AMD_PERF_API_LINUX
+		if (lib_ != nullptr) {
+			dlclose (lib_);
+		}
+#elif AMD_PERF_API_WINDOWS
+		if (lib_ != NULL) {
+			FreeLibrary (lib_);
+		}
+#endif
+	}
+
+private:
+	void InitFunctions ()
+	{
+		initialize_ 			= function_pointer_cast<GPA_InitializePtrType> (LoadFunction ("GPA_Initialize"));
+		destroy_ 				= function_pointer_cast<GPA_DestroyPtrType> (LoadFunction ("GPA_Destroy"));
+		openContext_ 			= function_pointer_cast<GPA_OpenContextPtrType> (LoadFunction ("GPA_OpenContext"));
+		closeContext_ 			= function_pointer_cast<GPA_CloseContextPtrType> (LoadFunction ("GPA_CloseContext"));
+		getNumCounters_ 		= function_pointer_cast<GPA_GetNumCountersPtrType> (LoadFunction ("GPA_GetNumCounters"));
+		getCounterName_ 		= function_pointer_cast<GPA_GetCounterNamePtrType> (LoadFunction ("GPA_GetCounterName"));
+		getCounterDataType_ 	= function_pointer_cast<GPA_GetCounterDataTypePtrType> (LoadFunction ("GPA_GetCounterDataType"));
+		enableCounter_ 			= function_pointer_cast<GPA_EnableCounterPtrType> (LoadFunction ("GPA_EnableCounter"));
+		disableCounter_ 		= function_pointer_cast<GPA_DisableCounterPtrType> (LoadFunction ("GPA_DisableCounter"));
+		getPassCount_ 			= function_pointer_cast<GPA_GetPassCountPtrType> (LoadFunction ("GPA_GetPassCount"));
+		beginSession_ 			= function_pointer_cast<GPA_BeginSessionPtrType> (LoadFunction ("GPA_BeginSession"));
+		endSession_ 			= function_pointer_cast<GPA_EndSessionPtrType> (LoadFunction ("GPA_EndSession"));
+		beginPass_ 				= function_pointer_cast<GPA_BeginPassPtrType> (LoadFunction ("GPA_BeginPass"));
+		endPass_ 				= function_pointer_cast<GPA_EndPassPtrType> (LoadFunction ("GPA_EndPass"));
+		beginSample_ 			= function_pointer_cast<GPA_BeginSamplePtrType> (LoadFunction ("GPA_BeginSample"));
+		endSample_ 				= function_pointer_cast<GPA_EndSamplePtrType> (LoadFunction ("GPA_EndSample"));
+		isSessionReady_ 		= function_pointer_cast<GPA_IsSessionReadyPtrType> (LoadFunction ("GPA_IsSessionReady"));
+		getSampleUInt64_ 		= function_pointer_cast<GPA_GetSampleUInt64PtrType> (LoadFunction ("GPA_GetSampleUInt64"));
+		getSampleUInt32_ 		= function_pointer_cast<GPA_GetSampleUInt32PtrType> (LoadFunction ("GPA_GetSampleUInt32"));
+		getSampleFloat32_ 		= function_pointer_cast<GPA_GetSampleFloat32PtrType> (LoadFunction ("GPA_GetSampleFloat32"));
+		getSampleFloat64_ 		= function_pointer_cast<GPA_GetSampleFloat64PtrType> (LoadFunction ("GPA_GetSampleFloat64"));
+		getEnabledCount_ 		= function_pointer_cast<GPA_GetEnabledCountPtrType> (LoadFunction ("GPA_GetEnabledCount"));
+		getEnabledIndex_ 		= function_pointer_cast<GPA_GetEnabledIndexPtrType> (LoadFunction ("GPA_GetEnabledIndex"));
+		registerLoggingCallback_= function_pointer_cast<GPA_RegisterLoggingCallbackPtrType> (LoadFunction ("GPA_RegisterLoggingCallback"));
+	}
+
+	void* LoadFunction (const char* name) const
+	{
+#if AMD_PERF_API_LINUX
+		return dlsym (lib_, name);
+#elif AMD_PERF_API_WINDOWS
+		return GetProcAddress (lib_, name);
+#else
+		return nullptr;
+#endif
+	}
+
+public:
+	std::vector<CounterInfo>	GetAvailableCounters () const
+	{
+		std::vector<CounterInfo> result;
+
+		gpa_uint32 availableCounters = 0;
+
+		NIV_SAFE_GPA (getNumCounters_ (&availableCounters));
+		result.reserve (availableCounters);
+
+		for (gpa_uint32 i = 0; i < availableCounters; ++i) {
+			CounterInfo ci;
+
+			const char* name = nullptr;
+			NIV_SAFE_GPA (getCounterName_ (i, &name));
+
+			ci.name = name;
+
+			GPA_Type dataType;
+
+			NIV_SAFE_GPA (getCounterDataType_ (i, &dataType));
+
+			switch (dataType) {
+				case GPA_TYPE_UINT32: ci.type = DataType::uint32; break;
+				case GPA_TYPE_UINT64: ci.type = DataType::uint64; break;
+				case GPA_TYPE_FLOAT32: ci.type = DataType::float32; break;
+				case GPA_TYPE_FLOAT64: ci.type = DataType::float64; break;
+
+				default:
+					throw std::runtime_error ("Unhandled data type.");
+			}
+
+			ci.index = i;
+
+			result.push_back (ci);
+		}
+
+		return result;
+	}
+
+	void EnableCounters (const std::vector<CounterInfo>& counters)
+	{
+		for (const auto& counter : counters) {
+			NIV_SAFE_GPA (enableCounter_ (counter.index));
+		}
+	}
+
+	void BeginPass ()
+	{
+		NIV_SAFE_GPA (beginPass_ ());
+	}
+
+	void EndPass ()
+	{
+		NIV_SAFE_GPA (endPass_ ());
+	}
+
+	ProfileSessionHandle BeginProfileSession ()
+	{
+		gpa_uint32 sessionId = 0;
+		NIV_SAFE_GPA (beginSession_ (&sessionId));
+
+		return sessionId;
+	}
+
+	void EndProfileSession ()
+	{
+		NIV_SAFE_GPA (endSession_ ());
+	}
+
+	bool GetProfileSessionResult (const ProfileSessionHandle handle,
+		ProfileResult& result, const bool block) const
+	{
+		bool ready = false;
+		while (! ready) {
+			NIV_SAFE_GPA (isSessionReady_ (&ready, handle));
+
+			if (! block) {
+				continue;
+			}
+		}
+
+		if (! ready) {
+			return false;
+		}
+
+		gpa_uint32 enabledCounterCount = 0;
+		NIV_SAFE_GPA (getEnabledCount_ (&enabledCounterCount));
+
+		for (gpa_uint32 i = 0; i < enabledCounterCount; ++i) {
+			gpa_uint32 index = 0;
+
+			NIV_SAFE_GPA (getEnabledIndex_ (i, &index));
+			const char* name = nullptr;
+
+			NIV_SAFE_GPA (getCounterName_ (index, &name));
+
+			GPA_Type type;
+			NIV_SAFE_GPA (getCounterDataType_ (index, &type));
+
+			switch (type) {
+				case GPA_TYPE_INT32:
+				{
+					gpa_uint32 value;
+					NIV_SAFE_GPA (getSampleUInt32_ (handle, 0, index, &value));
+					result [name] = static_cast<std::int32_t> (value);
+					break;
+				}
+				case GPA_TYPE_INT64:
+				{
+					gpa_uint64 value;
+					NIV_SAFE_GPA (getSampleUInt64_ (handle, 0, index, &value));
+					result [name] = static_cast<std::int32_t> (value);
+					break;
+				}
+				case GPA_TYPE_UINT32:
+				{
+					gpa_uint32 value;
+					NIV_SAFE_GPA (getSampleUInt32_ (handle, 0, index, &value));
+					result [name] = value;
+					break;
+				}
+				case GPA_TYPE_UINT64:
+				{
+					gpa_uint64 value;
+					NIV_SAFE_GPA (getSampleUInt64_ (handle, 0, index, &value));
+					result [name] = value;
+					break;
+				}
+				case GPA_TYPE_FLOAT32:
+				{
+					gpa_float32 value;
+					NIV_SAFE_GPA (getSampleFloat32_ (handle, 0, index, &value));
+					result [name] = value;
+					break;
+				}
+				case GPA_TYPE_FLOAT64:
+				{
+					gpa_float64 value;
+					NIV_SAFE_GPA (getSampleFloat64_ (handle, 0, index, &value));
+					result [name] = value;
+					break;
+				}
+
+				default:
+					throw std::runtime_error ("Unsupported data type.");
+			}
+		}
+
+		return true;
+	}
+
+	void BeginSampling ()
+	{
+		NIV_SAFE_GPA (beginSample_ (0));
+	}
+
+	void EndSampling ()
+	{
+		NIV_SAFE_GPA (endSample_ ());
+	}
+
+	void OpenContext (void* ctx)
+	{
+		NIV_SAFE_GPA (openContext_ (ctx));
+	}
+
+	void CloseContext ()
+	{
+		NIV_SAFE_GPA (closeContext_ ());
+	}
+
+	std::uint32_t GetRequiredPassCount () const
+	{
+		gpa_uint32 numPasses;
+		NIV_SAFE_GPA (getPassCount_ (&numPasses));
+
+		return numPasses;
+	}
+
+private:
+#if AMD_PERF_API_LINUX
+	void*	lib_;
+#elif AMD_PERF_API_WINDOWS
+	HINSTANCE lib_;
+#endif
+
+	GPA_InitializePtrType 			initialize_;
+	GPA_DestroyPtrType 				destroy_;
+
+	GPA_OpenContextPtrType			openContext_;
+	GPA_CloseContextPtrType			closeContext_;
+
+	GPA_GetNumCountersPtrType		getNumCounters_;
+	GPA_GetCounterNamePtrType		getCounterName_;
+	GPA_GetCounterDataTypePtrType	getCounterDataType_;
+
+	GPA_EnableCounterPtrType		enableCounter_;
+	GPA_DisableCounterPtrType		disableCounter_;
+
+	GPA_GetPassCountPtrType 		getPassCount_;
+
+	GPA_BeginSessionPtrType 		beginSession_;
+	GPA_EndSessionPtrType 			endSession_;
+
+	GPA_BeginPassPtrType 			beginPass_;
+	GPA_EndPassPtrType 				endPass_;
+
+	GPA_BeginSamplePtrType 			beginSample_;
+	GPA_EndSamplePtrType 			endSample_;
+
+	GPA_GetEnabledCountPtrType		getEnabledCount_;
+	GPA_GetEnabledIndexPtrType		getEnabledIndex_;
+
+	GPA_IsSessionReadyPtrType 		isSessionReady_;
+	GPA_GetSampleUInt64PtrType 		getSampleUInt64_;
+	GPA_GetSampleUInt32PtrType 		getSampleUInt32_;
+	GPA_GetSampleFloat32PtrType 	getSampleFloat32_;
+	GPA_GetSampleFloat64PtrType 	getSampleFloat64_;
+
+	GPA_RegisterLoggingCallbackPtrType	registerLoggingCallback_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+PerformanceLibrary::PerformanceLibrary (const ProfileApi::Enum targetApi)
+: impl_ (new Impl (targetApi))
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+PerformanceLibrary::~PerformanceLibrary ()
+{
+	delete impl_;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int PerformanceLibrary::GetRequiredPassCount ()
+{
+	return static_cast<int> (impl_->GetRequiredPassCount ());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::vector<CounterInfo>	PerformanceLibrary::GetAvailableCounters () const
+{
+	return impl_->GetAvailableCounters ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::EnableCounters (const std::vector<CounterInfo>& counters)
+{
+	impl_->EnableCounters (counters);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::BeginPass ()
+{
+	impl_->BeginPass ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::EndPass ()
+{
+	impl_->EndPass ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+PerformanceLibrary::ProfileSessionHandle PerformanceLibrary::BeginProfileSession ()
+{
+	return impl_->BeginProfileSession ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::EndProfileSession ()
+{
+	impl_->EndProfileSession ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+bool PerformanceLibrary::GetProfileSessionResult (const ProfileSessionHandle handle,
+	ProfileResult& result, const bool block) const
+{
+	return impl_->GetProfileSessionResult (handle, result, block);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::BeginSampling ()
+{
+	impl_->BeginSampling ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::EndSampling ()
+{
+	impl_->EndSampling ();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::OpenContext (void* ctx)
+{
+	impl_->OpenContext (ctx);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void PerformanceLibrary::CloseContext ()
+{
+	impl_->CloseContext ();
+}
+}
+#ifndef NIV_AMD_PERF_LIB_PERFAPI_H_645363EE_8979_484F_8902_62C026502B0F
+#define NIV_AMD_PERF_LIB_PERFAPI_H_645363EE_8979_484F_8902_62C026502B0F
+
+#include <boost/noncopyable.hpp>
+#include <boost/variant.hpp>
+#include <string>
+#include <cstdint>
+#include <map>
+#include <vector>
+#include <functional>
+
+namespace Amd {
+struct DataType
+{
+	enum Enum
+	{
+		float32,
+		float64,
+		uint32,
+		uint64,
+		int32,
+		int64
+	};
+};
+
+struct ProfileApi
+{
+	enum Enum
+	{
+		Direct3D10,
+		Direct3D11,
+		OpenGL,
+		OpenCL
+	};
+};
+
+typedef std::map<std::string, boost::variant<float, double,
+	std::uint32_t, std::uint64_t, std::int32_t, std::int64_t>> ProfileResult;
+
+struct CounterInfo
+{
+	std::string 	name;
+	int				index;
+	DataType::Enum 	type;
+};
+
+class PerformanceLibrary : public boost::noncopyable
+{
+public:
+	PerformanceLibrary (const ProfileApi::Enum targetApi);
+	~PerformanceLibrary ();
+
+	typedef std::uint32_t ProfileSessionHandle;
+
+	int GetRequiredPassCount ();
+
+	std::vector<CounterInfo>	GetAvailableCounters () const;
+	void EnableCounters (const std::vector<CounterInfo>& counters);
+
+	void BeginPass ();
+	void EndPass ();
+
+	ProfileSessionHandle BeginProfileSession ();
+	void EndProfileSession ();
+
+	bool GetProfileSessionResult (const ProfileSessionHandle handle,
+		ProfileResult& result, const bool block) const;
+
+	void BeginSampling ();
+	void EndSampling ();
+
+	void OpenContext (void* ctx);
+	void CloseContext ();
+
+	void RegisterLoggingCallback (std::function<void (const int messageType,
+		const char* message) callback);
+private:
+	struct Impl;
+	Impl*	impl_;
+};
+}
+
+#endif