Add gpu throttling status

Co-authored-by: Martin Roukala <martin.roukala@mupuf.org>
pull/758/head
FlightlessMango 2 years ago
parent ae85730448
commit f9cfdeb080

@ -31,6 +31,12 @@ struct amdgpu_common_metrics {
uint16_t soc_temp_c;
uint16_t gpu_temp_c;
uint16_t apu_cpu_temp_c;
/* throttling status */
bool is_power_throttled;
bool is_current_throttled;
bool is_temp_throttled;
bool is_other_throttled;
} amdgpu_common_metrics;
std::mutex amdgpu_common_metrics_m;
@ -71,6 +77,7 @@ void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) {
struct metrics_table_header header;
std::ifstream in(metrics_path, std::ios_base::in | std::ios_base::binary);
in.read((char*)&header, sizeof(header));
int64_t indep_throttle_status = 0;
if (header.format_revision == 1) {
// Desktop GPUs
struct gpu_metrics_v1_3 amdgpu_metrics;
@ -86,6 +93,7 @@ void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) {
metrics->current_uclk_mhz = amdgpu_metrics.current_uclk;
metrics->gpu_temp_c = amdgpu_metrics.temperature_edge;
indep_throttle_status = amdgpu_metrics.indep_throttle_status;
} else if (header.format_revision == 2) {
// APUs
cpuStats.cpu_type = "APU";
@ -108,7 +116,16 @@ void amdgpu_get_instant_metrics(struct amdgpu_common_metrics *metrics) {
for (unsigned i = 0; i < 8; i++)
cpu_temp = MAX(cpu_temp, amdgpu_metrics.temperature_core[i]);
metrics->apu_cpu_temp_c = cpu_temp / 100;
indep_throttle_status = amdgpu_metrics.indep_throttle_status;
}
/* Throttling: See
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h
for the offsets */
metrics->is_power_throttled = ((indep_throttle_status >> 0) & 0xFF) != 0;
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;
}
}
@ -149,6 +166,10 @@ void amdgpu_metrics_polling_thread() {
UPDATE_METRIC_MAX(soc_temp_c);
UPDATE_METRIC_MAX(gpu_temp_c);
UPDATE_METRIC_MAX(apu_cpu_temp_c);
UPDATE_METRIC_MAX(is_power_throttled);
UPDATE_METRIC_MAX(is_current_throttled);
UPDATE_METRIC_MAX(is_temp_throttled);
UPDATE_METRIC_MAX(is_other_throttled);
amdgpu_common_metrics_m.unlock();
}
}
@ -170,5 +191,11 @@ void amdgpu_get_metrics(){
gpu_info.temp = amdgpu_common_metrics.gpu_temp_c;
gpu_info.apu_cpu_power = amdgpu_common_metrics.apu_cpu_temp_c;
gpu_info.is_power_throttled = amdgpu_common_metrics.is_power_throttled;
gpu_info.is_current_throttled = amdgpu_common_metrics.is_current_throttled;
gpu_info.is_temp_throttled = amdgpu_common_metrics.is_temp_throttled;
gpu_info.is_other_throttled = amdgpu_common_metrics.is_other_throttled;
amdgpu_common_metrics_m.unlock();
}

@ -46,6 +46,9 @@ void getNvidiaGpuInfo(){
gpu_info.MemClock = nvidiaMemClock;
gpu_info.powerUsage = nvidiaPowerUsage / 1000;
gpu_info.memoryTotal = nvidiaMemory.total / (1024.f * 1024.f * 1024.f);
gpu_info.is_temp_throttled = (nvml_throttle_reasons & 0x0000000000000060LL) != 0;
gpu_info.is_power_throttled = (nvml_throttle_reasons & 0x000000000000008CLL) != 0;
gpu_info.is_other_throttled = (nvml_throttle_reasons & 0x0000000000000112LL) != 0;
return;
}
#endif

@ -29,6 +29,10 @@ struct gpuInfo{
float powerUsage;
float apu_cpu_power;
int apu_cpu_temp;
bool is_power_throttled;
bool is_current_throttled;
bool is_temp_throttled;
bool is_other_throttled;
};
extern struct gpuInfo gpu_info;

