mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
Merge pull request #108 from ilya-zlobintsev/rx-6000-fixes
feat: voltage offset support, fixes for rx 6000 series format
This commit is contained in:
commit
b9f8f1cc86
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -25,9 +25,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "amdgpu-sysfs"
|
||||
version = "0.9.5"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae160ad9551e11cf5aa19fc78b590ee5f8ccfe07f983a99bead7a6680907da30"
|
||||
checksum = "6667682d11c8face0277986d0cfc0862399febf666e0d9a9d8b12fa0362373ba"
|
||||
dependencies = [
|
||||
"enum_dispatch",
|
||||
"serde",
|
||||
|
@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
amdgpu-sysfs = { version = "0.9.5", features = ["serde"] }
|
||||
amdgpu-sysfs = { version = "0.9.7", features = ["serde"] }
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3"
|
||||
nix = "0.26"
|
||||
|
@ -41,6 +41,7 @@ pub struct Gpu {
|
||||
pub max_core_clock: Option<u32>,
|
||||
pub max_memory_clock: Option<u32>,
|
||||
pub max_voltage: Option<u32>,
|
||||
pub voltage_offset: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
|
@ -11,8 +11,8 @@ use amdgpu_sysfs::{
|
||||
};
|
||||
use anyhow::{anyhow, Context};
|
||||
use lact_schema::{
|
||||
ClocksInfo, ClocksTable, ClockspeedStats, DeviceInfo, DeviceStats, FanStats, GpuPciInfo,
|
||||
LinkInfo, PciInfo, PerformanceLevel, PowerStats, VoltageStats, VramStats,
|
||||
ClocksInfo, ClocksTable, ClocksTableGen, ClockspeedStats, DeviceInfo, DeviceStats, FanStats,
|
||||
GpuPciInfo, LinkInfo, PciInfo, PerformanceLevel, PowerStats, VoltageStats, VramStats,
|
||||
};
|
||||
use pciid_parser::Database;
|
||||
use std::{
|
||||
@ -347,6 +347,15 @@ impl GpuController {
|
||||
{
|
||||
let mut table = self.handle.get_clocks_table()?;
|
||||
|
||||
if let ClocksTableGen::Vega20(ref mut table) = table {
|
||||
// Avoid writing settings to the clocks table except the user-specified ones
|
||||
// There is an issue on some GPU models where the default values are actually outside of the allowed range
|
||||
// See https://github.com/sibradzic/amdgpu-clocks/issues/32#issuecomment-829953519 (part 2) for an example
|
||||
table.clear();
|
||||
|
||||
table.voltage_offset = config.voltage_offset;
|
||||
}
|
||||
|
||||
if let Some(clockspeed) = config.max_core_clock {
|
||||
table.set_max_sclk(clockspeed)?;
|
||||
}
|
||||
|
@ -214,6 +214,7 @@ impl<'a> Handler {
|
||||
SetClocksCommand::MaxCoreClock(clock) => gpu_config.max_core_clock = Some(clock),
|
||||
SetClocksCommand::MaxMemoryClock(clock) => gpu_config.max_memory_clock = Some(clock),
|
||||
SetClocksCommand::MaxVoltage(voltage) => gpu_config.max_voltage = Some(voltage),
|
||||
SetClocksCommand::VoltageOffset(offset) => gpu_config.voltage_offset = Some(offset),
|
||||
SetClocksCommand::Reset => {
|
||||
gpu_config.max_core_clock = None;
|
||||
gpu_config.max_memory_clock = None;
|
||||
|
@ -297,6 +297,12 @@ impl App {
|
||||
.context("Could not set the maximum voltage")?;
|
||||
}
|
||||
|
||||
if let Some(offset) = clocks_settings.voltage_offset {
|
||||
self.daemon_client
|
||||
.set_clocks_value(&gpu_id, SetClocksCommand::VoltageOffset(offset))
|
||||
.context("Could not set the voltage offset")?;
|
||||
}
|
||||
|
||||
self.set_initial(&gpu_id);
|
||||
|
||||
Ok(())
|
||||
|
@ -34,7 +34,7 @@ impl InformationPage {
|
||||
let gpu_name_label = label_row("GPU Model:", &values_grid, 0, 0, true);
|
||||
let gpu_manufacturer_label = label_row("GPU Manufacturer:", &values_grid, 1, 0, true);
|
||||
let vbios_version_label = label_row("VBIOS Version:", &values_grid, 2, 0, true);
|
||||
let driver_label = label_row("Driver Version:", &values_grid, 3, 0, true);
|
||||
let driver_label = label_row("Driver Used:", &values_grid, 3, 0, true);
|
||||
let vram_size_label = label_row("VRAM Size:", &values_grid, 4, 0, true);
|
||||
let link_speed_label = label_row("Link Speed:", &values_grid, 5, 0, true);
|
||||
|
||||
|
@ -4,6 +4,9 @@ use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use lact_client::schema::{ClocksTable, ClocksTableGen};
|
||||
|
||||
const VOLTAGE_OFFSET_RANGE: f64 = 250.0;
|
||||
const WARNING_TEXT: &str = "Warning: changing these values may lead to system instability and potentially damage your hardware!";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClocksFrame {
|
||||
pub container: Box,
|
||||
@ -11,6 +14,7 @@ pub struct ClocksFrame {
|
||||
max_sclk_adjustment: Adjustment,
|
||||
max_mclk_adjustment: Adjustment,
|
||||
max_voltage_adjustment: Adjustment,
|
||||
voltage_offset_adjustment: Adjustment,
|
||||
reset_button: Button,
|
||||
clocks_data_unavailable_label: Label,
|
||||
}
|
||||
@ -20,15 +24,29 @@ impl ClocksFrame {
|
||||
let container = section_box("Maximum Clocks");
|
||||
|
||||
let tweaking_grid = Grid::builder().row_spacing(5).build();
|
||||
let max_sclk_adjustment = oc_adjustment("GPU Clock (MHz)", &tweaking_grid, 0);
|
||||
let max_voltage_adjustment = oc_adjustment("GPU voltage (mV)", &tweaking_grid, 1);
|
||||
let max_mclk_adjustment = oc_adjustment("VRAM Clock (MHz)", &tweaking_grid, 2);
|
||||
|
||||
let warning_label = Label::builder()
|
||||
.label(WARNING_TEXT)
|
||||
.wrap_mode(pango::WrapMode::Word)
|
||||
.halign(Align::Start)
|
||||
.hexpand(true)
|
||||
.margin_top(5)
|
||||
.margin_bottom(5)
|
||||
.build();
|
||||
tweaking_grid.attach(&warning_label, 0, 0, 7, 1);
|
||||
|
||||
let max_sclk_adjustment = oc_adjustment("GPU Clock (MHz)", &tweaking_grid, 1);
|
||||
let max_voltage_adjustment = oc_adjustment("GPU voltage (mV)", &tweaking_grid, 2);
|
||||
let max_mclk_adjustment = oc_adjustment("VRAM Clock (MHz)", &tweaking_grid, 3);
|
||||
let voltage_offset_adjustment = oc_adjustment("GPU voltage offset (mV)", &tweaking_grid, 4);
|
||||
|
||||
let reset_button = Button::builder()
|
||||
.label("Defaults")
|
||||
.label("Reset")
|
||||
.halign(Align::End)
|
||||
.tooltip_text("Warning: this resets all clock settings to defaults!")
|
||||
.css_classes(["destructive-action"])
|
||||
.build();
|
||||
tweaking_grid.attach(&reset_button, 6, 3, 1, 1);
|
||||
tweaking_grid.attach(&reset_button, 6, 5, 1, 1);
|
||||
|
||||
let clocks_data_unavailable_label = Label::new(Some("No clocks data available"));
|
||||
|
||||
@ -43,10 +61,12 @@ impl ClocksFrame {
|
||||
max_voltage_adjustment,
|
||||
reset_button,
|
||||
clocks_data_unavailable_label,
|
||||
voltage_offset_adjustment,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_table(&self, table: ClocksTableGen) -> anyhow::Result<()> {
|
||||
// The upper value "0.0" is used to hide the adjustment when info is not available
|
||||
if let Some((current_sclk_max, sclk_min, sclk_max)) =
|
||||
extract_value_and_range(&table, |table| {
|
||||
(table.get_max_sclk(), table.get_max_sclk_range())
|
||||
@ -55,6 +75,8 @@ impl ClocksFrame {
|
||||
self.max_sclk_adjustment.set_lower(sclk_min.into());
|
||||
self.max_sclk_adjustment.set_upper(sclk_max.into());
|
||||
self.max_sclk_adjustment.set_value(current_sclk_max.into());
|
||||
} else {
|
||||
self.max_sclk_adjustment.set_upper(0.0);
|
||||
}
|
||||
|
||||
if let Some((current_mclk_max, mclk_min, mclk_max)) =
|
||||
@ -65,6 +87,8 @@ impl ClocksFrame {
|
||||
self.max_mclk_adjustment.set_lower(mclk_min.into());
|
||||
self.max_mclk_adjustment.set_upper(mclk_max.into());
|
||||
self.max_mclk_adjustment.set_value(current_mclk_max.into());
|
||||
} else {
|
||||
self.max_mclk_adjustment.set_upper(0.0);
|
||||
}
|
||||
|
||||
if let Some((current_voltage_max, voltage_min, voltage_max)) =
|
||||
@ -76,8 +100,30 @@ impl ClocksFrame {
|
||||
self.max_voltage_adjustment.set_upper(voltage_max.into());
|
||||
self.max_voltage_adjustment
|
||||
.set_value(current_voltage_max.into());
|
||||
} else {
|
||||
self.max_voltage_adjustment.set_upper(0.0);
|
||||
}
|
||||
|
||||
if let ClocksTableGen::Vega20(table) = table {
|
||||
if let Some(offset) = table.voltage_offset {
|
||||
// TODO: check this
|
||||
self.voltage_offset_adjustment
|
||||
.set_lower(VOLTAGE_OFFSET_RANGE * -1.0);
|
||||
self.voltage_offset_adjustment
|
||||
.set_upper(VOLTAGE_OFFSET_RANGE);
|
||||
self.voltage_offset_adjustment.set_value(offset.into());
|
||||
} else {
|
||||
self.voltage_offset_adjustment.set_upper(0.0);
|
||||
}
|
||||
} else {
|
||||
self.voltage_offset_adjustment.set_upper(0.0);
|
||||
}
|
||||
|
||||
emit_changed(&self.max_sclk_adjustment);
|
||||
emit_changed(&self.max_mclk_adjustment);
|
||||
emit_changed(&self.max_voltage_adjustment);
|
||||
emit_changed(&self.voltage_offset_adjustment);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -95,7 +141,8 @@ impl ClocksFrame {
|
||||
let f = clone!(@strong f => move |_: &Adjustment| f());
|
||||
self.max_sclk_adjustment.connect_value_changed(f.clone());
|
||||
self.max_mclk_adjustment.connect_value_changed(f.clone());
|
||||
self.max_voltage_adjustment.connect_value_changed(f);
|
||||
self.max_voltage_adjustment.connect_value_changed(f.clone());
|
||||
self.voltage_offset_adjustment.connect_value_changed(f);
|
||||
}
|
||||
|
||||
pub fn connect_clocks_reset<F: Fn() + 'static + Clone>(&self, f: F) {
|
||||
@ -108,10 +155,17 @@ impl ClocksFrame {
|
||||
let max_memory_clock = zero_to_option(self.max_mclk_adjustment.value());
|
||||
let max_voltage = zero_to_option(self.max_voltage_adjustment.value());
|
||||
|
||||
let voltage_offset = if self.voltage_offset_adjustment.upper() == 0.0 {
|
||||
None
|
||||
} else {
|
||||
Some(self.voltage_offset_adjustment.value() as i32)
|
||||
};
|
||||
|
||||
ClocksSettings {
|
||||
max_core_clock,
|
||||
max_memory_clock,
|
||||
max_voltage,
|
||||
voltage_offset,
|
||||
}
|
||||
} else {
|
||||
ClocksSettings::default()
|
||||
@ -130,7 +184,7 @@ fn extract_value_and_range(
|
||||
}
|
||||
|
||||
fn oc_adjustment(title: &'static str, grid: &Grid, row: i32) -> Adjustment {
|
||||
let label = Label::new(Some(title));
|
||||
let label = Label::builder().label(title).halign(Align::Start).build();
|
||||
|
||||
let adjustment = Adjustment::new(0.0, 0.0, 0.0, 1.0, 10.0, 0.0);
|
||||
|
||||
@ -148,17 +202,36 @@ fn oc_adjustment(title: &'static str, grid: &Grid, row: i32) -> Adjustment {
|
||||
let value_selector = SpinButton::new(Some(&adjustment), 1.0, 0);
|
||||
let value_label = Label::new(None);
|
||||
|
||||
adjustment.connect_value_changed(clone!(@strong value_label => move |adjustment| {
|
||||
let value = adjustment.value();
|
||||
value_label.set_text(&value.to_string());
|
||||
}));
|
||||
|
||||
let popover = Popover::builder().child(&value_selector).build();
|
||||
let value_button = MenuButton::builder()
|
||||
.popover(&popover)
|
||||
.child(&value_label)
|
||||
.build();
|
||||
|
||||
adjustment.connect_value_changed(clone!(@strong value_label => move |adjustment| {
|
||||
let value = adjustment.value();
|
||||
value_label.set_text(&value.to_string());
|
||||
}));
|
||||
|
||||
adjustment.connect_changed(
|
||||
clone!(@strong label, @strong value_label, @strong scale, @strong value_button => move |adjustment| {
|
||||
let value = adjustment.value();
|
||||
value_label.set_text(&value.to_string());
|
||||
|
||||
if adjustment.upper() == 0.0 {
|
||||
label.hide();
|
||||
value_label.hide();
|
||||
scale.hide();
|
||||
value_button.hide();
|
||||
} else {
|
||||
label.show();
|
||||
value_label.show();
|
||||
scale.show();
|
||||
value_button.show();
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
grid.attach(&label, 0, row, 1, 1);
|
||||
grid.attach(&scale, 1, row, 4, 1);
|
||||
grid.attach(&value_button, 6, row, 4, 1);
|
||||
@ -171,6 +244,7 @@ pub struct ClocksSettings {
|
||||
pub max_core_clock: Option<u32>,
|
||||
pub max_memory_clock: Option<u32>,
|
||||
pub max_voltage: Option<u32>,
|
||||
pub voltage_offset: Option<i32>,
|
||||
}
|
||||
|
||||
fn zero_to_option(value: f64) -> Option<u32> {
|
||||
@ -180,3 +254,7 @@ fn zero_to_option(value: f64) -> Option<u32> {
|
||||
Some(value as u32)
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_changed(adjustment: &Adjustment) {
|
||||
adjustment.emit_by_name::<()>("changed", &[]);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ version = "0.2.2"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
amdgpu-sysfs = { version = "0.9.5", features = ["serde"] }
|
||||
amdgpu-sysfs = { version = "0.9.7", features = ["serde"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
indexmap = { version = "*", features = ["serde"] }
|
||||
|
||||
|
@ -42,5 +42,6 @@ pub enum SetClocksCommand {
|
||||
MaxCoreClock(u32),
|
||||
MaxMemoryClock(u32),
|
||||
MaxVoltage(u32),
|
||||
VoltageOffset(i32),
|
||||
Reset,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user