From 1216d050b13541ebe0f260a133e728c50ee968d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Thu, 13 Sep 2018 17:58:01 -0700 Subject: [PATCH] D3D11: Added NVAftermath support. --- src/nvapi.cpp | 96 +++++++++++++++++++++++++++++++++++------- src/nvapi.h | 25 ++++++++++- src/renderer_d3d11.cpp | 2 + 3 files changed, 106 insertions(+), 17 deletions(-) diff --git a/src/nvapi.cpp b/src/nvapi.cpp index 63a1f5cd3..c5db84e38 100644 --- a/src/nvapi.cpp +++ b/src/nvapi.cpp @@ -76,6 +76,8 @@ namespace bgfx * https://developer.nvidia.com/nvidia-aftermath */ + typedef int32_t (*PFN_NVAFTERMATH_DX11_INITIALIZE)(int32_t _version, int32_t _flags, const ID3D11Device* _device); + typedef int32_t (*PFN_NVAFTERMATH_DX11_CREATECONTEXTHANDLE)(const ID3D11DeviceContext* _deviceCtx, NvAftermathContextHandle** _outContextHandle); typedef int32_t (*PFN_NVAFTERMATH_DX12_INITIALIZE)(int32_t _version, int32_t _flags, const ID3D12Device* _device); typedef int32_t (*PFN_NVAFTERMATH_DX12_CREATECONTEXTHANDLE)(const ID3D12CommandList* _commandList, NvAftermathContextHandle** _outContextHandle); typedef int32_t (*PFN_NVAFTERMATH_RELEASECONTEXTHANDLE)(const NvAftermathContextHandle* _contextHandle); @@ -84,6 +86,8 @@ namespace bgfx typedef int32_t (*PFN_NVAFTERMATH_GETDEVICESTATUS)(void* _outStatus); typedef int32_t (*PFN_NVAFTERMATH_GETPAGEFAULTINFORMATION)(void* _outPageFaultInformation); + static PFN_NVAFTERMATH_DX11_INITIALIZE nvAftermathDx11Initialize; + static PFN_NVAFTERMATH_DX11_CREATECONTEXTHANDLE nvAftermathDx11CreateContextHandle; static PFN_NVAFTERMATH_DX12_INITIALIZE nvAftermathDx12Initialize; static PFN_NVAFTERMATH_DX12_CREATECONTEXTHANDLE nvAftermathDx12CreateContextHandle; static PFN_NVAFTERMATH_RELEASECONTEXTHANDLE nvAftermathReleaseContextHandle; @@ -213,7 +217,7 @@ namespace bgfx } } - bool NvApi::initAftermath(const ID3D12Device* _device, const ID3D12CommandList* _commandList) + bool NvApi::loadAftermath() { m_nvAftermathDll = bx::dlopen( "GFSDK_Aftermath_Lib." @@ -227,6 +231,8 @@ namespace bgfx if (NULL != m_nvAftermathDll) { + nvAftermathDx11Initialize = (PFN_NVAFTERMATH_DX11_INITIALIZE )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_DX11_Initialize"); + nvAftermathDx11CreateContextHandle = (PFN_NVAFTERMATH_DX11_CREATECONTEXTHANDLE)bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_DX11_CreateContextHandle"); nvAftermathDx12Initialize = (PFN_NVAFTERMATH_DX12_INITIALIZE )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_DX12_Initialize"); nvAftermathDx12CreateContextHandle = (PFN_NVAFTERMATH_DX12_CREATECONTEXTHANDLE)bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_DX12_CreateContextHandle"); nvAftermathReleaseContextHandle = (PFN_NVAFTERMATH_RELEASECONTEXTHANDLE )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_ReleaseContextHandle"); @@ -236,6 +242,8 @@ namespace bgfx nvAftermathGetPageFaultInformation = (PFN_NVAFTERMATH_GETPAGEFAULTINFORMATION )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_GetPageFaultInformation"); bool initialized = true + && NULL != nvAftermathDx11Initialize + && NULL != nvAftermathDx11CreateContextHandle && NULL != nvAftermathDx12Initialize && NULL != nvAftermathDx12CreateContextHandle && NULL != nvAftermathReleaseContextHandle @@ -247,25 +255,37 @@ namespace bgfx if (initialized) { - int32_t result; - result = nvAftermathDx12Initialize(0x13, 1, _device); + return true; + } + + shutdownAftermath(); + } + + return false; + } + + bool NvApi::initAftermath(const ID3D11Device* _device, const ID3D11DeviceContext* _deviceCtx) + { + if (loadAftermath() ) + { + int32_t result; + result = nvAftermathDx11Initialize(0x13, 1, _device); + if (1 == result) + { + result = nvAftermathDx11CreateContextHandle(_deviceCtx, &m_aftermathHandle); + BX_WARN(1 == result, "NV Aftermath: nvAftermathDx12CreateContextHandle failed %x", result); + if (1 == result) { - result = nvAftermathDx12CreateContextHandle(_commandList, &m_aftermathHandle); - BX_WARN(1 == result, "NV Aftermath: nvAftermathDx12CreateContextHandle failed %x", result); - - if (1 == result) - { - return true; - } + return true; } - else + } + else + { + switch (result) { - switch (result) - { - case int32_t(0xbad0000a): BX_TRACE("NV Aftermath: Debug layer not compatible with Aftermath."); break; - default: BX_TRACE("NV Aftermath: Failed to initialize."); break; - } + case int32_t(0xbad0000a): BX_TRACE("NV Aftermath: Debug layer not compatible with Aftermath."); break; + default: BX_TRACE("NV Aftermath: Failed to initialize."); break; } } @@ -275,6 +295,50 @@ namespace bgfx return false; } + bool NvApi::initAftermath(const ID3D12Device* _device, const ID3D12CommandList* _commandList) + { + if (loadAftermath() ) + { + int32_t result; + result = nvAftermathDx12Initialize(0x13, 1, _device); + if (1 == result) + { + result = nvAftermathDx12CreateContextHandle(_commandList, &m_aftermathHandle); + BX_WARN(1 == result, "NV Aftermath: nvAftermathDx12CreateContextHandle failed %x", result); + + if (1 == result) + { + return true; + } + } + else + { + switch (result) + { + case int32_t(0xbad0000a): BX_TRACE("NV Aftermath: Debug layer not compatible with Aftermath."); break; + default: BX_TRACE("NV Aftermath: Failed to initialize."); break; + } + } + + shutdownAftermath(); + } + + return false; + } + + NvAftermathDeviceStatus::Enum NvApi::getDeviceStatus() const + { + if (NULL != m_aftermathHandle) + { + int32_t status; + nvAftermathGetDeviceStatus(&status); + + return NvAftermathDeviceStatus::Enum(status); + } + + return NvAftermathDeviceStatus::NotInitialized; + } + void NvApi::shutdownAftermath() { if (NULL != m_nvAftermathDll) diff --git a/src/nvapi.h b/src/nvapi.h index 452d08f03..8fe5b967d 100644 --- a/src/nvapi.h +++ b/src/nvapi.h @@ -6,6 +6,7 @@ #ifndef BGFX_NVAPI_H_HEADER_GUARD #define BGFX_NVAPI_H_HEADER_GUARD +struct ID3D11Device; struct ID3D11DeviceContext; struct ID3D11Buffer; struct ID3D12Device; @@ -16,6 +17,19 @@ namespace bgfx struct NvPhysicalGpuHandle; struct NvAftermathContextHandle; + struct NvAftermathDeviceStatus + { + enum Enum + { + Active, + Timeout, + OutOfMemory, + PageFault, + Unknown, + NotInitialized + }; + }; + typedef void (*PFN_NVAPI_MULTIDRAWINDIRECT)(ID3D11DeviceContext* _deviceCtx, uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); /// @@ -35,10 +49,19 @@ namespace bgfx /// void getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax); - + + /// + bool loadAftermath(); + + /// + bool initAftermath(const ID3D11Device* _device, const ID3D11DeviceContext* _deviceCtx); + /// bool initAftermath(const ID3D12Device* _device, const ID3D12CommandList* _commandList); + /// + NvAftermathDeviceStatus::Enum getDeviceStatus() const; + /// void shutdownAftermath(); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 4ab6d6ded..11dd8eb09 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1512,6 +1512,8 @@ namespace bgfx { namespace d3d11 postReset(); } + m_nvapi.initAftermath(m_device, m_deviceCtx); + g_internalData.context = m_device; return true;