Files
fastfetch/src/modules/gpu.c
T

161 lines
4.5 KiB
C
Raw Normal View History

2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
2021-04-09 14:07:05 +02:00
#include <string.h>
2021-02-28 17:38:26 +01:00
#include <dlfcn.h>
2021-04-09 14:07:05 +02:00
#include <pci/pci.h>
2021-02-18 22:25:36 +01:00
2021-04-03 21:51:50 +02:00
static void getKey(FFinstance* instance, FFstrbuf* key, uint8_t counter, bool showCounter)
2021-03-27 18:14:19 +01:00
{
2021-04-03 11:39:59 +02:00
if(instance->config.gpuKey.length == 0)
{
2021-04-03 21:51:50 +02:00
if(showCounter)
ffStrbufAppendF(key, "GPU %hhu", counter);
else
ffStrbufSetS(key, "GPU");
2021-04-03 11:39:59 +02:00
}
else
{
2021-04-03 21:51:50 +02:00
ffParseFormatString(key, &instance->config.gpuKey, 1,
(FFformatarg){FF_FORMAT_ARG_TYPE_UINT8, &counter}
2021-04-03 11:39:59 +02:00
);
}
2021-04-03 21:51:50 +02:00
}
static void handleGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...))
{
char cacheKey[8];
sprintf(cacheKey, "GPU%hhu", counter);
FF_STRBUF_CREATE(key);
getKey(instance, &key, counter, true);
2021-04-03 11:39:59 +02:00
if(ffPrintCachedValue(instance, &key, cacheKey))
2021-02-22 16:52:51 +01:00
return;
char vendor[512];
2021-02-28 17:38:26 +01:00
ffpci_lookup_name(pacc, vendor, sizeof(vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id);
2021-02-18 22:25:36 +01:00
2021-03-19 20:57:07 +01:00
char vendorPretty[512];
if(strcasecmp(vendor, "Advanced Micro Devices, Inc. [AMD/ATI]") == 0)
strcpy(vendorPretty, "AMD ATI");
else
strcpy(vendorPretty, vendor);
2021-02-22 16:52:51 +01:00
char name[512];
2021-02-28 17:38:26 +01:00
ffpci_lookup_name(pacc, name, sizeof(name), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
2021-02-18 22:25:36 +01:00
2021-04-03 12:14:25 +02:00
FFstrbuf gpu;
ffStrbufInitA(&gpu, 128);
2021-03-19 20:57:07 +01:00
2021-03-23 19:48:52 +01:00
if(instance->config.gpuFormat.length == 0)
2021-02-22 16:52:51 +01:00
{
2021-03-19 20:57:07 +01:00
ffStrbufSetF(&gpu, "%s %s", vendorPretty, name);
2021-02-22 16:52:51 +01:00
}
2021-02-18 22:25:36 +01:00
else
2021-02-22 16:52:51 +01:00
{
2021-03-27 18:14:19 +01:00
ffParseFormatString(&gpu, &instance->config.gpuFormat, 2,
2021-03-19 20:57:07 +01:00
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, vendorPretty},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name}
);
2021-02-22 16:52:51 +01:00
}
2021-04-03 11:39:59 +02:00
ffPrintAndSaveCachedValue(instance, &key, cacheKey, &gpu);
2021-04-03 21:51:50 +02:00
2021-03-19 20:57:07 +01:00
ffStrbufDestroy(&gpu);
2021-04-03 11:39:59 +02:00
ffStrbufDestroy(&key);
2021-02-18 22:25:36 +01:00
}
2021-02-27 18:30:05 +01:00
void ffPrintGPU(FFinstance* instance)
2021-02-18 22:25:36 +01:00
{
2021-04-03 21:51:50 +02:00
FF_STRBUF_CREATE(key);
getKey(instance, &key, 1, false);
2021-03-19 20:57:07 +01:00
void* pci;
2021-03-23 19:48:52 +01:00
if(instance->config.libPCI.length == 0)
2021-03-19 20:57:07 +01:00
pci = dlopen("libpci.so", RTLD_LAZY);
else
pci = dlopen(instance->config.libPCI.chars, RTLD_LAZY);
2021-04-05 23:42:07 +02:00
2021-02-28 17:38:26 +01:00
if(pci == NULL)
{
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlopen(\"libpci.so\", RTLD_LAZY) == NULL");
2021-02-28 17:38:26 +01:00
return;
}
struct pci_access*(*ffpci_alloc)() = dlsym(pci, "pci_alloc");
if(ffpci_alloc == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_alloc\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
void(*ffpci_init)(struct pci_access*) = dlsym(pci, "pci_init");
if(ffpci_init == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_init\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
void(*ffpci_scan_bus)(struct pci_access*) = dlsym(pci, "pci_scan_bus");
if(ffpci_scan_bus == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_init\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
int(*ffpci_fill_info)(struct pci_dev*, int) = dlsym(pci, "pci_fill_info");
if(ffpci_fill_info == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_fill_info\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...) = dlsym(pci, "pci_lookup_name");
if(ffpci_lookup_name == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_lookup_name\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
void(*ffpci_cleanup)(struct pci_access*) = dlsym(pci, "pci_cleanup");
if(ffpci_cleanup == NULL)
{
2021-04-05 23:42:07 +02:00
dlclose(pci);
2021-04-03 21:51:50 +02:00
ffPrintError(instance, &key, NULL, "dlsym(pci, \"pci_cleanup\") == NULL");
2021-02-28 17:38:26 +01:00
return;
}
2021-04-03 21:51:50 +02:00
uint8_t counter = 1;
2021-02-18 22:25:36 +01:00
struct pci_access *pacc;
struct pci_dev *dev;
2021-02-28 17:38:26 +01:00
pacc = ffpci_alloc();
ffpci_init(pacc);
ffpci_scan_bus(pacc);
2021-02-18 22:25:36 +01:00
for (dev=pacc->devices; dev; dev=dev->next)
{
2021-02-28 17:38:26 +01:00
ffpci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
2021-02-18 22:25:36 +01:00
char class[1024];
2021-02-28 17:38:26 +01:00
ffpci_lookup_name(pacc, class, sizeof(class), PCI_LOOKUP_CLASS, dev->device_class);
2021-02-18 22:25:36 +01:00
if(
2021-02-27 21:10:27 +01:00
strcasecmp("VGA compatible controller", class) == 0 ||
strcasecmp("3D controller", class) == 0 ||
strcasecmp("Display controller", class) == 0 )
2021-02-18 22:25:36 +01:00
{
2021-02-28 17:38:26 +01:00
handleGPU(instance, pacc, dev, counter++, ffpci_lookup_name);
2021-02-18 22:25:36 +01:00
}
}
2021-02-28 17:38:26 +01:00
ffpci_cleanup(pacc);
dlclose(pci);
2021-04-03 21:51:50 +02:00
if(counter == 1)
ffPrintError(instance, &key, NULL, "No GPU found");
2021-03-27 18:14:19 +01:00
}