Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/amdgpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,15 @@ AMDGPU::AMDGPU(std::string pci_dev, uint32_t device_id, uint32_t vendor_id) {
}
}

// Probe voltage before the polling thread starts; it shares this FILE*.
if (sysfs_nodes.gpu_voltage_soc) {
int64_t value = 0;
rewind(sysfs_nodes.gpu_voltage_soc);
fflush(sysfs_nodes.gpu_voltage_soc);
if (fscanf(sysfs_nodes.gpu_voltage_soc, "%" PRId64, &value) == 1 && value > 0)
voltage_is_valid = true;
}

throttling = std::make_shared<Throttling>(0x1002);
#ifndef TEST_ONLY
fdinfo_helper = std::make_unique<GPU_fdinfo>("amdgpu", pci_dev, "", /*called_from_amdgpu_cpp=*/ true);
Expand Down
8 changes: 8 additions & 0 deletions src/amdgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,13 @@ class AMDGPU {
cond_var.notify_one();
}

bool has_fan_sensor() const { return sysfs_nodes.fan != nullptr; }
bool has_junction_temp_sensor() const { return sysfs_nodes.junction_temp != nullptr; }
bool has_memory_temp_sensor() const { return sysfs_nodes.memory_temp != nullptr; }
bool has_power_limit_sensor() const { return sysfs_nodes.power_limit != nullptr; }
// in0_input exists on some APUs but always reads 0, so require a reading
bool has_voltage_sensor() const { return sysfs_nodes.gpu_voltage_soc != nullptr && voltage_is_valid; }

private:
std::string pci_dev;
std::string gpu_metrics_path;
Expand All @@ -515,6 +522,7 @@ class AMDGPU {
std::thread thread;
struct amdgpu_files sysfs_nodes = {};
bool gpu_metrics_is_valid = false;
bool voltage_is_valid = false; // gpu_voltage_soc read non-zero at init
std::condition_variable cond_var;
std::atomic<bool> stop_thread{false};
std::atomic<bool> paused{false};
Expand Down
7 changes: 7 additions & 0 deletions src/gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ class GPU {
return false;
}

// Sensor availability: AMD and Intel report it from hwmon
bool has_fan_sensor() { return amdgpu ? amdgpu->has_fan_sensor() : fdinfo ? fdinfo->has_fan_sensor() : true; }
bool has_junction_temp_sensor() { return amdgpu ? amdgpu->has_junction_temp_sensor() : fdinfo ? fdinfo->has_junction_temp_sensor() : true; }
bool has_memory_temp_sensor() { return amdgpu ? amdgpu->has_memory_temp_sensor() : fdinfo ? fdinfo->has_memory_temp_sensor() : true; }
bool has_voltage_sensor() { return amdgpu ? amdgpu->has_voltage_sensor() : fdinfo ? fdinfo->has_voltage_sensor() : true; }
bool has_power_limit_sensor() { return amdgpu ? amdgpu->has_power_limit_sensor() : fdinfo ? fdinfo->has_power_limit_sensor() : true; }

std::shared_ptr<Throttling> throttling() {
if (nvidia)
return nvidia->throttling;
Expand Down
18 changes: 18 additions & 0 deletions src/gpu_fdinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class GPU_fdinfo {
uint64_t fdinfo_last_update_ms = 0;

std::map<std::string, hwmon_sensor> hwmon_sensors;
bool fan_avail = false, voltage_avail = false;
bool mem_temp_avail = false, power_limit_avail = false;

std::string drm_engine_type = "EMPTY";
std::string drm_memory_type = "EMPTY";
Expand All @@ -83,6 +85,10 @@ class GPU_fdinfo {

float get_memory_used();

bool hwmon_has(const std::string& key) const {
auto it = hwmon_sensors.find(key);
return it != hwmon_sensors.end() && !it->second.filename.empty();
}
void find_hwmon_sensors();
std::string find_hwmon_dir();
std::string find_hwmon_sensor_dir(std::string name);
Expand Down Expand Up @@ -208,6 +214,12 @@ class GPU_fdinfo {

find_hwmon_sensors();

// Snapshot availability before the worker thread starts mutating the map.
fan_avail = hwmon_has("fan_speed");
voltage_avail = hwmon_has("voltage");
mem_temp_avail = hwmon_has("vram_temp");
power_limit_avail = hwmon_has("power_limit");

if (module == "i915")
find_i915_gt_dir();
else if (module == "xe")
Expand Down Expand Up @@ -242,4 +254,10 @@ class GPU_fdinfo {
}

float amdgpu_helper_get_proc_vram();

bool has_fan_sensor() const { return fan_avail; }
bool has_voltage_sensor() const { return voltage_avail; }
bool has_memory_temp_sensor() const { return mem_temp_avail; }
bool has_power_limit_sensor() const { return power_limit_avail; }
bool has_junction_temp_sensor() const { return false; } // not exposed via fdinfo
};
3 changes: 2 additions & 1 deletion src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,8 @@ void HudElements::ram(){
ImGui::PopFont();
}

if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram_temp]) {
// only when an spd5118 RAM temp sensor exists, else mem_temp is a bogus 0
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram_temp] && mem_temp_available) {
ImguiNextColumnOrNewRow();
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_temp_fahrenheit])
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%i", HUDElements.convert_to_fahrenheit(mem_temp));
Expand Down
2 changes: 2 additions & 0 deletions src/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

