From 85d96fceecb1e7a6950d163e683f4eafedd512bb Mon Sep 17 00:00:00 2001 From: EnumDev Date: Wed, 24 Dec 2025 17:28:42 +0200 Subject: [PATCH] Improve GPU name fetching --- config/config.yml | 1 + src/config.go | 9 +++++---- src/hardware.go | 38 +++++++++++++++++++++++++++++++++----- src/modules.go | 4 +++- src/utils.go | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 10 deletions(-) diff --git a/config/config.yml b/config/config.yml index 76ab440..e9d0072 100644 --- a/config/config.yml +++ b/config/config.yml @@ -1,4 +1,5 @@ distro_ascii: auto +disable_amdgpu_ids_warning: false modules: - name: distribution - name: hostname diff --git a/src/config.go b/src/config.go index 7ba3804..3641025 100644 --- a/src/config.go +++ b/src/config.go @@ -9,10 +9,11 @@ import ( ) type StormfetchConfig struct { - Ascii string `yaml:"distro_ascii"` - Modules []stormfetchModuleConfig `yaml:"modules"` - AnsiiColors []int `yaml:"ansii_colors"` - ForceConfigAnsii bool `yaml:"force_config_ansii"` + Ascii string `yaml:"distro_ascii"` + DisableAmdgpuIdsWarning bool `yaml:"disable_amdgpu_ids_warning"` + Modules []stormfetchModuleConfig `yaml:"modules"` + AnsiiColors []int `yaml:"ansii_colors"` + ForceConfigAnsii bool `yaml:"force_config_ansii"` } var config = StormfetchConfig{ diff --git a/src/hardware.go b/src/hardware.go index b911016..44a7eab 100644 --- a/src/hardware.go +++ b/src/hardware.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "slices" "strings" @@ -18,6 +19,7 @@ type CPU struct { type GPU struct { PCIAddress string Vendor string + Name string Product string Subsystem string Driver string @@ -101,17 +103,43 @@ func GetGPUModels(hiddenGPUs []int) []GPU { vendor = gpu.DeviceInfo.Vendor.Name } - // Fallback subsystem name to product name - subsystem := gpu.DeviceInfo.Subsystem.Name - if subsystem == "" || subsystem == "unknown" { - subsystem = gpu.DeviceInfo.Product.Name + // Set GPU name + name := "" + + // Use GPU name from amdgpu.ids database + if vendor == "AMD" { + fetchedName, err := fetchAmdGpuName(gpu.DeviceInfo.Product.ID, gpu.DeviceInfo.Revision) + if err == nil && !config.DisableAmdgpuIdsWarning { + name = fetchedName + } else { + fmt.Println("Warning: could not fetch GPU name from amdgpu.ids database! Error: " + err.Error()) + fmt.Println(" You can disable this warning in the configuration file") + } + } + + if name == "" { + if gpu.DeviceInfo.Subsystem.Name == "" || gpu.DeviceInfo.Subsystem.Name == "unknown" { + // Set GPU name to product name + name = gpu.DeviceInfo.Product.Name + } else { + // Set GPU name to subsystem name + name = gpu.DeviceInfo.Subsystem.Name + } + + // Use GPU name in brackets + leftBracket := strings.IndexByte(name, '[') + rightBracket := strings.IndexByte(name, ']') + if leftBracket != -1 && rightBracket != -1 { + name = name[leftBracket+1 : rightBracket] + } } ret = append(ret, GPU{ PCIAddress: gpu.Address, Vendor: vendor, + Name: name, Product: gpu.DeviceInfo.Product.Name, - Subsystem: subsystem, + Subsystem: gpu.DeviceInfo.Subsystem.Name, Driver: gpu.DeviceInfo.Driver, }) } diff --git a/src/modules.go b/src/modules.go index 564763d..0a35843 100644 --- a/src/modules.go +++ b/src/modules.go @@ -219,7 +219,7 @@ func initializeModuleMap() { RegisterModule(cpusModule) // GPUs module - gpusModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "gpus", Format: "%3GPU: %4$GPU_VENDOR $GPU_SUBSYSTEM"}, Execute: func(sm StormfetchModule) string { + gpusModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "gpus", Format: "%3GPU: %4$GPU_VENDOR $GPU_NAME"}, Execute: func(sm StormfetchModule) string { hiddenGPUsInterface, _ := sm.GetData("hidden_gpus", make([]any, 0)) // Convert interface slices to string slices @@ -240,6 +240,8 @@ func initializeModuleMap() { return strconv.Itoa(i + 1) case "GPU_VENDOR": return gpu.Vendor + case "GPU_NAME": + return gpu.Name case "GPU_PRODUCT": return gpu.Product case "GPU_SUBSYSTEM": diff --git a/src/utils.go b/src/utils.go index e6841ec..6bba61d 100644 --- a/src/utils.go +++ b/src/utils.go @@ -5,6 +5,7 @@ import ( "math" "os" "os/exec" + "path" "regexp" "strings" ) @@ -58,6 +59,46 @@ func ReadKeyValueFile(filepath string) (map[string]string, error) { return ret, nil } +func fetchAmdGpuName(productId, revision string) (string, error) { + productId = strings.ToUpper(productId) + revision = strings.ToUpper(revision[2:]) + + // Get cache directory + cachedir, err := os.UserCacheDir() + if err != nil { + return "", err + } + + // Ensure amdgpu.ids file exists and download it if it doesn't + if _, err := os.Stat(path.Join(cachedir, "amdgpu.ids")); err != nil { + cmd := exec.Command("curl", "-o", path.Join(cachedir, "amdgpu.ids"), "https://gitlab.freedesktop.org/mesa/libdrm/-/raw/main/data/amdgpu.ids") + err = cmd.Run() + if err != nil { + return "", fmt.Errorf("Could not fetch amdgpu.ids using curl") + } + } + + // Read amdgpu.ids file + amdgpuIds, err := os.ReadFile(path.Join(cachedir, "amdgpu.ids")) + if err != nil { + return "", err + } + + // Parse read data and find GPU + for _, line := range strings.Split(string(amdgpuIds), "\n") { + if len(line) < 2 || line[0] == '#' { + continue + } + + fields := strings.Split(line, ",\t") + if fields[0] == productId && fields[1] == revision { + return strings.TrimPrefix(fields[2], "AMD "), nil + } + } + + return "", nil +} + func runCommand(command string, shell string) string { cmd := exec.Command(shell, "-c", command) workdir, err := os.Getwd()