diff --git a/src/gpu.cpp b/src/gpu.cpp index 876feab..a91e532 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -6,6 +6,7 @@ struct gpuInfo gpu_info; amdgpu_files amdgpu {}; void getNvidiaGpuInfo(){ +#ifdef __gnu_linux__ if (nvmlSuccess){ getNVMLInfo(); gpu_info.load = nvidiaUtilization.gpu; @@ -26,6 +27,10 @@ void getNvidiaGpuInfo(){ gpu_info.powerUsage = 0; } #endif +#endif +#ifdef __WIN32 + nvapi_util(); +#endif } void getAmdGpuInfo(){ diff --git a/src/meson.build b/src/meson.build index a3f2d51..5b840ab 100644 --- a/src/meson.build +++ b/src/meson.build @@ -48,6 +48,7 @@ if ['windows', 'mingw'].contains(host_machine.system()) 'file_utils_win32.cpp', 'loaders/loader_nvml_win32.cpp', 'cpu_win32.cpp', + 'nvapi.cpp', # 'MangoHud.def', ) endif diff --git a/src/nvapi.cpp b/src/nvapi.cpp new file mode 100644 index 0000000..5ddce7e --- /dev/null +++ b/src/nvapi.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "nvidia_info.h" +#include "gpu.h" + +// magic numbers, do not change them +#define NVAPI_MAX_PHYSICAL_GPUS 64 +#define NVAPI_MAX_USAGES_PER_GPU 34 + +// function pointer types +typedef int *(*NvAPI_QueryInterface_t)(unsigned int offset); +typedef int (*NvAPI_Initialize_t)(); +typedef int (*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count); +typedef int (*NvAPI_GPU_GetUsages_t)(int *handle, unsigned int *usages); + +NvAPI_QueryInterface_t NvAPI_QueryInterface = NULL; +NvAPI_Initialize_t NvAPI_Initialize = NULL; +NvAPI_EnumPhysicalGPUs_t NvAPI_EnumPhysicalGPUs = NULL; +NvAPI_GPU_GetUsages_t NvAPI_GPU_GetUsages = NULL; +HMODULE hmod; +bool init_nvapi_bool; +int *gpuHandles[NVAPI_MAX_PHYSICAL_GPUS] = { NULL }; +int gpuCount = 0; +unsigned int gpuUsages[NVAPI_MAX_USAGES_PER_GPU] = { 0 }; + +bool checkNVAPI(){ + + if (MANGOHUD_ARCH == "64bit") + hmod = LoadLibraryA("nvapi64.dll"); + else + hmod = LoadLibraryA("nvapi.dll"); + if (hmod == NULL) + { + printf("Failed to load nvapi.dll"); + return false; + } + NvAPI_QueryInterface = (NvAPI_QueryInterface_t) GetProcAddress(hmod, "nvapi_QueryInterface"); + NvAPI_Initialize = (NvAPI_Initialize_t) (*NvAPI_QueryInterface)(0x0150E828); + NvAPI_EnumPhysicalGPUs = (NvAPI_EnumPhysicalGPUs_t) (*NvAPI_QueryInterface)(0xE5AC921F); + NvAPI_GPU_GetUsages = (NvAPI_GPU_GetUsages_t) (*NvAPI_QueryInterface)(0x189A1FDF); + if (NvAPI_Initialize == NULL || NvAPI_EnumPhysicalGPUs == NULL || + NvAPI_EnumPhysicalGPUs == NULL || NvAPI_GPU_GetUsages == NULL) + { + std::cerr << "Couldn't get functions in nvapi.dll" << std::endl; + return 2; + } + (*NvAPI_Initialize)(); + + int *gpuHandles[NVAPI_MAX_PHYSICAL_GPUS] = { NULL }; + + return true; +} + +void nvapi_util() +{ + if (!init_nvapi_bool){ + init_nvapi_bool = checkNVAPI(); + } + + gpuUsages[0] = (NVAPI_MAX_USAGES_PER_GPU * 4) | 0x10000; + (*NvAPI_EnumPhysicalGPUs)(gpuHandles, &gpuCount); + (*NvAPI_GPU_GetUsages)(gpuHandles[0], gpuUsages); + gpu_info.load = gpuUsages[3]; + +} \ No newline at end of file diff --git a/src/nvidia_info.h b/src/nvidia_info.h index aa51db7..c59cdc2 100644 --- a/src/nvidia_info.h +++ b/src/nvidia_info.h @@ -8,4 +8,6 @@ extern struct nvmlMemory_st nvidiaMemory; extern bool nvmlSuccess; bool checkNVML(const char* pciBusId); +bool checkNVAPI(void); bool getNVMLInfo(void); +void nvapi_util(void); \ No newline at end of file