diff --git a/CMakeLists.txt b/CMakeLists.txt index f23be3551..87a1f56bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,7 @@ set(LIBFASTFETCH_SRC src/detection/host/host.c src/detection/os/os.c src/detection/cpu/cpu.c + src/detection/gpu/gpu.c src/detection/memory/memory.c src/detection/displayserver/displayServer.c src/detection/displayserver/wayland.c @@ -219,6 +220,7 @@ if(APPLE) src/detection/host/host_apple.c src/detection/os/os_apple.c src/detection/cpu/cpu_apple.c + src/detection/gpu/gpu_apple.c src/detection/memory/memory_apple.c ) elseif(ANDROID) @@ -226,6 +228,7 @@ elseif(ANDROID) src/detection/host/host_android.c src/detection/os/os_android.c src/detection/cpu/cpu_linux.c + src/detection/gpu/gpu_android.c src/detection/memory/memory_linux.c ) elseif(UNIX) @@ -233,6 +236,7 @@ elseif(UNIX) src/detection/host/host_linux.c src/detection/os/os_linux.c src/detection/cpu/cpu_linux.c + src/detection/gpu/gpu_linux.c src/detection/memory/memory_linux.c ) else() diff --git a/src/common/format.c b/src/common/format.c index a8499d9f2..1b50145ba 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/format.h" +#include "common/parsing.h" void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) { @@ -63,11 +64,10 @@ static inline void appendEmptyPlaceholder(FFstrbuf* buffer, const char* placehol static inline bool formatArgSet(const FFformatarg* arg) { return arg->value != NULL && ( - (arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0) || - (arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value == *(double*)arg->value) || //NaN + (arg->type == FF_FORMAT_ARG_TYPE_DOUBLE && *(double*)arg->value > 0.0) || //Also is false for NaN (arg->type == FF_FORMAT_ARG_TYPE_INT && *(int*)arg->value > 0) || (arg->type == FF_FORMAT_ARG_TYPE_STRBUF && ((FFstrbuf*)arg->value)->length > 0) || - (arg->type == FF_FORMAT_ARG_TYPE_STRING && *(const char*)arg->value != '\0') || + (arg->type == FF_FORMAT_ARG_TYPE_STRING && ffStrSet(arg->value)) || (arg->type == FF_FORMAT_ARG_TYPE_UINT8 && *(uint8_t*)arg->value > 0) || (arg->type == FF_FORMAT_ARG_TYPE_UINT16 && *(uint16_t*)arg->value > 0) || (arg->type == FF_FORMAT_ARG_TYPE_UINT && *(uint32_t*)arg->value > 0) diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c new file mode 100644 index 000000000..5ff2870e5 --- /dev/null +++ b/src/detection/gpu/gpu.c @@ -0,0 +1,12 @@ +#include "gpu.h" +#include "detection/internal.h" + +void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance); + +const FFlist* ffDetectGPU(const FFinstance* instance) +{ + FF_DETECTION_INTERNAL_GUARD(FFlist, + ffListInit(&result, sizeof(FFGPUResult)); + ffDetectGPUImpl(&result, instance); + ); +} diff --git a/src/detection/gpu/gpu.h b/src/detection/gpu/gpu.h new file mode 100644 index 000000000..0b750b4e5 --- /dev/null +++ b/src/detection/gpu/gpu.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_gpu_gpu +#define FF_INCLUDED_detection_gpu_gpu + +#include "fastfetch.h" + +#define FF_GPU_TEMP_UNSET (0/0.0) + +typedef struct FFGPUResult +{ + FFstrbuf vendor; + FFstrbuf name; + FFstrbuf driver; + double temperature; +} FFGPUResult; + +const FFlist* ffDetectGPU(const FFinstance* instance); + +#endif diff --git a/src/detection/gpu/gpu_android.c b/src/detection/gpu/gpu_android.c new file mode 100644 index 000000000..9b07669a2 --- /dev/null +++ b/src/detection/gpu/gpu_android.c @@ -0,0 +1,6 @@ +#include "gpu.h" + +void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +{ + FF_UNUSED(gpus, instance); +} diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c new file mode 100644 index 000000000..9b07669a2 --- /dev/null +++ b/src/detection/gpu/gpu_apple.c @@ -0,0 +1,6 @@ +#include "gpu.h" + +void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +{ + FF_UNUSED(gpus, instance); +} diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c new file mode 100644 index 000000000..7b2f841b8 --- /dev/null +++ b/src/detection/gpu/gpu_linux.c @@ -0,0 +1,208 @@ +#include "gpu.h" +#include "detection/vulkan.h" + +#define FF_GPU_VENDOR_NAME_AMD "AMD" +#define FF_GPU_VENDOR_NAME_INTEL "Intel" +#define FF_GPU_VENDOR_NAME_NVIDIA "NVIDIA" + +#ifdef FF_HAVE_LIBPCI +#include "common/library.h" +#include "common/properties.h" +#include "common/parsing.h" +#include "detection/temps.h" +#include +#include +#include + +typedef struct PCIData +{ + struct pci_access* access; + FF_LIBRARY_SYMBOL(pci_read_byte); + FF_LIBRARY_SYMBOL(pci_read_word); + FF_LIBRARY_SYMBOL(pci_lookup_name); + FF_LIBRARY_SYMBOL(pci_get_param); +} PCIData; + +static bool pciIDsContains(u16 searched, const u16* ids) +{ + while(*ids != 0) + { + if(*ids == searched) + return true; + ids++; + } + return false; +} + +static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + if(pciIDsContains(device->vendor_id, (const u16[]) {0x1002, 0x1022, 0})) + ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); + else if(pciIDsContains(device->vendor_id, (const u16[]) {0x03e7, 0x8086, 0x8087, 0})) + ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL); + else if(pciIDsContains(device->vendor_id, (const u16[]) {0x0955, 0x10de, 0x12d2, 0})) + ffStrbufAppendS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); + + if(gpu->vendor.length > 0) + return; + + pci->ffpci_lookup_name(pci->access, gpu->vendor.chars, (int) ffStrbufGetFree(&gpu->vendor), PCI_LOOKUP_VENDOR, device->vendor_id); + ffStrbufRecalculateLength(&gpu->vendor); + + if(ffStrbufFirstIndexS(&gpu->vendor, "AMD") < gpu->vendor.length || ffStrbufFirstIndexS(&gpu->vendor, "ATI") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD); + else if(ffStrbufFirstIndexS(&gpu->vendor, "Intel") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_INTEL); + else if(ffStrbufFirstIndexS(&gpu->vendor, "NVIDIA") < gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, FF_GPU_VENDOR_NAME_NVIDIA); +} + +static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + FFstrbuf query; + ffStrbufInit(&query); + ffStrbufAppendF(&query, "%X, %X,", device->device_id, pci->ffpci_read_byte(device, PCI_REVISION_ID)); + + ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/libdrm/amdgpu.ids", query.chars, &gpu->name); + + ffStrbufDestroy(&query); + + const char* removeStrings[] = { + "AMD ", "ATI ", + " (TM)", "(TM)", + " Graphics Adapter", " Graphics", " Series", " Edition" + }; + ffStrbufRemoveStringsA(&gpu->name, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); +} + +static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + if(ffStrbufCompS(&gpu->vendor, FF_GPU_VENDOR_NAME_AMD) == 0) + { + drmDetectDeviceName(gpu, pci, device); + if(gpu->name.length > 0) + return; + } + + pci->ffpci_lookup_name(pci->access, gpu->name.chars, (int) ffStrbufGetFree(&gpu->name), PCI_LOOKUP_DEVICE, device->vendor_id, device->device_id); + ffStrbufRecalculateLength(&gpu->name); +} + +static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) +{ + const char* base = pci->ffpci_get_param(pci->access, "sysfs.path"); + if(!ffStrSet(base)) + return; + + FFstrbuf path; + ffStrbufInitA(&path, 64); + ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); + + ffStrbufEnsureFree(&gpu->driver, 1023); + ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator + if(resultLength > 0) + { + gpu->driver.length = (uint32_t) resultLength; + gpu->driver.chars[resultLength] = '\0'; + ffStrbufSubstrAfterLastC(&gpu->driver, '/'); + } + + ffStrbufDestroy(&path); +} + +static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) +{ + const FFTempsResult* tempsResult = ffDetectTemps(); + + for(uint32_t i = 0; i < tempsResult->values.length; i++) + { + FFTempValue* tempValue = ffListGet(&tempsResult->values, i); + + uint32_t tempClass; + if(sscanf(tempValue->deviceClass.chars, "%x", &tempClass) != 1) + continue; + + //The kernel exposes the device class multiplied by 256 for some reason + if(tempClass == device->device_class * 256) + { + gpu->temperature = tempValue->value; + return; + } + } +} + +static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* device) +{ + device->device_class = pci->ffpci_read_word(device, PCI_CLASS_DEVICE); + + char class[1024]; + pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class); + + if( + strcasecmp("VGA compatible controller", class) != 0 && + strcasecmp("3D controller", class) != 0 && + strcasecmp("Display controller", class) != 0 + ) return; + + device->vendor_id = pci->ffpci_read_word(device, PCI_VENDOR_ID); + device->device_id = pci->ffpci_read_word(device, PCI_DEVICE_ID); + + FFGPUResult* gpu = ffListAdd(results); + + ffStrbufInit(&gpu->vendor); + pciDetectVendorName(gpu, pci, device); + + ffStrbufInit(&gpu->name); + pciDetectDeviceName(gpu, pci, device); + + ffStrbufInit(&gpu->driver); + pciDetectDriverName(gpu, pci, device); + + gpu->temperature = FF_GPU_TEMP_UNSET; + pciDetectTemperatur(gpu, device); +} + +static bool pciDetectGPUs(const FFinstance* instance, FFlist* gpus) +{ + PCIData pci; + + FF_LIBRARY_LOAD(libpci, instance->config.libPCI, false, "libpci.so", 4) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, false) + FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, false) + + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_byte, pci_read_byte, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_word, pci_read_word, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_lookup_name, pci_lookup_name, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_get_param, pci_get_param, false) + + pci.access = ffpci_alloc(); + ffpci_init(pci.access); + ffpci_scan_bus(pci.access); + + struct pci_dev* device = pci.access->devices; + while(device != NULL) + { + pciHandleDevice(gpus, &pci, device); + device = device->next; + } + + ffpci_cleanup(pci.access); + dlclose(libpci); + + return gpus->length > 0; +} + +#endif + +void ffDetectGPUImpl(FFlist* gpus, const FFinstance* instance) +{ + #ifdef FF_HAVE_LIBPCI + if(pciDetectGPUs(instance, gpus)) + return; + #endif + + const FFVulkanResult* vulkan = ffDetectVulkan(instance); + *gpus = vulkan->gpus; +} diff --git a/src/detection/vulkan.c b/src/detection/vulkan.c index 4eb49f4c7..48e9c636e 100644 --- a/src/detection/vulkan.c +++ b/src/detection/vulkan.c @@ -7,6 +7,7 @@ #include "common/library.h" #include "common/io.h" #include "common/parsing.h" +#include "detection/gpu/gpu.h" #include #include @@ -175,12 +176,15 @@ static void detectVulkan(const FFinstance* instance, FFVulkanResult* result) if(physicalDeviceProperties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) continue; - FFGPUResult* gpu = ffListAdd(&result->devices); + FFGPUResult* gpu = ffListAdd(&result->gpus); + + ffStrbufInit(&gpu->name); + ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName); + + //No way to detect those using vulkan ffStrbufInit(&gpu->vendor); - ffStrbufInit(&gpu->device); ffStrbufInit(&gpu->driver); - gpu->temperature = 0.0 / 0.0; //NaN, no way to detect temperature using vulkan - ffStrbufAppendS(&gpu->device, physicalDeviceProperties.properties.deviceName); + gpu->temperature = FF_GPU_TEMP_UNSET; } //If the highest device version is lower than the instance version, use it as our vulkan version @@ -218,7 +222,7 @@ const FFVulkanResult* ffDetectVulkan(const FFinstance* instance) ffStrbufInit(&result.driver); ffStrbufInit(&result.apiVersion); ffStrbufInit(&result.conformanceVersion); - ffListInit(&result.devices, sizeof(FFGPUResult)); + ffListInit(&result.gpus, sizeof(FFGPUResult)); #ifdef FF_HAVE_VULKAN detectVulkan(instance, &result); diff --git a/src/detection/vulkan.h b/src/detection/vulkan.h index ebc0c7eba..64db1b844 100644 --- a/src/detection/vulkan.h +++ b/src/detection/vulkan.h @@ -5,22 +5,12 @@ #include "fastfetch.h" -#define FF_GPU_TEMP_UNSET (0/0.0) - -typedef struct FFGPUResult -{ - FFstrbuf vendor; - FFstrbuf device; - FFstrbuf driver; - double temperature; -} FFGPUResult; - typedef struct FFVulkanResult { FFstrbuf driver; FFstrbuf apiVersion; FFstrbuf conformanceVersion; - FFlist devices; //List of FFGPUResult + FFlist gpus; //List of FFGPUResult, see detection/gpu/gpu.h } FFVulkanResult; const FFVulkanResult* ffDetectVulkan(const FFinstance* instance); diff --git a/src/modules/gpu.c b/src/modules/gpu.c index a6e087bf1..599843e00 100644 --- a/src/modules/gpu.c +++ b/src/modules/gpu.c @@ -1,265 +1,35 @@ #include "fastfetch.h" #include "common/printing.h" #include "common/caching.h" -#include "common/parsing.h" -#include "common/properties.h" -#include "detection/temps.h" -#include "detection/vulkan.h" #include "detection/host/host.h" +#include "detection/gpu/gpu.h" #include #define FF_GPU_MODULE_NAME "GPU" #define FF_GPU_NUM_FORMAT_ARGS 4 -#define FF_PCI_VENDOR_NAME_AMD "AMD" -#define FF_PCI_VENDOR_NAME_INTEL "Intel" -#define FF_PCI_VENDOR_NAME_NVIDIA "NVIDIA" - -static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* result) +static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* gpu) { - FFstrbuf gpu; - ffStrbufInitA(&gpu, result->vendor.length + 1 + result->device.length); - - if(result->vendor.length > 0) - { - ffStrbufAppend(&gpu, &result->vendor); - ffStrbufAppendC(&gpu, ' '); - } - - ffStrbufAppend(&gpu, &result->device); - - ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, cache, &gpu, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->device}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->driver}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature} - }); - - ffStrbufDestroy(&gpu); -} - -static void printGPUList(FFinstance* instance, const FFlist* list) -{ - FFcache cache; - ffCacheOpenWrite(instance, FF_GPU_MODULE_NAME, &cache); - - for(uint8_t i = 0; i < (uint8_t) list->length; i++) - printGPUResult(instance, list->length == 1 ? 0 : (uint8_t) (i + 1), &cache, ffListGet(list, i)); - - ffCacheClose(&cache); -} - -#ifdef FF_HAVE_LIBPCI -#include "common/library.h" -#include -#include -#include - -typedef struct PCIData -{ - struct pci_access* access; - FF_LIBRARY_SYMBOL(pci_read_byte); - FF_LIBRARY_SYMBOL(pci_read_word); - FF_LIBRARY_SYMBOL(pci_lookup_name); - FF_LIBRARY_SYMBOL(pci_get_param); -} PCIData; - -static bool pciIDsContains(u16 searched, const u16* ids) -{ - while(*ids != 0) - { - if(*ids == searched) - return true; - ids++; - } - return false; -} - -static void pciDetectVendorName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) -{ - if(pciIDsContains(device->vendor_id, (const u16[]) {0x1002, 0x1022, 0})) - ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD); - else if(pciIDsContains(device->vendor_id, (const u16[]) {0x03e7, 0x8086, 0x8087, 0})) - ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_INTEL); - else if(pciIDsContains(device->vendor_id, (const u16[]) {0x0955, 0x10de, 0x12d2, 0})) - ffStrbufAppendS(&gpu->vendor, FF_PCI_VENDOR_NAME_NVIDIA); + FFstrbuf output; + ffStrbufInitA(&output, gpu->vendor.length + 1 + gpu->name.length); if(gpu->vendor.length > 0) - return; - - pci->ffpci_lookup_name(pci->access, gpu->vendor.chars, (int) ffStrbufGetFree(&gpu->vendor), PCI_LOOKUP_VENDOR, device->vendor_id); - ffStrbufRecalculateLength(&gpu->vendor); - - if(ffStrbufFirstIndexS(&gpu->vendor, "AMD") < gpu->vendor.length || ffStrbufFirstIndexS(&gpu->vendor, "ATI") < gpu->vendor.length) - ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD); - else if(ffStrbufFirstIndexS(&gpu->vendor, "Intel") < gpu->vendor.length) - ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_INTEL); - else if(ffStrbufFirstIndexS(&gpu->vendor, "NVIDIA") < gpu->vendor.length) - ffStrbufSetS(&gpu->vendor, FF_PCI_VENDOR_NAME_NVIDIA); -} - -static void drmDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) -{ - FFstrbuf query; - ffStrbufInit(&query); - ffStrbufAppendF(&query, "%X, %X,", device->device_id, pci->ffpci_read_byte(device, PCI_REVISION_ID)); - - ffParsePropFile(FASTFETCH_TARGET_DIR_USR"/share/libdrm/amdgpu.ids", query.chars, &gpu->device); - - ffStrbufDestroy(&query); - - const char* removeStrings[] = { - "AMD ", "ATI ", - " (TM)", "(TM)", - " Graphics Adapter", " Graphics", " Series", " Edition" - }; - ffStrbufRemoveStringsA(&gpu->device, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings); -} - -static void pciDetectDeviceName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) -{ - if(ffStrbufCompS(&gpu->vendor, FF_PCI_VENDOR_NAME_AMD) == 0) { - drmDetectDeviceName(gpu, pci, device); - if(gpu->device.length > 0) - return; + ffStrbufAppend(&output, &gpu->vendor); + ffStrbufAppendC(&output, ' '); } - pci->ffpci_lookup_name(pci->access, gpu->device.chars, (int) ffStrbufGetFree(&gpu->device), PCI_LOOKUP_DEVICE, device->vendor_id, device->device_id); - ffStrbufRecalculateLength(&gpu->device); -} + ffStrbufAppend(&output, &gpu->name); -static void pciDetectDriverName(FFGPUResult* gpu, PCIData* pci, struct pci_dev* device) -{ - const char* base = pci->ffpci_get_param(pci->access, "sysfs.path"); - if(!ffStrSet(base)) - return; + ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpu, cache, &output, 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} + }); - FFstrbuf path; - ffStrbufInitA(&path, 64); - ffStrbufAppendF(&path, "%s/devices/%04x:%02x:%02x.%d/driver", base, device->domain, device->bus, device->dev, device->func); - - ffStrbufEnsureFree(&gpu->driver, 1023); - ssize_t resultLength = readlink(path.chars, gpu->driver.chars, gpu->driver.allocated - 1); //-1 for null terminator - if(resultLength > 0) - { - gpu->driver.length = (uint32_t) resultLength; - gpu->driver.chars[resultLength] = '\0'; - ffStrbufSubstrAfterLastC(&gpu->driver, '/'); - } - - ffStrbufDestroy(&path); -} - -static void pciDetectTemperatur(FFGPUResult* gpu, struct pci_dev* device) -{ - const FFTempsResult* tempsResult = ffDetectTemps(); - - for(uint32_t i = 0; i < tempsResult->values.length; i++) - { - FFTempValue* tempValue = ffListGet(&tempsResult->values, i); - - uint32_t tempClass; - if(sscanf(tempValue->deviceClass.chars, "%x", &tempClass) != 1) - continue; - - //The kernel exposes the device class multiplied by 256 for some reason - if(tempClass == device->device_class * 256) - { - gpu->temperature = tempValue->value; - return; - } - } -} - -static void pciHandleDevice(FFlist* results, PCIData* pci, struct pci_dev* device) -{ - device->device_class = pci->ffpci_read_word(device, PCI_CLASS_DEVICE); - - char class[1024]; - pci->ffpci_lookup_name(pci->access, class, sizeof(class) - 1, PCI_LOOKUP_CLASS, device->device_class); - - if( - strcasecmp("VGA compatible controller", class) != 0 && - strcasecmp("3D controller", class) != 0 && - strcasecmp("Display controller", class) != 0 - ) return; - - device->vendor_id = pci->ffpci_read_word(device, PCI_VENDOR_ID); - device->device_id = pci->ffpci_read_word(device, PCI_DEVICE_ID); - - FFGPUResult* gpu = ffListAdd(results); - - ffStrbufInit(&gpu->vendor); - pciDetectVendorName(gpu, pci, device); - - ffStrbufInit(&gpu->device); - pciDetectDeviceName(gpu, pci, device); - - ffStrbufInit(&gpu->driver); - pciDetectDriverName(gpu, pci, device); - - gpu->temperature = FF_GPU_TEMP_UNSET; - pciDetectTemperatur(gpu, device); -} - -static bool pciPrintGPUs(FFinstance* instance) -{ - PCIData pci; - - FF_LIBRARY_LOAD(libpci, instance->config.libPCI, false, "libpci.so", 4) - FF_LIBRARY_LOAD_SYMBOL(libpci, pci_alloc, false) - FF_LIBRARY_LOAD_SYMBOL(libpci, pci_init, false) - FF_LIBRARY_LOAD_SYMBOL(libpci, pci_scan_bus, false) - FF_LIBRARY_LOAD_SYMBOL(libpci, pci_cleanup, false) - - FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_byte, pci_read_byte, false) - FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_read_word, pci_read_word, false) - FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_lookup_name, pci_lookup_name, false) - FF_LIBRARY_LOAD_SYMBOL_ADRESS(libpci, pci.ffpci_get_param, pci_get_param, false) - - FFlist results; - ffListInit(&results, sizeof(FFGPUResult)); - - pci.access = ffpci_alloc(); - ffpci_init(pci.access); - ffpci_scan_bus(pci.access); - - struct pci_dev* device = pci.access->devices; - while(device != NULL) - { - pciHandleDevice(&results, &pci, device); - device = device->next; - } - - ffpci_cleanup(pci.access); - dlclose(libpci); - - printGPUList(instance, &results); - - for(uint32_t i = 0; i < results.length; i++) - { - FFGPUResult* gpu = ffListGet(&results, i); - ffStrbufDestroy(&gpu->vendor); - ffStrbufDestroy(&gpu->device); - ffStrbufDestroy(&gpu->driver); - } - - ffListDestroy(&results); - return results.length > 0; -} - -#endif - -static bool vulkanPrintGPUs(FFinstance* instance) -{ - const FFVulkanResult* result = ffDetectVulkan(instance); - if(result->devices.length == 0) - return false; - - printGPUList(instance, &result->devices); - return true; + ffStrbufDestroy(&output); } void ffPrintGPU(FFinstance* instance) @@ -273,13 +43,19 @@ void ffPrintGPU(FFinstance* instance) return; } - #ifdef FF_HAVE_LIBPCI - if(pciPrintGPUs(instance)) - return; - #endif + const FFlist* gpus = ffDetectGPU(instance); - if(vulkanPrintGPUs(instance)) + if(gpus->length == 0) + { + ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found"); return; + } - ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpu, "No GPUs found."); + FFcache cache; + ffCacheOpenWrite(instance, FF_GPU_MODULE_NAME, &cache); + + for(uint8_t i = 0; i < (uint8_t) gpus->length; i++) + printGPUResult(instance, gpus->length == 1 ? 0 : (uint8_t) (i + 1), &cache, ffListGet(gpus, i)); + + ffCacheClose(&cache); }