mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 10:22:12 +02:00
GPU (Windows): support vmem total / usage detection #416
vmem usage detection is guarded behind `--allow-slow-operations` because it's really slow sometimes
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#define FF_GPU_TEMP_UNSET (0/0.0)
|
||||
#define FF_GPU_CORE_COUNT_UNSET -1
|
||||
#define FF_GPU_VMEM_SIZE_UNSET ((uint64_t)-1)
|
||||
|
||||
extern const char* FF_GPU_VENDOR_NAME_APPLE;
|
||||
extern const char* FF_GPU_VENDOR_NAME_AMD;
|
||||
@@ -15,20 +16,24 @@ extern const char* FF_GPU_VENDOR_NAME_NVIDIA;
|
||||
|
||||
typedef enum FFGpuType
|
||||
{
|
||||
FF_GPU_TYPE_UNKNOWN,
|
||||
FF_GPU_TYPE_INTEGRATED,
|
||||
FF_GPU_TYPE_DISCRETE,
|
||||
FF_GPU_TYPE_UNKNOWN
|
||||
} FFGpuType;
|
||||
|
||||
typedef struct FFGPUResult
|
||||
{
|
||||
uint64_t id;
|
||||
FFGpuType type;
|
||||
FFstrbuf vendor;
|
||||
FFstrbuf name;
|
||||
FFstrbuf driver;
|
||||
double temperature;
|
||||
uint64_t memory;
|
||||
int coreCount;
|
||||
uint64_t dedicatedTotal;
|
||||
uint64_t dedicatedUsed;
|
||||
uint64_t sharedTotal;
|
||||
uint64_t sharedUsed;
|
||||
} FFGPUResult;
|
||||
|
||||
const FFlist* ffDetectGPU(const FFinstance* instance);
|
||||
|
||||
@@ -60,6 +60,8 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance)
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(gpus);
|
||||
|
||||
gpu->id = 0;
|
||||
gpu->dedicatedTotal = gpu->dedicatedUsed = gpu->sharedTotal = gpu->sharedUsed = FF_GPU_VMEM_SIZE_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
|
||||
@@ -199,6 +199,9 @@ static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData
|
||||
|
||||
FFGPUResult* gpu = ffListAdd(results);
|
||||
|
||||
gpu->id = 0;
|
||||
gpu->dedicatedTotal = gpu->dedicatedUsed = gpu->sharedTotal = gpu->sharedUsed = FF_GPU_VMEM_SIZE_UNSET;
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
pciDetectVendorName(gpu, pci, device);
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ static const char* detectWithRegistry(FFlist* gpus)
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
gpu->id = 0;
|
||||
gpu->dedicatedTotal = gpu->dedicatedUsed = gpu->sharedTotal = gpu->sharedUsed = FF_GPU_VMEM_SIZE_UNSET;
|
||||
|
||||
ffRegReadUint64(hSubKey, L"AdapterLuid", &gpu->id, nullptr);
|
||||
|
||||
ffRegReadStrbuf(hSubKey, L"Description", &gpu->name, nullptr);
|
||||
|
||||
@@ -55,10 +59,18 @@ static const char* detectWithRegistry(FFlist* gpus)
|
||||
if(ffRegReadUint(hSubKey, L"VendorId", &vendorId, nullptr))
|
||||
ffStrbufAppendS(&gpu->vendor, ffGetGPUVendorString(vendorId));
|
||||
|
||||
uint64_t dedicatedVideoMemory;
|
||||
uint64_t dedicatedVideoMemory = 0;
|
||||
if(ffRegReadUint64(hSubKey, L"DedicatedVideoMemory", &dedicatedVideoMemory, nullptr))
|
||||
gpu->type = dedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
|
||||
uint64_t dedicatedSystemMemory, sharedSystemMemory;
|
||||
if(ffRegReadUint64(hSubKey, L"DedicatedSystemMemory", &dedicatedSystemMemory, nullptr) &&
|
||||
ffRegReadUint64(hSubKey, L"SharedSystemMemory", &sharedSystemMemory, nullptr))
|
||||
{
|
||||
gpu->dedicatedTotal = dedicatedVideoMemory + dedicatedSystemMemory;
|
||||
gpu->sharedTotal = sharedSystemMemory;
|
||||
}
|
||||
|
||||
uint64_t driverVersion;
|
||||
if(ffRegReadUint64(hSubKey, L"DriverVersion", &driverVersion, nullptr))
|
||||
{
|
||||
@@ -90,16 +102,21 @@ static const char* detectWithDxgi(FFlist* gpus)
|
||||
continue;
|
||||
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
gpu->dedicatedTotal = gpu->dedicatedUsed = gpu->sharedTotal = gpu->sharedUsed = FF_GPU_VMEM_SIZE_UNSET;
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufAppendS(&gpu->vendor, ffGetGPUVendorString(desc.VendorId));
|
||||
|
||||
gpu->id = (uint64_t&)desc.AdapterLuid;
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
ffStrbufSetWS(&gpu->name, desc.Description);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
|
||||
gpu->type = desc.DedicatedVideoMemory >= 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
|
||||
gpu->dedicatedTotal = desc.DedicatedVideoMemory + desc.DedicatedSystemMemory;
|
||||
gpu->sharedTotal = desc.SharedSystemMemory;
|
||||
|
||||
adapter->Release();
|
||||
|
||||
@@ -112,46 +129,44 @@ static const char* detectWithDxgi(FFlist* gpus)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const char* detectWithWmi(FFlist* gpus)
|
||||
static const char* detectMemoryUsage(FFlist* gpus)
|
||||
{
|
||||
FFWmiQuery query(L"SELECT Name, AdapterCompatibility, DriverVersion FROM Win32_VideoController", nullptr);
|
||||
FFWmiQuery query(L"SELECT Name, DedicatedUsage, SharedUsage FROM Win32_PerfRawData_GPUPerformanceCounters_GPUAdapterMemory", nullptr);
|
||||
if(!query)
|
||||
return "Query WMI service failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name;
|
||||
ffStrbufInit(&name);
|
||||
|
||||
while(FFWmiRecord record = query.next())
|
||||
{
|
||||
FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus);
|
||||
record.getString(L"Name", &name); // luid_0x00000000_0x000146E8_phys_0
|
||||
assert(name.length == strlen("luid_0x00000000_0x000146E8_phys_0"));
|
||||
ffStrbufSubstrBefore(&name, strlen("luid_0x00000000_0x000146E8")); // luid_0x00000000_0x000146E8
|
||||
ffStrbufSubstrAfter(&name, strlen("luid_0x00000000_0x") - 1); // 000146E8
|
||||
uint64_t luid = strtoull(name.chars, nullptr, 16);
|
||||
|
||||
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
||||
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
record.getString(L"AdapterCompatibility", &gpu->vendor);
|
||||
if(ffStrbufStartsWithS(&gpu->vendor, "Intel "))
|
||||
FF_LIST_FOR_EACH(FFGPUResult, gpu, *gpus)
|
||||
{
|
||||
//Intel returns "Intel Corporation", not sure about AMD
|
||||
ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL);
|
||||
if (gpu->id != luid) continue;
|
||||
record.getUnsigned(L"DedicatedUsage", &gpu->dedicatedUsed);
|
||||
record.getUnsigned(L"SharedUsage", &gpu->sharedUsed);
|
||||
break;
|
||||
}
|
||||
|
||||
ffStrbufInit(&gpu->name);
|
||||
record.getString(L"Name", &gpu->name);
|
||||
|
||||
ffStrbufInit(&gpu->driver);
|
||||
record.getString(L"DriverVersion", &gpu->driver);
|
||||
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
const char* ffDetectGPUImpl(FFlist* gpus, FF_MAYBE_UNUSED const FFinstance* instance)
|
||||
{
|
||||
if (instance->config.allowSlowOperations)
|
||||
return detectWithWmi(gpus);
|
||||
const char* error = detectWithRegistry(gpus);
|
||||
if (error)
|
||||
error = detectWithDxgi(gpus);
|
||||
|
||||
if (!detectWithRegistry(gpus))
|
||||
return nullptr;
|
||||
return detectWithDxgi(gpus);
|
||||
if (!error && gpus->length > 0 && instance->config.allowSlowOperations)
|
||||
detectMemoryUsage(gpus);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -195,12 +195,14 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu
|
||||
gpu->type = FF_GPU_TYPE_INTEGRATED;
|
||||
else
|
||||
gpu->type = FF_GPU_TYPE_DISCRETE;
|
||||
gpu->id = physicalDeviceProperties.properties.deviceID;
|
||||
ffStrbufInitS(&gpu->vendor, ffGetGPUVendorString(physicalDeviceProperties.properties.vendorID));
|
||||
ffStrbufInitF(&gpu->driver, "%X", (unsigned) physicalDeviceProperties.properties.driverVersion);
|
||||
|
||||
//No way to detect those using vulkan
|
||||
ffStrbufInit(&gpu->vendor);
|
||||
ffStrbufInit(&gpu->driver);
|
||||
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
||||
gpu->temperature = FF_GPU_TEMP_UNSET;
|
||||
gpu->dedicatedTotal = gpu->dedicatedUsed = gpu->sharedTotal = gpu->sharedUsed = 0; //VkPhysicalDeviceMemoryProperties?
|
||||
}
|
||||
|
||||
//If the highest device version is lower than the instance version, use it as our vulkan version
|
||||
|
||||
+21
-3
@@ -1,4 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/bar.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/printing.h"
|
||||
#include "detection/host/host.h"
|
||||
#include "detection/gpu/gpu.h"
|
||||
@@ -14,7 +16,7 @@ static void printGPUResult(FFinstance* instance, uint8_t index, const FFGPUResul
|
||||
{
|
||||
ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu.key);
|
||||
|
||||
FFstrbuf output;
|
||||
FF_STRBUF_AUTO_DESTROY output;
|
||||
ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length);
|
||||
|
||||
if(gpu->vendor.length > 0 && !ffStrbufStartsWith(&gpu->name, &gpu->vendor))
|
||||
@@ -31,9 +33,25 @@ static void printGPUResult(FFinstance* instance, uint8_t index, const FFGPUResul
|
||||
if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET
|
||||
ffStrbufAppendF(&output, " - %.1f°C", gpu->temperature);
|
||||
|
||||
ffStrbufPutTo(&output, stdout);
|
||||
if(gpu->dedicatedTotal != FF_GPU_VMEM_SIZE_UNSET)
|
||||
{
|
||||
ffStrbufAppendS(&output, " (");
|
||||
|
||||
ffStrbufDestroy(&output);
|
||||
if(gpu->dedicatedUsed != FF_GPU_VMEM_SIZE_UNSET)
|
||||
{
|
||||
ffParseSize(gpu->dedicatedUsed, instance->config.binaryPrefixType, &output);
|
||||
ffStrbufAppendS(&output, " / ");
|
||||
}
|
||||
ffParseSize(gpu->dedicatedTotal, instance->config.binaryPrefixType, &output);
|
||||
if(gpu->dedicatedUsed != FF_GPU_VMEM_SIZE_UNSET)
|
||||
{
|
||||
ffStrbufAppendS(&output, ", ");
|
||||
ffAppendPercentNum(instance, &output, (uint8_t) (gpu->dedicatedUsed * 100 / gpu->dedicatedTotal), 50, 80, false);
|
||||
}
|
||||
ffStrbufAppendC(&output, ')');
|
||||
}
|
||||
|
||||
ffStrbufPutTo(&output, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user