diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f7fab9b6..96842bd7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,7 +97,7 @@ endif() set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type") set(CMAKE_C_STANDARD 11) -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion") if(WIN32 OR ENABLE_DIRECTX_HEADERS) enable_language(CXX) @@ -392,6 +392,7 @@ if(LINUX) src/detection/displayserver/linux/xlib.c src/detection/font/font_linux.c src/detection/gpu/gpu_linux.c + src/detection/gpu/gpu_nvidia.c src/detection/gtk_qt/gtk.c src/detection/host/host_linux.c src/detection/icons/icons_linux.c @@ -412,7 +413,6 @@ if(LINUX) src/detection/sound/sound_linux.c src/detection/swap/swap_linux.c src/detection/temps/temps_linux.c - src/detection/temps/temps_nvidia.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c src/detection/terminalsize/terminalsize_linux.c @@ -499,6 +499,7 @@ elseif(BSD) src/detection/displayserver/linux/xlib.c src/detection/font/font_linux.c src/detection/gpu/gpu_linux.c + src/detection/gpu/gpu_nvidia.c src/detection/gtk_qt/gtk.c src/detection/host/host_bsd.c src/detection/lm/lm_linux.c @@ -519,7 +520,6 @@ elseif(BSD) src/detection/sound/sound_linux.c src/detection/swap/swap_bsd.c src/detection/temps/temps_bsd.c - src/detection/temps/temps_nvidia.c src/detection/terminalfont/terminalfont_linux.c src/detection/terminalshell/terminalshell_linux.c src/detection/terminalsize/terminalsize_linux.c @@ -603,6 +603,7 @@ elseif(WIN32) src/detection/displayserver/displayserver_windows.c src/detection/font/font_windows.c src/detection/gpu/gpu_windows.c + src/detection/gpu/gpu_nvidia.c src/detection/host/host_windows.c src/detection/icons/icons_windows.c src/detection/libc/libc_windows.cpp @@ -624,7 +625,6 @@ elseif(WIN32) src/detection/terminalshell/terminalshell_windows.c src/detection/terminalsize/terminalsize_windows.c src/detection/temps/temps_windows.cpp - src/detection/temps/temps_nvidia.c src/detection/theme/theme_nosupport.c src/detection/uptime/uptime_windows.c src/detection/users/users_windows.c diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index d252994b6..1401ebd88 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -1,6 +1,6 @@ #include "detection/gpu/gpu.h" +#include "detection/gpu/gpu_nvidia.h" #include "detection/vulkan/vulkan.h" -#include "detection/temps/temps_nvidia.h" #ifdef FF_HAVE_LIBPCI #include "common/io/io.h" @@ -247,11 +247,18 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* pciDetectTemp(gpu, device); #endif - if (gpu->temperature != gpu->temperature && gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA) + if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA) { char pciDeviceId[32]; snprintf(pciDeviceId, sizeof(pciDeviceId) - 1, "%04x:%02x:%02x.%d", device->domain, device->bus, device->dev, device->func); - ffDetectNvidiaGpuTemp(&gpu->temperature, pciDeviceId, 0, 0); + + ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) { .pciBusId = pciDeviceId }, (FFGpuNvidiaResult) { + .temp = gpu->temperature != gpu->temperature ? &gpu->temperature : NULL, + .memory = &gpu->dedicated, + .coreCount = (uint32_t*) &gpu->coreCount, + }); + + gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED; } } diff --git a/src/detection/temps/temps_nvidia.c b/src/detection/gpu/gpu_nvidia.c similarity index 63% rename from src/detection/temps/temps_nvidia.c rename to src/detection/gpu/gpu_nvidia.c index 61194f3a1..9ce4b2f8d 100644 --- a/src/detection/temps/temps_nvidia.c +++ b/src/detection/gpu/gpu_nvidia.c @@ -1,4 +1,4 @@ -#include "temps_nvidia.h" +#include "gpu_nvidia.h" #include "3rdparty/nvml/nvml.h" #include "common/library.h" @@ -9,14 +9,13 @@ struct FFNvmlData { FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByPciBusId_v2) FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3) FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature) + FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2) + FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores) bool inited; } nvmlData; -// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise -// pciBusId = "domain:bus:device.function" -// pciDeviceId = (deviceId << 16) | vendorId -const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t pciDeviceId, uint32_t pciSubSystemId) +const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result) { if (!nvmlData.inited) { @@ -27,7 +26,7 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p #else "libnvidia-ml" #endif - FF_LIBRARY_EXTENSION, -1 + FF_LIBRARY_EXTENSION, -1 ); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown) @@ -36,23 +35,25 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByPciBusId_v2) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores) if (ffnvmlInit_v2() != NVML_SUCCESS) { - nvmlData.ffnvmlDeviceGetTemperature = NULL; + nvmlData.ffnvmlDeviceGetNumGpuCores = NULL; return "nvmlInit_v2() failed"; } atexit((void*) ffnvmlShutdown); libnvml = NULL; // don't close nvml } - if (nvmlData.ffnvmlDeviceGetTemperature == NULL) + if (nvmlData.ffnvmlDeviceGetNumGpuCores == NULL) return "loading nvml library failed"; nvmlDevice_t device = NULL; - if (pciBusId) + if (cond.pciBusId) { - nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(pciBusId, &device); + nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(cond.pciBusId, &device); if (ret != NVML_SUCCESS) return "nvmlDeviceGetHandleByPciBusId_v2() failed"; } @@ -71,7 +72,7 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p if (nvmlData.ffnvmlDeviceGetPciInfo_v3(device, &pciInfo) != NVML_SUCCESS) continue; - if (pciInfo.pciDeviceId != pciDeviceId || pciInfo.pciSubSystemId != pciSubSystemId) + if (pciInfo.pciDeviceId != cond.pciDeviceId || pciInfo.pciSubSystemId != cond.pciSubSystemId) continue; break; @@ -79,10 +80,25 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p if (!device) return "Device not found"; } - uint32_t value; - if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) != NVML_SUCCESS) - return "nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) failed"; + if (result.temp) + { + uint32_t value; + if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) == NVML_SUCCESS) + *result.temp = value; + } + + if (result.memory) + { + nvmlMemory_v2_t memory = { .version = nvmlMemory_v2 }; + if (nvmlData.ffnvmlDeviceGetMemoryInfo_v2(device, &memory) == NVML_SUCCESS) + { + result.memory->total = memory.used + memory.free; + result.memory->used = memory.used; + } + } + + if (result.coreCount) + nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount); - *temp = value; return NULL; } diff --git a/src/detection/gpu/gpu_nvidia.h b/src/detection/gpu/gpu_nvidia.h new file mode 100644 index 000000000..b891595cf --- /dev/null +++ b/src/detection/gpu/gpu_nvidia.h @@ -0,0 +1,23 @@ +#pragma once + +#include "gpu.h" + +// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise +// pciBusId = "domain:bus:device.function" +// pciDeviceId = (deviceId << 16) | vendorId +typedef struct FFGpuNvidiaCondition +{ + const char* pciBusId; + uint32_t pciDeviceId; + uint32_t pciSubSystemId; +} FFGpuNvidiaCondition; + +// detect x if not NULL +typedef struct FFGpuNvidiaResult +{ + double* temp; + FFGPUMemory* memory; + uint32_t* coreCount; +} FFGpuNvidiaResult; + +const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result); diff --git a/src/detection/gpu/gpu_windows.c b/src/detection/gpu/gpu_windows.c index 3ddba91fc..ce2d535c1 100644 --- a/src/detection/gpu/gpu_windows.c +++ b/src/detection/gpu/gpu_windows.c @@ -1,5 +1,5 @@ #include "gpu.h" -#include "detection/temps/temps_nvidia.h" +#include "detection/gpu/gpu_nvidia.h" #include "util/windows/unicode.h" #include "util/windows/registry.h" @@ -85,13 +85,22 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist* } } - if (options->temp && gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA) + if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || instance.config.general.allowSlowOperations)) { uint32_t vendorId, deviceId, subSystemId; // See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html // displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1" if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x", &vendorId, &deviceId, &subSystemId) == 3) - ffDetectNvidiaGpuTemp(&gpu->temperature, NULL, (deviceId << 16) | vendorId, subSystemId); + { + ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) { + .pciDeviceId = (deviceId << 16) | vendorId, + .pciSubSystemId = subSystemId, + }, (FFGpuNvidiaResult) { + .temp = options->temp ? &gpu->temperature : NULL, + .memory = &gpu->dedicated, + .coreCount = (uint32_t*) &gpu->coreCount, + }); + } } } diff --git a/src/detection/temps/temps_nvidia.h b/src/detection/temps/temps_nvidia.h deleted file mode 100644 index 3cf7dadda..000000000 --- a/src/detection/temps/temps_nvidia.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t pciDeviceId, uint32_t pciSubSystemId); diff --git a/src/modules/gpu/gpu.c b/src/modules/gpu/gpu.c index 2a48e463d..02321e20e 100644 --- a/src/modules/gpu/gpu.c +++ b/src/modules/gpu/gpu.c @@ -275,7 +275,10 @@ void ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_ else yyjson_mut_obj_add_null(doc, sharedObj, "used"); - yyjson_mut_obj_add_null(doc, obj, "temperature"); + if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET + yyjson_mut_obj_add_real(doc, obj, "temperature", gpu->temperature); + else + yyjson_mut_obj_add_null(doc, obj, "temperature"); const char* type; switch (gpu->type)