- Removed the `--disable-hiprt` flag from the runner command, simplifying the rendering options for users. - Updated the `jiggablend-runner` script and README to reflect the removal of the HIPRT control flag, enhancing clarity in usage instructions. - Enhanced the installation script to provide clearer examples for running the jiggablend manager and runner, improving user experience during setup. - Implemented a more robust GPU backend detection mechanism, allowing for better compatibility with various hardware configurations.
117 lines
2.7 KiB
Go
117 lines
2.7 KiB
Go
// Package blender: host GPU backend detection for AMD/NVIDIA/Intel.
|
|
package blender
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// DetectGPUBackends detects whether AMD, NVIDIA, and/or Intel GPUs are available
|
|
// using host-level hardware probing only.
|
|
func DetectGPUBackends() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
return detectGPUBackendsFromHost()
|
|
}
|
|
|
|
func detectGPUBackendsFromHost() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
if amd, nvidia, intel, found := detectGPUBackendsFromDRM(); found {
|
|
return amd, nvidia, intel, true
|
|
}
|
|
if amd, nvidia, intel, found := detectGPUBackendsFromLSPCI(); found {
|
|
return amd, nvidia, intel, true
|
|
}
|
|
return false, false, false, false
|
|
}
|
|
|
|
func detectGPUBackendsFromDRM() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
entries, err := os.ReadDir("/sys/class/drm")
|
|
if err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
name := entry.Name()
|
|
if !isDRMCardNode(name) {
|
|
continue
|
|
}
|
|
|
|
vendorPath := filepath.Join("/sys/class/drm", name, "device", "vendor")
|
|
vendorRaw, err := os.ReadFile(vendorPath)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
vendor := strings.TrimSpace(strings.ToLower(string(vendorRaw)))
|
|
switch vendor {
|
|
case "0x1002":
|
|
hasAMD = true
|
|
ok = true
|
|
case "0x10de":
|
|
hasNVIDIA = true
|
|
ok = true
|
|
case "0x8086":
|
|
hasIntel = true
|
|
ok = true
|
|
}
|
|
}
|
|
|
|
return hasAMD, hasNVIDIA, hasIntel, ok
|
|
}
|
|
|
|
func isDRMCardNode(name string) bool {
|
|
if !strings.HasPrefix(name, "card") {
|
|
return false
|
|
}
|
|
if strings.Contains(name, "-") {
|
|
// Connector entries like card0-DP-1 are not GPU device nodes.
|
|
return false
|
|
}
|
|
if len(name) <= len("card") {
|
|
return false
|
|
}
|
|
_, err := strconv.Atoi(strings.TrimPrefix(name, "card"))
|
|
return err == nil
|
|
}
|
|
|
|
func detectGPUBackendsFromLSPCI() (hasAMD, hasNVIDIA, hasIntel bool, ok bool) {
|
|
if _, err := exec.LookPath("lspci"); err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
out, err := exec.Command("lspci").CombinedOutput()
|
|
if err != nil {
|
|
return false, false, false, false
|
|
}
|
|
|
|
scanner := bufio.NewScanner(strings.NewReader(string(out)))
|
|
for scanner.Scan() {
|
|
line := strings.ToLower(strings.TrimSpace(scanner.Text()))
|
|
if !isGPUControllerLine(line) {
|
|
continue
|
|
}
|
|
|
|
if strings.Contains(line, "nvidia") {
|
|
hasNVIDIA = true
|
|
ok = true
|
|
}
|
|
if strings.Contains(line, "amd") || strings.Contains(line, "ati") || strings.Contains(line, "radeon") {
|
|
hasAMD = true
|
|
ok = true
|
|
}
|
|
if strings.Contains(line, "intel") {
|
|
hasIntel = true
|
|
ok = true
|
|
}
|
|
}
|
|
|
|
return hasAMD, hasNVIDIA, hasIntel, ok
|
|
}
|
|
|
|
func isGPUControllerLine(line string) bool {
|
|
return strings.Contains(line, "vga compatible controller") ||
|
|
strings.Contains(line, "3d controller") ||
|
|
strings.Contains(line, "display controller")
|
|
}
|