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-15 18:59:26 +02:00
|
|
|
#define FF_GPU_MODULE_NAME "GPU"
|
2021-05-07 17:10:22 +02:00
|
|
|
#define FF_GPU_NUM_FORMAT_ARGS 4
|
2021-04-03 21:51:50 +02:00
|
|
|
|
2021-05-08 17:18:59 +02:00
|
|
|
static void printGPU(FFinstance* instance, struct pci_access* pacc, struct pci_dev* dev, FFcache* cache, uint8_t counter, char*(*ffpci_lookup_name)(struct pci_access*, char*, int, int, ...))
|
2021-04-03 21:51:50 +02:00
|
|
|
{
|
2021-02-22 16:52:51 +01:00
|
|
|
char vendor[512];
|
2021-05-07 17:10:22 +02:00
|
|
|
vendor[0] = '\0';
|
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-04-15 18:59:26 +02:00
|
|
|
const char* vendorPretty;
|
2021-03-19 20:57:07 +01:00
|
|
|
if(strcasecmp(vendor, "Advanced Micro Devices, Inc. [AMD/ATI]") == 0)
|
2021-04-15 18:59:26 +02:00
|
|
|
vendorPretty = "AMD ATI";
|
|
|
|
|
else if(strcasecmp(vendor, "NVIDIA Corporation") == 0)
|
|
|
|
|
vendorPretty = "Nvidia";
|
|
|
|
|
else if(strcasecmp(vendor, "Intel Corporation") == 0)
|
|
|
|
|
vendorPretty = "Intel";
|
2021-03-19 20:57:07 +01:00
|
|
|
else
|
2021-04-15 18:59:26 +02:00
|
|
|
vendorPretty = vendor;
|
2021-03-19 20:57:07 +01:00
|
|
|
|
2021-02-22 16:52:51 +01:00
|
|
|
char name[512];
|
2021-05-07 17:10:22 +02:00
|
|
|
name[0] = '\0';
|
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-05-07 17:10:22 +02:00
|
|
|
FFstrbuf namePretty;
|
|
|
|
|
ffStrbufInitA(&namePretty, 512);
|
|
|
|
|
ffStrbufAppendS(&namePretty, name);
|
|
|
|
|
ffStrbufSubstrBeforeLastC(&namePretty, ']');
|
|
|
|
|
ffStrbufSubstrAfterFirstC(&namePretty, '[');
|
|
|
|
|
|
2021-04-03 12:14:25 +02:00
|
|
|
FFstrbuf gpu;
|
|
|
|
|
ffStrbufInitA(&gpu, 128);
|
2021-03-19 20:57:07 +01:00
|
|
|
|
2021-05-07 17:10:22 +02:00
|
|
|
ffStrbufSetF(&gpu, "%s %s", vendorPretty, namePretty.chars);
|
2021-02-22 16:52:51 +01:00
|
|
|
|
2021-04-15 18:59:26 +02:00
|
|
|
ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, counter, &instance->config.gpuKey, cache, &gpu, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){
|
|
|
|
|
{FF_FORMAT_ARG_TYPE_STRING, vendor},
|
|
|
|
|
{FF_FORMAT_ARG_TYPE_STRING, vendorPretty},
|
2021-05-07 17:10:22 +02:00
|
|
|
{FF_FORMAT_ARG_TYPE_STRING, name},
|
|
|
|
|
{FF_FORMAT_ARG_TYPE_STRBUF, &namePretty}
|
2021-04-15 18:59:26 +02:00
|
|
|
});
|
2021-04-03 21:51:50 +02:00
|
|
|
|
2021-03-19 20:57:07 +01:00
|
|
|
ffStrbufDestroy(&gpu);
|
2021-05-07 17:10:22 +02:00
|
|
|
ffStrbufDestroy(&namePretty);
|
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-15 18:59:26 +02:00
|
|
|
if(ffPrintFromCache(instance, FF_GPU_MODULE_NAME, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS))
|
|
|
|
|
return;
|
2021-04-03 21:51:50 +02:00
|
|
|
|
2021-05-16 15:10:15 +02:00
|
|
|
const char* pciLibName = instance->config.libPCI.length == 0 ? "libpci.so" : instance->config.libPCI.chars;
|
|
|
|
|
void* pci = dlopen(pciLibName, RTLD_LAZY);
|
2021-02-28 17:38:26 +01:00
|
|
|
if(pci == NULL)
|
|
|
|
|
{
|
2021-05-16 15:10:15 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlopen(\"%s\", RTLD_LAZY) == NULL", pciLibName);
|
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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "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-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "dlsym(pci, \"pci_cleanup\") == NULL");
|
2021-02-28 17:38:26 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-08 17:18:59 +02:00
|
|
|
struct pci_access *pacc = ffpci_alloc();
|
|
|
|
|
ffpci_init(pacc);
|
|
|
|
|
ffpci_scan_bus(pacc);
|
|
|
|
|
|
|
|
|
|
FFlist devices;
|
|
|
|
|
ffListInitA(&devices, sizeof(struct pci_dev*), 4);
|
2021-02-18 22:25:36 +01:00
|
|
|
|
2021-04-15 18:59:26 +02:00
|
|
|
FFcache cache;
|
|
|
|
|
ffCacheOpenWrite(instance, FF_GPU_MODULE_NAME, &cache);
|
|
|
|
|
|
2021-05-08 17:18:59 +02:00
|
|
|
struct pci_dev* dev;
|
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 ||
|
2021-05-08 17:18:59 +02:00
|
|
|
strcasecmp("Display controller", class) == 0
|
|
|
|
|
) *(struct pci_dev**)ffListAdd(&devices) = dev;
|
2021-02-18 22:25:36 +01:00
|
|
|
}
|
2021-03-03 19:59:39 +01:00
|
|
|
|
2021-05-08 17:18:59 +02:00
|
|
|
for(uint32_t i = 0; i < devices.length; i++)
|
|
|
|
|
printGPU(instance, pacc, *(struct pci_dev**)ffListGet(&devices, i), &cache, devices.length == 1 ? 0 : i + 1, ffpci_lookup_name);
|
2021-04-03 21:51:50 +02:00
|
|
|
|
2021-05-08 17:18:59 +02:00
|
|
|
if(devices.length == 0)
|
2021-04-15 18:59:26 +02:00
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "No GPU found");
|
2021-05-08 17:18:59 +02:00
|
|
|
|
|
|
|
|
ffCacheClose(&cache);
|
|
|
|
|
ffListDestroy(&devices);
|
|
|
|
|
ffpci_cleanup(pacc);
|
|
|
|
|
dlclose(pci);
|
2021-03-27 18:14:19 +01:00
|
|
|
}
|