mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-04-20 03:24:52 +00:00
fix: show amd gpu power profile warning only on amd gpus and with the correct card index
This commit is contained in:
parent
5c2e5b26b4
commit
528afe12ab
2 changed files with 86 additions and 18 deletions
|
@ -1,10 +1,14 @@
|
|||
use crate::file_utils::get_reader;
|
||||
use std::{error::Error, fmt::Display, io::Read, str::FromStr};
|
||||
|
||||
const POW_PROF_PATH: &str = "/sys/class/drm/card0/device/pp_power_profile_mode";
|
||||
// const POW_PROF_PATH: &str = "/sys/class/drm/card0/device/pp_power_profile_mode";
|
||||
|
||||
pub fn get_set_vr_pow_prof_cmd() -> String {
|
||||
format!("sudo sh -c \"echo '4' > {}\"", POW_PROF_PATH)
|
||||
fn power_profile_mode_file(card_dir: &str) -> String {
|
||||
format!("{}/device/pp_power_profile_mode", card_dir)
|
||||
}
|
||||
|
||||
pub fn get_set_amd_vr_pow_prof_cmd(card_dir: &str) -> String {
|
||||
format!("sudo sh -c \"echo '4' > {}\"", power_profile_mode_file(card_dir))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
@ -75,13 +79,53 @@ impl FromStr for GpuPowerProfile {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_gpu_power_profile() -> Option<GpuPowerProfile> {
|
||||
if let Some(mut reader) = get_reader(&POW_PROF_PATH.into()) {
|
||||
let mut txt = String::new();
|
||||
reader.read_to_string(&mut txt).ok()?;
|
||||
for line in txt.split('\n') {
|
||||
if let Ok(pp) = GpuPowerProfile::from_str(line) {
|
||||
return Some(pp);
|
||||
const AMD_VENDOR_ID: &str = "0x1002";
|
||||
// TODO: add these other ids
|
||||
// const INTEL_VENDOR_ID: &str = "0xGGGG";
|
||||
// const NVIDIA_VENDOR_ID: &str = "0xGGGG";
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum GpuSysDrm {
|
||||
Amd(String),
|
||||
Intel(String),
|
||||
Nvidia(String),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
fn list_gpus() -> Vec<GpuSysDrm> {
|
||||
let mut res = vec![];
|
||||
|
||||
for i in 0..5 { // arbitrary range, find a better way
|
||||
let card_dir = format!("/sys/class/drm/card{}", i);
|
||||
let vendor_file = format!("{}/device/vendor", card_dir);
|
||||
if let Some(mut reader) = get_reader(&vendor_file) {
|
||||
let mut buf = String::new();
|
||||
if reader.read_to_string(&mut buf).is_ok() {
|
||||
res.push(match buf.to_lowercase().trim() {
|
||||
AMD_VENDOR_ID => GpuSysDrm::Amd(card_dir),
|
||||
_ => GpuSysDrm::Other(card_dir),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn get_first_amd_gpu() -> Option<GpuSysDrm> {
|
||||
list_gpus().iter().filter(|g| matches!(g, GpuSysDrm::Amd(_))).next().cloned()
|
||||
}
|
||||
|
||||
pub fn get_amd_gpu_power_profile() -> Option<GpuPowerProfile> {
|
||||
let amd_gpu = get_first_amd_gpu();
|
||||
if let Some(GpuSysDrm::Amd(card_dir)) = amd_gpu {
|
||||
if let Some(mut reader) = get_reader(&power_profile_mode_file(card_dir.as_str())) {
|
||||
let mut txt = String::new();
|
||||
reader.read_to_string(&mut txt).ok()?;
|
||||
for line in txt.split('\n') {
|
||||
if let Ok(pp) = GpuPowerProfile::from_str(line) {
|
||||
return Some(pp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsB
|
|||
use crate::config::Config;
|
||||
use crate::constants::APP_NAME;
|
||||
use crate::file_utils::mount_has_nosuid;
|
||||
use crate::gpu_profile::{get_gpu_power_profile, get_set_vr_pow_prof_cmd, GpuPowerProfile};
|
||||
use crate::gpu_profile::{get_amd_gpu_power_profile, get_set_amd_vr_pow_prof_cmd, GpuPowerProfile, get_first_amd_gpu, GpuSysDrm};
|
||||
use crate::profile::{LighthouseDriver, Profile};
|
||||
use crate::steamvr_utils::chaperone_info_exists;
|
||||
use crate::ui::app::{
|
||||
|
@ -57,6 +57,7 @@ pub enum MainViewMsg {
|
|||
SetSelectedProfile(u32),
|
||||
ProfileSelected(u32),
|
||||
UpdateSelectedProfile(Profile),
|
||||
TickSelectedProfileTracker,
|
||||
EditProfile,
|
||||
CreateProfile,
|
||||
DeleteProfile,
|
||||
|
@ -290,7 +291,11 @@ impl SimpleComponent for MainView {
|
|||
set_margin_bottom: 12,
|
||||
// TODO: maybe add manual refresh btn?
|
||||
#[track = "model.changed(Self::selected_profile())"]
|
||||
set_visible: get_gpu_power_profile() != Some(GpuPowerProfile::VR),
|
||||
set_visible: match get_amd_gpu_power_profile() {
|
||||
None => false,
|
||||
Some(GpuPowerProfile::VR) => false,
|
||||
Some(_) => true,
|
||||
},
|
||||
gtk::Separator {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_hexpand: true,
|
||||
|
@ -313,7 +318,7 @@ impl SimpleComponent for MainView {
|
|||
},
|
||||
gtk::Label {
|
||||
set_label: concat!(
|
||||
"Your GPU Power Profile is not set to VR. ",
|
||||
"Your AMD GPU Power Profile is not set to VR. ",
|
||||
"This will cause noticeable stutter when running XR ",
|
||||
"applications. Activate the VR profile witrh the ",
|
||||
"following command:",
|
||||
|
@ -344,7 +349,14 @@ impl SimpleComponent for MainView {
|
|||
set_bottom_margin: 18,
|
||||
#[wrap(Some)]
|
||||
set_buffer: cmdbuf = >k::TextBuffer {
|
||||
set_text: get_set_vr_pow_prof_cmd().as_str(),
|
||||
set_text: &{
|
||||
let mut res = String::new();
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
let ds = d.as_str();
|
||||
res = get_set_amd_vr_pow_prof_cmd(ds);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -356,13 +368,22 @@ impl SimpleComponent for MainView {
|
|||
set_vexpand: false,
|
||||
set_valign: gtk::Align::Center,
|
||||
connect_clicked => move |_| {
|
||||
gtk::gdk::Display::default()
|
||||
.expect("Could not find default display")
|
||||
.clipboard()
|
||||
.set_text(get_set_vr_pow_prof_cmd().as_str());
|
||||
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||
gtk::gdk::Display::default()
|
||||
.expect("Could not find default display")
|
||||
.clipboard()
|
||||
.set_text(get_set_amd_vr_pow_prof_cmd(d.as_str()).as_str());
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
gtk::Button {
|
||||
set_halign: gtk::Align::Start,
|
||||
set_label: "Refresh",
|
||||
connect_clicked[sender] => move |_| {
|
||||
sender.input(Self::Input::TickSelectedProfileTracker);
|
||||
}
|
||||
},
|
||||
},
|
||||
model.steam_launch_options_box.widget(),
|
||||
model.install_wivrn_box.widget(),
|
||||
|
@ -537,6 +558,9 @@ impl SimpleComponent for MainView {
|
|||
.sender()
|
||||
.emit(InstallWivrnBoxMsg::UpdateSelectedProfile(prof.clone()));
|
||||
}
|
||||
Self::Input::TickSelectedProfileTracker => {
|
||||
self.set_selected_profile(self.selected_profile.clone());
|
||||
}
|
||||
Self::Input::UpdateProfiles(profiles, config) => {
|
||||
self.set_profiles(profiles);
|
||||
// why send another message to set the dropdown selection?
|
||||
|
|
Loading…
Add table
Reference in a new issue