From 670cf6fe900a2f5ac656f9a2dd4408afd1d37e6e Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Thu, 12 Jan 2023 11:41:07 +0100 Subject: [PATCH] GPU selection options #379 --- CHANGELOG.md | 2 ++ completions/bash | 2 ++ src/common/init.c | 3 +++ src/data/config_user.txt | 7 ++++++ src/data/help.txt | 2 ++ src/detection/gpu/gpu.h | 8 ++++++ src/detection/gpu/gpu_apple.c | 2 ++ src/detection/gpu/gpu_linux.c | 24 +++++++++++++++++- src/detection/gpu/gpu_windows.cpp | 4 +++ src/detection/vulkan.c | 5 ++++ src/fastfetch.c | 9 +++++-- src/fastfetch.h | 3 +++ src/modules/gpu.c | 42 +++++++++++++++++++++++++------ 13 files changed, 102 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44402b68a..097671066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Features: * Add `Brightness` module support * Add `Battery` module support for FreeBSD * Add `--disk-show-unknown` option for Disk module +* Add `--gpu-hide-integrated` option (#379) +* Add `--gpu-hide-discrete` option (#379) Logos: * Raspbian (@IamNoRobot, #373) diff --git a/completions/bash b/completions/bash index 5dedf5f6f..d71e6c83b 100644 --- a/completions/bash +++ b/completions/bash @@ -191,6 +191,8 @@ __fastfetch_completion() "--escape-bedrock" "--disk-show-removable" "--disk-show-hidden" + "--gpu-hide-integrated" + "--gpu-hide-discrete" ) local FF_OPTIONS_STRING=( diff --git a/src/common/init.c b/src/common/init.c index c333e03b6..85ef35668 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -315,6 +315,9 @@ static void defaultConfig(FFinstance* instance) instance->config.gpuTemp = false; instance->config.batteryTemp = false; + instance->config.gpuHideIntegrated = false; + instance->config.gpuHideDiscrete = false; + instance->config.titleFQDN = false; ffStrbufInitA(&instance->config.diskFolders, 0); diff --git a/src/data/config_user.txt b/src/data/config_user.txt index d2faddb78..859267bcc 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -212,6 +212,13 @@ # Default is auto. #--gl auto +# GPU hide options +# Sets weather to hide certain gpu types +# Must be either true or false +# Default is false. +#--gpu-hide-integrated +#--gpu-hide-discrete + # Disk option # Sets if removable volume should be printed # Must be either true or false diff --git a/src/data/help.txt b/src/data/help.txt index 5fb36821a..9cd91fd9f 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -110,6 +110,8 @@ Module specific options: --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --cpu-temp : Detect and display CPU temperature if supported. Default is false --gpu-temp : Detect and display GPU temperature if supported. Default is false + --gpu-hide-integrated : Hide integrated GPU if supported. Default is false + --gpu-hide-discrete : Hide discrete GPU if supported. Default is false --battery-temp : Detect and display Battery temperature if supported. Default is false --localip-show-ipv4 : Show IPv4 addresses in local ip module. Default is true --localip-show-ipv6 : Show IPv6 addresses in local ip module. Default is false diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h index 16bd2ff53..e36e1d5ea 100644 --- a/src/detection/gpu/gpu.h +++ b/src/detection/gpu/gpu.h @@ -12,8 +12,16 @@ #define FF_GPU_VENDOR_NAME_INTEL "Intel" #define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA" +typedef enum FFGpuType +{ + FF_GPU_TYPE_INTEGRATED, + FF_GPU_TYPE_DISCRETE, + FF_GPU_TYPE_UNKNOWN +} FFGpuType; + typedef struct FFGPUResult { + FFGpuType type; FFstrbuf vendor; FFstrbuf name; FFstrbuf driver; diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 52292d83e..d8867207f 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -59,6 +59,8 @@ const char* ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) FFGPUResult* gpu = ffListAdd(gpus); + gpu->type = FF_GPU_TYPE_UNKNOWN; + ffStrbufInitA(&gpu->vendor, 0); ffStrbufInit(&gpu->driver); diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index 5877f6176..0fb0dc061 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -61,7 +61,7 @@ static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* static void drmDetectDeviceName(const FFinstance* instance, FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) { u8 revId; - bool revIdSet = false;; + bool revIdSet = false; #if PCI_LIB_VERSION >= 0x030800 revIdSet = pci->ffpci_fill_info(device, PCI_FILL_CLASS_EXT) & PCI_FILL_CLASS_EXT; @@ -167,6 +167,24 @@ static void pciDetectTemperatur(const FFinstance* instance, FFGPUResult* gpu, st } } +static void detectType(FFGPUResult* gpu, const PCIData* pci, struct pci_dev* device) +{ + //There is no straightforward way to detect the type of a GPU. + //The approach taken here is to look at the memory sizes of the device. + //Since integrated GPUs usually use the system ram, they don't have expansive ROMs + + if(!(pci->ffpci_fill_info(device, PCI_FILL_SIZES) & PCI_FILL_SIZES)) + { + gpu->type = FF_GPU_TYPE_UNKNOWN; + return; + } + + if(device->rom_size > 0) + gpu->type = FF_GPU_TYPE_DISCRETE; + else + gpu->type = FF_GPU_TYPE_INTEGRATED; +} + static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData* pci, struct pci_dev* device) { pci->ffpci_fill_info(device, PCI_FILL_CLASS); @@ -175,7 +193,9 @@ static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class); if( + //https://pci-ids.ucw.cz/read/PD/03 strcasecmp("VGA compatible controller", class) != 0 && + strcasecmp("XGA compatible controller", class) != 0 && strcasecmp("3D controller", class) != 0 && strcasecmp("Display controller", class) != 0 ) return; @@ -193,6 +213,8 @@ static void pciHandleDevice(const FFinstance* instance, FFlist* results, PCIData ffStrbufInit(&gpu->driver); pciDetectDriverName(gpu, pci, device); + detectType(gpu, pci, device); + gpu->coreCount = FF_GPU_CORE_COUNT_UNSET; gpu->temperature = FF_GPU_TEMP_UNSET; diff --git a/src/detection/gpu/gpu_windows.cpp b/src/detection/gpu/gpu_windows.cpp index f5d0f4946..41eab75cc 100644 --- a/src/detection/gpu/gpu_windows.cpp +++ b/src/detection/gpu/gpu_windows.cpp @@ -26,6 +26,8 @@ static const char* detectWithDxgi(FFlist* gpus) FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); + gpu->type = FF_GPU_TYPE_UNKNOWN; + if(wmemchr((const wchar_t[]) {0x1002, 0x1022}, (wchar_t)desc.VendorId, 2)) ffStrbufInitS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); else if(wmemchr((const wchar_t[]) {0x03e7, 0x8086, 0x8087}, (wchar_t)desc.VendorId, 3)) @@ -65,6 +67,8 @@ static const char* detectWithWmi(FFlist* gpus) { FFGPUResult* gpu = (FFGPUResult*)ffListAdd(gpus); + gpu->type = FF_GPU_TYPE_UNKNOWN; + ffStrbufInit(&gpu->vendor); record.getString(L"AdapterCompatibility", &gpu->vendor); if(ffStrbufStartsWithS(&gpu->vendor, "Intel ")) diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 4119280a7..dbda127bb 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -190,6 +190,11 @@ static const char* detectVulkan(const FFinstance* instance, FFVulkanResult* resu ffStrbufInit(&gpu->name); ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName); + if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + gpu->type = FF_GPU_TYPE_INTEGRATED; + else + gpu->type = FF_GPU_TYPE_DISCRETE; + //No way to detect those using vulkan ffStrbufInit(&gpu->vendor); ffStrbufInit(&gpu->driver); diff --git a/src/fastfetch.c b/src/fastfetch.c index 62935fc73..543aea831 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -288,12 +288,13 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "gpu-format") == 0) { - constructAndPrintCommandHelpFormat("gpu", "{} {}", 5, + constructAndPrintCommandHelpFormat("gpu", "{} {}", 6, "GPU vendor", "GPU name", "GPU driver", "GPU temperature", - "GPU core count" + "GPU core count", + "GPU type" ); } else if(strcasecmp(command, "memory-format") == 0) @@ -1246,6 +1247,10 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.gpuTemp = optionParseBoolean(value); else if(strcasecmp(key, "--battery-temp") == 0) instance->config.batteryTemp = optionParseBoolean(value); + else if(strcasecmp(key, "--gpu-hide-integrated") == 0) + instance->config.gpuHideIntegrated = optionParseBoolean(value); + else if(strcasecmp(key, "--gpu-hide-discrete") == 0) + instance->config.gpuHideDiscrete = optionParseBoolean(value); else if(strcasecmp(key, "--title-fqdn") == 0) instance->config.titleFQDN = optionParseBoolean(value); else if(strcasecmp(key, "--disk-folders") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index e215d3e3f..1c6316957 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -175,6 +175,9 @@ typedef struct FFconfig bool gpuTemp; bool batteryTemp; + bool gpuHideIntegrated; + bool gpuHideDiscrete; + bool titleFQDN; FFstrbuf diskFolders; diff --git a/src/modules/gpu.c b/src/modules/gpu.c index 0d0ae8266..a2daad515 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -6,13 +6,13 @@ #include #define FF_GPU_MODULE_NAME "GPU" -#define FF_GPU_NUM_FORMAT_ARGS 5 +#define FF_GPU_NUM_FORMAT_ARGS 6 -static void printGPUResult(FFinstance* instance, uint8_t index, FFGPUResult* gpu) +static void printGPUResult(FFinstance* instance, uint8_t index, const FFGPUResult* gpu) { if(instance->config.gpu.outputFormat.length == 0) { - ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu.key); + ffPrintLogoAndKey(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu.key); FFstrbuf output; ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); @@ -37,13 +37,24 @@ static void printGPUResult(FFinstance* instance, uint8_t index, FFGPUResult* gpu } else { + FFstrbuf type; + if(gpu->type == FF_GPU_TYPE_INTEGRATED) + ffStrbufInitS(&type, "Integrated"); + else if(gpu->type == FF_GPU_TYPE_DISCRETE) + ffStrbufInitS(&type, "Discrete"); + else + ffStrbufInitS(&type, "Unknown"); + ffPrintFormat(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->vendor}, {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->name}, {FF_FORMAT_ARG_TYPE_STRBUF, &gpu->driver}, {FF_FORMAT_ARG_TYPE_DOUBLE, &gpu->temperature}, {FF_FORMAT_ARG_TYPE_INT, &gpu->coreCount}, + {FF_FORMAT_ARG_TYPE_STRBUF, &type}, }); + + ffStrbufDestroy(&type); } } @@ -51,12 +62,27 @@ void ffPrintGPU(FFinstance* instance) { const FFlist* gpus = ffDetectGPU(instance); - if(gpus->length == 0) + FFlist selectedGpus; + ffListInitA(&selectedGpus, sizeof(const FFGPUResult*), gpus->length); + + for(uint32_t i = 0; i < gpus->length; i++) { - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found"); - return; + const FFGPUResult* gpu = ffListGet(gpus, i); + + if(gpu->type == FF_GPU_TYPE_INTEGRATED && instance->config.gpuHideIntegrated) + continue; + + if(gpu->type == FF_GPU_TYPE_DISCRETE && instance->config.gpuHideDiscrete) + continue; + + * (const FFGPUResult**) ffListAdd(&selectedGpus) = gpu; } - for(uint8_t i = 0; i < (uint8_t) gpus->length; i++) - printGPUResult(instance, gpus->length == 1 ? 0 : (uint8_t) (i + 1), ffListGet(gpus, i)); + for(uint32_t i = 0; i < selectedGpus.length; i++) + printGPUResult(instance, selectedGpus.length == 1 ? 0 : (uint8_t) (i + 1), * (const FFGPUResult**) ffListGet(&selectedGpus, i)); + + if(selectedGpus.length == 0) + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found"); + + ffListDestroy(&selectedGpus); }