mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 10:52:08 +02:00
GPU: support memory, core count detection
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "gpu_nvidia.h"
|
||||
|
||||
#include "3rdparty/nvml/nvml.h"
|
||||
#include "common/library.h"
|
||||
|
||||
struct FFNvmlData {
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetCount_v2)
|
||||
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByIndex_v2)
|
||||
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;
|
||||
|
||||
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result)
|
||||
{
|
||||
if (!nvmlData.inited)
|
||||
{
|
||||
nvmlData.inited = true;
|
||||
FF_LIBRARY_LOAD(libnvml, NULL, "dlopen nvml failed",
|
||||
#ifdef _WIN32
|
||||
"nvml"
|
||||
#else
|
||||
"libnvidia-ml"
|
||||
#endif
|
||||
FF_LIBRARY_EXTENSION, -1
|
||||
);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetCount_v2)
|
||||
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByIndex_v2)
|
||||
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.ffnvmlDeviceGetNumGpuCores = NULL;
|
||||
return "nvmlInit_v2() failed";
|
||||
}
|
||||
atexit((void*) ffnvmlShutdown);
|
||||
libnvml = NULL; // don't close nvml
|
||||
}
|
||||
|
||||
if (nvmlData.ffnvmlDeviceGetNumGpuCores == NULL)
|
||||
return "loading nvml library failed";
|
||||
|
||||
nvmlDevice_t device = NULL;
|
||||
if (cond.pciBusId)
|
||||
{
|
||||
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(cond.pciBusId, &device);
|
||||
if (ret != NVML_SUCCESS)
|
||||
return "nvmlDeviceGetHandleByPciBusId_v2() failed";
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t count;
|
||||
if (nvmlData.ffnvmlDeviceGetCount_v2(&count) != NVML_SUCCESS)
|
||||
return "nvmlDeviceGetCount_v2() failed";
|
||||
|
||||
for (uint32_t i = 0; i < count; i++, device = NULL)
|
||||
{
|
||||
if (nvmlData.ffnvmlDeviceGetHandleByIndex_v2(i, &device) != NVML_SUCCESS)
|
||||
continue;
|
||||
|
||||
nvmlPciInfo_t pciInfo;
|
||||
if (nvmlData.ffnvmlDeviceGetPciInfo_v3(device, &pciInfo) != NVML_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (pciInfo.pciDeviceId != cond.pciDeviceId || pciInfo.pciSubSystemId != cond.pciSubSystemId)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
if (!device) return "Device not found";
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user