diff --git a/include/gpu.hpp b/include/gpu.hpp index daf268d..8f1fc01 100644 --- a/include/gpu.hpp +++ b/include/gpu.hpp @@ -8,10 +8,8 @@ #include #include -#define REL_METRICS_PATH "/../../gpu_metrics" -#define MAX_METRICS_LENGTH 512 - -#define METRICS_IS(m) auto metrics = reinterpret_cast(raw_metrics) +#define REL_METRICS_PATH "/../../gpu_metrics" // gpu_metrics path relative to hwmon path +#define MAX_METRICS_LENGTH 512 // length of the metrics buffer /* should refactor this struct so its a little cleaner and closer to gpu_metrics */ /* clean abstraction for gpu_metrics or metrics in filesystem in sane units */ @@ -22,25 +20,31 @@ struct sensors { std::string hwmon = ""; bool hasGpuMetrics = false; - uint16_t fan_speed = 0; - uint16_t core_clock = 0; - uint16_t mem_clock = 0; float vcore = 0.0f; + + uint16_t clock_core = 0; + uint16_t clock_mem = 0; + + uint8_t fan_pwm = 0; + uint16_t fan_speed = 0; + uint16_t power_avg = 0; uint16_t power_cap = 0; - uint16_t power_max = 0; - uint8_t fan_pwm = 0; - uint8_t edge_temp = 0; - uint8_t hotspot_temp = 0; - uint8_t mem_temp = 0; - uint8_t gfx_vrm_temp = 0; - uint8_t soc_vrm_temp = 0; - uint8_t mem_vrm_temp = 0; + uint16_t power_cap_max = 0; + + uint8_t temp_edge = 0; + uint8_t temp_hotspot = 0; + uint8_t temp_mem = 0; + uint8_t temp_vrm_gfx = 0; + uint8_t temp_vrm_soc = 0; + uint8_t temp_vrm_mem = 0; + + uint8_t usage_core = 0; + uint8_t usage_media = 0; + uint8_t usage_umc = 0; + uint64_t vram_used = 0; uint64_t vram_total = 0; - uint8_t core_usage = 0; - uint8_t media_usage = 0; - uint8_t umc_usage = 0; }; void detectHwmon(sensors* target, std::string pci); diff --git a/main.cpp b/main.cpp index 5382bf7..ba7d266 100644 --- a/main.cpp +++ b/main.cpp @@ -101,16 +101,16 @@ void displayThread(std::stop_token st, Sensors* s) { { std::lock_guard lock(s->mtx); - auto gpu_temps = (s->gpu.hotspot_temp) ? "/" + std::to_string(s->gpu.hotspot_temp) : ""; - gpu_temps += (s->gpu.mem_temp) ? "/" + std::to_string(s->gpu.mem_temp) : ""; + auto gpu_temps = (s->gpu.temp_hotspot) ? "/" + std::to_string(s->gpu.temp_hotspot) : ""; + gpu_temps += (s->gpu.temp_mem) ? "/" + std::to_string(s->gpu.temp_mem) : ""; - lcd.writeBuf(0, 0, pad(s->td[1], 11, true) + " " + s->td[0] + lcd.bar(1, s->gpu.core_usage / 100.0) + pad(s->loadavg, 17)); + lcd.writeBuf(0, 0, pad(s->td[1], 11, true) + " " + s->td[0] + lcd.bar(1, s->gpu.usage_core / 100.0) + pad(s->loadavg, 17)); lcd.writeBuf(1, 0, pad(std::to_string(s->cpu.tctl) + "/" + std::to_string(s->cpu.tccd1) + lcd.cc[0], 8, true)); lcd.writeBuf(1, 8, pad(pBytes(s->ram.used, true) + "B", 7, true)); lcd.writeBuf(1, 16, pad(pNum(s->hass_state) + "W", 4)); lcd.writeBuf(1, 22, pad(pBytes(s->gpu.vram_used) + "B", 7)); - lcd.writeBuf(1, 29, pad(std::to_string(s->gpu.edge_temp) + gpu_temps + lcd.cc[0], 11)); + lcd.writeBuf(1, 29, pad(std::to_string(s->gpu.temp_edge) + gpu_temps + lcd.cc[0], 11)); lcd.writeBuf(2, 0, pad(pNum(s->cpu.ptotal, 1) + "W", 8, true)); lcd.writeBuf(2, 8, "home:" + pad(pBytes(s->home.free), 5)); @@ -121,7 +121,7 @@ void displayThread(std::stop_token st, Sensors* s) { lcd.writeBuf(3, 0, pad(pNum(s->cpu.vcore, 3) + "V", 7, true)); lcd.writeBuf(3, 7, std::to_string(s->cpu.avg_freq) + "MHz"); - lcd.writeBuf(3, 21, pad(std::to_string(s->gpu.core_clock) + "/" + std::to_string(s->gpu.mem_clock) + "MHz ", 13)); + lcd.writeBuf(3, 21, pad(std::to_string(s->gpu.clock_core) + "/" + std::to_string(s->gpu.clock_mem) + "MHz ", 13)); lcd.writeBuf(3, 34, pad(pNum(s->gpu.vcore, 3) + "V", 5)); } diff --git a/src/gpu.cpp b/src/gpu.cpp index e5809a2..99f9c9e 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -1,7 +1,7 @@ #include /* maybe have a read pp_table function */ -/* would be neat to wrap it in a class but eh */ +/* would be neat to wrap it in a class but eh namespace is good enough */ namespace gpu { @@ -19,22 +19,22 @@ void detectHwmon(sensors* target, std::string pci) { /* some metrics are missing in gpu_metrics, we always fill them from fs */ void fillMissingMetrics(sensors* g) { - g->fan_speed = std::stol(readFile(g->hwmon + "/fan1_input", 4)); g->vcore = std::stol(readFile(g->hwmon + "/in0_input", 4)) / 1000.0f; - g->power_cap = std::stol(readFile(g->hwmon + "/power1_cap", 16)) / 1000000; - g->power_max = std::stol(readFile(g->hwmon + "/power1_cap_max", 16)) / 1000000; g->fan_pwm = std::stoi(readFile(g->hwmon + "/pwm1", 4)) * 100 / 256; + g->fan_speed = std::stol(readFile(g->hwmon + "/fan1_input", 4)); + g->power_cap = std::stol(readFile(g->hwmon + "/power1_cap", 16)) / 1000000; + g->power_cap_max = std::stol(readFile(g->hwmon + "/power1_cap_max", 16)) / 1000000; g->vram_used = std::stoul(readFile(g->hwmon + "/../../mem_info_vram_used", 16)); g->vram_total = std::stoul(readFile(g->hwmon + "/../../mem_info_vram_total", 16)); } /* get sensors for pre-vega cards (rx480/580) */ void updateFromFs(sensors* g) { - g->core_clock = std::stoll(readFile(g->hwmon + "/freq1_input", 16)) / 1000000; - g->mem_clock = std::stoll(readFile(g->hwmon + "/freq2_input", 16)) / 1000000; + g->clock_core = std::stoll(readFile(g->hwmon + "/freq1_input", 16)) / 1000000; + g->clock_mem = std::stoll(readFile(g->hwmon + "/freq2_input", 16)) / 1000000; g->power_avg = std::stol(readFile(g->hwmon + "/power1_input", 16)) / 1000000; - g->edge_temp = std::stol(readFile(g->hwmon + "/temp1_input", 2)); - g->core_usage = std::stoi(readFile(g->hwmon + "/../../gpu_busy_percent")); + g->temp_edge = std::stol(readFile(g->hwmon + "/temp1_input", 2)); + g->usage_core = std::stoi(readFile(g->hwmon + "/../../gpu_busy_percent")); } /* get sensors for vega and newer (rx5700xt, rx7800xt [*]) */ @@ -44,35 +44,37 @@ void updateFromMetrics(sensors* g) { auto header = reinterpret_cast(raw_metrics); switch (header->format_revision * 10 + header->content_revision) { - /* rx5700xt, rx7800xt */ case 13: { - METRICS_IS(metrics::gpu_metrics_v1_3); - // rx7800xt - g->core_clock = metrics->average_vclk1_frequency; // why not gfxclock? - g->mem_clock = metrics->average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping - g->core_usage = metrics->average_gfx_activity; - g->media_usage = metrics->average_mm_activity; - g->umc_usage = metrics->average_umc_activity; - g->edge_temp = metrics->temperature_edge; - g->hotspot_temp = metrics->temperature_hotspot; - g->mem_temp = metrics->temperature_mem; - g->gfx_vrm_temp = metrics->temperature_vrgfx; - g->soc_vrm_temp = metrics->temperature_vrsoc; - g->mem_vrm_temp = metrics->temperature_vrmem; + auto metrics = reinterpret_cast(raw_metrics); + g->usage_core = metrics->average_gfx_activity; + g->usage_umc = metrics->average_umc_activity; + g->usage_media = metrics->average_mm_activity; + + g->temp_edge = metrics->temperature_edge; + g->temp_hotspot = metrics->temperature_hotspot; + g->temp_mem = metrics->temperature_mem; + + g->temp_vrm_gfx = metrics->temperature_vrgfx; + g->temp_vrm_soc = metrics->temperature_vrsoc; + g->temp_vrm_mem = metrics->temperature_vrmem; g->power_avg = metrics->average_socket_power; g->fan_speed = metrics->current_fan_speed; + // hacks for rx7800xt + // g->clock_core = metrics->average_vclk1_frequency; // why not gfxclock? + // g->clock_mem = metrics->average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping + // hacks for rx5700xt - g->core_clock = metrics->average_gfxclk_frequency; - g->mem_clock = metrics->current_uclk * 2; // mem controller clock, actual mem is 2x that. average shows 871-872 + g->clock_core = metrics->average_gfxclk_frequency; + g->clock_mem = metrics->average_uclk_frequency * 2; // mem controller clock, actual mem is 2x that break; } /* ryzen 5 5600g */ case 22: { - METRICS_IS(metrics::gpu_metrics_v2_2); - g->edge_temp = metrics->temperature_gfx / 100; + auto metrics = reinterpret_cast(raw_metrics); + g->temp_edge = metrics->temperature_gfx / 100; break; } @@ -92,6 +94,8 @@ void update(sensors* g) { gpu::updateFromMetrics(g); else gpu::updateFromFs(g); + + if (g->fan_speed > 9999) g->fan_speed = 9999; // sanity check fan speed } } // namespace gpu \ No newline at end of file