diff --git a/src/nvapi.cpp b/src/nvapi.cpp index 868917b25..93d5c5c50 100644 --- a/src/nvapi.cpp +++ b/src/nvapi.cpp @@ -15,6 +15,7 @@ namespace bgfx * 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 NvPhysicalGpuHandle; #define NVAPI_MAX_PHYSICAL_GPUS 64 @@ -68,9 +69,34 @@ namespace bgfx static PFN_NVAPI_GPUGETMEMORYINFO nvApiGpuGetMemoryInfo; static PFN_NVAPI_GPUGETFULLNAME nvApiGpuGetFullName; + /* + * NVIDIA Aftermath + * + * Reference: + * https://developer.nvidia.com/nvidia-aftermath + */ + + 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); + typedef int32_t (*PFN_NVAFTERMATH_SETEVENTMARKER)(const NvAftermathContextHandle* _contextHandle, const void* _markerData, uint32_t _markerSize); + typedef int32_t (*PFN_NVAFTERMATH_GETDATA)(uint32_t _numContexts, const NvAftermathContextHandle** _contextHandles, void* _outContextData); + typedef int32_t (*PFN_NVAFTERMATH_GETDEVICESTATUS)(void* _outStatus); + typedef int32_t (*PFN_NVAFTERMATH_GETPAGEFAULTINFORMATION)(void* _outPageFaultInformation); + + static PFN_NVAFTERMATH_DX12_INITIALIZE nvAftermathDx12Initialize; + static PFN_NVAFTERMATH_DX12_CREATECONTEXTHANDLE nvAftermathDx12CreateContextHandle; + static PFN_NVAFTERMATH_RELEASECONTEXTHANDLE nvAftermathReleaseContextHandle; + static PFN_NVAFTERMATH_SETEVENTMARKER nvAftermathSetEventMarker; + static PFN_NVAFTERMATH_GETDATA nvAftermathGetData; + static PFN_NVAFTERMATH_GETDEVICESTATUS nvAftermathGetDeviceStatus; + static PFN_NVAFTERMATH_GETPAGEFAULTINFORMATION nvAftermathGetPageFaultInformation; + NvApi::NvApi() : m_nvApiDll(NULL) , m_nvGpu(NULL) + , m_nvAftermathDll(NULL) + , m_aftermathHandle(NULL) { } @@ -78,11 +104,11 @@ namespace bgfx { m_nvGpu = NULL; m_nvApiDll = bx::dlopen( -#if BX_ARCH_32BIT - "nvapi.dll" -#else - "nvapi64.dll" + "nvapi" +#if BX_ARCH_64BIT + "64" #endif // BX_ARCH_32BIT + ".dll" ); if (NULL != m_nvApiDll) @@ -99,8 +125,8 @@ namespace bgfx nvApiGpuGetMemoryInfo = (PFN_NVAPI_GPUGETMEMORYINFO )nvApiQueryInterface(NVAPI_GPUGETMEMORYINFO); nvApiGpuGetFullName = (PFN_NVAPI_GPUGETFULLNAME )nvApiQueryInterface(NVAPI_GPUGETFULLNAME); - nvApiD3D11MultiDrawInstancedIndirect = (NvMultiDrawIndirectFn)nvApiQueryInterface(NVAPI_MULTIDRAWINSTANCEDINDIRECT); - nvApiD3D11MultiDrawIndexedInstancedIndirect = (NvMultiDrawIndirectFn)nvApiQueryInterface(NVAPI_MULTIDRAWINDEXEDINSTANCEDINDIRECT); + nvApiD3D11MultiDrawInstancedIndirect = (PFN_NVAPI_MULTIDRAWINDIRECT)nvApiQueryInterface(NVAPI_MULTIDRAWINSTANCEDINDIRECT); + nvApiD3D11MultiDrawIndexedInstancedIndirect = (PFN_NVAPI_MULTIDRAWINDIRECT)nvApiQueryInterface(NVAPI_MULTIDRAWINDEXEDINSTANCEDINDIRECT); initialized = true && NULL != nvApiInitialize @@ -159,6 +185,8 @@ namespace bgfx bx::dlclose(m_nvApiDll); m_nvApiDll = NULL; } + + shutdownAftermath(); } void NvApi::getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax) @@ -185,4 +213,87 @@ namespace bgfx } } + bool NvApi::initAftermath(const ID3D12Device* _device, const ID3D12CommandList* _commandList) + { + m_nvAftermathDll = bx::dlopen( + "GFSDK_Aftermath_Lib." +#if BX_ARCH_32BIT + "x86" +#else + "x64" +#endif // BX_ARCH_32BIT + ".dll" + ); + + if (NULL != m_nvAftermathDll) + { + 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"); + nvAftermathSetEventMarker = (PFN_NVAFTERMATH_SETEVENTMARKER )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_SetEventMarker"); + nvAftermathGetData = (PFN_NVAFTERMATH_GETDATA )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_GetData"); + nvAftermathGetDeviceStatus = (PFN_NVAFTERMATH_GETDEVICESTATUS )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_GetDeviceStatus"); + nvAftermathGetPageFaultInformation = (PFN_NVAFTERMATH_GETPAGEFAULTINFORMATION )bx::dlsym(m_nvAftermathDll, "GFSDK_Aftermath_GetPageFaultInformation"); + + bool initialized = true + && NULL != nvAftermathDx12Initialize + && NULL != nvAftermathDx12CreateContextHandle + && NULL != nvAftermathReleaseContextHandle + && NULL != nvAftermathSetEventMarker + && NULL != nvAftermathGetData + && NULL != nvAftermathGetDeviceStatus + && NULL != nvAftermathGetPageFaultInformation + ; + + if (initialized) + { + int32_t result; + result = nvAftermathDx12Initialize(0x13, 1, _device); + if (1 == result) + { + result = nvAftermathDx12CreateContextHandle(_commandList, &m_aftermathHandle); + BX_WARN(1 == result, "%x", result); + + if (1 == result) + { + return true; + } + } + } + + shutdownAftermath(); + } + + return false; + } + + void NvApi::shutdownAftermath() + { + if (NULL != m_nvAftermathDll) + { + if (NULL != m_aftermathHandle) + { + nvAftermathReleaseContextHandle(m_aftermathHandle); + m_aftermathHandle = NULL; + } + + bx::dlclose(m_nvAftermathDll); + m_nvAftermathDll = NULL; + } + } + +#define NVA_CHECK(_call) \ + BX_MACRO_BLOCK_BEGIN \ + int32_t __result__ = _call; \ + BX_CHECK(1 == __result__, #_call " FAILED 0x%08x\n", __result__); \ + BX_MACRO_BLOCK_END + + void NvApi::setMarker(const bx::StringView& _marker) + { + if (NULL != m_aftermathHandle) + { + NVA_CHECK(nvAftermathSetEventMarker(m_aftermathHandle, _marker.getPtr(), _marker.getLength() ) ); + } + } + } // namespace bgfx diff --git a/src/nvapi.h b/src/nvapi.h index f6f71c8a2..452d08f03 100644 --- a/src/nvapi.h +++ b/src/nvapi.h @@ -8,12 +8,15 @@ struct ID3D11DeviceContext; struct ID3D11Buffer; +struct ID3D12Device; +struct ID3D12CommandList; namespace bgfx { struct NvPhysicalGpuHandle; + struct NvAftermathContextHandle; - typedef void (* NvMultiDrawIndirectFn)(ID3D11DeviceContext* _deviceCtx, uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + typedef void (*PFN_NVAPI_MULTIDRAWINDIRECT)(ID3D11DeviceContext* _deviceCtx, uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); /// struct NvApi @@ -32,13 +35,25 @@ namespace bgfx /// void getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax); + + /// + bool initAftermath(const ID3D12Device* _device, const ID3D12CommandList* _commandList); + + /// + void shutdownAftermath(); + + /// + void setMarker(const bx::StringView& _marker); /// void* m_nvApiDll; NvPhysicalGpuHandle* m_nvGpu; - NvMultiDrawIndirectFn nvApiD3D11MultiDrawInstancedIndirect; - NvMultiDrawIndirectFn nvApiD3D11MultiDrawIndexedInstancedIndirect; + void* m_nvAftermathDll; + NvAftermathContextHandle* m_aftermathHandle; + + PFN_NVAPI_MULTIDRAWINDIRECT nvApiD3D11MultiDrawInstancedIndirect; + PFN_NVAPI_MULTIDRAWINDIRECT nvApiD3D11MultiDrawIndexedInstancedIndirect; }; } // namespace bgfx diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index d75165d66..6706750d4 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -676,6 +676,8 @@ namespace bgfx { namespace d3d12 errorState = ErrorState::LoadedKernel32; + m_nvapi.init(); + m_d3d12dll = bx::dlopen("d3d12.dll"); if (NULL == m_d3d12dll) { @@ -724,7 +726,7 @@ namespace bgfx { namespace d3d12 { if (BX_ENABLED(BGFX_CONFIG_DEBUG) ) { - debug0->EnableDebugLayer(); +// debug0->EnableDebugLayer(); #if BX_PLATFORM_WINDOWS { @@ -790,6 +792,11 @@ namespace bgfx { namespace d3d12 m_dxgi.update(m_device); + if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId) + { + m_nvapi.shutdown(); + } + { uint32_t numNodes = m_device->GetNodeCount(); BX_TRACE("D3D12 GPU Architecture (num nodes: %d):", numNodes); @@ -1201,6 +1208,13 @@ namespace bgfx { namespace d3d12 } } + if (m_nvapi.isInitialized() ) + { + finish(); + m_commandList = m_cmd.alloc(); + m_nvapi.initAftermath(m_device, m_commandList); + } + g_internalData.context = m_device; return true; @@ -1229,6 +1243,8 @@ namespace bgfx { namespace d3d12 #endif // USE_D3D12_DYNAMIC_LIB case ErrorState::Default: default: + m_nvapi.shutdown(); + unloadRenderDoc(m_renderdocdll); bx::dlclose(m_winPixEvent); m_winPixEvent = NULL; @@ -1286,13 +1302,13 @@ namespace bgfx { namespace d3d12 } DX_RELEASE(m_rootSignature, 0); - DX_RELEASE(m_swapChain, 0); m_cmd.shutdown(); DX_RELEASE(m_device, 0); + m_nvapi.shutdown(); m_dxgi.shutdown(); unloadRenderDoc(m_renderdocdll); @@ -2976,6 +2992,7 @@ data.NumQualityLevels = 0; } Dxgi m_dxgi; + NvApi m_nvapi; void* m_kernel32dll; void* m_d3d12dll; diff --git a/src/renderer_d3d12.h b/src/renderer_d3d12.h index 91f29c853..e6b52ead8 100644 --- a/src/renderer_d3d12.h +++ b/src/renderer_d3d12.h @@ -49,6 +49,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); #include "renderer_d3d.h" #include "shader_dxbc.h" #include "debug_renderdoc.h" +#include "nvapi.h" #include "dxgi.h" #if BGFX_CONFIG_DEBUG_PIX