2021-02-18 22:25:36 +01:00
|
|
|
#include "fastfetch.h"
|
|
|
|
|
|
2021-04-09 14:07:05 +02:00
|
|
|
#include <string.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-11-13 18:25:35 +01:00
|
|
|
typedef struct GPUResult
|
|
|
|
|
{
|
|
|
|
|
FFstrbuf vendor;
|
|
|
|
|
FFstrbuf name;
|
|
|
|
|
} GPUResult;
|
2021-10-19 18:44:59 +02:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
#ifdef FF_HAVE_VULKAN
|
|
|
|
|
#include <vulkan/vulkan.h>
|
|
|
|
|
|
|
|
|
|
static void vulkanFillGPUs(FFinstance* instance, FFlist* results)
|
2021-10-19 18:44:59 +02:00
|
|
|
{
|
2021-11-13 18:25:35 +01:00
|
|
|
FF_LIBRARY_LOAD(vulkan, "libvulkan.so", instance->config.libVulkan,)
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(vulkan, vkCreateInstance,)
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(vulkan, vkDestroyInstance,)
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(vulkan, vkEnumeratePhysicalDevices,)
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(vulkan, vkGetPhysicalDeviceProperties,)
|
|
|
|
|
|
2021-12-15 15:42:33 +01:00
|
|
|
//Some drivers (nvdc) print messages to stdout
|
|
|
|
|
//and thats the best way i found to disable that
|
2021-12-15 19:12:07 +01:00
|
|
|
ffSuppressIO(true);
|
2021-12-15 15:42:33 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
const VkApplicationInfo applicationInfo = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
|
|
|
|
.pNext = NULL,
|
|
|
|
|
.pApplicationName = FASTFETCH_PROJECT_NAME,
|
2021-11-13 18:43:33 +01:00
|
|
|
.applicationVersion = VK_MAKE_VERSION(FASTFETCH_PROJECT_VERSION_MAJOR, 0, 0),
|
2021-11-13 18:25:35 +01:00
|
|
|
.pEngineName = "vulkanPrintGPUs",
|
2021-11-13 18:43:33 +01:00
|
|
|
.engineVersion = VK_MAKE_VERSION(FASTFETCH_PROJECT_VERSION_MAJOR, 0, 0),
|
2021-11-13 18:25:35 +01:00
|
|
|
.apiVersion = VK_API_VERSION_1_0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const VkInstanceCreateInfo instanceCreateInfo = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
|
|
|
|
.pNext = NULL,
|
|
|
|
|
.pApplicationInfo = &applicationInfo,
|
|
|
|
|
.enabledLayerCount = 0,
|
|
|
|
|
.ppEnabledLayerNames = NULL,
|
|
|
|
|
.enabledExtensionCount = 0,
|
|
|
|
|
.ppEnabledExtensionNames = NULL,
|
|
|
|
|
.flags = 0
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkInstance vkInstance;
|
|
|
|
|
if(ffvkCreateInstance(&instanceCreateInfo, NULL, &vkInstance) != VK_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
dlclose(vulkan);
|
2021-12-15 19:12:07 +01:00
|
|
|
ffSuppressIO(false);
|
2021-11-13 18:25:35 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t physicalDeviceCount;
|
|
|
|
|
if(ffvkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, NULL) != VK_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
ffvkDestroyInstance(vkInstance, NULL);
|
|
|
|
|
dlclose(vulkan);
|
2021-12-15 19:12:07 +01:00
|
|
|
ffSuppressIO(false);
|
2021-11-13 18:25:35 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkPhysicalDevice* physicalDevices = malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
|
|
|
|
|
if(ffvkEnumeratePhysicalDevices(vkInstance, &physicalDeviceCount, physicalDevices) != VK_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
free(physicalDevices);
|
|
|
|
|
ffvkDestroyInstance(vkInstance, NULL);
|
|
|
|
|
dlclose(vulkan);
|
2021-12-15 19:12:07 +01:00
|
|
|
ffSuppressIO(false);
|
2021-11-13 18:25:35 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < physicalDeviceCount; i++)
|
|
|
|
|
{
|
|
|
|
|
VkPhysicalDeviceProperties physicalDeviceProperties;
|
|
|
|
|
ffvkGetPhysicalDeviceProperties(physicalDevices[i], &physicalDeviceProperties);
|
|
|
|
|
|
|
|
|
|
//We don't want softare rasterizers
|
|
|
|
|
if(physicalDeviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
GPUResult* result = ffListAdd(results);
|
|
|
|
|
ffStrbufInit(&result->vendor);
|
|
|
|
|
ffStrbufInit(&result->name);
|
|
|
|
|
|
|
|
|
|
ffStrbufAppendS(&result->name, physicalDeviceProperties.deviceName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(physicalDevices);
|
|
|
|
|
ffvkDestroyInstance(vkInstance, NULL);
|
|
|
|
|
dlclose(vulkan);
|
2021-12-15 19:12:07 +01:00
|
|
|
ffSuppressIO(false);
|
2021-11-13 18:25:35 +01:00
|
|
|
return;
|
2021-10-19 18:44:59 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
#endif
|
2021-10-19 18:44:59 +02:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
#ifdef FF_HAVE_LIBPCI
|
2021-10-19 18:44:59 +02:00
|
|
|
#include <pci/pci.h>
|
|
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
static void pciFillGPUs(FFinstance* instance, FFlist* results)
|
2021-04-03 21:51:50 +02:00
|
|
|
{
|
2021-11-13 18:25:35 +01:00
|
|
|
FF_LIBRARY_LOAD(pci, "libpci.so", instance->config.libPCI,)
|
|
|
|
|
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(pci, pci_alloc,)
|
|
|
|
|
FF_LIBRARY_LOAD_SYMBOL(pci, pci_init,)
|
|
|
|
|
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_cleanup,)
|
2021-02-18 22:25:36 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
struct pci_access *pacc = ffpci_alloc();
|
|
|
|
|
ffpci_init(pacc);
|
|
|
|
|
ffpci_scan_bus(pacc);
|
|
|
|
|
|
|
|
|
|
struct pci_dev* dev;
|
|
|
|
|
for (dev=pacc->devices; dev; dev=dev->next)
|
|
|
|
|
{
|
|
|
|
|
ffpci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS);
|
|
|
|
|
char class[1024];
|
|
|
|
|
ffpci_lookup_name(pacc, class, sizeof(class), PCI_LOOKUP_CLASS, dev->device_class);
|
|
|
|
|
if(
|
|
|
|
|
strcasecmp("VGA compatible controller", class) == 0 ||
|
|
|
|
|
strcasecmp("3D controller", class) == 0 ||
|
|
|
|
|
strcasecmp("Display controller", class) == 0
|
|
|
|
|
) {
|
|
|
|
|
GPUResult* result = ffListAdd(results);
|
|
|
|
|
|
|
|
|
|
ffStrbufInitA(&result->vendor, 256);
|
2021-11-17 18:38:57 +01:00
|
|
|
ffpci_lookup_name(pacc, result->vendor.chars, (int) result->vendor.allocated -1, PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id);
|
2021-11-13 18:25:35 +01:00
|
|
|
ffStrbufRecalculateLength(&result->vendor);
|
|
|
|
|
|
|
|
|
|
ffStrbufInitA(&result->name, 256);
|
2021-11-17 18:38:57 +01:00
|
|
|
ffpci_lookup_name(pacc, result->name.chars, (int) result->name.allocated - 1, PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
|
2021-11-13 18:25:35 +01:00
|
|
|
ffStrbufRecalculateLength(&result->name);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ffpci_cleanup(pacc);
|
|
|
|
|
dlclose(pci);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, GPUResult* result)
|
|
|
|
|
{
|
2021-04-15 18:59:26 +02:00
|
|
|
const char* vendorPretty;
|
2021-11-13 18:25:35 +01:00
|
|
|
if(ffStrbufIgnCaseCompS(&result->vendor, "Advanced Micro Devices, Inc. [AMD/ATI]") == 0)
|
2021-04-15 18:59:26 +02:00
|
|
|
vendorPretty = "AMD ATI";
|
2021-11-13 18:25:35 +01:00
|
|
|
else if(ffStrbufIgnCaseCompS(&result->vendor, "NVIDIA Corporation") == 0)
|
2021-04-15 18:59:26 +02:00
|
|
|
vendorPretty = "Nvidia";
|
2021-11-13 18:25:35 +01:00
|
|
|
else if(ffStrbufIgnCaseCompS(&result->vendor, "Intel Corporation") == 0)
|
2021-04-15 18:59:26 +02:00
|
|
|
vendorPretty = "Intel";
|
2021-03-19 20:57:07 +01:00
|
|
|
else
|
2021-11-13 18:25:35 +01:00
|
|
|
vendorPretty = result->vendor.chars;
|
2021-02-18 22:25:36 +01:00
|
|
|
|
2021-05-07 17:10:22 +02:00
|
|
|
FFstrbuf namePretty;
|
2021-11-13 18:25:35 +01:00
|
|
|
ffStrbufInitCopy(&namePretty, &result->name);
|
2021-05-07 17:10:22 +02:00
|
|
|
ffStrbufSubstrBeforeLastC(&namePretty, ']');
|
|
|
|
|
ffStrbufSubstrAfterFirstC(&namePretty, '[');
|
|
|
|
|
|
2021-04-03 12:14:25 +02:00
|
|
|
FFstrbuf gpu;
|
2021-11-13 18:25:35 +01:00
|
|
|
ffStrbufInitA(&gpu, result->vendor.length + namePretty.length);
|
|
|
|
|
|
|
|
|
|
if(*vendorPretty != '\0')
|
|
|
|
|
{
|
|
|
|
|
ffStrbufAppendS(&gpu, vendorPretty);
|
|
|
|
|
ffStrbufAppendC(&gpu, ' ');
|
|
|
|
|
}
|
2021-03-19 20:57:07 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
ffStrbufAppend(&gpu, &namePretty);
|
2021-02-22 16:52:51 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
ffPrintAndAppendToCache(instance, FF_GPU_MODULE_NAME, index, &instance->config.gpuKey, cache, &gpu, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, (FFformatarg[]){
|
|
|
|
|
{FF_FORMAT_ARG_TYPE_STRBUF, &result->vendor},
|
2021-04-15 18:59:26 +02:00
|
|
|
{FF_FORMAT_ARG_TYPE_STRING, vendorPretty},
|
2021-11-13 18:25:35 +01:00
|
|
|
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name},
|
2021-05-07 17:10:22 +02:00
|
|
|
{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-11-13 18:25:35 +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))
|
2021-11-13 18:25:35 +01:00
|
|
|
return;
|
2021-02-28 17:38:26 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
FFlist gpus;
|
|
|
|
|
ffListInitA(&gpus, sizeof(GPUResult), 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-11-13 18:25:35 +01:00
|
|
|
#ifdef FF_HAVE_LIBPCI
|
|
|
|
|
pciFillGPUs(instance, &gpus);
|
|
|
|
|
#endif
|
2021-03-03 19:59:39 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
#ifdef FF_HAVE_VULKAN
|
|
|
|
|
if(gpus.length == 0)
|
|
|
|
|
vulkanFillGPUs(instance, &gpus);
|
|
|
|
|
#endif
|
2021-04-03 21:51:50 +02:00
|
|
|
|
2021-12-19 22:39:22 +01:00
|
|
|
for(uint8_t i = 0; i < (uint8_t) gpus.length; i++)
|
2021-11-13 18:25:35 +01:00
|
|
|
printGPUResult(instance, gpus.length == 1 ? 0 : i + 1, &cache, ffListGet(&gpus, i));
|
2021-11-13 14:10:30 +01:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
if(gpus.length == 0)
|
|
|
|
|
ffPrintError(instance, FF_GPU_MODULE_NAME, 0, &instance->config.gpuKey, &instance->config.gpuFormat, FF_GPU_NUM_FORMAT_ARGS, "No GPUs found.");
|
2021-10-19 18:44:59 +02:00
|
|
|
|
2021-11-13 18:25:35 +01:00
|
|
|
ffCacheClose(&cache);
|
|
|
|
|
ffListDestroy(&gpus);
|
|
|
|
|
}
|