diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp new file mode 100644 index 00000000..bf1933d9 --- /dev/null +++ b/src/amdgpu.cpp @@ -0,0 +1,10 @@ +#include "amdgpu.h" +#include "overlay.h" + +struct gpu_metrics_v2_2 amdgpu_metrics; + +void amdgpu_get_metrics() +{ + std::ifstream in("/sys/class/drm/renderD128/device/gpu_metrics", std::ios_base::in | std::ios_base::binary); + in.read((char*)&amdgpu_metrics, sizeof(amdgpu_metrics)); +} \ No newline at end of file diff --git a/src/amdgpu.h b/src/amdgpu.h new file mode 100644 index 00000000..db78446e --- /dev/null +++ b/src/amdgpu.h @@ -0,0 +1,68 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +struct metrics_table_header { + uint16_t structure_size; + uint8_t format_revision; + uint8_t content_revision; +}; + +struct gpu_metrics_v2_2 { + struct metrics_table_header common_header; + + /* Temperature */ + uint16_t temperature_gfx; // gfx temperature on APUs + uint16_t temperature_soc; // soc temperature on APUs + uint16_t temperature_core[8]; // CPU core temperature on APUs + uint16_t temperature_l3[2]; + + /* Utilization */ + uint16_t average_gfx_activity; + uint16_t average_mm_activity; // UVD or VCN + + /* Driver attached timestamp (in ns) */ + uint64_t system_clock_counter; + + /* Power/Energy */ + uint16_t average_socket_power; // dGPU + APU power on A + A platform + uint16_t average_cpu_power; + uint16_t average_soc_power; + uint16_t average_gfx_power; + uint16_t average_core_power[8]; // CPU core power on APUs + + /* Average clocks */ + uint16_t average_gfxclk_frequency; + uint16_t average_socclk_frequency; + uint16_t average_uclk_frequency; + uint16_t average_fclk_frequency; + uint16_t average_vclk_frequency; + uint16_t average_dclk_frequency; + + /* Current clocks */ + uint16_t current_gfxclk; + uint16_t current_socclk; + uint16_t current_uclk; + uint16_t current_fclk; + uint16_t current_vclk; + uint16_t current_dclk; + uint16_t current_coreclk[8]; // CPU core clocks + uint16_t current_l3clk[2]; + + /* Throttle status (ASIC dependent) */ + uint32_t throttle_status; + + /* Fans */ + uint16_t fan_pwm; + + uint16_t padding[3]; + + /* Throttle status (ASIC independent) */ + uint64_t indep_throttle_status; +}; + +extern void amdgpu_get_metrics(); \ No newline at end of file diff --git a/src/cpu.cpp b/src/cpu.cpp index 70dfee6f..1c5c6e07 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -11,6 +11,9 @@ #include #include #include "string_utils.h" +#include "hud_elements.h" +#include "overlay.h" +#include "amdgpu.h" #ifndef PROCDIR #define PROCDIR "/proc" @@ -244,6 +247,9 @@ bool CPUStats::UpdateCoreMhz() { } bool CPUStats::UpdateCpuTemp() { +#ifdef MANGOAPP + m_cpuDataTotal.temp = amdgpu_metrics.temperature_soc / 100; +#else if (!m_cpuTempFile) return false; @@ -254,6 +260,8 @@ bool CPUStats::UpdateCpuTemp() { m_cpuDataTotal.temp = temp / 1000; return ret; +#endif + return true; } static bool get_cpu_power_k10temp(CPUPowerData* cpuPowerData, int& power) { @@ -340,6 +348,12 @@ static bool get_cpu_power_rapl(CPUPowerData* cpuPowerData, int& power) { return true; } +static bool get_cpu_power_amdgpu(int& power) { + int _power; + power = amdgpu_metrics.average_cpu_power / 1000; + return true; +} + bool CPUStats::UpdateCpuPower() { if(!m_cpuPowerData) return false; @@ -356,6 +370,9 @@ bool CPUStats::UpdateCpuPower() { case CPU_POWER_RAPL: if (!get_cpu_power_rapl(m_cpuPowerData.get(), power)) return false; break; + case CPU_POWER_AMDGPU: + if (!get_cpu_power_amdgpu(power)) return false; + break; default: return false; } @@ -425,20 +442,20 @@ bool CPUStats::GetCpuFile() { break; } else if (name == "atk0110") { find_temp_input(path, input, "CPU Temperature"); - break; + break; } else { path.clear(); } } - +#ifndef MANGOAPP if (path.empty() || (!file_exists(input) && !find_fallback_temp_input(path, input))) { SPDLOG_ERROR("Could not find cpu temp sensor location"); return false; } else { - SPDLOG_DEBUG("hwmon: using input: {}", input); m_cpuTempFile = fopen(input.c_str(), "r"); } +#endif return true; } @@ -521,6 +538,7 @@ bool CPUStats::InitCpuPowerData() { std::string name, path; std::string hwmon = "/sys/class/hwmon/"; + bool intel = false; CPUPowerData* cpuPowerData = nullptr; @@ -536,10 +554,12 @@ bool CPUStats::InitCpuPowerData() { } else if (name == "zenpower") { cpuPowerData = (CPUPowerData*)init_cpu_power_data_zenpower(path); break; + } else if (name == "coretemp") { + intel = true; } } - if (!cpuPowerData) { + if (!cpuPowerData && intel) { std::string powercap = "/sys/class/powercap/"; auto powercap_dirs = ls(powercap.c_str()); for (auto& dir : powercap_dirs) { @@ -551,6 +571,9 @@ bool CPUStats::InitCpuPowerData() { break; } } + } else { + auto powerData = std::make_unique(); + cpuPowerData = (CPUPowerData*)powerData.release(); } if(cpuPowerData == nullptr) { diff --git a/src/cpu.h b/src/cpu.h index 8dbdefad..9da49049 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -45,7 +45,8 @@ typedef struct CPUData_ { enum { CPU_POWER_K10TEMP, CPU_POWER_ZENPOWER, - CPU_POWER_RAPL + CPU_POWER_RAPL, + CPU_POWER_AMDGPU }; struct CPUPowerData { @@ -107,6 +108,12 @@ struct CPUPowerData_rapl : public CPUPowerData { Clock::time_point lastCounterValueTime; }; +struct CPUPowerData_amdgpu : public CPUPowerData { + CPUPowerData_amdgpu() { + this->source = CPU_POWER_AMDGPU; + }; +}; + class CPUStats { public: diff --git a/src/meson.build b/src/meson.build index 182cde7d..0cdc4902 100644 --- a/src/meson.build +++ b/src/meson.build @@ -54,6 +54,7 @@ vklayer_files = files( 'vulkan.cpp', 'blacklist.cpp', 'file_utils.cpp', + 'amdgpu.cpp', ) opengl_files = [] if ['windows', 'mingw'].contains(host_machine.system()) diff --git a/src/overlay.cpp b/src/overlay.cpp index 532e1150..6692a111 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -95,6 +95,9 @@ void update_hw_info(struct swapchain_stats& sw_stats, struct overlay_params& par graph_data.push_back(currentLogData); logger->notify_data_valid(); HUDElements.update_exec(); +#ifdef MANGOAPP + amdgpu_get_metrics(); +#endif } struct hw_info_updater diff --git a/src/overlay.h b/src/overlay.h index 08745ba9..8b2dee9f 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -16,6 +16,8 @@ #include "vk_enum_to_str.h" #include "notify.h" #include +#include "amdgpu.h" + #ifdef HAVE_DBUS #include "dbus_info.h" extern float g_overflow; @@ -141,6 +143,7 @@ extern ImVec2 real_font_size; extern std::string wineVersion; extern std::vector graph_data; extern overlay_params *_params; +extern struct gpu_metrics_v2_2 amdgpu_metrics; void position_layer(struct swapchain_stats& data, struct overlay_params& params, ImVec2 window_size); void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan);