2026-06-12 16:11:35 +08:00
|
|
|
#include "gpu.h"
|
2024-01-25 10:18:19 +08:00
|
|
|
#include "gpu_driver_specific.h"
|
|
|
|
|
|
2026-01-06 09:48:38 +08:00
|
|
|
#include "common/io.h"
|
2024-01-25 10:18:19 +08:00
|
|
|
|
|
|
|
|
#include <sys/pciio.h>
|
|
|
|
|
#include <fcntl.h>
|
2024-11-03 08:35:11 +08:00
|
|
|
#if __has_include(<dev/pci/pcireg.h>)
|
2026-04-15 16:16:46 +08:00
|
|
|
#include <dev/pci/pcireg.h> // FreeBSD
|
2024-11-03 08:35:11 +08:00
|
|
|
#else
|
2026-04-15 16:16:46 +08:00
|
|
|
#include <bus/pci/pcireg.h> // DragonFly
|
2024-11-03 08:35:11 +08:00
|
|
|
#endif
|
2024-01-25 10:18:19 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
static const char* detectByPci(const FFGPUOptions* options, FFlist* gpus) {
|
2025-06-19 22:41:30 +08:00
|
|
|
FF_AUTO_CLOSE_FD int fd = open("/dev/pci", O_RDONLY | O_CLOEXEC);
|
2026-03-29 09:28:49 +08:00
|
|
|
if (fd < 0) {
|
2025-06-19 18:11:54 +08:00
|
|
|
return "open(\"/dev/pci\", O_RDONLY | O_CLOEXEC, 0) failed";
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2025-03-25 11:03:47 +08:00
|
|
|
|
2024-01-25 10:18:19 +08:00
|
|
|
struct pci_conf confs[128];
|
|
|
|
|
struct pci_match_conf match = {
|
|
|
|
|
.pc_class = PCIC_DISPLAY,
|
|
|
|
|
.flags = PCI_GETCONF_MATCH_CLASS,
|
|
|
|
|
};
|
|
|
|
|
struct pci_conf_io pcio = {
|
|
|
|
|
.pat_buf_len = sizeof(match),
|
|
|
|
|
.num_patterns = 1,
|
|
|
|
|
.patterns = &match,
|
|
|
|
|
.match_buf_len = sizeof(confs),
|
|
|
|
|
.matches = confs,
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
if (ioctl(fd, PCIOCGETCONF, &pcio) < 0) {
|
2024-01-25 10:18:19 +08:00
|
|
|
return "ioctl(fd, PCIOCGETCONF, &pc) failed";
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2024-01-25 10:18:19 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
if (pcio.status == PCI_GETCONF_ERROR) {
|
2024-01-25 10:18:19 +08:00
|
|
|
return "ioctl(fd, PCIOCGETCONF, &pc) returned error";
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2024-01-25 10:18:19 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
for (uint32_t i = 0; i < pcio.num_matches; ++i) {
|
2024-01-25 20:22:28 +08:00
|
|
|
struct pci_conf* pc = &confs[i];
|
2024-01-25 10:18:19 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
if (pc->pc_sel.pc_func > 0 && pc->pc_subclass == 0x80 /*PCI_CLASS_DISPLAY_OTHER*/) {
|
2025-10-30 14:46:30 +08:00
|
|
|
continue; // Likely an auxiliary display controller (#2034)
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2025-10-30 14:46:30 +08:00
|
|
|
|
2026-04-14 10:41:18 +08:00
|
|
|
FFGPUResult* gpu = FF_LIST_ADD(FFGPUResult, *gpus);
|
2024-12-28 15:26:17 +08:00
|
|
|
ffStrbufInitStatic(&gpu->vendor, ffGPUGetVendorString(pc->pc_vendor));
|
2024-01-25 10:18:19 +08:00
|
|
|
ffStrbufInit(&gpu->name);
|
|
|
|
|
ffStrbufInitS(&gpu->driver, pc->pd_name);
|
2025-03-24 15:19:34 +08:00
|
|
|
ffStrbufInitStatic(&gpu->platformApi, "/dev/pci");
|
|
|
|
|
ffStrbufInit(&gpu->memoryType);
|
2024-09-19 15:22:09 +08:00
|
|
|
gpu->index = FF_GPU_INDEX_UNSET;
|
2024-01-25 10:18:19 +08:00
|
|
|
gpu->temperature = FF_GPU_TEMP_UNSET;
|
|
|
|
|
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
|
2024-08-01 13:54:03 +08:00
|
|
|
gpu->coreUsage = FF_GPU_CORE_USAGE_UNSET;
|
2024-01-25 10:18:19 +08:00
|
|
|
gpu->type = FF_GPU_TYPE_UNKNOWN;
|
|
|
|
|
gpu->dedicated.total = gpu->dedicated.used = gpu->shared.total = gpu->shared.used = FF_GPU_VMEM_SIZE_UNSET;
|
2025-10-30 10:26:35 +08:00
|
|
|
gpu->deviceId = ffGPUPciAddr2Id(pc->pc_sel.pc_domain, pc->pc_sel.pc_bus, pc->pc_sel.pc_dev, pc->pc_sel.pc_func);
|
2024-01-25 10:18:19 +08:00
|
|
|
gpu->frequency = FF_GPU_FREQUENCY_UNSET;
|
|
|
|
|
|
2025-06-18 10:01:32 +08:00
|
|
|
ffGPUDetectDriverSpecific(options, gpu, (FFGpuDriverPciBusId) {
|
2026-03-29 09:28:49 +08:00
|
|
|
.domain = (uint32_t) pc->pc_sel.pc_domain,
|
|
|
|
|
.bus = pc->pc_sel.pc_bus,
|
|
|
|
|
.device = pc->pc_sel.pc_dev,
|
|
|
|
|
.func = pc->pc_sel.pc_func,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (gpu->name.length == 0) {
|
|
|
|
|
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_AMD) {
|
2025-02-13 10:43:11 +08:00
|
|
|
ffGPUQueryAmdGpuName(pc->pc_device, pc->pc_revid, gpu);
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
|
|
|
|
if (gpu->name.length == 0) {
|
2025-03-25 11:03:47 +08:00
|
|
|
ffGPUFillVendorAndName(pc->pc_subclass, pc->pc_vendor, pc->pc_device, gpu);
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2024-09-27 10:58:35 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-12 16:08:07 +08:00
|
|
|
ffGPUFillVendorByDeviceName(gpu);
|
2024-01-25 10:18:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2025-06-17 20:38:30 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) {
|
|
|
|
|
#if FF_HAVE_DRM
|
|
|
|
|
if (options->detectionMethod == FF_GPU_DETECTION_METHOD_AUTO) {
|
2026-06-12 16:11:35 +08:00
|
|
|
ffGPUDetectByDrmBSD(options, gpus);
|
2026-03-29 09:28:49 +08:00
|
|
|
if (gpus->length > 0) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2025-06-17 20:38:30 +08:00
|
|
|
}
|
2026-03-29 09:28:49 +08:00
|
|
|
#endif
|
2025-06-17 20:38:30 +08:00
|
|
|
|
|
|
|
|
return detectByPci(options, gpus);
|
|
|
|
|
}
|