mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2025-02-25 18:55:26 -06:00
feat: show effective VRAM clockspeed in the GUI on GDDR6 (#368)
* feat: refactor clocks frame adjustments into a separate widget * feat: show effective VRAM clockspeed in the GUI on GDDR6
This commit is contained in:
parent
99f6e9ee35
commit
9dbce2a812
@ -189,6 +189,8 @@ impl GpuController {
|
||||
|
||||
#[cfg(feature = "libdrm_amdgpu_sys")]
|
||||
fn get_drm_info(&self) -> Option<DrmInfo> {
|
||||
use libdrm_amdgpu_sys::AMDGPU::VRAM_TYPE;
|
||||
|
||||
trace!("Reading DRM info");
|
||||
let drm_handle = self.drm_handle.as_ref();
|
||||
|
||||
@ -211,6 +213,10 @@ impl GpuController {
|
||||
chip_class: drm_info.get_chip_class().to_string(),
|
||||
compute_units: drm_info.cu_active_number,
|
||||
vram_type: drm_info.get_vram_type().to_string(),
|
||||
vram_clock_ratio: match drm_info.get_vram_type() {
|
||||
VRAM_TYPE::GDDR6 => 2.0,
|
||||
_ => 1.0,
|
||||
},
|
||||
vram_bit_width: drm_info.vram_bit_width,
|
||||
vram_max_bw: drm_info.peak_memory_bw_gb().to_string(),
|
||||
l1_cache_per_cu: drm_info.get_l1_cache_size(),
|
||||
|
@ -18,7 +18,7 @@ glib::wrapper! {
|
||||
|
||||
impl GraphsWindow {
|
||||
pub fn new() -> Self {
|
||||
Object::builder().build()
|
||||
Object::builder().property("vram_clock_ratio", 1.0).build()
|
||||
}
|
||||
|
||||
pub fn set_stats(&self, stats: &DeviceStats) {
|
||||
@ -79,7 +79,7 @@ impl GraphsWindow {
|
||||
clockspeed_plot.push_line_series("GPU (Trgt)", point as f64);
|
||||
}
|
||||
if let Some(point) = stats.clockspeed.vram_clockspeed {
|
||||
clockspeed_plot.push_line_series("VRAM", point as f64);
|
||||
clockspeed_plot.push_line_series("VRAM", point as f64 * self.vram_clock_ratio());
|
||||
}
|
||||
|
||||
if let Some(max_speed) = stats.fan.speed_max {
|
||||
@ -132,7 +132,7 @@ impl Default for GraphsWindow {
|
||||
mod imp {
|
||||
use super::plot::Plot;
|
||||
use gtk::{
|
||||
glib::{self, subclass::InitializingObject},
|
||||
glib::{self, subclass::InitializingObject, Properties},
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
@ -140,8 +140,10 @@ mod imp {
|
||||
},
|
||||
CompositeTemplate,
|
||||
};
|
||||
use std::cell::Cell;
|
||||
|
||||
#[derive(CompositeTemplate, Default)]
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::GraphsWindow)]
|
||||
#[template(file = "ui/graphs_window.blp")]
|
||||
pub struct GraphsWindow {
|
||||
#[template_child]
|
||||
@ -152,6 +154,9 @@ mod imp {
|
||||
pub(super) power_plot: TemplateChild<Plot>,
|
||||
#[template_child]
|
||||
pub(super) fan_plot: TemplateChild<Plot>,
|
||||
|
||||
#[property(get, set)]
|
||||
pub vram_clock_ratio: Cell<f64>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
@ -171,6 +176,7 @@ mod imp {
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for GraphsWindow {}
|
||||
|
||||
impl WidgetImpl for GraphsWindow {}
|
||||
|
@ -361,6 +361,14 @@ impl App {
|
||||
trace!("setting info {info:?}");
|
||||
|
||||
self.root_stack.info_page.set_info(&info);
|
||||
self.root_stack.oc_page.set_info(&info);
|
||||
|
||||
let vram_clock_ratio = info
|
||||
.drm_info
|
||||
.as_ref()
|
||||
.map(|info| info.vram_clock_ratio)
|
||||
.unwrap_or(1.0);
|
||||
self.graphs_window.set_vram_clock_ratio(vram_clock_ratio);
|
||||
|
||||
self.set_initial(gpu_id);
|
||||
self.root_stack.thermals_page.set_info(&info);
|
||||
|
@ -1,10 +1,13 @@
|
||||
mod adjustment_row;
|
||||
|
||||
use crate::app::page_section::PageSection;
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use adjustment_row::AdjustmentRow;
|
||||
use amdgpu_sysfs::gpu_handle::overdrive::{ClocksTable, ClocksTableGen};
|
||||
use glib::clone;
|
||||
use gtk::prelude::*;
|
||||
use gtk::*;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use subclass::prelude::ObjectSubclassIsExt;
|
||||
use tracing::debug;
|
||||
|
||||
const DEFAULT_VOLTAGE_OFFSET_RANGE: i32 = 250;
|
||||
@ -19,13 +22,13 @@ pub struct ClocksFrame {
|
||||
basic_togglebutton: ToggleButton,
|
||||
advanced_togglebutton: ToggleButton,
|
||||
min_values_grid: Grid,
|
||||
min_sclk_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
min_mclk_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
min_voltage_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
max_sclk_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
max_mclk_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
max_voltage_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
voltage_offset_adjustment: (Adjustment, Scale, Rc<AtomicBool>),
|
||||
min_sclk_adjustment: AdjustmentRow,
|
||||
min_mclk_adjustment: AdjustmentRow,
|
||||
min_voltage_adjustment: AdjustmentRow,
|
||||
max_sclk_adjustment: AdjustmentRow,
|
||||
max_mclk_adjustment: AdjustmentRow,
|
||||
max_voltage_adjustment: AdjustmentRow,
|
||||
voltage_offset_adjustment: AdjustmentRow,
|
||||
reset_button: Button,
|
||||
warning_label: Label,
|
||||
clocks_data_unavailable_label: Label,
|
||||
@ -62,18 +65,25 @@ impl ClocksFrame {
|
||||
|
||||
let min_values_grid = Grid::builder().row_spacing(5).build();
|
||||
|
||||
let min_sclk_adjustment = oc_adjustment("Minimum GPU Clock (MHz)", &min_values_grid, 0);
|
||||
let min_mclk_adjustment = oc_adjustment("Minimum VRAM Clock (MHz)", &min_values_grid, 1);
|
||||
let min_voltage_adjustment = oc_adjustment("Minimum GPU voltage (mV)", &min_values_grid, 2);
|
||||
let min_sclk_adjustment =
|
||||
AdjustmentRow::new_and_attach("Minimum GPU Clock (MHz)", &min_values_grid, 0);
|
||||
let min_mclk_adjustment =
|
||||
AdjustmentRow::new_and_attach("Minimum VRAM Clock (MHz)", &min_values_grid, 1);
|
||||
let min_voltage_adjustment =
|
||||
AdjustmentRow::new_and_attach("Minimum GPU voltage (mV)", &min_values_grid, 2);
|
||||
|
||||
container.append(&min_values_grid);
|
||||
|
||||
let tweaking_grid = Grid::builder().row_spacing(5).build();
|
||||
|
||||
let max_sclk_adjustment = oc_adjustment("Maximum GPU Clock (MHz)", &tweaking_grid, 1);
|
||||
let max_voltage_adjustment = oc_adjustment("Maximum GPU voltage (mV)", &tweaking_grid, 2);
|
||||
let max_mclk_adjustment = oc_adjustment("Maximum VRAM Clock (MHz)", &tweaking_grid, 3);
|
||||
let voltage_offset_adjustment = oc_adjustment("GPU voltage offset (mV)", &tweaking_grid, 4);
|
||||
let max_sclk_adjustment =
|
||||
AdjustmentRow::new_and_attach("Maximum GPU Clock (MHz)", &tweaking_grid, 1);
|
||||
let max_voltage_adjustment =
|
||||
AdjustmentRow::new_and_attach("Maximum GPU voltage (mV)", &tweaking_grid, 2);
|
||||
let max_mclk_adjustment =
|
||||
AdjustmentRow::new_and_attach("Maximum VRAM Clock (MHz)", &tweaking_grid, 3);
|
||||
let voltage_offset_adjustment =
|
||||
AdjustmentRow::new_and_attach("GPU voltage offset (mV)", &tweaking_grid, 4);
|
||||
|
||||
let reset_button = Button::builder()
|
||||
.label("Reset")
|
||||
@ -145,15 +155,14 @@ impl ClocksFrame {
|
||||
)
|
||||
})
|
||||
{
|
||||
self.min_sclk_adjustment.0.set_lower(sclk_min.into());
|
||||
self.min_sclk_adjustment.0.set_upper(sclk_max.into());
|
||||
self.min_sclk_adjustment
|
||||
.0
|
||||
.set_value(current_sclk_min.into());
|
||||
let min_sclk_adjustment = &self.min_sclk_adjustment.imp().adjustment;
|
||||
min_sclk_adjustment.set_lower(sclk_min.into());
|
||||
min_sclk_adjustment.set_upper(sclk_max.into());
|
||||
min_sclk_adjustment.set_initial_value(current_sclk_min.into());
|
||||
|
||||
self.min_sclk_adjustment.1.set_visible(true);
|
||||
self.min_sclk_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.min_sclk_adjustment.1.set_visible(false);
|
||||
self.min_sclk_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let Some((current_mclk_min, mclk_min, mclk_max)) =
|
||||
@ -164,14 +173,14 @@ impl ClocksFrame {
|
||||
)
|
||||
})
|
||||
{
|
||||
self.min_mclk_adjustment.0.set_lower(mclk_min.into());
|
||||
self.min_mclk_adjustment.0.set_upper(mclk_max.into());
|
||||
self.min_mclk_adjustment
|
||||
.0
|
||||
.set_value(current_mclk_min.into());
|
||||
self.min_mclk_adjustment.1.set_visible(true);
|
||||
let min_mclk_adjustment = &self.min_mclk_adjustment.imp().adjustment;
|
||||
min_mclk_adjustment.set_lower(mclk_min.into());
|
||||
min_mclk_adjustment.set_upper(mclk_max.into());
|
||||
min_mclk_adjustment.set_initial_value(current_mclk_min.into());
|
||||
|
||||
self.min_mclk_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.min_mclk_adjustment.1.set_visible(false);
|
||||
self.min_mclk_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let Some((current_min_voltage, voltage_min, voltage_max)) =
|
||||
@ -184,14 +193,15 @@ impl ClocksFrame {
|
||||
)
|
||||
})
|
||||
{
|
||||
self.min_voltage_adjustment.0.set_lower(voltage_min.into());
|
||||
self.min_voltage_adjustment.0.set_upper(voltage_max.into());
|
||||
self.min_voltage_adjustment
|
||||
.0
|
||||
.set_value(current_min_voltage.into());
|
||||
self.min_voltage_adjustment.1.set_visible(true);
|
||||
let min_voltage_adjustment = &self.min_voltage_adjustment.imp().adjustment;
|
||||
|
||||
min_voltage_adjustment.set_lower(voltage_min.into());
|
||||
min_voltage_adjustment.set_upper(voltage_max.into());
|
||||
min_voltage_adjustment.set_value(current_min_voltage.into());
|
||||
|
||||
self.min_voltage_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.min_voltage_adjustment.1.set_visible(false);
|
||||
self.min_voltage_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let Some((current_sclk_max, sclk_min, sclk_max)) =
|
||||
@ -199,14 +209,15 @@ impl ClocksFrame {
|
||||
(table.get_max_sclk(), table.get_max_sclk_range())
|
||||
})
|
||||
{
|
||||
self.max_sclk_adjustment.0.set_lower(sclk_min.into());
|
||||
self.max_sclk_adjustment.0.set_upper(sclk_max.into());
|
||||
self.max_sclk_adjustment
|
||||
.0
|
||||
.set_value(current_sclk_max.into());
|
||||
self.max_sclk_adjustment.1.set_visible(true);
|
||||
let max_sclk_adjustment = &self.max_sclk_adjustment.imp().adjustment;
|
||||
|
||||
max_sclk_adjustment.set_lower(sclk_min.into());
|
||||
max_sclk_adjustment.set_upper(sclk_max.into());
|
||||
max_sclk_adjustment.set_value(current_sclk_max.into());
|
||||
|
||||
self.max_sclk_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.max_sclk_adjustment.1.set_visible(false);
|
||||
self.max_sclk_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let Some((current_mclk_max, mclk_min, mclk_max)) =
|
||||
@ -214,14 +225,14 @@ impl ClocksFrame {
|
||||
(table.get_max_mclk(), table.get_max_mclk_range())
|
||||
})
|
||||
{
|
||||
self.max_mclk_adjustment.0.set_lower(mclk_min.into());
|
||||
self.max_mclk_adjustment.0.set_upper(mclk_max.into());
|
||||
self.max_mclk_adjustment
|
||||
.0
|
||||
.set_value(current_mclk_max.into());
|
||||
self.max_mclk_adjustment.1.set_visible(true);
|
||||
let max_mclk_adjustment = &self.max_mclk_adjustment.imp().adjustment;
|
||||
max_mclk_adjustment.set_lower(mclk_min.into());
|
||||
max_mclk_adjustment.set_upper(mclk_max.into());
|
||||
max_mclk_adjustment.set_value(current_mclk_max.into());
|
||||
|
||||
self.max_mclk_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.max_mclk_adjustment.1.set_visible(false);
|
||||
self.max_mclk_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let Some((current_voltage_max, voltage_min, voltage_max)) =
|
||||
@ -229,14 +240,14 @@ impl ClocksFrame {
|
||||
(table.get_max_sclk_voltage(), table.get_max_voltage_range())
|
||||
})
|
||||
{
|
||||
self.max_voltage_adjustment.0.set_lower(voltage_min.into());
|
||||
self.max_voltage_adjustment.0.set_upper(voltage_max.into());
|
||||
self.max_voltage_adjustment
|
||||
.0
|
||||
.set_value(current_voltage_max.into());
|
||||
self.max_voltage_adjustment.1.set_visible(true);
|
||||
let max_voltage_adjustment = &self.max_voltage_adjustment.imp().adjustment;
|
||||
max_voltage_adjustment.set_lower(voltage_min.into());
|
||||
max_voltage_adjustment.set_upper(voltage_max.into());
|
||||
max_voltage_adjustment.set_value(current_voltage_max.into());
|
||||
|
||||
self.max_voltage_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.max_voltage_adjustment.1.set_visible(false);
|
||||
self.max_voltage_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
if let ClocksTableGen::Vega20(table) = table {
|
||||
@ -247,28 +258,26 @@ impl ClocksFrame {
|
||||
.and_then(|range| range.into_full())
|
||||
.unwrap_or((-DEFAULT_VOLTAGE_OFFSET_RANGE, DEFAULT_VOLTAGE_OFFSET_RANGE));
|
||||
|
||||
self.voltage_offset_adjustment
|
||||
.0
|
||||
.set_lower(min_offset as f64);
|
||||
self.voltage_offset_adjustment
|
||||
.0
|
||||
.set_upper(max_offset as f64);
|
||||
self.voltage_offset_adjustment.0.set_value(offset.into());
|
||||
self.voltage_offset_adjustment.1.set_visible(true);
|
||||
let voltage_offset_adjustment = &self.voltage_offset_adjustment.imp().adjustment;
|
||||
voltage_offset_adjustment.set_lower(min_offset as f64);
|
||||
voltage_offset_adjustment.set_upper(max_offset as f64);
|
||||
voltage_offset_adjustment.set_value(offset.into());
|
||||
|
||||
self.voltage_offset_adjustment.set_visible(true);
|
||||
} else {
|
||||
self.voltage_offset_adjustment.1.set_visible(false);
|
||||
self.voltage_offset_adjustment.set_visible(false);
|
||||
}
|
||||
} else {
|
||||
self.voltage_offset_adjustment.1.set_visible(false);
|
||||
self.voltage_offset_adjustment.set_visible(false);
|
||||
}
|
||||
|
||||
emit_changed(&self.min_sclk_adjustment);
|
||||
emit_changed(&self.min_mclk_adjustment);
|
||||
emit_changed(&self.min_voltage_adjustment);
|
||||
emit_changed(&self.max_sclk_adjustment);
|
||||
emit_changed(&self.max_mclk_adjustment);
|
||||
emit_changed(&self.max_voltage_adjustment);
|
||||
emit_changed(&self.voltage_offset_adjustment);
|
||||
self.min_sclk_adjustment.refresh();
|
||||
self.min_mclk_adjustment.refresh();
|
||||
self.min_voltage_adjustment.refresh();
|
||||
self.max_sclk_adjustment.refresh();
|
||||
self.max_mclk_adjustment.refresh();
|
||||
self.max_voltage_adjustment.refresh();
|
||||
self.voltage_offset_adjustment.refresh();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -287,23 +296,46 @@ impl ClocksFrame {
|
||||
self.clocks_data_unavailable_label.show();
|
||||
}
|
||||
|
||||
pub fn set_vram_clock_ratio(&self, ratio: f64) {
|
||||
self.min_mclk_adjustment.set_value_ratio(ratio);
|
||||
self.max_mclk_adjustment.set_value_ratio(ratio);
|
||||
}
|
||||
|
||||
pub fn connect_clocks_changed<F: Fn() + 'static + Clone>(&self, f: F) {
|
||||
let f = clone!(
|
||||
#[strong]
|
||||
f,
|
||||
move |_: &Adjustment| f()
|
||||
move |_: &OcAdjustment| f()
|
||||
);
|
||||
self.min_sclk_adjustment.0.connect_value_changed(f.clone());
|
||||
self.min_mclk_adjustment.0.connect_value_changed(f.clone());
|
||||
|
||||
self.min_sclk_adjustment
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.min_mclk_adjustment
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.min_voltage_adjustment
|
||||
.0
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.max_sclk_adjustment
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.max_mclk_adjustment
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.max_sclk_adjustment.0.connect_value_changed(f.clone());
|
||||
self.max_mclk_adjustment.0.connect_value_changed(f.clone());
|
||||
self.max_voltage_adjustment
|
||||
.0
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f.clone());
|
||||
self.voltage_offset_adjustment.0.connect_value_changed(f);
|
||||
self.voltage_offset_adjustment
|
||||
.imp()
|
||||
.adjustment
|
||||
.connect_value_changed(f);
|
||||
}
|
||||
|
||||
pub fn connect_clocks_reset<F: Fn() + 'static + Clone>(&self, f: F) {
|
||||
@ -312,15 +344,15 @@ impl ClocksFrame {
|
||||
|
||||
pub fn get_settings(&self) -> ClocksSettings {
|
||||
if self.tweaking_grid.get_visible() {
|
||||
let min_core_clock = get_adjustment_value(&self.min_sclk_adjustment);
|
||||
let min_memory_clock = get_adjustment_value(&self.min_mclk_adjustment);
|
||||
let min_voltage = get_adjustment_value(&self.min_voltage_adjustment);
|
||||
let max_core_clock = get_adjustment_value(&self.max_sclk_adjustment);
|
||||
let max_memory_clock = get_adjustment_value(&self.max_mclk_adjustment);
|
||||
let max_voltage = get_adjustment_value(&self.max_voltage_adjustment);
|
||||
let min_core_clock = self.min_sclk_adjustment.get_value();
|
||||
let min_memory_clock = self.min_mclk_adjustment.get_value();
|
||||
let min_voltage = self.min_voltage_adjustment.get_value();
|
||||
let max_core_clock = self.max_sclk_adjustment.get_value();
|
||||
let max_memory_clock = self.max_mclk_adjustment.get_value();
|
||||
let max_voltage = self.max_voltage_adjustment.get_value();
|
||||
|
||||
let voltage_offset = if self.voltage_offset_adjustment.1.get_visible() {
|
||||
Some(self.voltage_offset_adjustment.0.value() as i32)
|
||||
let voltage_offset = if self.voltage_offset_adjustment.get_visible() {
|
||||
self.voltage_offset_adjustment.get_value()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -362,71 +394,6 @@ fn extract_value_and_range(
|
||||
Some((value, min, max))
|
||||
}
|
||||
|
||||
fn oc_adjustment(
|
||||
title: &'static str,
|
||||
grid: &Grid,
|
||||
row: i32,
|
||||
) -> (Adjustment, Scale, Rc<AtomicBool>) {
|
||||
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);
|
||||
|
||||
let scale = Scale::builder()
|
||||
.orientation(Orientation::Horizontal)
|
||||
.adjustment(&adjustment)
|
||||
.hexpand(true)
|
||||
.round_digits(0)
|
||||
.digits(0)
|
||||
.value_pos(PositionType::Right)
|
||||
.margin_start(5)
|
||||
.margin_end(5)
|
||||
.build();
|
||||
|
||||
let value_selector = SpinButton::new(Some(&adjustment), 1.0, 0);
|
||||
let value_label = Label::new(None);
|
||||
|
||||
let popover = Popover::builder().child(&value_selector).build();
|
||||
let value_button = MenuButton::builder()
|
||||
.popover(&popover)
|
||||
.child(&value_label)
|
||||
.build();
|
||||
|
||||
let changed = Rc::new(AtomicBool::new(false));
|
||||
|
||||
adjustment.connect_value_changed(clone!(
|
||||
#[strong]
|
||||
value_label,
|
||||
#[strong]
|
||||
changed,
|
||||
move |adjustment| {
|
||||
changed.store(true, Ordering::SeqCst);
|
||||
|
||||
let value = adjustment.value();
|
||||
value_label.set_text(&value.to_string());
|
||||
}
|
||||
));
|
||||
|
||||
scale.connect_visible_notify(clone!(
|
||||
#[strong]
|
||||
label,
|
||||
#[strong]
|
||||
value_label,
|
||||
#[strong]
|
||||
value_button,
|
||||
move |scale| {
|
||||
label.set_visible(scale.get_visible());
|
||||
value_button.set_visible(scale.get_visible());
|
||||
value_label.set_visible(scale.get_visible());
|
||||
}
|
||||
));
|
||||
|
||||
grid.attach(&label, 0, row, 1, 1);
|
||||
grid.attach(&scale, 1, row, 4, 1);
|
||||
grid.attach(&value_button, 6, row, 4, 1);
|
||||
|
||||
(adjustment, scale, changed)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClocksSettings {
|
||||
pub min_core_clock: Option<i32>,
|
||||
@ -437,26 +404,3 @@ pub struct ClocksSettings {
|
||||
pub max_voltage: Option<i32>,
|
||||
pub voltage_offset: Option<i32>,
|
||||
}
|
||||
|
||||
fn get_adjustment_value(
|
||||
(adjustment, scale, changed): &(Adjustment, Scale, Rc<AtomicBool>),
|
||||
) -> Option<i32> {
|
||||
let changed = changed.load(Ordering::SeqCst);
|
||||
|
||||
if changed {
|
||||
let value = adjustment.value();
|
||||
if scale.get_visible() {
|
||||
Some(value as i32)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_changed(adjustment: &(Adjustment, Scale, Rc<AtomicBool>)) {
|
||||
adjustment.0.emit_by_name::<()>("value-changed", &[]);
|
||||
adjustment.1.notify("visible");
|
||||
adjustment.2.store(false, Ordering::SeqCst);
|
||||
}
|
||||
|
@ -0,0 +1,151 @@
|
||||
use gtk::{
|
||||
glib::{self, Object},
|
||||
prelude::WidgetExt,
|
||||
prelude::{GridExt, ObjectExt},
|
||||
subclass::prelude::ObjectSubclassIsExt,
|
||||
Grid,
|
||||
};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct AdjustmentRow(ObjectSubclass<imp::AdjustmentRow>)
|
||||
@extends gtk::Widget,
|
||||
@implements gtk::Orientable, gtk::Accessible, gtk::Buildable;
|
||||
}
|
||||
|
||||
impl AdjustmentRow {
|
||||
pub fn new(title: &str) -> Self {
|
||||
Object::builder()
|
||||
.property("title", title)
|
||||
.property("visible", true)
|
||||
.property("value_ratio", 1.0)
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn new_and_attach(title: &str, grid: &Grid, row: i32) -> Self {
|
||||
let adj_row = Self::new(title);
|
||||
adj_row.attach_to_grid(grid, row);
|
||||
adj_row
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> Option<i32> {
|
||||
self.imp()
|
||||
.adjustment
|
||||
.get_changed_value(false)
|
||||
.map(|value| value as i32)
|
||||
}
|
||||
|
||||
pub fn attach_to_grid(&self, grid: &Grid, row: i32) {
|
||||
let obj = self.imp();
|
||||
|
||||
obj.label.unparent();
|
||||
obj.scale.unparent();
|
||||
obj.value_button.unparent();
|
||||
|
||||
grid.attach(&obj.label.get(), 0, row, 1, 1);
|
||||
grid.attach(&obj.scale.get(), 1, row, 4, 1);
|
||||
grid.attach(&obj.value_button.get(), 6, row, 4, 1);
|
||||
}
|
||||
|
||||
pub fn refresh(&self) {
|
||||
let obj = self.imp();
|
||||
obj.adjustment.emit_by_name::<()>("value-changed", &[]);
|
||||
self.notify("visible");
|
||||
obj.adjustment.imp().changed.store(false, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
mod imp {
|
||||
use crate::app::root_stack::oc_adjustment::OcAdjustment;
|
||||
use glib::{clone, subclass::InitializingObject};
|
||||
use gtk::{
|
||||
glib::{self, Properties},
|
||||
prelude::*,
|
||||
subclass::{
|
||||
prelude::*,
|
||||
widget::{CompositeTemplateClass, WidgetImpl},
|
||||
},
|
||||
CompositeTemplate, Label, MenuButton, Scale, SpinButton, TemplateChild,
|
||||
};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::AdjustmentRow)]
|
||||
#[template(file = "ui/oc_page/clocks_frame/adjustment_row.blp")]
|
||||
pub struct AdjustmentRow {
|
||||
#[property(get, set)]
|
||||
pub visible: Rc<RefCell<bool>>,
|
||||
#[property(get, set)]
|
||||
pub value_ratio: Rc<RefCell<f64>>,
|
||||
#[property(get, set)]
|
||||
pub title: Rc<RefCell<String>>,
|
||||
|
||||
#[template_child]
|
||||
pub label: TemplateChild<Label>,
|
||||
#[template_child]
|
||||
pub scale: TemplateChild<Scale>,
|
||||
#[template_child]
|
||||
pub value_button: TemplateChild<MenuButton>,
|
||||
#[template_child]
|
||||
pub value_spinbutton: TemplateChild<SpinButton>,
|
||||
#[template_child]
|
||||
pub adjustment: TemplateChild<OcAdjustment>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for AdjustmentRow {
|
||||
const NAME: &'static str = "AdjustmentRow";
|
||||
type Type = super::AdjustmentRow;
|
||||
type ParentType = gtk::Widget;
|
||||
|
||||
fn class_init(class: &mut Self::Class) {
|
||||
OcAdjustment::ensure_type();
|
||||
class.bind_template();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for AdjustmentRow {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
self.adjustment.connect_value_changed(clone!(
|
||||
#[strong(rename_to = value_button)]
|
||||
self.value_button,
|
||||
#[strong(rename_to = value_ratio)]
|
||||
self.value_ratio,
|
||||
move |adj| {
|
||||
let ratio = *value_ratio.borrow();
|
||||
let text = (adj.value() * ratio).to_string();
|
||||
value_button.set_label(&text);
|
||||
}
|
||||
));
|
||||
|
||||
self.value_spinbutton.connect_input(clone!(
|
||||
#[strong(rename_to = value_ratio)]
|
||||
self.value_ratio,
|
||||
move |spin| {
|
||||
let text = spin.text();
|
||||
let value: f64 = text.parse().ok()?;
|
||||
Some(Ok(value / *value_ratio.borrow()))
|
||||
}
|
||||
));
|
||||
|
||||
self.value_spinbutton.connect_output(clone!(
|
||||
#[strong(rename_to = value_ratio)]
|
||||
self.value_ratio,
|
||||
move |spin| {
|
||||
let display_value = spin.value() * *value_ratio.borrow();
|
||||
spin.set_text(&display_value.to_string());
|
||||
glib::Propagation::Stop
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for AdjustmentRow {}
|
||||
}
|
@ -10,7 +10,7 @@ glib::wrapper! {
|
||||
|
||||
impl GpuStatsSection {
|
||||
pub fn new() -> Self {
|
||||
Object::builder().build()
|
||||
Object::builder().property("vram_clock_ratio", 1.0).build()
|
||||
}
|
||||
|
||||
pub fn set_stats(&self, stats: &DeviceStats) {
|
||||
@ -28,9 +28,12 @@ impl GpuStatsSection {
|
||||
));
|
||||
|
||||
let clockspeed = stats.clockspeed;
|
||||
self.set_core_clock(format_clockspeed(clockspeed.gpu_clockspeed));
|
||||
self.set_core_clock(format_clockspeed(clockspeed.gpu_clockspeed, 1.0));
|
||||
self.set_current_core_clock(format_current_gfxclk(clockspeed.current_gfxclk));
|
||||
self.set_vram_clock(format_clockspeed(clockspeed.vram_clockspeed));
|
||||
self.set_vram_clock(format_clockspeed(
|
||||
clockspeed.vram_clockspeed,
|
||||
self.vram_clock_ratio(),
|
||||
));
|
||||
|
||||
let voltage = format!("{:.3} V", stats.voltage.gpu.unwrap_or(0) as f64 / 1000f64);
|
||||
self.set_voltage(voltage);
|
||||
@ -99,7 +102,7 @@ mod imp {
|
||||
},
|
||||
CompositeTemplate,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
#[derive(CompositeTemplate, Default, Properties)]
|
||||
#[properties(wrapper_type = super::GpuStatsSection)]
|
||||
@ -125,6 +128,9 @@ mod imp {
|
||||
vram_usage_text: RefCell<String>,
|
||||
#[property(get, set)]
|
||||
throttling: RefCell<String>,
|
||||
|
||||
#[property(get, set)]
|
||||
vram_clock_ratio: Cell<f64>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
@ -150,8 +156,8 @@ mod imp {
|
||||
impl BoxImpl for GpuStatsSection {}
|
||||
}
|
||||
|
||||
fn format_clockspeed(value: Option<u64>) -> String {
|
||||
format!("{:.3} GHz", value.unwrap_or(0) as f64 / 1000.0)
|
||||
fn format_clockspeed(value: Option<u64>, ratio: f64) -> String {
|
||||
format!("{:.3} GHz", value.unwrap_or(0) as f64 / 1000.0 * ratio)
|
||||
}
|
||||
|
||||
fn format_current_gfxclk(value: Option<u16>) -> String {
|
||||
@ -161,7 +167,7 @@ fn format_current_gfxclk(value: Option<u16>) -> String {
|
||||
if v == u16::MAX {
|
||||
"N/A".to_string()
|
||||
} else {
|
||||
format_clockspeed(Some(v as u64))
|
||||
format_clockspeed(Some(v as u64), 1.0)
|
||||
}
|
||||
} else {
|
||||
"N/A".to_string()
|
||||
|
@ -12,7 +12,7 @@ use clocks_frame::ClocksFrame;
|
||||
use gpu_stats_section::GpuStatsSection;
|
||||
use gtk::*;
|
||||
use gtk::{glib::clone, prelude::*};
|
||||
use lact_client::schema::{DeviceStats, SystemInfo};
|
||||
use lact_client::schema::{DeviceInfo, DeviceStats, SystemInfo};
|
||||
use performance_frame::PerformanceFrame;
|
||||
// use power_cap_frame::PowerCapFrame;
|
||||
use std::collections::HashMap;
|
||||
@ -113,6 +113,17 @@ impl OcPage {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_info(&self, info: &DeviceInfo) {
|
||||
let vram_clock_ratio = info
|
||||
.drm_info
|
||||
.as_ref()
|
||||
.map(|info| info.vram_clock_ratio)
|
||||
.unwrap_or(1.0);
|
||||
|
||||
self.stats_section.set_vram_clock_ratio(vram_clock_ratio);
|
||||
self.clocks_frame.set_vram_clock_ratio(vram_clock_ratio);
|
||||
}
|
||||
|
||||
pub fn set_clocks_table(&self, table: Option<ClocksTableGen>) {
|
||||
match table {
|
||||
Some(table) => match self.clocks_frame.set_table(table) {
|
||||
|
37
lact-gui/ui/oc_page/clocks_frame/adjustment_row.blp
Normal file
37
lact-gui/ui/oc_page/clocks_frame/adjustment_row.blp
Normal file
@ -0,0 +1,37 @@
|
||||
using Gtk 4.0;
|
||||
|
||||
template $AdjustmentRow: Widget {
|
||||
Label label {
|
||||
label: bind template.title;
|
||||
visible: bind template.visible;
|
||||
halign: start;
|
||||
}
|
||||
|
||||
Scale scale {
|
||||
adjustment: adjustment;
|
||||
orientation: horizontal;
|
||||
hexpand: true;
|
||||
digits: 0;
|
||||
round-digits: 0;
|
||||
value-pos: right;
|
||||
margin-start: 5;
|
||||
margin-end: 5;
|
||||
visible: bind template.visible;
|
||||
}
|
||||
|
||||
MenuButton value_button {
|
||||
popover: Popover {
|
||||
child: SpinButton value_spinbutton {
|
||||
adjustment: adjustment;
|
||||
};
|
||||
};
|
||||
|
||||
direction: none;
|
||||
visible: bind template.visible;
|
||||
}
|
||||
}
|
||||
|
||||
$OcAdjustment adjustment {
|
||||
step-increment: 1;
|
||||
page-increment: 10;
|
||||
}
|
@ -100,6 +100,7 @@ pub struct DrmInfo {
|
||||
pub chip_class: String,
|
||||
pub compute_units: u32,
|
||||
pub vram_type: String,
|
||||
pub vram_clock_ratio: f64,
|
||||
pub vram_bit_width: u32,
|
||||
pub vram_max_bw: String,
|
||||
pub l1_cache_per_cu: u32,
|
||||
|
Loading…
Reference in New Issue
Block a user