Initial multi-gpu support

This commit is contained in:
Ilya Zlobintsev 2020-11-08 09:07:45 +02:00
parent a4a639534c
commit c78f18eaee
10 changed files with 324 additions and 179 deletions

View File

@ -9,3 +9,5 @@ edition = "2018"
[dependencies]
daemon = { path = "../daemon" }
structopt = "0.3"
log = "0.4"
env_logger = "0.8"

View File

@ -5,40 +5,58 @@ use structopt::StructOpt;
#[structopt(rename_all = "lower")]
enum Opt {
///Gets realtime GPU information
Stats,
Info,
StartFanControl,
StopFanControl,
GetFanControl,
Stats {
gpu_id: u32,
},
Gpus,
Info {
gpu_id: u32,
},
StartFanControl {
gpu_id: u32,
},
StopFanControl {
gpu_id: u32,
},
GetFanControl {
gpu_id: u32,
},
Stop,
}
fn main() {
env_logger::init();
let opt = Opt::from_args();
let d = DaemonConnection::new().unwrap();
log::trace!("connection established");
match opt {
Opt::Stats => {
let gpu_stats = d.get_gpu_stats();
Opt::Gpus => {
let gpus = d.get_gpus();
println!("{:?}", gpus);
},
Opt::Stats { gpu_id } => {
let gpu_stats = d.get_gpu_stats(gpu_id);
println!("VRAM: {}/{}", gpu_stats.mem_used, gpu_stats.mem_total);
println!("{:?}", gpu_stats);
},
Opt::Info => {
let gpu_info = d.get_gpu_info();
Opt::Info { gpu_id } => {
let gpu_info = d.get_gpu_info(gpu_id);
println!("GPU Vendor: {}", gpu_info.gpu_vendor);
println!("GPU Model: {}", gpu_info.card_model);
println!("Driver in use: {}", gpu_info.driver);
print!("VBIOS Version: {}", gpu_info.vbios_version);
},
Opt::StartFanControl => {
println!("{:?}", d.start_fan_control());
Opt::StartFanControl { gpu_id } => {
println!("{:?}", d.start_fan_control(gpu_id));
},
Opt::StopFanControl => {
println!("{:?}", d.stop_fan_control());
Opt::StopFanControl { gpu_id } => {
println!("{:?}", d.stop_fan_control(gpu_id));
},
Opt::GetFanControl => {
println!("{:?}", d.get_fan_control());
Opt::GetFanControl { gpu_id } => {
println!("{:?}", d.get_fan_control(gpu_id));
},
Opt::Stop => d.shutdown(),
}

View File

@ -13,3 +13,4 @@ serde_json = "1.0"
vulkano = "0.19"
log = "0.4"
env_logger = "0.8"
rand = "0.7"

View File

@ -1,5 +1,5 @@
use std::{collections::BTreeMap, io, fs, path::PathBuf};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fs, io, path::PathBuf};
#[derive(Debug)]
pub enum ConfigError {

View File

@ -1,6 +1,14 @@
use crate::{Action, SOCK_PATH, gpu_controller::GpuInfo, gpu_controller::{FanControlInfo, GpuStats}, hw_mon::HWMonError};
use std::{collections::BTreeMap, io::{Read, Write}};
use std::os::unix::net::UnixStream;
use crate::{
gpu_controller::GpuInfo,
gpu_controller::{FanControlInfo, GpuStats},
hw_mon::HWMonError,
Action, SOCK_PATH,
};
use std::{collections::HashMap, os::unix::net::UnixStream};
use std::{
collections::BTreeMap,
io::{Read, Write},
};
#[derive(Debug)]
pub enum DaemonConnectionError {
@ -9,21 +17,26 @@ pub enum DaemonConnectionError {
}
#[derive(Clone, Copy)]
pub struct DaemonConnection {
}
pub struct DaemonConnection {}
impl DaemonConnection {
pub fn new() -> Result<Self, DaemonConnectionError> {
match UnixStream::connect(SOCK_PATH) {
Ok(mut stream) => {
stream.write(&bincode::serialize(&Action::CheckAlive).unwrap()).unwrap();
let mut buffer = Vec::<u8>::new();
stream.read_to_end(&mut buffer).unwrap();
stream
.write(&bincode::serialize(&Action::CheckAlive).unwrap())
.unwrap();
stream
.shutdown(std::net::Shutdown::Write)
.expect("Could not shut down");
let mut buffer: [u8; 1] = [0; 1];
stream.read(&mut buffer).unwrap();
if buffer[0] == 1 {
Ok(DaemonConnection {})
}
else {
} else {
Err(DaemonConnectionError::ConnectionFailed)
}
}
@ -31,27 +44,12 @@ impl DaemonConnection {
}
}
pub fn get_gpu_stats(&self) -> GpuStats {
let mut stream = UnixStream::connect(SOCK_PATH).expect("Failed to connect to daemon");
stream
.write(&bincode::serialize(&Action::GetStats).unwrap())
pub fn get_gpu_stats(&self, gpu_id: u32) -> GpuStats {
let mut s = UnixStream::connect(SOCK_PATH).expect("Failed to connect to daemon");
s
.write(&bincode::serialize(&Action::GetStats(gpu_id)).unwrap())
.unwrap();
/*stream
.shutdown(std::net::Shutdown::Write)
.expect("Could not shut down");*/
let mut buffer = Vec::<u8>::new();
stream.read_to_end(&mut buffer).unwrap();
bincode::deserialize(&buffer).unwrap()
}
pub fn get_gpu_info(&self) -> GpuInfo {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::GetInfo).unwrap())
.unwrap();
/*s.shutdown(std::net::Shutdown::Write)
.expect("Could not shut down");*/
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
@ -59,11 +57,46 @@ impl DaemonConnection {
bincode::deserialize(&buffer).unwrap()
}
pub fn start_fan_control(&self) -> Result<(), DaemonConnectionError> {
pub fn get_gpu_info(&self, gpu_id: u32) -> GpuInfo {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::StartFanControl).unwrap())
s.write_all(&bincode::serialize(&Action::GetInfo(gpu_id)).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write)
.expect("Could not shut down");
log::trace!("Sent action, receiving response");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
log::trace!("Response recieved");
bincode::deserialize(&buffer).unwrap()
}
pub fn start_fan_control(&self, gpu_id: u32) -> Result<(), DaemonConnectionError> {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::StartFanControl(gpu_id)).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
log::trace!("Sent action, receiving response");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
log::trace!("Response recieved");
let result: Result<(), HWMonError> = bincode::deserialize(&buffer).unwrap();
match result {
Ok(_) => Ok(()),
Err(_) => Err(DaemonConnectionError::PermissionDenied),
}
}
pub fn stop_fan_control(&self, gpu_id: u32) -> Result<(), DaemonConnectionError> {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::StopFanControl(gpu_id)).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
@ -75,39 +108,46 @@ impl DaemonConnection {
}
}
pub fn stop_fan_control(&self) -> Result<(), DaemonConnectionError> {
pub fn get_fan_control(&self, gpu_id: u32) -> FanControlInfo {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::StopFanControl).unwrap()).unwrap();
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
let result: Result<(), HWMonError> = bincode::deserialize(&buffer).unwrap();
match result {
Ok(_) => Ok(()),
Err(_) => Err(DaemonConnectionError::PermissionDenied),
}
}
pub fn get_fan_control(&self)-> FanControlInfo {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::GetFanControl).unwrap()).unwrap();
s.write_all(&bincode::serialize(&Action::GetFanControl(gpu_id)).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
bincode::deserialize(&buffer).unwrap()
}
pub fn set_fan_curve(&self, curve: BTreeMap<i32, f64>) {
pub fn set_fan_curve(&self, gpu_id: u32, curve: BTreeMap<i32, f64>) {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::SetFanCurve).unwrap()).unwrap();
s.write_all(&bincode::serialize(&Action::SetFanCurve(gpu_id)).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
s.write_all(&bincode::serialize(&curve).unwrap()).unwrap();
}
pub fn get_gpus(&self) -> HashMap<u32, String> {
log::trace!("sending request");
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::GetGpus).unwrap())
.unwrap();
s.shutdown(std::net::Shutdown::Write).expect("Could not shut down");
log::trace!("sent request");
let mut buffer = Vec::<u8>::new();
s.read_to_end(&mut buffer).unwrap();
log::trace!("read response");
bincode::deserialize(&buffer).unwrap()
}
pub fn shutdown(&self) {
let mut s = UnixStream::connect(SOCK_PATH).unwrap();
s.write_all(&bincode::serialize(&Action::Shutdown).unwrap()).unwrap();
s.write_all(&bincode::serialize(&Action::Shutdown).unwrap())
.unwrap();
}
}

View File

@ -1,9 +1,9 @@
use crate::config::Config;
use crate::hw_mon::{HWMon, HWMonError};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fs};
use std::path::PathBuf;
use std::{collections::BTreeMap, fs};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use crate::config::Config;
#[derive(Serialize, Deserialize, Debug)]
pub struct GpuStats {
@ -58,9 +58,18 @@ pub struct GpuInfo {
impl GpuController {
pub fn new(hw_path: PathBuf, config: Config, config_path: PathBuf) -> Self {
let hwmon_path = fs::read_dir(&hw_path.join("hwmon")).unwrap().next().unwrap().unwrap().path();
let hwmon_path = fs::read_dir(&hw_path.join("hwmon"))
.unwrap()
.next()
.unwrap()
.unwrap()
.path();
let hw_mon = HWMon::new(&hwmon_path, config.fan_control_enabled, config.fan_curve.clone());
let hw_mon = HWMon::new(
&hwmon_path,
config.fan_control_enabled,
config.fan_curve.clone(),
);
let mut controller = GpuController {
hw_path: hw_path.clone(),
@ -118,7 +127,12 @@ impl GpuController {
card_model_id.to_lowercase()
);
for line in full_hwid_list.split('\n') {
let lines: Vec<&str> = full_hwid_list.split('\n').collect();
//for line in full_hwid_list.split('\n') {
for i in 0..lines.len() {
let line = lines[i];
if line.len() > card_vendor_id.len() {
if line[0..card_vendor_id.len()] == card_vendor_id.to_lowercase() {
card_vendor = line.splitn(2, ' ').collect::<Vec<&str>>()[1]
@ -156,7 +170,6 @@ impl GpuController {
Err(_) => 0,
};
let vulkan_info = GpuController::get_vulkan_info(&model_id);
let max_fan_speed = self.hw_mon.fan_max_speed;
@ -214,9 +227,11 @@ impl GpuController {
match self.hw_mon.start_fan_control() {
Ok(_) => {
self.config.fan_control_enabled = true;
self.config.save(&self.config_path).expect("Failed to save config");
self.config
.save(&self.config_path)
.expect("Failed to save config");
Ok(())
},
}
Err(e) => Err(e),
}
}
@ -225,9 +240,11 @@ impl GpuController {
match self.hw_mon.stop_fan_control() {
Ok(_) => {
self.config.fan_control_enabled = false;
self.config.save(&self.config_path).expect("Failed to save config");
self.config
.save(&self.config_path)
.expect("Failed to save config");
Ok(())
},
}
Err(e) => Err(e),
}
}
@ -244,7 +261,9 @@ impl GpuController {
pub fn set_fan_curve(&mut self, curve: BTreeMap<i32, f64>) {
self.hw_mon.set_fan_curve(curve.clone());
self.config.fan_curve = curve;
self.config.save(&self.config_path).expect("Failed to save config");
self.config
.save(&self.config_path)
.expect("Failed to save config");
}
fn get_vulkan_info(pci_id: &str) -> VulkanInfo {

View File

@ -26,12 +26,15 @@ pub struct HWMon {
}
impl HWMon {
pub fn new(hwmon_path: &PathBuf, fan_control_enabled: bool, fan_curve: BTreeMap<i32, f64>) -> HWMon {
let fan_max_speed = fs::read_to_string(hwmon_path.join("fan1_max"))
.unwrap()
.trim()
.parse::<i32>()
.unwrap();
pub fn new(
hwmon_path: &PathBuf,
fan_control_enabled: bool,
fan_curve: BTreeMap<i32, f64>,
) -> HWMon {
let fan_max_speed = match fs::read_to_string(hwmon_path.join("fan1_max")) {
Ok(s) => s.trim().parse::<i32>().unwrap(),
Err(_) => 0,
};
let mon = HWMon {
hwmon_path: hwmon_path.clone(),

View File

@ -1,38 +1,44 @@
pub mod config;
pub mod daemon_connection;
pub mod gpu_controller;
pub mod hw_mon;
pub mod daemon_connection;
pub mod config;
use std::{io::{Read, Write}, path::PathBuf, thread};
use config::Config;
use serde::{Deserialize, Serialize};
use std::fs;
use std::{collections::HashMap, fs};
use std::os::unix::net::{UnixListener, UnixStream};
use std::process::Command;
use std::{
io::{Read, Write},
path::PathBuf,
thread,
};
use rand::prelude::*;
use crate::gpu_controller::GpuController;
pub const SOCK_PATH: &str = "/tmp/amdgpu-configurator.sock";
pub struct Daemon {
gpu_controller: GpuController,
gpu_controllers: HashMap<u32, GpuController>,
listener: UnixListener,
}
#[derive(Serialize, Deserialize, Debug)]
pub enum Action {
CheckAlive,
GetInfo,
GetStats,
StartFanControl,
StopFanControl,
GetFanControl,
SetFanCurve,
GetGpus,
GetInfo(u32),
GetStats(u32),
StartFanControl(u32),
StopFanControl(u32),
GetFanControl(u32),
SetFanCurve(u32),
Shutdown,
}
impl Daemon {
pub fn new() -> Daemon {
pub fn new(unpriveleged: bool) -> Daemon {
if fs::metadata(SOCK_PATH).is_ok() {
fs::remove_file(SOCK_PATH).expect("Failed to take control over socket");
}
@ -46,19 +52,43 @@ impl Daemon {
.expect("Failed to chmod");
let config_path = PathBuf::from("/etc/lact.json");
let config = match Config::read_from_file(&config_path) {
let config = if unpriveleged {
Config::new()
} else {
match Config::read_from_file(&config_path) {
Ok(c) => c,
Err(_) => {
let c = Config::new();
c.save(&config_path).expect("Failed to save config");
c
}
}
};
log::trace!("Using config {:?}", config);
let gpu_controller = GpuController::new(PathBuf::from("/sys/class/drm/card0/device"), config, config_path);
let mut gpu_controllers: HashMap<u32, GpuController> = HashMap::new();
Daemon { listener, gpu_controller }
for entry in fs::read_dir("/sys/class/drm").expect("Could not open /sys/class/drm") {
let entry = entry.unwrap();
if entry.file_name().len() == 5 {
if entry.file_name().to_str().unwrap().split_at(4).0 == "card" {
log::info!("Initializing {:?}", entry.path());
loop {
let id: u32 = random();
if !gpu_controllers.contains_key(&id) {
gpu_controllers.insert(id, GpuController::new(entry.path().join("device"), config.clone(), config_path.clone()));
break;
}
}
}
}
}
Daemon {
listener,
gpu_controllers,
}
}
pub fn listen(mut self) {
@ -67,7 +97,7 @@ impl Daemon {
Ok(stream) => {
//let mut controller = self.gpu_controller.clone();
//thread::spawn(move || Daemon::handle_connection(&mut controller, stream));
Daemon::handle_connection(&mut self.gpu_controller, stream);
Daemon::handle_connection(&mut self.gpu_controllers, stream);
}
Err(err) => {
log::error!("Error: {}", err);
@ -77,40 +107,67 @@ impl Daemon {
}
}
fn handle_connection(gpu_controller: &mut GpuController, mut stream: UnixStream) {
let mut buffer: [u8; 4] = [0; 4];
stream.read(&mut buffer).unwrap();
fn handle_connection(gpu_controllers: &mut HashMap<u32, GpuController>, mut stream: UnixStream) {
log::trace!("Reading buffer");
let mut buffer = Vec::<u8>::new();
stream.read_to_end(&mut buffer).unwrap();
//log::trace!("finished reading, buffer size {}", buffer.len());
log::trace!("Attempting to deserialize {:?}", &buffer);
let action: Action = bincode::deserialize(&buffer).expect("Failed to deserialize buffer");
//log::trace!("{:?}", action);
log::trace!("Executing action {:?}", action);
let response: Option<Vec<u8>> = match action {
Action::GetStats => Some(bincode::serialize(&gpu_controller.get_stats()).unwrap()),
Action::GetInfo => Some(bincode::serialize(&gpu_controller.gpu_info).unwrap()),
Action::StartFanControl => Some(bincode::serialize(&gpu_controller.start_fan_control()).unwrap()),
Action::StopFanControl => Some(bincode::serialize(&gpu_controller.stop_fan_control()).unwrap()),
Action::GetFanControl => Some(bincode::serialize(&gpu_controller.get_fan_control()).unwrap()),
Action::SetFanCurve => {
Action::CheckAlive => Some(vec![1]),
Action::GetGpus => {
let mut gpus: HashMap<u32, String> = HashMap::new();
for controller in gpu_controllers {
gpus.insert(*controller.0, controller.1.gpu_info.gpu_model.clone());
}
Some(bincode::serialize(&gpus).unwrap())
},
Action::GetStats(i) => match gpu_controllers.get(&i) {
Some(controller) => Some(bincode::serialize(&controller.get_stats()).unwrap()),
_ => None,
},
Action::GetInfo(i) => match gpu_controllers.get(&i) {
Some(controller) => Some(bincode::serialize(&controller.gpu_info).unwrap()),
_ => None,
},
Action::StartFanControl(i) => match gpu_controllers.get_mut(&i) {
Some(controller) => Some(bincode::serialize(&controller.start_fan_control()).unwrap()),
_ => None,
},
Action::StopFanControl(i) => match gpu_controllers.get_mut(&i) {
Some(controller) => Some(bincode::serialize(&controller.stop_fan_control()).unwrap()),
_ => None,
},
Action::GetFanControl(i) => match gpu_controllers.get(&i) {
Some(controller) => Some(bincode::serialize(&controller.get_fan_control()).unwrap()),
_ => None,
}
Action::SetFanCurve(i) => {
let mut buffer = Vec::new();
stream.read_to_end(&mut buffer).unwrap();
gpu_controller.set_fan_curve(bincode::deserialize(&buffer).expect("Failed to deserialize curve"));
gpu_controllers.get_mut(&i).unwrap().set_fan_curve(
bincode::deserialize(&buffer).expect("Failed to deserialize curve"),
);
None
},
Action::CheckAlive => Some(vec![1]),
}
Action::Shutdown => std::process::exit(0),
};
if let Some(r) = &response {
stream
.write_all(&r)
.expect("Failed writing response");
log::trace!("Responding");
stream.write_all(&r).expect("Failed writing response");
//stream
// .shutdown(std::net::Shutdown::Write)
// .expect("Could not shut down");
log::trace!("Finished responding");
}
}
}
#[derive(Debug)]
pub enum DaemonError {
ConnectionFailed,

View File

@ -2,6 +2,6 @@ use daemon::Daemon;
fn main() {
env_logger::init();
let d = Daemon::new();
let d = Daemon::new(false);
d.listen();
}

View File

@ -2,13 +2,22 @@ extern crate gdk;
extern crate gio;
extern crate gtk;
use daemon::{Daemon, daemon_connection::DaemonConnection};
use daemon::{daemon_connection::DaemonConnection, Daemon};
use gio::prelude::*;
use gtk::{Adjustment, Button, ButtonsType, DialogFlags, Frame, Label, LevelBar, MessageType, Switch, prelude::*};
use gtk::{
prelude::*, Adjustment, Button, ButtonsType, DialogFlags, Frame, Label, LevelBar, MessageType,
Switch,
};
use gtk::{Builder, MessageDialog, TextBuffer, Window};
use std::{collections::BTreeMap, env::args, sync::{Arc, RwLock}, thread, time::Duration};
use std::{
collections::BTreeMap,
env::args,
sync::{Arc, RwLock},
thread,
time::Duration,
};
fn build_ui(application: &gtk::Application) {
let glade_src = include_str!("main_window.glade");
@ -63,30 +72,22 @@ fn build_ui(application: &gtk::Application) {
.get_object("vram_usage_label")
.expect("Couldn't get label");
let gpu_clock_text_buffer: TextBuffer = builder
.get_object("gpu_clock_text_buffer").unwrap();
let gpu_clock_text_buffer: TextBuffer = builder.get_object("gpu_clock_text_buffer").unwrap();
let vram_clock_text_buffer: TextBuffer = builder
.get_object("vram_clock_text_buffer").unwrap();
let vram_clock_text_buffer: TextBuffer = builder.get_object("vram_clock_text_buffer").unwrap();
let gpu_temp_text_buffer: TextBuffer = builder
.get_object("gpu_temp_text_buffer").unwrap();
let gpu_temp_text_buffer: TextBuffer = builder.get_object("gpu_temp_text_buffer").unwrap();
let gpu_power_text_buffer: TextBuffer = builder
.get_object("gpu_power_text_buffer").unwrap();
let gpu_power_text_buffer: TextBuffer = builder.get_object("gpu_power_text_buffer").unwrap();
let fan_speed_text_buffer: TextBuffer = builder
.get_object("fan_speed_text_buffer").unwrap();
let fan_speed_text_buffer: TextBuffer = builder.get_object("fan_speed_text_buffer").unwrap();
let automatic_fan_control_switch: Switch = builder
.get_object("automatic_fan_control_switch").unwrap();
let automatic_fan_control_switch: Switch =
builder.get_object("automatic_fan_control_switch").unwrap();
let apply_button: Button = builder
.get_object("apply_button").unwrap();
let fan_curve_frame: Frame = builder
.get_object("fan_curve_frame").unwrap();
let apply_button: Button = builder.get_object("apply_button").unwrap();
let fan_curve_frame: Frame = builder.get_object("fan_curve_frame").unwrap();
let mut unpriviliged: bool = false;
@ -95,7 +96,7 @@ fn build_ui(application: &gtk::Application) {
Err(_) => {
unpriviliged = true;
let daemon = Daemon::new();
let daemon = Daemon::new(unpriviliged);
thread::spawn(move || {
daemon.listen();
});
@ -139,16 +140,13 @@ fn build_ui(application: &gtk::Application) {
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
thread::spawn(move || {
loop {
thread::spawn(move || loop {
let gpu_stats = d.get_gpu_stats();
tx.send(gpu_stats).expect("Couldn't send text");
thread::sleep(Duration::from_millis(500));
}
});
rx.attach(None, move |gpu_stats| {
vram_usage_level_bar.set_max_value(gpu_stats.mem_total as f64);
vram_usage_level_bar.set_value(gpu_stats.mem_used as f64);
@ -161,9 +159,14 @@ fn build_ui(application: &gtk::Application) {
gpu_temp_text_buffer.set_text(&format!("{}°C", gpu_stats.gpu_temp));
gpu_power_text_buffer.set_text(&format!("{}/{}W", gpu_stats.power_avg, gpu_stats.power_max));
gpu_power_text_buffer
.set_text(&format!("{}/{}W", gpu_stats.power_avg, gpu_stats.power_max));
fan_speed_text_buffer.set_text(&format!("{}RPM({}%)", gpu_stats.fan_speed, (gpu_stats.fan_speed as f64 / gpu_info.max_fan_speed as f64 * 100 as f64) as i32));
fan_speed_text_buffer.set_text(&format!(
"{}RPM({}%)",
gpu_stats.fan_speed,
(gpu_stats.fan_speed as f64 / gpu_info.max_fan_speed as f64 * 100 as f64) as i32
));
glib::Continue(true)
});
@ -174,8 +177,7 @@ fn build_ui(application: &gtk::Application) {
println!("Automatic fan control disabled!");
automatic_fan_control_switch.set_active(false);
fan_curve_frame.set_visible(true);
}
else {
} else {
println!("Automatic fan control enabled");
fan_curve_frame.set_visible(false);
}
@ -187,7 +189,7 @@ fn build_ui(application: &gtk::Application) {
match switch.get_active() {
true => {
fan_curve_frame.set_visible(false);
},
}
false => {
fan_curve_frame.set_visible(true);
}
@ -200,9 +202,14 @@ fn build_ui(application: &gtk::Application) {
for i in 1..6 {
let curve_temperature_adjustment: Adjustment = builder
.get_object(&format!("curve_temperature_adjustment_{}", i)).unwrap();
.get_object(&format!("curve_temperature_adjustment_{}", i))
.unwrap();
let value = *curve.read().unwrap().get(&(i * 20)).expect("Could not get by index");
let value = *curve
.read()
.unwrap()
.get(&(i * 20))
.expect("Could not get by index");
println!("Setting value {} on adjustment {}", value, i);
curve_temperature_adjustment.set_value(value);
@ -213,7 +220,6 @@ fn build_ui(application: &gtk::Application) {
c.write().unwrap().insert(20 * i, adj.get_value());
b.set_sensitive(true);
});
}
apply_button.connect_clicked(move |b| {
@ -225,7 +231,7 @@ fn build_ui(application: &gtk::Application) {
match automatic_fan_control_switch.get_active() {
true => {
d.stop_fan_control().unwrap();
},
}
false => {
d.start_fan_control().unwrap();
}
@ -237,7 +243,6 @@ fn build_ui(application: &gtk::Application) {
main_window.show();
}
fn main() {
println!("Initializing gtk");
let application = gtk::Application::new(Some("com.ilyaz.yagc"), Default::default())