@ -927,6 +927,25 @@ void HudElements::fan(){
}
}
void HudElements::throttling_status(){
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_throttling_status]){
if (gpu_info.is_power_throttled || gpu_info.is_current_throttled || gpu_info.is_temp_throttled || gpu_info.is_other_throttled){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::TextColored(HUDElements.colors.engine, "%s", "Throttling");
ImGui::TableNextColumn();
ImGui::TableNextColumn();
if (gpu_info.is_power_throttled)
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "Power");
if (gpu_info.is_current_throttled)
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "Current");
if (gpu_info.is_temp_throttled)
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "Temp");
if (gpu_info.is_other_throttled)
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "Other");
}
}
}
void HudElements::graphs(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
@ -1082,7 +1101,8 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
if (param == "debug") { ordered_functions.push_back({gamescope_frame_timing, value}); }
if (param == "gamepad_battery") { ordered_functions.push_back({gamepad_battery, value}); }
if (param == "framecount") { ordered_functions.push_back({framecount, value}); }
if (param == "fan") { ordered_functions.push_back({fan, value}); }
if (param == "fan") { ordered_functions.push_back({fan, value}); }
if (param == "throttling_status") { ordered_functions.push_back({throttling_status, value}); }
if (param == "graphs"){
if (!HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs])
HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_graphs] = true;
@ -1115,6 +1135,7 @@ void HudElements::legacy_elements(){
ordered_functions.push_back({battery, value});
ordered_functions.push_back({fan, value});
ordered_functions.push_back({gamescope_fsr, value});
ordered_functions.push_back({throttling_status, value});
ordered_functions.push_back({fps, value});
ordered_functions.push_back({fps_only, value});
#ifndef MANGOAPP

@ -64,6 +64,7 @@ class HudElements{
static void gamepad_battery();
static void framecount();
static void fan();
static void throttling_status();
void convert_colors(const struct overlay_params& params);
void convert_colors(bool do_conv, const struct overlay_params& params);

@ -188,6 +188,19 @@ bool libnvml_loader::Load(const std::string& library_name) {
return false;
}
#if defined(LIBRARY_LOADER_NVML_H_DLOPEN)
nvmlDeviceGetCurrentClocksThrottleReasons =
reinterpret_cast<decltype(this->nvmlDeviceGetCurrentClocksThrottleReasons)>(
dlsym(library_, "nvmlDeviceGetCurrentClocksThrottleReasons"));
#endif
#if defined(LIBRARY_LOADER_NVML_H_DT_NEEDED)
nvmlDeviceGetCurrentClocksThrottleReasons = &::nvmlDeviceGetCurrentClocksThrottleReasons;
#endif
if (!nvmlErrorString) {
CleanUp(true);
return false;
}
#if defined(LIBRARY_LOADER_NVML_H_DLOPEN)
nvmlDeviceGetPowerUsage =
reinterpret_cast<decltype(this->nvmlDeviceGetPowerUsage)>(
@ -205,6 +218,7 @@ bool libnvml_loader::Load(const std::string& library_name) {
return true;
}
void libnvml_loader::CleanUp(bool unload) {
#if defined(LIBRARY_LOADER_NVML_H_DLOPEN)
if (unload) {
@ -221,5 +235,5 @@ void libnvml_loader::CleanUp(bool unload) {
nvmlDeviceGetCount_v2 = NULL;
nvmlDeviceGetHandleByIndex_v2 = NULL;
nvmlDeviceGetHandleByPciBusId_v2 = NULL;
nvmlDeviceGetCurrentClocksThrottleReasons = NULL;
}

@ -37,6 +37,7 @@ class libnvml_loader {
decltype(&::nvmlDeviceGetClockInfo) nvmlDeviceGetClockInfo;
decltype(&::nvmlErrorString) nvmlErrorString;
decltype(&::nvmlDeviceGetPowerUsage) nvmlDeviceGetPowerUsage;
decltype(&::nvmlDeviceGetCurrentClocksThrottleReasons) nvmlDeviceGetCurrentClocksThrottleReasons;
private:
void CleanUp(bool unload);

@ -10,6 +10,7 @@ extern nvmlDevice_t nvidiaDevice;
extern struct nvmlUtilization_st nvidiaUtilization;
extern struct nvmlMemory_st nvidiaMemory;
extern bool nvmlSuccess;
extern unsigned long long nvml_throttle_reasons;
bool checkNVML(const char* pciBusId);
bool getNVMLInfo(void);

@ -9,6 +9,7 @@ nvmlDevice_t nvidiaDevice;
nvmlPciInfo_t nvidiaPciInfo;
bool nvmlSuccess = false;
unsigned int nvidiaTemp = 0, nvidiaCoreClock = 0, nvidiaMemClock = 0, nvidiaPowerUsage = 0;
unsigned long long nvml_throttle_reasons;
struct nvmlUtilization_st nvidiaUtilization;
struct nvmlMemory_st nvidiaMemory {};
@ -55,6 +56,8 @@ bool getNVMLInfo(){
nvml.nvmlDeviceGetPowerUsage(nvidiaDevice, &nvidiaPowerUsage);
deviceID = nvidiaPciInfo.pciDeviceId >> 16;
nvml.nvmlDeviceGetCurrentClocksThrottleReasons(nvidiaDevice, &nvml_throttle_reasons);
if (response == NVML_ERROR_NOT_SUPPORTED) {
if (nvmlSuccess)
SPDLOG_ERROR("nvmlDeviceGetUtilizationRates failed");

@ -82,6 +82,7 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(gamepad_battery_icon) \
OVERLAY_PARAM_BOOL(hide_fsr_sharpness) \
OVERLAY_PARAM_BOOL(fan) \
OVERLAY_PARAM_BOOL(throttling_status) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \

Loading…
Cancel
Save