43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import { execFileSync } from "node:child_process";
|
|
|
|
export type GpuVendor = "nvidia" | "amd" | "intel";
|
|
|
|
// ponytail: card-generation nuance (e.g. Nouveau for pre-Turing NVIDIA cards) isn't
|
|
// handled — add if an unsupported-card report comes in.
|
|
const DRIVER_PACKAGES: Record<GpuVendor, string[]> = {
|
|
nvidia: ["nvidia-open-dkms", "nvidia-utils", "egl-wayland"],
|
|
amd: ["mesa", "vulkan-radeon", "libva-mesa-driver"],
|
|
intel: ["mesa", "vulkan-intel", "intel-media-driver"],
|
|
};
|
|
|
|
const VENDOR_PATTERNS: [RegExp, GpuVendor][] = [
|
|
[/nvidia/i, "nvidia"],
|
|
[/\b(amd|ati)\b/i, "amd"],
|
|
[/intel/i, "intel"],
|
|
];
|
|
|
|
export function detectGpuVendors(): GpuVendor[] {
|
|
let output: string;
|
|
try {
|
|
output = execFileSync("lspci", [], { encoding: "utf8" });
|
|
} catch {
|
|
return [];
|
|
}
|
|
|
|
const controllerLines = output
|
|
.split("\n")
|
|
.filter((line) => /VGA compatible controller|3D controller/i.test(line));
|
|
|
|
const found = new Set<GpuVendor>();
|
|
for (const line of controllerLines) {
|
|
for (const [pattern, vendor] of VENDOR_PATTERNS) {
|
|
if (pattern.test(line)) found.add(vendor);
|
|
}
|
|
}
|
|
return [...found];
|
|
}
|
|
|
|
export function driverPackagesFor(vendors: GpuVendor[]): string[] {
|
|
return vendors.flatMap((vendor) => DRIVER_PACKAGES[vendor]);
|
|
}
|