diff --git a/Cargo.lock b/Cargo.lock
index 9785308..a940e31 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,7 +26,7 @@ dependencies = [
[[package]]
name = "amdgpu-sysfs"
version = "0.5.0"
-source = "git+https://github.com/ilya-zlobintsev/amdgpu-sysfs-rs?branch=blocking#55ddcc95cddde27e5c5147d9b5ee4831b5d7aaf8"
+source = "git+https://github.com/ilya-zlobintsev/amdgpu-sysfs-rs?branch=blocking#0308d4c475f5091f7e8bc4b7b5d8c101f8dd40d7"
dependencies = [
"serde",
]
diff --git a/lact-gui/src/app.rs b/lact-gui/src/app.rs
index c295b01..8701e73 100644
--- a/lact-gui/src/app.rs
+++ b/lact-gui/src/app.rs
@@ -80,7 +80,8 @@ impl App {
});
}
- let devices = self.daemon_client.list_devices()?;
+ let devices_buf = self.daemon_client.list_devices()?;
+ let devices = devices_buf.inner()?;
self.header.set_devices(&devices);
// Show apply button on setting changes
@@ -96,10 +97,10 @@ impl App {
let apply_revealer = self.apply_revealer.clone();
- self.root_stack.oc_page.connect_settings_changed(move || {
- debug!("Settings changed, showing apply button");
- apply_revealer.show();
- });
+ // self.root_stack.oc_page.connect_settings_changed(move || {
+ // debug!("Settings changed, showing apply button");
+ // apply_revealer.show();
+ // });
}
{
@@ -185,13 +186,17 @@ impl App {
}
fn set_info(&self, gpu_id: &str) {
- let info = self.daemon_client.get_device_info(gpu_id).unwrap();
+ let info_buf = self
+ .daemon_client
+ .get_device_info(gpu_id)
+ .expect("Could not fetch info");
+ let info = info_buf.inner().unwrap();
trace!("Setting info {info:?}");
self.root_stack.info_page.set_info(&info);
- trace!("Setting clocks");
- self.root_stack.oc_page.set_info(&info);
+ // trace!("Setting clocks");
+ // self.root_stack.oc_page.set_info(&info);
// TODO: this should be stats
/*trace!("Setting performance level {:?}", info.power_profile);
@@ -221,15 +226,15 @@ impl App {
let ppfeaturemask: u64 =
u64::from_str_radix(ppfeaturemask, 16).expect("Invalid ppfeaturemask");
- if (ppfeaturemask & PP_OVERDRIVE_MASK as u64) > 0 {
+ /*if (ppfeaturemask & PP_OVERDRIVE_MASK as u64) > 0 {
self.root_stack.oc_page.warning_frame.hide();
} else {
self.root_stack.oc_page.warning_frame.show();
- }
+ }*/
}
Err(_) => {
info!("Failed to read feature mask! This is expected if your system doesn't have an AMD GPU.");
- self.root_stack.oc_page.warning_frame.hide();
+ // self.root_stack.oc_page.warning_frame.hide();
}
}
}
@@ -249,7 +254,10 @@ impl App {
thread::spawn(move || loop {
let gpu_id = current_gpu_id.read().unwrap();
- match daemon_connection.get_device_stats(&gpu_id) {
+ match daemon_connection
+ .get_device_stats(&gpu_id)
+ .and_then(|stats| stats.inner())
+ {
Ok(stats) => {
sender.send(GuiUpdateMsg::GpuStats(stats)).unwrap();
}
@@ -264,14 +272,14 @@ impl App {
// Receiving stats into the gui event loop
{
let thermals_page = self.root_stack.thermals_page.clone();
- let oc_page = self.root_stack.oc_page.clone();
+ // let oc_page = self.root_stack.oc_page.clone();
receiver.attach(None, move |msg| {
match msg {
GuiUpdateMsg::GpuStats(stats) => {
trace!("New stats received, updating {stats:?}");
thermals_page.set_stats(&stats);
- oc_page.set_stats(&stats);
+ // oc_page.set_stats(&stats);
} /*GuiUpdateMsg::FanControlInfo(fan_control_info) => {
thermals_page.set_ventilation_info(fan_control_info)
}*/
diff --git a/lact-gui/src/app/root_stack.rs b/lact-gui/src/app/root_stack.rs
index 60bd65f..0b232c2 100644
--- a/lact-gui/src/app/root_stack.rs
+++ b/lact-gui/src/app/root_stack.rs
@@ -1,5 +1,5 @@
mod info_page;
-mod oc_page;
+// mod oc_page;
mod software_page;
mod thermals_page;
@@ -7,7 +7,7 @@ use gtk::prelude::*;
use gtk::*;
use info_page::InformationPage;
-use oc_page::OcPage;
+// use oc_page::OcPage;
use software_page::SoftwarePage;
use thermals_page::ThermalsPage;
@@ -17,7 +17,7 @@ pub struct RootStack {
pub info_page: InformationPage,
pub thermals_page: ThermalsPage,
pub software_page: SoftwarePage,
- pub oc_page: OcPage,
+ // pub oc_page: OcPage,
}
impl RootStack {
@@ -28,9 +28,9 @@ impl RootStack {
container.add_titled(&info_page.container, "info_page", "Information");
- let oc_page = OcPage::new();
+ // let oc_page = OcPage::new();
- container.add_titled(&oc_page.container, "oc_page", "OC");
+ // container.add_titled(&oc_page.container, "oc_page", "OC");
let thermals_page = ThermalsPage::new();
@@ -44,7 +44,7 @@ impl RootStack {
container,
info_page,
thermals_page,
- oc_page,
+ // oc_page,
software_page,
}
}
diff --git a/lact-gui/src/app/root_stack/info_page.rs b/lact-gui/src/app/root_stack/info_page.rs
index 0c0b597..86819ce 100644
--- a/lact-gui/src/app/root_stack/info_page.rs
+++ b/lact-gui/src/app/root_stack/info_page.rs
@@ -151,11 +151,13 @@ impl InformationPage {
pub fn set_info(&self, gpu_info: &DeviceInfo) {
let gpu_name = gpu_info
.pci_info
+ .as_ref()
.and_then(|pci_info| {
pci_info
.subsystem_pci_info
.model
- .or_else(|| pci_info.device_pci_info.model)
+ .as_deref()
+ .or_else(|| pci_info.device_pci_info.model.as_deref())
})
.unwrap_or_default();
self.gpu_name_label
@@ -163,43 +165,48 @@ impl InformationPage {
let gpu_manufacturer = gpu_info
.pci_info
+ .as_ref()
.and_then(|pci_info| {
pci_info
.subsystem_pci_info
.vendor
- .or_else(|| pci_info.device_pci_info.model)
+ .as_deref()
+ .or_else(|| pci_info.device_pci_info.model.as_deref())
})
.unwrap_or_default();
self.gpu_manufacturer_label
.set_markup(&format!("{gpu_manufacturer}",));
- let vbios_version = gpu_info.vbios_version.as_deref().unwrap_or("");
+ let vbios_version = gpu_info.vbios_version.as_deref().unwrap_or("unknown");
self.vbios_version_label
.set_markup(&format!("{vbios_version}",));
self.driver_label
.set_markup(&format!("{}", gpu_info.driver));
- let vram_size = gpu_info
- .vram_size
- .map_or_else(|| "".to_owned(), |size| size.to_string());
- self.vram_size_label
- .set_markup(&format!("{vram_size}"));
+ // TODO
+ // let vram_size = gpu_info
+ // .vram_size
+ // .map_or_else(|| "unknown".to_owned(), |size| size.to_string());
+ // self.vram_size_label
+ // .set_markup(&format!("{vram_size}"));
let link_speed = gpu_info
.link_info
.current_speed
.as_deref()
- .unwrap_or("");
+ .unwrap_or("unknown");
let link_width = gpu_info
.link_info
.current_width
.as_deref()
- .unwrap_or("");
+ .unwrap_or("unknown");
self.link_speed_label
.set_markup(&format!("{link_speed} x{link_width}",));
- self.vulkan_info_frame.set_info(&gpu_info.vulkan_info);
+ if let Some(vulkan_info) = &gpu_info.vulkan_info {
+ self.vulkan_info_frame.set_info(vulkan_info);
+ }
self.container.show_all();
}
diff --git a/lact-gui/src/app/root_stack/oc_page.rs b/lact-gui/src/app/root_stack/oc_page.rs
index 1adcea5..c792cb3 100644
--- a/lact-gui/src/app/root_stack/oc_page.rs
+++ b/lact-gui/src/app/root_stack/oc_page.rs
@@ -1,12 +1,10 @@
-mod clocks_frame;
+// mod clocks_frame;
mod performance_level_frame;
mod power_cap_frame;
mod stats_grid;
mod warning_frame;
use amdgpu_sysfs::gpu_handle::PerformanceLevel;
-use clocks_frame::ClocksFrame;
-use clocks_frame::ClocksSettings;
use gtk::prelude::*;
use gtk::*;
use lact_schema::{DeviceInfo, DeviceStats};
@@ -21,7 +19,7 @@ pub struct OcPage {
stats_grid: StatsGrid,
performance_level_frame: PowerProfileFrame,
power_cap_frame: PowerCapFrame,
- clocks_frame: ClocksFrame,
+ // clocks_frame: ClocksFrame,
pub warning_frame: WarningFrame,
}
@@ -45,15 +43,15 @@ impl OcPage {
container.pack_start(&power_profile_frame.container, false, true, 0);
- let clocks_frame = ClocksFrame::new();
+ // let clocks_frame = ClocksFrame::new();
- container.pack_start(&clocks_frame.container, false, true, 0);
+ // container.pack_start(&clocks_frame.container, false, true, 0);
Self {
container,
stats_grid,
performance_level_frame: power_profile_frame,
- clocks_frame,
+ // clocks_frame,
warning_frame,
power_cap_frame,
}
@@ -100,9 +98,12 @@ impl OcPage {
}
}
- pub fn get_power_profile(&self) -> Option {
+ pub fn get_performance_level(&self) -> Option {
match self.performance_level_frame.get_visibility() {
- true => Some(self.performance_level_frame.get_selected_power_profile()),
+ true => Some(
+ self.performance_level_frame
+ .get_selected_performance_level(),
+ ),
false => None,
}
}
diff --git a/lact-gui/src/app/root_stack/oc_page/clocks_frame.rs b/lact-gui/src/app/root_stack/oc_page/clocks_frame.rs
index 6605b12..8c249c8 100644
--- a/lact-gui/src/app/root_stack/oc_page/clocks_frame.rs
+++ b/lact-gui/src/app/root_stack/oc_page/clocks_frame.rs
@@ -1,4 +1,3 @@
-use daemon::gpu_controller::ClocksTable;
use gtk::prelude::*;
use gtk::*;
diff --git a/lact-gui/src/app/root_stack/oc_page/performance_level_frame.rs b/lact-gui/src/app/root_stack/oc_page/performance_level_frame.rs
index 43a054f..f7445ba 100644
--- a/lact-gui/src/app/root_stack/oc_page/performance_level_frame.rs
+++ b/lact-gui/src/app/root_stack/oc_page/performance_level_frame.rs
@@ -1,4 +1,4 @@
-use daemon::gpu_controller::PowerProfile;
+use amdgpu_sysfs::gpu_handle::PerformanceLevel;
use gtk::prelude::*;
use gtk::*;
@@ -57,11 +57,12 @@ impl PowerProfileFrame {
}
}
- pub fn set_active_profile(&self, profile: &PowerProfile) {
- match profile {
- PowerProfile::Auto => self.combo_box.set_active_id(Some("0")),
- PowerProfile::High => self.combo_box.set_active_id(Some("1")),
- PowerProfile::Low => self.combo_box.set_active_id(Some("2")),
+ pub fn set_active_profile(&self, level: PerformanceLevel) {
+ match level {
+ PerformanceLevel::Auto => self.combo_box.set_active_id(Some("0")),
+ PerformanceLevel::High => self.combo_box.set_active_id(Some("1")),
+ PerformanceLevel::Low => self.combo_box.set_active_id(Some("2")),
+ PerformanceLevel::Manual => todo!(),
};
}
@@ -71,11 +72,11 @@ impl PowerProfileFrame {
});
}
- pub fn get_selected_power_profile(&self) -> PowerProfile {
+ pub fn get_selected_performance_level(&self) -> PerformanceLevel {
match self.combo_box.active().unwrap() {
- 0 => PowerProfile::Auto,
- 1 => PowerProfile::High,
- 2 => PowerProfile::Low,
+ 0 => PerformanceLevel::Auto,
+ 1 => PerformanceLevel::High,
+ 2 => PerformanceLevel::Low,
_ => unreachable!(),
}
}
diff --git a/lact-gui/src/app/root_stack/thermals_page/fan_curve_frame.rs b/lact-gui/src/app/root_stack/thermals_page/fan_curve_frame.rs
index 60f0fda..1395ef8 100644
--- a/lact-gui/src/app/root_stack/thermals_page/fan_curve_frame.rs
+++ b/lact-gui/src/app/root_stack/thermals_page/fan_curve_frame.rs
@@ -1,7 +1,7 @@
-use std::collections::BTreeMap;
-
use gtk::prelude::*;
use gtk::*;
+use std::collections::BTreeMap;
+use tracing::debug;
#[derive(Clone)]
pub struct FanCurveFrame {
@@ -189,12 +189,12 @@ impl FanCurveFrame {
}
pub fn show(&self) {
- log::info!("Manual fan control enaged, showing fan curve");
+ debug!("Manual fan control enaged, showing fan curve");
self.container.set_visible(true);
}
pub fn hide(&self) {
- log::info!("Manual fan control disenaged, hiding fan curve");
+ debug!("Manual fan control disenaged, hiding fan curve");
self.container.set_visible(false);
}
diff --git a/lact-gui/src/client.rs b/lact-gui/src/client.rs
index 72b34a0..071148b 100644
--- a/lact-gui/src/client.rs
+++ b/lact-gui/src/client.rs
@@ -1,9 +1,11 @@
use anyhow::{anyhow, Context};
use lact_schema::{request::Request, response::Response, DeviceInfo, DeviceListEntry, DeviceStats};
use nix::unistd::getuid;
-use serde::de::DeserializeOwned;
+use serde::{de::DeserializeOwned, Deserialize};
use std::{
io::{BufRead, BufReader, Write},
+ marker::PhantomData,
+ ops::DerefMut,
os::unix::net::UnixStream,
path::PathBuf,
sync::{Arc, Mutex},
@@ -26,8 +28,12 @@ impl DaemonClient {
})
}
- fn make_request(&self, request: Request) -> anyhow::Result {
- let (reader, writer) = *self.stream.lock().map_err(|err| anyhow!("{err}"))?;
+ fn make_request<'a, T: Deserialize<'a>>(
+ &self,
+ request: Request,
+ ) -> anyhow::Result> {
+ let mut stream_guard = self.stream.lock().map_err(|err| anyhow!("{err}"))?;
+ let (reader, writer) = stream_guard.deref_mut();
if !reader.buffer().is_empty() {
return Err(anyhow!("Another request was not processed properly"));
@@ -38,30 +44,29 @@ impl DaemonClient {
writer.write_all(b"\n")?;
let mut response_payload = String::new();
- reader.read_line(&mut response_payload);
+ reader.read_line(&mut response_payload)?;
- let response: Response = serde_json::from_str(&response_payload)
- .context("Could not deserialize response from daemon")?;
-
- match response {
- Response::Ok(data) => Ok(data),
- Response::Error(error) => Err(anyhow!("Error from daemon: {error}")),
- }
+ Ok(ResponseBuffer {
+ buf: response_payload,
+ _phantom: PhantomData,
+ })
}
- pub fn list_devices<'a>(&self) -> anyhow::Result>> {
+ pub fn list_devices<'a>(&self) -> anyhow::Result>>> {
self.make_request(Request::ListDevices)
}
pub fn set_fan_control(&self, id: &str, enabled: bool) -> anyhow::Result<()> {
- self.make_request(Request::SetFanControl { id, enabled })
+ self.make_request::<()>(Request::SetFanControl { id, enabled })?
+ .inner()?;
+ Ok(())
}
- pub fn get_device_info(&self, id: &str) -> anyhow::Result {
+ pub fn get_device_info(&self, id: &str) -> anyhow::Result> {
self.make_request(Request::DeviceInfo { id })
}
- pub fn get_device_stats(&self, id: &str) -> anyhow::Result {
+ pub fn get_device_stats(&self, id: &str) -> anyhow::Result> {
self.make_request(Request::DeviceStats { id })
}
}
@@ -82,3 +87,19 @@ fn get_socket_path() -> Option {
None
}
}
+
+pub struct ResponseBuffer {
+ buf: String,
+ _phantom: PhantomData,
+}
+
+impl<'a, T: Deserialize<'a>> ResponseBuffer {
+ pub fn inner(&'a self) -> anyhow::Result {
+ let response: Response = serde_json::from_str(&self.buf)
+ .context("Could not deserialize response from daemon")?;
+ match response {
+ Response::Ok(data) => Ok(data),
+ Response::Error(err) => Err(anyhow!("Got error from daemon: {err}")),
+ }
+ }
+}