From accaaa7de5fbeaf7793465b6d7c8e295f924e245 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Wed, 12 Jan 2022 18:57:35 +0100 Subject: [PATCH] Expose GPU driver to gpu format string --- presets/verbose | 2 +- src/fastfetch.c | 5 +++-- src/modules/gpu.c | 42 ++++++++++++++++++++++++++++++++++++++++-- src/util/FFstrbuf.c | 10 +++++++++- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/presets/verbose b/presets/verbose index 6def292e4..90d3468ee 100644 --- a/presets/verbose +++ b/presets/verbose @@ -19,7 +19,7 @@ --terminal-font-format "Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}" --cpu-format "Name: {}; Pretty: {}; Vendor: {}; Logical online: {}; Logical configured: {}; Physical: {}; Cores: {}; bios: {}; scaling max: {}; scaling min: {}; info max: {}; info min: {}; cpuinfo: {}; frequency: {}" --cpu-usage-format "Percentage: {}" ---gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}" +--gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}" --memory-format "Used: {}; Total: {}; Percentage: {}" --disk-format "Used: {}; Total: {}; Files: {}; Percentage: {}" --battery-format "Manufactor: {}; Model: {}; Technology: {}; Capacaty: {}; Status: {}" diff --git a/src/fastfetch.c b/src/fastfetch.c index 11d81ed00..018fa0b7a 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -249,11 +249,12 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "gpu-format") == 0) { - constructAndPrintCommandHelpFormat("gpu", "{2} {4}", 4, + constructAndPrintCommandHelpFormat("gpu", "{2} {4}", 5, "GPU vendor", "GPU vendor pretty", "GPU name", - "GPU name pretty" + "GPU name pretty", + "GPU driver" ); } else if(strcasecmp(command, "memory-format") == 0) diff --git a/src/modules/gpu.c b/src/modules/gpu.c index df79c4956..80ecf5950 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -3,12 +3,13 @@ #include #define FF_GPU_MODULE_NAME "GPU" -#define FF_GPU_NUM_FORMAT_ARGS 4 +#define FF_GPU_NUM_FORMAT_ARGS 5 typedef struct GPUResult { FFstrbuf vendor; FFstrbuf name; + FFstrbuf driver; } GPUResult; #ifdef FF_HAVE_VULKAN @@ -86,6 +87,7 @@ static void vulkanFillGPUs(FFinstance* instance, FFlist* results) GPUResult* result = ffListAdd(results); ffStrbufInit(&result->vendor); ffStrbufInit(&result->name); + ffStrbufInit(&result->driver); ffStrbufAppendS(&result->name, physicalDeviceProperties.deviceName); } @@ -101,6 +103,33 @@ static void vulkanFillGPUs(FFinstance* instance, FFlist* results) #ifdef FF_HAVE_LIBPCI #include +#include + +//see https://github.com/pciutils/pciutils/blob/5bdf63b6b1bc35b59c4b3f47f7ca83ca1868155b/ls-kernel.c#L220 +static void pciGetDriver(struct pci_dev* dev, FFstrbuf* driver, char*(*ffpci_get_param)(struct pci_access*, char*)) +{ + if(dev->access->method != PCI_ACCESS_SYS_BUS_PCI) + return; + + const char* base = ffpci_get_param(dev->access, "sysfs.path"); + if(!ffStrSet(base)) + return; + + FFstrbuf path; + ffStrbufInitA(&path, 64); + ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, dev->domain, dev->bus, dev->dev, dev->func); + + ffStrbufEnsureFree(driver, 1023); + ssize_t resultLength = readlink(path.chars, driver->chars, driver->allocated - 1); //-1 for null terminator + if(resultLength > 0) + { + driver->length = (uint32_t) resultLength; + driver->chars[resultLength] = '\0'; + ffStrbufSubstrAfterLastC(driver, '/'); + } + + ffStrbufDestroy(&path); +} static void pciFillGPUs(FFinstance* instance, FFlist* results) { @@ -110,6 +139,7 @@ static void pciFillGPUs(FFinstance* instance, FFlist* results) FF_LIBRARY_LOAD_SYMBOL(pci, pci_scan_bus,) FF_LIBRARY_LOAD_SYMBOL(pci, pci_fill_info,) FF_LIBRARY_LOAD_SYMBOL(pci, pci_lookup_name,) + FF_LIBRARY_LOAD_SYMBOL(pci, pci_get_param,) FF_LIBRARY_LOAD_SYMBOL(pci, pci_cleanup,) struct pci_access *pacc = ffpci_alloc(); @@ -136,6 +166,10 @@ static void pciFillGPUs(FFinstance* instance, FFlist* results) ffStrbufInitA(&result->name, 256); ffpci_lookup_name(pacc, result->name.chars, (int) result->name.allocated - 1, PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id); ffStrbufRecalculateLength(&result->name); + + ffStrbufInit(&result->driver); + if(instance->config.gpuFormat.length > 0) //We only need it for the format string, so don't detect it if it isn't needed + pciGetDriver(dev, &result->driver, ffpci_get_param); }; } @@ -177,9 +211,13 @@ static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, {FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor}, {FF_FORMAT_ARG_TYPE_STRING, vendorPretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->name}, - {FF_FORMAT_ARG_TYPE_STRBUF, &namePretty} + {FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result->driver}, }); + ffStrbufDestroy(&result->vendor); + ffStrbufDestroy(&result->name); + ffStrbufDestroy(&result->driver); ffStrbufDestroy(&gpu); ffStrbufDestroy(&namePretty); } diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 9b8f7f41c..93d8f3318 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -176,15 +176,23 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments) if(format == NULL) return; + va_list copy; + va_copy(copy, arguments); + uint32_t free = ffStrbufGetFree(strbuf); uint32_t written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, free, format, arguments); if(strbuf->length + written > free) { ffStrbufEnsureFree(strbuf, written); - written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, ffStrbufGetFree(strbuf), format, arguments); + written = (uint32_t) vsnprintf(strbuf->chars + strbuf->length, ffStrbufGetFree(strbuf), format, copy); } + va_end(copy); + + if(written <= 0) + return; + strbuf->length += written; strbuf->chars[strbuf->length] = '\0'; }