Skip to content

Commit

Permalink
D3D11: Added GPU memory stats.
Browse files Browse the repository at this point in the history
  • Loading branch information
bkaradzic committed Sep 27, 2017
1 parent fe00409 commit aa567d3
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 20 deletions.
17 changes: 10 additions & 7 deletions include/bgfx/bgfx.h
Expand Up @@ -741,14 +741,14 @@ namespace bgfx
///
struct Stats
{
uint64_t cpuTimeFrame; //!< CPU time between two `bgfx::frame` calls.
uint64_t cpuTimeBegin; //!< Render thread CPU submit begin time.
uint64_t cpuTimeEnd; //!< Render thread CPU submit end time.
uint64_t cpuTimerFreq; //!< CPU timer frequency.
int64_t cpuTimeFrame; //!< CPU time between two `bgfx::frame` calls.
int64_t cpuTimeBegin; //!< Render thread CPU submit begin time.
int64_t cpuTimeEnd; //!< Render thread CPU submit end time.
int64_t cpuTimerFreq; //!< CPU timer frequency.

uint64_t gpuTimeBegin; //!< GPU frame begin time.
uint64_t gpuTimeEnd; //!< GPU frame end time.
uint64_t gpuTimerFreq; //!< GPU timer frequency.
int64_t gpuTimeBegin; //!< GPU frame begin time.
int64_t gpuTimeEnd; //!< GPU frame end time.
int64_t gpuTimerFreq; //!< GPU timer frequency.

int64_t waitRender; //!< Time spent waiting for render backend thread to finish issuing
//! draw commands to underlying graphics API.
Expand All @@ -758,6 +758,9 @@ namespace bgfx
uint32_t numCompute; //!< Number of compute calls submitted.
uint32_t maxGpuLatency; //!< GPU driver latency.

int64_t gpuMemoryMax; //!< Maximum available GPU memory.
int64_t gpuMemoryUsed; //!< Available GPU memory.

uint16_t width; //!< Backbuffer width in pixels.
uint16_t height; //!< Backbuffer height in pixels.
uint16_t textWidth; //!< Debug text width in characters.
Expand Down
17 changes: 10 additions & 7 deletions include/bgfx/c99/bgfx.h
Expand Up @@ -348,14 +348,14 @@ typedef struct bgfx_view_stats
/**/
typedef struct bgfx_stats
{
uint64_t cpuTimeFrame;
uint64_t cpuTimeBegin;
uint64_t cpuTimeEnd;
uint64_t cpuTimerFreq;
int64_t cpuTimeFrame;
int64_t cpuTimeBegin;
int64_t cpuTimeEnd;
int64_t cpuTimerFreq;

uint64_t gpuTimeBegin;
uint64_t gpuTimeEnd;
uint64_t gpuTimerFreq;
int64_t gpuTimeBegin;
int64_t gpuTimeEnd;
int64_t gpuTimerFreq;

int64_t waitRender;
int64_t waitSubmit;
Expand All @@ -364,6 +364,9 @@ typedef struct bgfx_stats
uint32_t numCompute;
uint32_t maxGpuLatency;

int64_t gpuMemoryMax;
int64_t gpuMemoryUsed;

uint16_t width;
uint16_t height;
uint16_t textWidth;
Expand Down
2 changes: 1 addition & 1 deletion include/bgfx/defines.h
Expand Up @@ -6,7 +6,7 @@
#ifndef BGFX_DEFINES_H_HEADER_GUARD
#define BGFX_DEFINES_H_HEADER_GUARD

#define BGFX_API_VERSION UINT32_C(49)
#define BGFX_API_VERSION UINT32_C(50)

/// Color RGB/alpha/depth write. When it's not specified write will be disabled.
#define BGFX_STATE_RGB_WRITE UINT64_C(0x0000000000000001) //!< Enable RGB write.
Expand Down
156 changes: 151 additions & 5 deletions src/renderer_d3d11.cpp
Expand Up @@ -562,8 +562,12 @@ namespace bgfx { namespace d3d11
#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
}

// Reference:
// https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK
/*
* AMD GPU Services (AGS) library
*
* Reference:
* https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK
*/
enum AGS_RETURN_CODE
{
AGS_SUCCESS,
Expand Down Expand Up @@ -625,6 +629,53 @@ namespace bgfx { namespace d3d11
static MultiDrawIndirectFn multiDrawInstancedIndirect;
static MultiDrawIndirectFn multiDrawIndexedInstancedIndirect;

/*
* NVAPI
*
* Reference:
* http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/index.html
* https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/info/NvAPI_IDs.txt
*/
struct NvDisplayHandle;

enum NvApiStatus
{
NVAPI_OK = 0,
NVAPI_ERROR = -1,
};

struct NvMemoryInfoV2
{
NvMemoryInfoV2()
: version(sizeof(NvMemoryInfoV2) | (2 << 16) )
{
}

uint32_t version;
uint32_t dedicatedVideoMemory;
uint32_t availableDedicatedVideoMemory;
uint32_t systemVideoMemory;
uint32_t sharedSystemMemory;
uint32_t curAvailableDedicatedVideoMemory;
};

typedef void* (__cdecl* PFN_NVAPI_QUERYINTERFACE)(uint32_t _functionOffset);
typedef NvApiStatus (__cdecl* PFN_NVAPI_INITIALIZE)();
typedef NvApiStatus (__cdecl* PFN_NVAPI_UNLOAD)();
typedef NvApiStatus (__cdecl* PFN_NVAPI_ENUMNVIDIADISPLAYHANDLE)(uint32_t _index, NvDisplayHandle** _handle);
typedef NvApiStatus (__cdecl* PFN_NVAPI_GPU_GETMEMORYINFO)(NvDisplayHandle* _handle, NvMemoryInfoV2* _memoryInfo);

#define NVAPI_INITIALIZE UINT32_C(0x0150e828)
#define NVAPI_UNLOAD UINT32_C(0xd22bdd7e)
#define NVAPI_ENUMNVIDIADISPLAYHANDLE UINT32_C(0x9abdd40d)
#define NVAPI_GPU_GETMEMORYINFO UINT32_C(0x774AA982) //UINT32_C(0x07f9b368)

static PFN_NVAPI_QUERYINTERFACE nvApiQueryInterface;
static PFN_NVAPI_INITIALIZE nvApiInitialize;
static PFN_NVAPI_UNLOAD nvApiUnload;
static PFN_NVAPI_ENUMNVIDIADISPLAYHANDLE nvApiEnumNvidiaDisplayHandle;
static PFN_NVAPI_GPU_GETMEMORYINFO nvApiGetMemoryInfo;

#if USE_D3D11_DYNAMIC_LIB
static PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
static PFN_CREATE_DXGI_FACTORY CreateDXGIFactory;
Expand Down Expand Up @@ -668,6 +719,8 @@ namespace bgfx { namespace d3d11
, m_renderdocdll(NULL)
, m_agsdll(NULL)
, m_ags(NULL)
, m_nvapidll(NULL)
, m_nvDisplayHandle(NULL)
, m_driverType(D3D_DRIVER_TYPE_NULL)
, m_featureLevel(D3D_FEATURE_LEVEL(0) )
, m_adapter(NULL)
Expand Down Expand Up @@ -737,11 +790,11 @@ namespace bgfx { namespace d3d11
m_ags = NULL;
m_agsdll = bx::dlopen(
#if BX_ARCH_32BIT
"amd_ags_x86.dll"
"amd_ags_x86.dll"
#else
"amd_ags_x64.dll"
"amd_ags_x64.dll"
#endif // BX_ARCH_32BIT
);
);
if (NULL != m_agsdll)
{
agsInit = (PFN_AGS_INIT )bx::dlsym(m_agsdll, "agsInit");
Expand Down Expand Up @@ -814,6 +867,59 @@ namespace bgfx { namespace d3d11
}
}

m_nvDisplayHandle = NULL;
m_nvapidll = bx::dlopen(
#if BX_ARCH_32BIT
"nvapi.dll"
#else
"nvapi64.dll"
#endif // BX_ARCH_32BIT
);

if (NULL != m_nvapidll)
{
nvApiQueryInterface = (PFN_NVAPI_QUERYINTERFACE)bx::dlsym(m_nvapidll, "nvapi_QueryInterface");

bool initialized = NULL != nvApiQueryInterface;

if (initialized)
{
nvApiInitialize = (PFN_NVAPI_INITIALIZE )nvApiQueryInterface(NVAPI_INITIALIZE);
nvApiUnload = (PFN_NVAPI_UNLOAD )nvApiQueryInterface(NVAPI_UNLOAD);
nvApiEnumNvidiaDisplayHandle = (PFN_NVAPI_ENUMNVIDIADISPLAYHANDLE)nvApiQueryInterface(NVAPI_ENUMNVIDIADISPLAYHANDLE);
nvApiGetMemoryInfo = (PFN_NVAPI_GPU_GETMEMORYINFO )nvApiQueryInterface(NVAPI_GPU_GETMEMORYINFO);

initialized &= true
&& NULL != nvApiInitialize
&& NULL != nvApiUnload
&& NULL != nvApiEnumNvidiaDisplayHandle
&& NULL != nvApiGetMemoryInfo
;

if (initialized)
{
initialized &= true
&& NVAPI_OK == nvApiInitialize()
&& NVAPI_OK == nvApiEnumNvidiaDisplayHandle(0, &m_nvDisplayHandle)
;
}

if (!initialized)
{
m_nvDisplayHandle = NULL;
nvApiUnload();
}
}

if (!initialized)
{
bx::dlclose(m_nvapidll);
m_nvapidll = NULL;
}

BX_TRACE("NVAPI supported.");
}

#if USE_D3D11_DYNAMIC_LIB
m_d3d11dll = bx::dlopen("d3d11.dll");

Expand Down Expand Up @@ -1702,12 +1808,24 @@ BX_PRAGMA_DIAGNOSTIC_POP();

case ErrorState::Default:
default:
if (NULL != m_nvDisplayHandle)
{
nvApiUnload();
m_nvDisplayHandle = NULL;
}

bx::dlclose(m_nvapidll);
m_nvapidll = NULL;

if (NULL != m_ags)
{
agsDeInit(m_ags);
m_ags = NULL;
}

bx::dlclose(m_agsdll);
m_agsdll = NULL;

unloadRenderDoc(m_renderdocdll);
m_ovr.shutdown();
break;
Expand All @@ -1721,6 +1839,15 @@ BX_PRAGMA_DIAGNOSTIC_POP();
preReset();
m_ovr.shutdown();

if (NULL != m_nvDisplayHandle)
{
nvApiUnload();
m_nvDisplayHandle = NULL;
}

bx::dlclose(m_nvapidll);
m_nvapidll = NULL;

if (NULL != m_ags)
{
agsDeInit(m_ags);
Expand Down Expand Up @@ -3652,6 +3779,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
void* m_renderdocdll;
void* m_agsdll;
AGSContext* m_ags;
void* m_nvapidll;
NvDisplayHandle* m_nvDisplayHandle;


D3D_DRIVER_TYPE m_driverType;
Expand Down Expand Up @@ -6479,6 +6608,23 @@ BX_PRAGMA_DIAGNOSTIC_POP();
perfStats.numDraw = statsKeyType[0];
perfStats.numCompute = statsKeyType[1];
perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

if (NULL != m_nvDisplayHandle)
{
NvMemoryInfoV2 memInfo;
if (NVAPI_OK == nvApiGetMemoryInfo(m_nvDisplayHandle, &memInfo) )
{
perfStats.gpuMemoryMax = 1024 * memInfo.availableDedicatedVideoMemory;
perfStats.gpuMemoryUsed = 1024 * (memInfo.availableDedicatedVideoMemory - memInfo.curAvailableDedicatedVideoMemory);
// BX_TRACE(" dedicatedVideoMemory: %d KiB", memInfo.dedicatedVideoMemory);
// BX_TRACE(" availableDedicatedVideoMemory: %d KiB", memInfo.availableDedicatedVideoMemory);
// BX_TRACE(" systemVideoMemory: %d KiB", memInfo.systemVideoMemory);
// BX_TRACE(" sharedSystemMemory: %d KiB", memInfo.sharedSystemMemory);
// BX_TRACE("curAvailableDedicatedVideoMemory: %d KiB", memInfo.curAvailableDedicatedVideoMemory);
}
}

if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
Expand Down
2 changes: 2 additions & 0 deletions src/renderer_d3d12.cpp
Expand Up @@ -5749,6 +5749,8 @@ data.NumQualityLevels = 0;
perfStats.numDraw = statsKeyType[0];
perfStats.numCompute = statsKeyType[1];
perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
Expand Down
2 changes: 2 additions & 0 deletions src/renderer_d3d9.cpp
Expand Up @@ -4382,6 +4382,8 @@ namespace bgfx { namespace d3d9
perfStats.numDraw = statsKeyType[0];
perfStats.numCompute = statsKeyType[1];
perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
Expand Down
2 changes: 2 additions & 0 deletions src/renderer_gl.cpp
Expand Up @@ -7631,6 +7631,8 @@ namespace bgfx { namespace gl
perfStats.numDraw = statsKeyType[0];
perfStats.numCompute = statsKeyType[1];
perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
Expand Down
2 changes: 2 additions & 0 deletions src/renderer_mtl.mm
Expand Up @@ -3930,6 +3930,8 @@ static void setTimestamp(void* _data)
perfStats.numDraw = statsKeyType[0];
perfStats.numCompute = statsKeyType[1];
perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

rce.setTriangleFillMode(MTLTriangleFillModeFill);
if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
Expand Down
2 changes: 2 additions & 0 deletions src/renderer_vk.cpp
Expand Up @@ -4396,6 +4396,8 @@ BX_UNUSED(presentMin, presentMax);
// perfStats.numDraw = statsKeyType[0];
// perfStats.numCompute = statsKeyType[1];
// perfStats.maxGpuLatency = maxGpuLatency;
perfStats.gpuMemoryMax = -INT64_MAX;
perfStats.gpuMemoryUsed = -INT64_MAX;

if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
{
Expand Down

0 comments on commit aa567d3

Please sign in to comment.