From 55c8be5b0b9142eb7afef699fb854e8cf59dd803 Mon Sep 17 00:00:00 2001 From: FlightlessMango Date: Thu, 21 Sep 2023 22:19:42 +0200 Subject: [PATCH] amdgpu: collect throttling data for graph --- src/amdgpu.cpp | 4 +++- src/amdgpu.h | 37 ++++++++++++++++++++++++++++++++++++- src/overlay.cpp | 9 +++++++-- src/overlay.h | 1 + 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/amdgpu.cpp b/src/amdgpu.cpp index 386c034e..0f28feac 100644 --- a/src/amdgpu.cpp +++ b/src/amdgpu.cpp @@ -17,6 +17,7 @@ std::mutex amdgpu_common_metrics_m; std::mutex amdgpu_m; std::condition_variable amdgpu_c; bool amdgpu_run_thread = true; +std::unique_ptr throttling; bool amdgpu_verify_metrics(const std::string& path) { @@ -52,7 +53,6 @@ bool amdgpu_verify_metrics(const std::string& path) return false; } -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define IS_VALID_METRIC(FIELD) (FIELD != 0xffff) void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) { FILE *f; @@ -183,6 +183,8 @@ void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) { metrics->is_current_throttled = ((indep_throttle_status >> 16) & 0xFF) != 0; metrics->is_temp_throttled = ((indep_throttle_status >> 32) & 0xFFFF) != 0; metrics->is_other_throttled = ((indep_throttle_status >> 56) & 0xFF) != 0; + if (throttling) + throttling->indep_throttle_status = indep_throttle_status; } void amdgpu_get_samples_and_copy(struct amdgpu_common_metrics metrics_buffer[METRICS_SAMPLE_COUNT], bool &gpu_load_needs_dividing) { diff --git a/src/amdgpu.h b/src/amdgpu.h index a41f05b7..79d296c7 100644 --- a/src/amdgpu.h +++ b/src/amdgpu.h @@ -8,7 +8,8 @@ #include "overlay_params.h" #include #include -// #include +#include +#include #define METRICS_UPDATE_PERIOD_MS 500 #define METRICS_POLLING_PERIOD_MS 25 @@ -19,6 +20,9 @@ #define UPDATE_METRIC_AVERAGE_FLOAT(FIELD) do { float value_sum = 0; for (size_t s=0; s < METRICS_SAMPLE_COUNT; s++) { value_sum += metrics_buffer[s].FIELD; } amdgpu_common_metrics.FIELD = value_sum / METRICS_SAMPLE_COUNT; } while(0) #define UPDATE_METRIC_MAX(FIELD) do { int cur_max = metrics_buffer[0].FIELD; for (size_t s=1; s < METRICS_SAMPLE_COUNT; s++) { cur_max = MAX(cur_max, metrics_buffer[s].FIELD); }; amdgpu_common_metrics.FIELD = cur_max; } while(0) #define UPDATE_METRIC_LAST(FIELD) do { amdgpu_common_metrics.FIELD = metrics_buffer[METRICS_SAMPLE_COUNT - 1].FIELD; } while(0) +#ifdef _WIN32 +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif struct metrics_table_header { uint16_t structure_size; @@ -195,3 +199,34 @@ extern bool amdgpu_run_thread; void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics); void amdgpu_metrics_polling_thread(); void amdgpu_get_samples_and_copy(struct amdgpu_common_metrics metrics_buffer[METRICS_SAMPLE_COUNT], bool &gpu_load_needs_dividing); +void amdgpu_trottling_thread(std::vector &power, std::vector &thermal); + +class Throttling { + public: + std::vector power; + std::vector thermal; + int64_t indep_throttle_status; + + Throttling() + : power(200, 0.0f), + thermal(200, 0.0f) {} + + void update(){ + if (((indep_throttle_status >> 0) & 0xFF) != 0) + power.push_back(0.1); + else + power.push_back(0); + + + if (((indep_throttle_status >> 32) & 0xFFFF) != 0) + thermal.push_back(0.1); + else + thermal.push_back(0); + + power.erase(power.begin()); + thermal.erase(thermal.begin()); + } + +}; + +extern std::unique_ptr throttling; diff --git a/src/overlay.cpp b/src/overlay.cpp index 8165274c..36b1f8d5 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -241,9 +241,13 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const stru if (sw_stats.last_present_time) { sw_stats.frames_stats[f_idx].stats[OVERLAY_PLOTS_frame_timing] = frametime_ns; - frametime_data[f_idx] = frametime_ms; + frametime_data.push_back(frametime_ms); + frametime_data.erase(frametime_data.begin()); } - +#ifdef __linux__ + if (throttling) + throttling->update(); +#endif frametime = frametime_ms; fps = double(1000 / frametime_ms); @@ -869,6 +873,7 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para if (amdgpu_verify_metrics(gpu_metrics_path)) { gpu_metrics_exists = true; metrics_path = gpu_metrics_path; + throttling = std::make_unique(); SPDLOG_DEBUG("Using gpu_metrics of {}", gpu_metrics_path); } diff --git a/src/overlay.h b/src/overlay.h index 909988a7..8b53285c 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -91,6 +91,7 @@ extern double min_frametime, max_frametime; extern bool steam_focused; extern int fan_speed; extern int current_preset; +extern std::vector frametime_data; void init_spdlog(); void overlay_new_frame(const struct overlay_params& params);