From 6e3815ca05b2046c517d41e8be690af89af287a2 Mon Sep 17 00:00:00 2001 From: drath Date: Thu, 28 Aug 2025 15:12:37 +0200 Subject: [PATCH] smarter gpu figuriung out --- include/gpu.hpp | 1 + main.cpp | 17 ++++++++----- src/gpu.cpp | 66 ++++++++++++++++++++++++++++++------------------- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/include/gpu.hpp b/include/gpu.hpp index 08d7a2c..85219da 100644 --- a/include/gpu.hpp +++ b/include/gpu.hpp @@ -29,4 +29,5 @@ struct GpuMetricsHeader_t { }; gpu_t getGpu(GpuMetricsHeader_t header, std::string hw); +gpu_t getGpu(std::string hw); GpuMetricsHeader_t getGpuMetricsHeader(std::string path); \ No newline at end of file diff --git a/main.cpp b/main.cpp index 73636ea..68818c3 100644 --- a/main.cpp +++ b/main.cpp @@ -175,13 +175,13 @@ int main(int argc, char *argv[]) { cpu_hwmon = findHwmonPath("zenpower"); } - /* figure out gpu path */ + /* figure out gpu metrics path */ std::string gpu_hwmon; - GpuMetricsHeader_t gpu_mtr_rev; + GpuMetricsHeader_t gpu_mtr_header; for (uint8_t c = 0; c < 10; c++) { gpu_hwmon = "/sys/class/drm/card" + std::to_string(c) + "/device"; - gpu_mtr_rev = getGpuMetricsHeader(gpu_hwmon + "/gpu_metrics"); - if (gpu_mtr_rev.structure_size > 0) + gpu_mtr_header = getGpuMetricsHeader(gpu_hwmon + "/gpu_metrics"); + if (readFile(gpu_hwmon + "/board_info").length() != 0) break; } @@ -200,7 +200,9 @@ int main(int argc, char *argv[]) { auto ram = getRam(); // auto anime = getDisk("/mnt/anime"); auto home = getDisk("/home/drath"); - auto gpu = getGpu(gpu_mtr_rev, gpu_hwmon); + // auto gpu = (gpu_mtr_header.structure_size != 0) ? getGpu(gpu_mtr_header, gpu_hwmon) : getGpu("/sys/class/drm/card1/device"); + auto gpu = getGpu(gpu_mtr_header, gpu_hwmon); + auto cpu = getCpuTemp(cpu_hwmon); lines[0] = pad(td[1], 11, true) + " " + td[0] + lcd.bar(1, gpu.core_usage / 100.0) + pad(getAvgs(), 17); @@ -209,7 +211,10 @@ int main(int argc, char *argv[]) { lines[1] += pad(pBytes(ram.used, true) + "B", 7, true); lines[1] += fill(7); lines[1] += pad(pBytes(gpu.vram_used) + "B", 7); - lines[1] += pad(std::to_string(gpu.edge_temp) + "/" + std::to_string(gpu.hotspot_temp) + "/" + std::to_string(gpu.mem_temp) + lcd.cc[0], 11); + + auto gpu_temps = (gpu.hotspot_temp) ? "/" + std::to_string(gpu.hotspot_temp) : ""; + gpu_temps += (gpu.mem_temp) ? "/" + std::to_string(gpu.mem_temp) : ""; + lines[1] += pad(std::to_string(gpu.edge_temp) + gpu_temps + lcd.cc[0], 11); lines[2] = pad(pNum(cpu.ptotal, 1) + "W", 8, true); lines[2] += pad("home: " + pBytes(home.free), 12); diff --git a/src/gpu.cpp b/src/gpu.cpp index 9c4b715..4326c07 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -98,46 +98,62 @@ GpuMetricsHeader_t getGpuMetricsHeader(std::string path) { return header; } +/* will return empty metric if fails */ auto getGpuMetrics(GpuMetricsHeader_t h, std::string path) { GpuMetrics_v1_3_t metrics; - if (h.format_revision == 1 && h.content_revision == 3) { - std::ifstream f(path, std::ios::binary); - if (f.good()) { - f.ignore(sizeof(h)); // skip header - f.read(reinterpret_cast(&metrics), sizeof(metrics)); - f.close(); - } - } else { - std::println("[GpuMetrics] read failed, unsupported format"); + uint8_t rev = h.format_revision * 10 + h.content_revision; + + switch (rev) { + case 13: { + std::ifstream f(path, std::ios::binary); + if (f.good()) { + f.ignore(sizeof(h)); // skip header + f.read(reinterpret_cast(&metrics), sizeof(metrics)); + f.close(); + } + } break; } return metrics; } -// clean abstraction of gpu_metrics + extra metrics from fs +// clean abstraction of gpu_metrics + extra metrics from fs, works with rx7800xt gpu_t getGpu(GpuMetricsHeader_t header, std::string hw) { gpu_t gpu; - auto metrics = getGpuMetrics(header, hw + "/gpu_metrics"); - // we want as much data as posible from gpu_metrics so we dont read filesystem as much + // these are always read from fs gpu.fan_speed = std::stol(readFile(hw + "/hwmon/hwmon2/fan1_input")); - gpu.core_clock = metrics.average_vclk1_frequency; // why not gfxclock? - gpu.mem_clock = metrics.average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping gpu.vcore = std::stod(readFile(hw + "/hwmon/hwmon2/in0_input")) / 1000.0; - gpu.power_avg = metrics.average_socket_power; gpu.power_cap = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap", 6)); gpu.power_max = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap_max", 6)); // gpu.fan_pwm = std::stoi(readFile(hw + "/hwmon/hwmon2/pwm1")); // not super useful - gpu.edge_temp = metrics.temperature_edge; - gpu.hotspot_temp = metrics.temperature_hotspot; - gpu.mem_temp = metrics.temperature_mem; - gpu.gfx_vrm_temp = metrics.temperature_vrgfx; - gpu.soc_vrm_temp = metrics.temperature_vrsoc; - gpu.mem_vrm_temp = metrics.temperature_vrmem; gpu.vram_used = std::stoul(readFile(hw + "/mem_info_vram_used")); gpu.vram_total = std::stoul(readFile(hw + "/mem_info_vram_total")); - gpu.core_usage = metrics.average_gfx_activity; - gpu.media_usage = metrics.average_mm_activity; - gpu.umc_usage = metrics.average_umc_activity; + + auto metrics = getGpuMetrics(header, hw + "/gpu_metrics"); + + // check if metrics valid, if not use fs + if (header.structure_size != 0) { + gpu.core_clock = metrics.average_vclk1_frequency; // why not gfxclock? + gpu.mem_clock = metrics.average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping + gpu.core_usage = metrics.average_gfx_activity; + gpu.media_usage = metrics.average_mm_activity; + gpu.umc_usage = metrics.average_umc_activity; + gpu.edge_temp = metrics.temperature_edge; + gpu.hotspot_temp = metrics.temperature_hotspot; + gpu.mem_temp = metrics.temperature_mem; + gpu.gfx_vrm_temp = metrics.temperature_vrgfx; + gpu.soc_vrm_temp = metrics.temperature_vrsoc; + gpu.mem_vrm_temp = metrics.temperature_vrmem; + gpu.power_avg = metrics.average_socket_power; + } else { + gpu.core_clock = std::stol(readFile(hw + "/hwmon/hwmon2/freq1_input", 6)); + gpu.mem_clock = std::stol(readFile(hw + "/hwmon/hwmon2/freq2_input", 6)); + gpu.vcore = std::stod(readFile(hw + "/hwmon/hwmon2/in0_input")) / 1000.0; + gpu.power_avg = std::stol(readFile(hw + "/hwmon/hwmon2/power1_input", 6)); + gpu.edge_temp = std::stol(readFile(hw + "/hwmon/hwmon2/temp1_input", 3)); + gpu.core_usage = std::stoi(readFile(hw + "/gpu_busy_percent")); + } + return gpu; -} \ No newline at end of file +}