float memused, memmax, swapused;
int mem_temp;
bool mem_temp_available = false;
uint64_t proc_mem_resident, proc_mem_shared, proc_mem_virt;

void update_meminfo() {
Expand Down Expand Up @@ -46,6 +47,7 @@ void update_mem_temp() {
if (read_line(path + dir + "/name") == "spd5118")
mem_temp_files.emplace_back(path + dir + "/temp1_input");
}
mem_temp_available = !mem_temp_files.empty();
if (mem_temp_files.empty())
SPDLOG_ERROR("failed to find known ram temp sensors");
}
Expand Down
1 change: 1 addition & 0 deletions src/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

extern float memused, memmax, swapused;
extern int mem_temp;
extern bool mem_temp_available;
extern uint64_t proc_mem_resident, proc_mem_shared, proc_mem_virt;

void update_meminfo();
Expand Down
28 changes: 16 additions & 12 deletions src/overlay_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1380,22 +1380,26 @@ void presets(int preset, struct overlay_params *params, bool inherit) {
add_to_options(params, "gpu_efficiency", "0");
add_to_options(params, "cpu_efficiency", "0");

// Disable some options if steamdeck / other known handhelds
// Hide GPU fields with no backing sensor on any detected GPU
if (!gpus)
gpus = std::make_unique<GPUS>(params);

for (auto gpu : gpus->available_gpus) {
if (gpu->device_id == 0x1435 || gpu->device_id == 0x163f || gpu->device_id == 0x1681 || gpu->device_id == 0x15bf){
add_to_options(params, "gpu_fan", "0");
add_to_options(params, "gpu_junction_temp", "0");
add_to_options(params, "gpu_voltage", "0");
add_to_options(params, "gpu_mem_temp", "0");
add_to_options(params, "gpu_efficiency", "0");
}
// Rembrandt and Phoenix APUs (Z1, Z1E, Z2 Go)
if (gpu->device_id == 0x1681 || gpu->device_id == 0x15bf){
add_to_options(params, "gpu_power_limit", "0");
if (!gpus->available_gpus.empty()) {
bool has_fan = false, has_junction_temp = false, has_memory_temp = false;
bool has_voltage = false, has_power_limit = false;
for (auto gpu : gpus->available_gpus) {
has_fan |= gpu->has_fan_sensor();
has_junction_temp |= gpu->has_junction_temp_sensor();
has_memory_temp |= gpu->has_memory_temp_sensor();
has_voltage |= gpu->has_voltage_sensor();
has_power_limit |= gpu->has_power_limit_sensor();
}

if (!has_fan) add_to_options(params, "gpu_fan", "0");
if (!has_junction_temp) add_to_options(params, "gpu_junction_temp", "0");
if (!has_memory_temp) add_to_options(params, "gpu_mem_temp", "0");
if (!has_voltage) add_to_options(params, "gpu_voltage", "0");
if (!has_power_limit) add_to_options(params, "gpu_power_limit", "0");
}

break;
Expand Down
Loading