diff --git a/src/hardware.go b/src/hardware.go index d18da66..9e34100 100644 --- a/src/hardware.go +++ b/src/hardware.go @@ -2,7 +2,6 @@ package main import ( "os" - "os/exec" "slices" "strings" @@ -17,6 +16,15 @@ type CPU struct { Threads int } +type GPU struct { + PCIAddress string + Vendor string + Product string + Subsystem string + Driver string + VRAM int64 +} + type Monitor struct { Width int Height int @@ -47,22 +55,46 @@ func GetCPUs(hiddenCPUs []int) []CPU { return ret } -func GetGPUModels(hiddenGPUS []int) (ret []string) { - cmd := exec.Command("sh", "-c", "lspci -v -m | grep 'VGA' -A6 | grep '^Device:'") - bytes, err := cmd.Output() +func GetGPUModels(hiddenGPUs []int) []GPU { + ret := make([]GPU, 0) + + // Set stderr to nil to avoid warnings + stderr := os.Stderr + os.Stderr = nil + + gpus, err := ghw.GPU() if err != nil { - return nil + return ret } - for i, gpu := range strings.Split(string(bytes), "\n") { - if slices.Contains(hiddenGPUS, i+1) { + // Restore stderr + os.Stderr = stderr + + for i, gpu := range gpus.GraphicsCards { + if slices.Contains(hiddenGPUs, i+1) { continue } - if gpu == "" { - continue + + // Set alternative names for vendors + var vendor string + switch gpu.DeviceInfo.Vendor.ID { + case "1002": + vendor = "AMD" + case "10de": + vendor = "Nvidia" + case "8086": + vendor = "Intel" + default: + vendor = gpu.DeviceInfo.Vendor.Name } - gpu = strings.TrimPrefix(strings.TrimSpace(gpu), "Device:\t") - ret = append(ret, gpu) + + ret = append(ret, GPU{ + PCIAddress: gpu.Address, + Vendor: vendor, + Product: gpu.DeviceInfo.Product.Name, + Subsystem: gpu.DeviceInfo.Subsystem.Name, + Driver: gpu.DeviceInfo.Driver, + }) } return ret diff --git a/src/modules.go b/src/modules.go index e7d2ec3..7aa39a3 100644 --- a/src/modules.go +++ b/src/modules.go @@ -221,7 +221,7 @@ func initializeModuleMap() { RegisterModule(cpusModule) // GPUs module - gpusModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "gpus", Format: "%3GPU: %4$GPU_MODEL"}, Execute: func(sm StormfetchModule) string { + gpusModule := StormfetchModule{stormfetchModuleConfig: stormfetchModuleConfig{Name: "gpus", Format: "%3GPU: %4$GPU_VENDOR $GPU_SUBSYSTEM"}, Execute: func(sm StormfetchModule) string { hiddenGPUsInterface, _ := sm.GetData("hidden_gpus", make([]any, 0)) // Convert interface slices to string slices @@ -234,12 +234,22 @@ func initializeModuleMap() { gpus := GetGPUModels(hiddenGPUs) for i, gpu := range gpus { + vram := strconv.FormatInt(gpu.VRAM, 10) + expanded := os.Expand(sm.Format, func(s string) string { switch s { case "GPU_NUM": return strconv.Itoa(i + 1) - case "GPU_MODEL": - return gpu + case "GPU_VENDOR": + return gpu.Vendor + case "GPU_PRODUCT": + return gpu.Product + case "GPU_SUBSYSTEM": + return gpu.Subsystem + case "GPU_DRIVER": + return gpu.Driver + case "GPU_VRAM": + return vram default: return "" }