nvapi.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include "bgfx_p.h"
  6. #include "nvapi.h"
  7. namespace bgfx
  8. {
  9. /*
  10. * NVAPI
  11. *
  12. * Reference:
  13. * http://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/index.html
  14. * https://github.com/jNizM/AHK_NVIDIA_NvAPI/blob/master/info/NvAPI_IDs.txt
  15. */
  16. struct NvPhysicalGpuHandle;
  17. #define NVAPI_MAX_PHYSICAL_GPUS 64
  18. #if BX_PLATFORM_WINDOWS
  19. # define NVAPICALL __cdecl
  20. #else
  21. # define NVAPICALL
  22. #endif // BX_PLATFORM_WINDOWS
  23. enum NvApiStatus
  24. {
  25. NVAPI_OK = 0,
  26. NVAPI_ERROR = -1,
  27. };
  28. struct NvMemoryInfoV2
  29. {
  30. NvMemoryInfoV2()
  31. : version(sizeof(NvMemoryInfoV2) | (2 << 16) )
  32. {
  33. }
  34. uint32_t version;
  35. uint32_t dedicatedVideoMemory;
  36. uint32_t availableDedicatedVideoMemory;
  37. uint32_t systemVideoMemory;
  38. uint32_t sharedSystemMemory;
  39. uint32_t curAvailableDedicatedVideoMemory;
  40. };
  41. typedef void* (NVAPICALL* PFN_NVAPI_QUERYINTERFACE)(uint32_t _functionOffset);
  42. typedef NvApiStatus (NVAPICALL* PFN_NVAPI_INITIALIZE)();
  43. typedef NvApiStatus (NVAPICALL* PFN_NVAPI_UNLOAD)();
  44. typedef NvApiStatus (NVAPICALL* PFN_NVAPI_ENUMPHYSICALGPUS)(NvPhysicalGpuHandle* _handle[NVAPI_MAX_PHYSICAL_GPUS], uint32_t* _gpuCount);
  45. typedef NvApiStatus (NVAPICALL* PFN_NVAPI_GPUGETMEMORYINFO)(NvPhysicalGpuHandle* _handle, NvMemoryInfoV2* _memoryInfo);
  46. typedef NvApiStatus (NVAPICALL* PFN_NVAPI_GPUGETFULLNAME)(NvPhysicalGpuHandle* _physicalGpu, char _name[64]);
  47. #define NVAPI_INITIALIZE UINT32_C(0x0150e828)
  48. #define NVAPI_UNLOAD UINT32_C(0xd22bdd7e)
  49. #define NVAPI_ENUMPHYSICALGPUS UINT32_C(0xe5ac921f)
  50. #define NVAPI_GPUGETMEMORYINFO UINT32_C(0x07f9b368)
  51. #define NVAPI_GPUGETFULLNAME UINT32_C(0xceee8e9f)
  52. #define NVAPI_MULTIDRAWINSTANCEDINDIRECT UINT32_C(0xd4e26bbf)
  53. #define NVAPI_MULTIDRAWINDEXEDINSTANCEDINDIRECT UINT32_C(0x59e890f9)
  54. static PFN_NVAPI_QUERYINTERFACE nvApiQueryInterface;
  55. static PFN_NVAPI_INITIALIZE nvApiInitialize;
  56. static PFN_NVAPI_UNLOAD nvApiUnload;
  57. static PFN_NVAPI_ENUMPHYSICALGPUS nvApiEnumPhysicalGPUs;
  58. static PFN_NVAPI_GPUGETMEMORYINFO nvApiGpuGetMemoryInfo;
  59. static PFN_NVAPI_GPUGETFULLNAME nvApiGpuGetFullName;
  60. NvApi::NvApi()
  61. : m_nvApiDll(NULL)
  62. , m_nvGpu(NULL)
  63. {
  64. }
  65. void NvApi::init()
  66. {
  67. m_nvGpu = NULL;
  68. m_nvApiDll = bx::dlopen(
  69. #if BX_ARCH_32BIT
  70. "nvapi.dll"
  71. #else
  72. "nvapi64.dll"
  73. #endif // BX_ARCH_32BIT
  74. );
  75. if (NULL != m_nvApiDll)
  76. {
  77. nvApiQueryInterface = (PFN_NVAPI_QUERYINTERFACE)bx::dlsym(m_nvApiDll, "nvapi_QueryInterface");
  78. bool initialized = NULL != nvApiQueryInterface;
  79. if (initialized)
  80. {
  81. nvApiInitialize = (PFN_NVAPI_INITIALIZE )nvApiQueryInterface(NVAPI_INITIALIZE);
  82. nvApiUnload = (PFN_NVAPI_UNLOAD )nvApiQueryInterface(NVAPI_UNLOAD);
  83. nvApiEnumPhysicalGPUs = (PFN_NVAPI_ENUMPHYSICALGPUS )nvApiQueryInterface(NVAPI_ENUMPHYSICALGPUS);
  84. nvApiGpuGetMemoryInfo = (PFN_NVAPI_GPUGETMEMORYINFO )nvApiQueryInterface(NVAPI_GPUGETMEMORYINFO);
  85. nvApiGpuGetFullName = (PFN_NVAPI_GPUGETFULLNAME )nvApiQueryInterface(NVAPI_GPUGETFULLNAME);
  86. nvApiD3D11MultiDrawInstancedIndirect = (NvMultiDrawIndirectFn)nvApiQueryInterface(NVAPI_MULTIDRAWINSTANCEDINDIRECT);
  87. nvApiD3D11MultiDrawIndexedInstancedIndirect = (NvMultiDrawIndirectFn)nvApiQueryInterface(NVAPI_MULTIDRAWINDEXEDINSTANCEDINDIRECT);
  88. initialized = true
  89. && NULL != nvApiInitialize
  90. && NULL != nvApiUnload
  91. && NULL != nvApiEnumPhysicalGPUs
  92. && NULL != nvApiGpuGetMemoryInfo
  93. && NULL != nvApiGpuGetFullName
  94. && NVAPI_OK == nvApiInitialize()
  95. ;
  96. if (initialized)
  97. {
  98. NvPhysicalGpuHandle* physicalGpus[NVAPI_MAX_PHYSICAL_GPUS];
  99. uint32_t numGpus = 0;
  100. nvApiEnumPhysicalGPUs(physicalGpus, &numGpus);
  101. initialized = 0 < numGpus;
  102. if (initialized)
  103. {
  104. m_nvGpu = physicalGpus[0];
  105. }
  106. char name[64];
  107. nvApiGpuGetFullName(m_nvGpu, name);
  108. BX_TRACE("%s", name);
  109. }
  110. initialized = NULL != m_nvGpu;
  111. if (!initialized)
  112. {
  113. nvApiUnload();
  114. }
  115. }
  116. if (!initialized)
  117. {
  118. bx::dlclose(m_nvApiDll);
  119. m_nvApiDll = NULL;
  120. }
  121. BX_WARN(!initialized, "NVAPI supported.");
  122. }
  123. }
  124. void NvApi::shutdown()
  125. {
  126. if (NULL != m_nvGpu)
  127. {
  128. nvApiUnload();
  129. m_nvGpu = NULL;
  130. }
  131. if (NULL != m_nvApiDll)
  132. {
  133. bx::dlclose(m_nvApiDll);
  134. m_nvApiDll = NULL;
  135. }
  136. }
  137. void NvApi::getMemoryInfo(int64_t& _gpuMemoryUsed, int64_t& _gpuMemoryMax)
  138. {
  139. if (NULL != m_nvGpu)
  140. {
  141. NvMemoryInfoV2 memInfo;
  142. NvApiStatus status = nvApiGpuGetMemoryInfo(m_nvGpu, &memInfo);
  143. if (NVAPI_OK == status)
  144. {
  145. _gpuMemoryMax = 1024 * int64_t(memInfo.availableDedicatedVideoMemory);
  146. _gpuMemoryUsed = 1024 * int64_t(memInfo.availableDedicatedVideoMemory - memInfo.curAvailableDedicatedVideoMemory);
  147. // BX_TRACE(" dedicatedVideoMemory: %d KiB", memInfo.dedicatedVideoMemory);
  148. // BX_TRACE(" availableDedicatedVideoMemory: %d KiB", memInfo.availableDedicatedVideoMemory);
  149. // BX_TRACE(" systemVideoMemory: %d KiB", memInfo.systemVideoMemory);
  150. // BX_TRACE(" sharedSystemMemory: %d KiB", memInfo.sharedSystemMemory);
  151. // BX_TRACE("curAvailableDedicatedVideoMemory: %d KiB", memInfo.curAvailableDedicatedVideoMemory);
  152. }
  153. }
  154. else
  155. {
  156. _gpuMemoryMax = -INT64_MAX;
  157. _gpuMemoryUsed = -INT64_MAX;
  158. }
  159. }
  160. } // namespace bgfx