mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-08-03 22:58:44 +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 crate::file_utils::get_reader;
|
||||||
use std::{error::Error, fmt::Display, io::Read, str::FromStr};
|
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 {
|
fn power_profile_mode_file(card_dir: &str) -> String {
|
||||||
format!("sudo sh -c \"echo '4' > {}\"", POW_PROF_PATH)
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -75,8 +79,47 @@ impl FromStr for GpuPowerProfile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_gpu_power_profile() -> Option<GpuPowerProfile> {
|
const AMD_VENDOR_ID: &str = "0x1002";
|
||||||
if let Some(mut reader) = get_reader(&POW_PROF_PATH.into()) {
|
// 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();
|
let mut txt = String::new();
|
||||||
reader.read_to_string(&mut txt).ok()?;
|
reader.read_to_string(&mut txt).ok()?;
|
||||||
for line in txt.split('\n') {
|
for line in txt.split('\n') {
|
||||||
|
@ -85,5 +128,6 @@ pub fn get_gpu_power_profile() -> Option<GpuPowerProfile> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsB
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::constants::APP_NAME;
|
use crate::constants::APP_NAME;
|
||||||
use crate::file_utils::mount_has_nosuid;
|
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::profile::{LighthouseDriver, Profile};
|
||||||
use crate::steamvr_utils::chaperone_info_exists;
|
use crate::steamvr_utils::chaperone_info_exists;
|
||||||
use crate::ui::app::{
|
use crate::ui::app::{
|
||||||
|
@ -57,6 +57,7 @@ pub enum MainViewMsg {
|
||||||
SetSelectedProfile(u32),
|
SetSelectedProfile(u32),
|
||||||
ProfileSelected(u32),
|
ProfileSelected(u32),
|
||||||
UpdateSelectedProfile(Profile),
|
UpdateSelectedProfile(Profile),
|
||||||
|
TickSelectedProfileTracker,
|
||||||
EditProfile,
|
EditProfile,
|
||||||
CreateProfile,
|
CreateProfile,
|
||||||
DeleteProfile,
|
DeleteProfile,
|
||||||
|
@ -290,7 +291,11 @@ impl SimpleComponent for MainView {
|
||||||
set_margin_bottom: 12,
|
set_margin_bottom: 12,
|
||||||
// TODO: maybe add manual refresh btn?
|
// TODO: maybe add manual refresh btn?
|
||||||
#[track = "model.changed(Self::selected_profile())"]
|
#[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 {
|
gtk::Separator {
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
set_hexpand: true,
|
set_hexpand: true,
|
||||||
|
@ -313,7 +318,7 @@ impl SimpleComponent for MainView {
|
||||||
},
|
},
|
||||||
gtk::Label {
|
gtk::Label {
|
||||||
set_label: concat!(
|
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 ",
|
"This will cause noticeable stutter when running XR ",
|
||||||
"applications. Activate the VR profile witrh the ",
|
"applications. Activate the VR profile witrh the ",
|
||||||
"following command:",
|
"following command:",
|
||||||
|
@ -344,7 +349,14 @@ impl SimpleComponent for MainView {
|
||||||
set_bottom_margin: 18,
|
set_bottom_margin: 18,
|
||||||
#[wrap(Some)]
|
#[wrap(Some)]
|
||||||
set_buffer: cmdbuf = >k::TextBuffer {
|
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_vexpand: false,
|
||||||
set_valign: gtk::Align::Center,
|
set_valign: gtk::Align::Center,
|
||||||
connect_clicked => move |_| {
|
connect_clicked => move |_| {
|
||||||
|
if let Some(GpuSysDrm::Amd(d)) = get_first_amd_gpu() {
|
||||||
gtk::gdk::Display::default()
|
gtk::gdk::Display::default()
|
||||||
.expect("Could not find default display")
|
.expect("Could not find default display")
|
||||||
.clipboard()
|
.clipboard()
|
||||||
.set_text(get_set_vr_pow_prof_cmd().as_str());
|
.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.steam_launch_options_box.widget(),
|
||||||
model.install_wivrn_box.widget(),
|
model.install_wivrn_box.widget(),
|
||||||
|
@ -537,6 +558,9 @@ impl SimpleComponent for MainView {
|
||||||
.sender()
|
.sender()
|
||||||
.emit(InstallWivrnBoxMsg::UpdateSelectedProfile(prof.clone()));
|
.emit(InstallWivrnBoxMsg::UpdateSelectedProfile(prof.clone()));
|
||||||
}
|
}
|
||||||
|
Self::Input::TickSelectedProfileTracker => {
|
||||||
|
self.set_selected_profile(self.selected_profile.clone());
|
||||||
|
}
|
||||||
Self::Input::UpdateProfiles(profiles, config) => {
|
Self::Input::UpdateProfiles(profiles, config) => {
|
||||||
self.set_profiles(profiles);
|
self.set_profiles(profiles);
|
||||||
// why send another message to set the dropdown selection?
|
// why send another message to set the dropdown selection?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue