Browse Source

NVAPI: Adding support for NV Aftermath.

Branimir Karadžić 7 years ago
parent
commit
4f64a4792b
4 changed files with 155 additions and 11 deletions
  1. 117 6
      src/nvapi.cpp
  2. 18 3
      src/nvapi.h
  3. 19 2
      src/renderer_d3d12.cpp
  4. 1 0
      src/renderer_d3d12.h

+ 117 - 6
src/nvapi.cpp

@@ -15,6 +15,7 @@ namespace bgfx
 	 * http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/index.html
 	 * http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/index.html
 	 * https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/info/NvAPI_IDs.txt
 	 * https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/info/NvAPI_IDs.txt
 	 */
 	 */
+
 	struct NvPhysicalGpuHandle;
 	struct NvPhysicalGpuHandle;
 
 
 #define NVAPI_MAX_PHYSICAL_GPUS 64
 #define NVAPI_MAX_PHYSICAL_GPUS 64
@@ -68,9 +69,34 @@ namespace bgfx
 	static PFN_NVAPI_GPUGETMEMORYINFO nvApiGpuGetMemoryInfo;
 	static PFN_NVAPI_GPUGETMEMORYINFO nvApiGpuGetMemoryInfo;
 	static PFN_NVAPI_GPUGETFULLNAME   nvApiGpuGetFullName;
 	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()
 	NvApi::NvApi()
 		: m_nvApiDll(NULL)
 		: m_nvApiDll(NULL)
 		, m_nvGpu(NULL)
 		, m_nvGpu(NULL)
+		, m_nvAftermathDll(NULL)
+		, m_aftermathHandle(NULL)
 	{
 	{
 	}
 	}
 
 
@@ -78,11 +104,11 @@ namespace bgfx
 	{
 	{
 		m_nvGpu = NULL;
 		m_nvGpu = NULL;
 		m_nvApiDll = bx::dlopen(
 		m_nvApiDll = bx::dlopen(
-#if BX_ARCH_32BIT
-			"nvapi.dll"
-#else
-			"nvapi64.dll"
+			"nvapi"
+#if BX_ARCH_64BIT
+			"64"
 #endif // BX_ARCH_32BIT
 #endif // BX_ARCH_32BIT
+			".dll"
 			);
 			);
 
 
 		if (NULL != m_nvApiDll)
 		if (NULL != m_nvApiDll)
@@ -99,8 +125,8 @@ namespace bgfx
 				nvApiGpuGetMemoryInfo = (PFN_NVAPI_GPUGETMEMORYINFO )nvApiQueryInterface(NVAPI_GPUGETMEMORYINFO);
 				nvApiGpuGetMemoryInfo = (PFN_NVAPI_GPUGETMEMORYINFO )nvApiQueryInterface(NVAPI_GPUGETMEMORYINFO);
 				nvApiGpuGetFullName   = (PFN_NVAPI_GPUGETFULLNAME   )nvApiQueryInterface(NVAPI_GPUGETFULLNAME);
 				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
 				initialized = true
 					&& NULL != nvApiInitialize
 					&& NULL != nvApiInitialize
@@ -159,6 +185,8 @@ namespace bgfx
 			bx::dlclose(m_nvApiDll);
 			bx::dlclose(m_nvApiDll);
 			m_nvApiDll = NULL;
 			m_nvApiDll = NULL;
 		}
 		}
+
+		shutdownAftermath();
 	}
 	}
 
 
 	void NvApi::getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax)
 	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
 } // namespace bgfx

+ 18 - 3
src/nvapi.h

@@ -8,12 +8,15 @@
 
 
 struct ID3D11DeviceContext;
 struct ID3D11DeviceContext;
 struct ID3D11Buffer;
 struct ID3D11Buffer;
+struct ID3D12Device;
+struct ID3D12CommandList;
 
 
 namespace bgfx
 namespace bgfx
 {
 {
 	struct NvPhysicalGpuHandle;
 	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
 	struct NvApi
@@ -32,13 +35,25 @@ namespace bgfx
 
 
 		///
 		///
 		void getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax);
 		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;
 		void* m_nvApiDll;
 		NvPhysicalGpuHandle* m_nvGpu;
 		NvPhysicalGpuHandle* m_nvGpu;
 
 
-		NvMultiDrawIndirectFn nvApiD3D11MultiDrawInstancedIndirect;
-		NvMultiDrawIndirectFn nvApiD3D11MultiDrawIndexedInstancedIndirect;
+		void* m_nvAftermathDll;
+		NvAftermathContextHandle* m_aftermathHandle;
+
+		PFN_NVAPI_MULTIDRAWINDIRECT nvApiD3D11MultiDrawInstancedIndirect;
+		PFN_NVAPI_MULTIDRAWINDIRECT nvApiD3D11MultiDrawIndexedInstancedIndirect;
 	};
 	};
 
 
 } // namespace bgfx
 } // namespace bgfx

+ 19 - 2
src/renderer_d3d12.cpp

@@ -676,6 +676,8 @@ namespace bgfx { namespace d3d12
 
 
 			errorState = ErrorState::LoadedKernel32;
 			errorState = ErrorState::LoadedKernel32;
 
 
+			m_nvapi.init();
+
 			m_d3d12dll = bx::dlopen("d3d12.dll");
 			m_d3d12dll = bx::dlopen("d3d12.dll");
 			if (NULL == m_d3d12dll)
 			if (NULL == m_d3d12dll)
 			{
 			{
@@ -724,7 +726,7 @@ namespace bgfx { namespace d3d12
 				{
 				{
 					if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
 					if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
 					{
 					{
-						debug0->EnableDebugLayer();
+//						debug0->EnableDebugLayer();
 
 
 #if BX_PLATFORM_WINDOWS
 #if BX_PLATFORM_WINDOWS
 						{
 						{
@@ -790,6 +792,11 @@ namespace bgfx { namespace d3d12
 
 
 			m_dxgi.update(m_device);
 			m_dxgi.update(m_device);
 
 
+			if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId)
+			{
+				m_nvapi.shutdown();
+			}
+
 			{
 			{
 				uint32_t numNodes = m_device->GetNodeCount();
 				uint32_t numNodes = m_device->GetNodeCount();
 				BX_TRACE("D3D12 GPU Architecture (num nodes: %d):", numNodes);
 				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;
 			g_internalData.context = m_device;
 			return true;
 			return true;
 
 
@@ -1229,6 +1243,8 @@ namespace bgfx { namespace d3d12
 #endif // USE_D3D12_DYNAMIC_LIB
 #endif // USE_D3D12_DYNAMIC_LIB
 			case ErrorState::Default:
 			case ErrorState::Default:
 			default:
 			default:
+				m_nvapi.shutdown();
+
 				unloadRenderDoc(m_renderdocdll);
 				unloadRenderDoc(m_renderdocdll);
 				bx::dlclose(m_winPixEvent);
 				bx::dlclose(m_winPixEvent);
 				m_winPixEvent = NULL;
 				m_winPixEvent = NULL;
@@ -1286,13 +1302,13 @@ namespace bgfx { namespace d3d12
 			}
 			}
 
 
 			DX_RELEASE(m_rootSignature, 0);
 			DX_RELEASE(m_rootSignature, 0);
-
 			DX_RELEASE(m_swapChain, 0);
 			DX_RELEASE(m_swapChain, 0);
 
 
 			m_cmd.shutdown();
 			m_cmd.shutdown();
 
 
 			DX_RELEASE(m_device,  0);
 			DX_RELEASE(m_device,  0);
 
 
+			m_nvapi.shutdown();
 			m_dxgi.shutdown();
 			m_dxgi.shutdown();
 
 
 			unloadRenderDoc(m_renderdocdll);
 			unloadRenderDoc(m_renderdocdll);
@@ -2976,6 +2992,7 @@ data.NumQualityLevels = 0;
 		}
 		}
 
 
 		Dxgi m_dxgi;
 		Dxgi m_dxgi;
+		NvApi m_nvapi;
 
 
 		void* m_kernel32dll;
 		void* m_kernel32dll;
 		void* m_d3d12dll;
 		void* m_d3d12dll;

+ 1 - 0
src/renderer_d3d12.h

@@ -49,6 +49,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
 #include "renderer_d3d.h"
 #include "renderer_d3d.h"
 #include "shader_dxbc.h"
 #include "shader_dxbc.h"
 #include "debug_renderdoc.h"
 #include "debug_renderdoc.h"
+#include "nvapi.h"
 #include "dxgi.h"
 #include "dxgi.h"
 
 
 #if BGFX_CONFIG_DEBUG_PIX
 #if BGFX_CONFIG_DEBUG_PIX