Improve memory clock selection for #140, fix dpm_performance enforcement check for GPU
This commit is contained in:
parent
622f161560
commit
a1c44cdea7
19 changed files with 285 additions and 113 deletions
|
@ -43,5 +43,5 @@ pub struct Gpu {
|
||||||
pub tdp: Option<u64>,
|
pub tdp: Option<u64>,
|
||||||
pub tdp_boost: Option<u64>,
|
pub tdp_boost: Option<u64>,
|
||||||
pub clock_limits: Option<MinMax<u64>>,
|
pub clock_limits: Option<MinMax<u64>>,
|
||||||
pub slow_memory: bool,
|
pub memory_clock: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,35 +16,11 @@ impl Default for Base {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Base {
|
Base {
|
||||||
configs: vec![
|
configs: vec![
|
||||||
super::Config {
|
|
||||||
name: "Steam Deck Custom".to_owned(),
|
|
||||||
conditions: super::Conditions {
|
|
||||||
dmi: None,
|
|
||||||
cpuinfo: Some("model name\t: AMD Custom APU (0405)|(0932)\n".to_owned()),
|
|
||||||
os: None,
|
|
||||||
command: None,
|
|
||||||
file_exists: Some("./limits_override.json".into()),
|
|
||||||
},
|
|
||||||
limits: super::Limits {
|
|
||||||
cpu: super::Limit {
|
|
||||||
provider: super::CpuLimitType::SteamDeckAdvance,
|
|
||||||
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeckAdvance),
|
|
||||||
},
|
|
||||||
gpu: super::Limit {
|
|
||||||
provider: super::GpuLimitType::SteamDeckAdvance,
|
|
||||||
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeckAdvance),
|
|
||||||
},
|
|
||||||
battery: super::Limit {
|
|
||||||
provider: super::BatteryLimitType::SteamDeckAdvance,
|
|
||||||
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeckAdvance),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
super::Config {
|
super::Config {
|
||||||
name: "Steam Deck".to_owned(),
|
name: "Steam Deck".to_owned(),
|
||||||
conditions: super::Conditions {
|
conditions: super::Conditions {
|
||||||
dmi: None,
|
dmi: None,
|
||||||
cpuinfo: Some("model name\t: AMD Custom APU (0405)|(0932)\n".to_owned()),
|
cpuinfo: Some("model name\t: AMD Custom APU 0405\n".to_owned()),
|
||||||
os: None,
|
os: None,
|
||||||
command: None,
|
command: None,
|
||||||
file_exists: None,
|
file_exists: None,
|
||||||
|
@ -64,6 +40,30 @@ impl Default for Base {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
super::Config {
|
||||||
|
name: "Steam Deck OLED".to_owned(),
|
||||||
|
conditions: super::Conditions {
|
||||||
|
dmi: None,
|
||||||
|
cpuinfo: Some("model name\t: AMD Custom APU 0932\n".to_owned()),
|
||||||
|
os: None,
|
||||||
|
command: None,
|
||||||
|
file_exists: None,
|
||||||
|
},
|
||||||
|
limits: super::Limits {
|
||||||
|
cpu: super::Limit {
|
||||||
|
provider: super::CpuLimitType::SteamDeck,
|
||||||
|
limits: super::GenericCpusLimit::default_for(super::CpuLimitType::SteamDeck),
|
||||||
|
},
|
||||||
|
gpu: super::Limit {
|
||||||
|
provider: super::GpuLimitType::SteamDeck,
|
||||||
|
limits: super::GenericGpuLimit::default_for(super::GpuLimitType::SteamDeckOLED),
|
||||||
|
},
|
||||||
|
battery: super::Limit {
|
||||||
|
provider: super::BatteryLimitType::SteamDeck,
|
||||||
|
limits: super::GenericBatteryLimit::default_for(super::BatteryLimitType::SteamDeck),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
super::Config {
|
super::Config {
|
||||||
name: "AMD R3 2300U".to_owned(),
|
name: "AMD R3 2300U".to_owned(),
|
||||||
conditions: super::Conditions {
|
conditions: super::Conditions {
|
||||||
|
|
|
@ -8,6 +8,8 @@ pub enum GpuLimitType {
|
||||||
SteamDeck,
|
SteamDeck,
|
||||||
#[serde(rename = "GabeBoyAdvance", alias = "SteamDeckAdvance")]
|
#[serde(rename = "GabeBoyAdvance", alias = "SteamDeckAdvance")]
|
||||||
SteamDeckAdvance,
|
SteamDeckAdvance,
|
||||||
|
#[serde(rename = "GabeBoy101", alias = "SteamDeckOLED")]
|
||||||
|
SteamDeckOLED,
|
||||||
Generic,
|
Generic,
|
||||||
GenericAMD,
|
GenericAMD,
|
||||||
Unknown,
|
Unknown,
|
||||||
|
@ -27,6 +29,8 @@ pub struct GenericGpuLimit {
|
||||||
pub clock_min: Option<RangeLimit<u64>>,
|
pub clock_min: Option<RangeLimit<u64>>,
|
||||||
pub clock_max: Option<RangeLimit<u64>>,
|
pub clock_max: Option<RangeLimit<u64>>,
|
||||||
pub clock_step: Option<u64>,
|
pub clock_step: Option<u64>,
|
||||||
|
pub memory_clock: Option<RangeLimit<u64>>,
|
||||||
|
pub memory_clock_step: Option<u64>,
|
||||||
pub skip_resume_reclock: bool,
|
pub skip_resume_reclock: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +38,7 @@ impl GenericGpuLimit {
|
||||||
pub fn default_for(t: GpuLimitType) -> Self {
|
pub fn default_for(t: GpuLimitType) -> Self {
|
||||||
match t {
|
match t {
|
||||||
GpuLimitType::SteamDeck | GpuLimitType::SteamDeckAdvance => Self::default_steam_deck(),
|
GpuLimitType::SteamDeck | GpuLimitType::SteamDeckAdvance => Self::default_steam_deck(),
|
||||||
|
GpuLimitType::SteamDeckOLED => Self::default_steam_deck_oled(),
|
||||||
_t => Self::default(),
|
_t => Self::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,10 +69,24 @@ impl GenericGpuLimit {
|
||||||
max: Some(1600),
|
max: Some(1600),
|
||||||
}),
|
}),
|
||||||
clock_step: Some(100),
|
clock_step: Some(100),
|
||||||
|
// Disabled for now since LCD version is a bit broken on sysfs right now
|
||||||
|
/*memory_clock: Some(RangeLimit {
|
||||||
|
min: Some(400),
|
||||||
|
max: Some(800),
|
||||||
|
}),
|
||||||
|
memory_clock_step: Some(400),*/
|
||||||
|
memory_clock: None,
|
||||||
|
memory_clock_step: None,
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_steam_deck_oled() -> Self {
|
||||||
|
let mut sd = Self::default_steam_deck();
|
||||||
|
sd.memory_clock_step = Some(200);
|
||||||
|
sd
|
||||||
|
}
|
||||||
|
|
||||||
pub fn apply_override(&mut self, limit_override: Self) {
|
pub fn apply_override(&mut self, limit_override: Self) {
|
||||||
if let Some(range) = limit_override.fast_ppt {
|
if let Some(range) = limit_override.fast_ppt {
|
||||||
if range.min.is_none() && range.max.is_none() {
|
if range.min.is_none() && range.max.is_none() {
|
||||||
|
|
|
@ -59,7 +59,8 @@ pub struct GpuLimits {
|
||||||
pub clock_min_limits: Option<RangeLimit<u64>>,
|
pub clock_min_limits: Option<RangeLimit<u64>>,
|
||||||
pub clock_max_limits: Option<RangeLimit<u64>>,
|
pub clock_max_limits: Option<RangeLimit<u64>>,
|
||||||
pub clock_step: u64,
|
pub clock_step: u64,
|
||||||
pub memory_control_capable: bool,
|
pub memory_control: Option<RangeLimit<u64>>,
|
||||||
|
pub memory_step: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
|
|
@ -160,17 +160,17 @@ pub fn set_slow_memory(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |value: bool| {
|
let setter = move |value: u64| {
|
||||||
sender
|
sender
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value)))
|
.send(ApiMessage::Gpu(GpuMessage::SetMemoryClock(Some(value))))
|
||||||
.expect("unset_clock_limits send failed")
|
.expect("unset_clock_limits send failed")
|
||||||
};
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
if let Some(&Primitive::F64(mem_clock)) = params_in.get(0) {
|
||||||
setter(memory_is_slow);
|
setter(mem_clock as _);
|
||||||
vec![memory_is_slow.into()]
|
vec![mem_clock.into()]
|
||||||
} else {
|
} else {
|
||||||
vec!["set_slow_memory missing parameter 0".into()]
|
vec!["set_slow_memory missing parameter 0".into()]
|
||||||
}
|
}
|
||||||
|
@ -183,14 +183,14 @@ pub fn get_slow_memory(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |value: bool| {
|
let callback = move |value: Option<u64>| {
|
||||||
tx.send(value)
|
tx.send(value)
|
||||||
.expect("get_slow_memory callback send failed")
|
.expect("get_slow_memory callback send failed")
|
||||||
};
|
};
|
||||||
sender2
|
sender2
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(
|
.send(ApiMessage::Gpu(GpuMessage::GetMemoryClock(Box::new(
|
||||||
callback,
|
callback,
|
||||||
))))
|
))))
|
||||||
.expect("get_slow_memory send failed");
|
.expect("get_slow_memory send failed");
|
||||||
|
@ -199,6 +199,23 @@ pub fn get_slow_memory(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |value: bool| vec![value.into()],
|
trans_getter: |value: Option<u64>| vec![super::utility::map_optional(value)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unset_slow_memory(
|
||||||
|
sender: Sender<ApiMessage>,
|
||||||
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
|
let setter = move || {
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::SetMemoryClock(None)))
|
||||||
|
.expect("unset_slow_memory send failed")
|
||||||
|
};
|
||||||
|
move |_: super::ApiParameterType| {
|
||||||
|
setter();
|
||||||
|
vec![true.into()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,8 +198,8 @@ pub enum GpuMessage {
|
||||||
GetPpt(Callback<(Option<u64>, Option<u64>)>),
|
GetPpt(Callback<(Option<u64>, Option<u64>)>),
|
||||||
SetClockLimits(Option<MinMax<u64>>),
|
SetClockLimits(Option<MinMax<u64>>),
|
||||||
GetClockLimits(Callback<Option<MinMax<u64>>>),
|
GetClockLimits(Callback<Option<MinMax<u64>>>),
|
||||||
SetSlowMemory(bool),
|
SetMemoryClock(Option<u64>),
|
||||||
GetSlowMemory(Callback<bool>),
|
GetMemoryClock(Callback<Option<u64>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GpuMessage {
|
impl GpuMessage {
|
||||||
|
@ -210,8 +210,8 @@ impl GpuMessage {
|
||||||
Self::GetPpt(cb) => cb(settings.get_ppt()),
|
Self::GetPpt(cb) => cb(settings.get_ppt()),
|
||||||
Self::SetClockLimits(clocks) => settings.clock_limits(clocks),
|
Self::SetClockLimits(clocks) => settings.clock_limits(clocks),
|
||||||
Self::GetClockLimits(cb) => cb(settings.get_clock_limits().map(|x| x.to_owned())),
|
Self::GetClockLimits(cb) => cb(settings.get_clock_limits().map(|x| x.to_owned())),
|
||||||
Self::SetSlowMemory(val) => *settings.slow_memory() = val,
|
Self::SetMemoryClock(val) => settings.memory_clock(val),
|
||||||
Self::GetSlowMemory(cb) => cb(*settings.slow_memory()),
|
Self::GetMemoryClock(cb) => cb(settings.get_memory_clock()),
|
||||||
}
|
}
|
||||||
dirty
|
dirty
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ impl GpuMessage {
|
||||||
fn is_modify(&self) -> bool {
|
fn is_modify(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
Self::SetPpt(_, _) | Self::SetClockLimits(_) | Self::SetSlowMemory(_)
|
Self::SetPpt(_, _) | Self::SetClockLimits(_) | Self::SetMemoryClock(_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ fn web_config_to_settings_json(meta: community_settings_core::v1::Metadata) -> c
|
||||||
min: lim.min,
|
min: lim.min,
|
||||||
max: lim.max,
|
max: lim.max,
|
||||||
}),
|
}),
|
||||||
slow_memory: meta.config.gpu.slow_memory,
|
memory_clock: meta.config.gpu.memory_clock,
|
||||||
root: None,
|
root: None,
|
||||||
},
|
},
|
||||||
battery: crate::persist::BatteryJson {
|
battery: crate::persist::BatteryJson {
|
||||||
|
@ -138,7 +138,7 @@ fn settings_to_web_config(app_id: u32, user_id: u64, username: String, settings:
|
||||||
min: lim.min,
|
min: lim.min,
|
||||||
max: lim.max,
|
max: lim.max,
|
||||||
}),
|
}),
|
||||||
slow_memory: settings.gpu.slow_memory,
|
memory_clock: settings.gpu.memory_clock,
|
||||||
},
|
},
|
||||||
battery: community_settings_core::v1::Battery {
|
battery: community_settings_core::v1::Battery {
|
||||||
charge_rate: settings.battery.charge_rate,
|
charge_rate: settings.battery.charge_rate,
|
||||||
|
|
|
@ -243,6 +243,10 @@ fn main() -> Result<(), ()> {
|
||||||
"GPU_get_slow_memory",
|
"GPU_get_slow_memory",
|
||||||
api::gpu::get_slow_memory(api_sender.clone()),
|
api::gpu::get_slow_memory(api_sender.clone()),
|
||||||
)
|
)
|
||||||
|
.register(
|
||||||
|
"GPU_unset_slow_memory",
|
||||||
|
api::gpu::unset_slow_memory(api_sender.clone()),
|
||||||
|
)
|
||||||
// general API functions
|
// general API functions
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_set_persistent",
|
"GENERAL_set_persistent",
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct GpuJson {
|
||||||
pub tdp: Option<u64>,
|
pub tdp: Option<u64>,
|
||||||
pub tdp_boost: Option<u64>,
|
pub tdp_boost: Option<u64>,
|
||||||
pub clock_limits: Option<MinMaxJson<u64>>,
|
pub clock_limits: Option<MinMaxJson<u64>>,
|
||||||
pub slow_memory: bool,
|
pub memory_clock: Option<u64>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub root: Option<String>,
|
pub root: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ impl Default for GpuJson {
|
||||||
tdp: None,
|
tdp: None,
|
||||||
tdp_boost: None,
|
tdp_boost: None,
|
||||||
clock_limits: None,
|
clock_limits: None,
|
||||||
slow_memory: false,
|
memory_clock: None,
|
||||||
root: None,
|
root: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,13 @@ pub fn auto_detect0(
|
||||||
relevant_limits.gpu.limits,
|
relevant_limits.gpu.limits,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
GpuLimitType::SteamDeckOLED => {
|
||||||
|
Box::new(crate::settings::steam_deck::Gpu::from_json_and_limits(
|
||||||
|
settings.gpu.clone(),
|
||||||
|
settings.version,
|
||||||
|
relevant_limits.gpu.limits,
|
||||||
|
))
|
||||||
|
}
|
||||||
GpuLimitType::Generic => {
|
GpuLimitType::Generic => {
|
||||||
Box::new(crate::settings::generic::Gpu::from_json_and_limits(
|
Box::new(crate::settings::generic::Gpu::from_json_and_limits(
|
||||||
settings.gpu.clone(),
|
settings.gpu.clone(),
|
||||||
|
@ -289,6 +296,9 @@ pub fn auto_detect0(
|
||||||
GpuLimitType::SteamDeckAdvance => {
|
GpuLimitType::SteamDeckAdvance => {
|
||||||
Box::new(crate::settings::steam_deck::Gpu::from_limits(relevant_limits.gpu.limits))
|
Box::new(crate::settings::steam_deck::Gpu::from_limits(relevant_limits.gpu.limits))
|
||||||
}
|
}
|
||||||
|
GpuLimitType::SteamDeckOLED => {
|
||||||
|
Box::new(crate::settings::steam_deck::Gpu::from_limits(relevant_limits.gpu.limits))
|
||||||
|
}
|
||||||
GpuLimitType::Generic => {
|
GpuLimitType::Generic => {
|
||||||
Box::new(crate::settings::generic::Gpu::from_limits(relevant_limits.gpu.limits))
|
Box::new(crate::settings::generic::Gpu::from_limits(relevant_limits.gpu.limits))
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ impl Into<GpuJson> for Gpu {
|
||||||
tdp: self.tdp,
|
tdp: self.tdp,
|
||||||
tdp_boost: self.tdp_boost,
|
tdp_boost: self.tdp_boost,
|
||||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||||
slow_memory: false,
|
memory_clock: None,
|
||||||
root: self.sysfs.root().and_then(|p| p.as_ref().to_str().map(|s| s.to_owned()))
|
root: self.sysfs.root().and_then(|p| p.as_ref().to_str().map(|s| s.to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,8 @@ impl TGpu for Gpu {
|
||||||
.clone()
|
.clone()
|
||||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
|
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
|
||||||
clock_step: self.limits.clock_step.unwrap_or(100),
|
clock_step: self.limits.clock_step.unwrap_or(100),
|
||||||
memory_control_capable: false,
|
memory_control: None,
|
||||||
|
memory_step: 100,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +228,10 @@ impl TGpu for Gpu {
|
||||||
self.clock_limits.as_ref()
|
self.clock_limits.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slow_memory(&mut self) -> &mut bool {
|
fn memory_clock(&mut self, _speed: Option<u64>) {}
|
||||||
&mut self.slow_memory
|
|
||||||
|
fn get_memory_clock(&self) -> Option<u64> {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
|
|
|
@ -299,7 +299,8 @@ fn bad_gpu_limits() -> crate::api::GpuLimits {
|
||||||
clock_min_limits: None,
|
clock_min_limits: None,
|
||||||
clock_max_limits: None,
|
clock_max_limits: None,
|
||||||
clock_step: 100,
|
clock_step: 100,
|
||||||
memory_control_capable: false,
|
memory_control: None,
|
||||||
|
memory_step: 400,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,8 +334,12 @@ impl TGpu for Gpu {
|
||||||
self.generic.get_clock_limits()
|
self.generic.get_clock_limits()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slow_memory(&mut self) -> &mut bool {
|
fn memory_clock(&mut self, speed: Option<u64>) {
|
||||||
self.generic.slow_memory()
|
self.generic.memory_clock(speed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_memory_clock(&self) -> Option<u64> {
|
||||||
|
self.generic.get_memory_clock()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use sysfuss::{BasicEntityPath, HwMonPath, SysEntity, capability::attributes, SysEntityAttributesExt, SysAttribute};
|
use sysfuss::{BasicEntityPath, HwMonPath, SysEntity, capability::attributes, SysEntityAttributes, SysEntityAttributesExt, SysAttribute};
|
||||||
|
|
||||||
use limits_core::json_v2::GenericGpuLimit;
|
use limits_core::json_v2::GenericGpuLimit;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ pub struct Gpu {
|
||||||
pub fast_ppt: Option<u64>,
|
pub fast_ppt: Option<u64>,
|
||||||
pub slow_ppt: Option<u64>,
|
pub slow_ppt: Option<u64>,
|
||||||
pub clock_limits: Option<MinMax<u64>>,
|
pub clock_limits: Option<MinMax<u64>>,
|
||||||
pub slow_memory: bool,
|
pub memory_clock: Option<u64>,
|
||||||
limits: GenericGpuLimit,
|
limits: GenericGpuLimit,
|
||||||
state: crate::state::steam_deck::Gpu,
|
state: crate::state::steam_deck::Gpu,
|
||||||
sysfs_card: BasicEntityPath,
|
sysfs_card: BasicEntityPath,
|
||||||
|
@ -47,6 +47,8 @@ enum ClockType {
|
||||||
|
|
||||||
const MAX_CLOCK: u64 = 1600;
|
const MAX_CLOCK: u64 = 1600;
|
||||||
const MIN_CLOCK: u64 = 200;
|
const MIN_CLOCK: u64 = 200;
|
||||||
|
const MAX_MEMORY_CLOCK: u64 = 800;
|
||||||
|
const MIN_MEMORY_CLOCK: u64 = 400;
|
||||||
const MAX_FAST_PPT: u64 = 30_000_000;
|
const MAX_FAST_PPT: u64 = 30_000_000;
|
||||||
const MIN_FAST_PPT: u64 = 1_000_000;
|
const MIN_FAST_PPT: u64 = 1_000_000;
|
||||||
const MAX_SLOW_PPT: u64 = 29_000_000;
|
const MAX_SLOW_PPT: u64 = 29_000_000;
|
||||||
|
@ -108,6 +110,63 @@ impl Gpu {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_memory_clock_maxed(&self) -> bool {
|
||||||
|
if let Some(clock) = &self.memory_clock {
|
||||||
|
if let Some(limit) = &self.limits.memory_clock {
|
||||||
|
if let Some(limit) = &limit.max {
|
||||||
|
if let Some(step) = &self.limits.memory_clock_step {
|
||||||
|
log::debug!("chosen_clock: {}, limit_clock: {}, step: {}", clock, limit, step);
|
||||||
|
return clock > &(limit - step);
|
||||||
|
} else {
|
||||||
|
log::debug!("chosen_clock: {}, limit_clock: {}", clock, limit);
|
||||||
|
return clock == limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn quantize_memory_clock(&self, clock: u64) -> u64 {
|
||||||
|
if let Ok(f) = self.sysfs_card.read_value(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned()) {
|
||||||
|
let options = parse_pp_dpm_fclk(&String::from_utf8_lossy(&f));
|
||||||
|
// round (and find) nearest valid clock step
|
||||||
|
// roughly price is right strategy (clock step will always be lower or equal to chosen)
|
||||||
|
for i in 0..options.len() {
|
||||||
|
let (current_val_opt, current_speed_opt) = &options[i];
|
||||||
|
let current_speed_opt = *current_speed_opt as u64;
|
||||||
|
if clock == current_speed_opt {
|
||||||
|
return *current_val_opt as _;
|
||||||
|
} else if current_speed_opt > clock {
|
||||||
|
if i == 0 {
|
||||||
|
return *current_val_opt as _;
|
||||||
|
} else {
|
||||||
|
return options[i-1].0 as _;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options[options.len() - 1].0 as _
|
||||||
|
} else {
|
||||||
|
self.is_memory_clock_maxed() as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_memory_clock_payload(&self, clock: u64) -> String {
|
||||||
|
let max_val = self.quantize_memory_clock(clock);
|
||||||
|
match max_val {
|
||||||
|
0 => "0\n".to_owned(),
|
||||||
|
max_val => {
|
||||||
|
use std::fmt::Write;
|
||||||
|
let mut payload = String::from("0");
|
||||||
|
for i in 1..max_val {
|
||||||
|
write!(payload, " {}", i).expect("Failed to write to memory payload (should be infallible!?)");
|
||||||
|
}
|
||||||
|
write!(payload, " {}\n", max_val).expect("Failed to write to memory payload (should be infallible!?)");
|
||||||
|
payload
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
|
fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
if let Some(clock_limits) = &self.clock_limits {
|
if let Some(clock_limits) = &self.clock_limits {
|
||||||
|
@ -130,7 +189,7 @@ impl Gpu {
|
||||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||||
{
|
{
|
||||||
self.state.clock_limits_set = false;
|
self.state.clock_limits_set = false;
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(!self.is_memory_clock_maxed());
|
||||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs_card)?;
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs_card)?;
|
||||||
// disable manual clock limits
|
// disable manual clock limits
|
||||||
|
@ -155,47 +214,36 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_slow_memory(&self, slow: bool) -> Result<(), SettingError> {
|
fn set_memory_speed(&self, clock: u64) -> Result<(), SettingError> {
|
||||||
let path = GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.path(&self.sysfs_card);
|
let path = GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.path(&self.sysfs_card);
|
||||||
if slow {
|
let payload = self.build_memory_clock_payload(clock);
|
||||||
self.sysfs_card.set(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned(), slow as u8).map_err(|e| {
|
log::debug!("Generated payload for gpu fclk (memory): `{}` (is maxed? {})", payload, self.is_memory_clock_maxed());
|
||||||
|
self.sysfs_card.set(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned(), payload).map_err(|e| {
|
||||||
SettingError {
|
SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
// NOTE: there is a GPU driver/hardware bug that prevents this from working
|
|
||||||
self.sysfs_card.set(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned(), "0 1\n").map_err(|e| {
|
|
||||||
SettingError {
|
|
||||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
|
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(!self.is_memory_clock_maxed() || self.clock_limits.is_some());
|
||||||
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||||
|
.enforce_level(&self.sysfs_card)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
// enable/disable downclock of GPU memory (to 400Mhz?)
|
// enable/disable downclock of GPU memory (to 400Mhz?)
|
||||||
if self.slow_memory {
|
self.set_memory_speed(
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
self.memory_clock
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
.or_else(|| self.limits.memory_clock
|
||||||
.enforce_level(&self.sysfs_card)
|
.map(|lim| lim.max.unwrap_or(MAX_MEMORY_CLOCK))
|
||||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
).unwrap_or(MAX_MEMORY_CLOCK)
|
||||||
self.set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
|
).unwrap_or_else(|e| errors.push(e));
|
||||||
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
|
||||||
self.set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
|
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
|
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
|
||||||
.enforce_level(&self.sysfs_card)
|
|
||||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
|
||||||
}
|
|
||||||
self.set_clocks()
|
self.set_clocks()
|
||||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
// commit changes (if no errors have already occured)
|
// commit changes (if no errors have already occured)
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
if self.slow_memory || self.clock_limits.is_some() {
|
if !self.is_memory_clock_maxed() || self.clock_limits.is_some() {
|
||||||
self.set_confirm().map_err(|e| {
|
self.set_confirm().map_err(|e| {
|
||||||
errors.push(e);
|
errors.push(e);
|
||||||
errors
|
errors
|
||||||
|
@ -294,6 +342,9 @@ impl Gpu {
|
||||||
Some(max.clamp(self.limits.clock_max.and_then(|lim| lim.min).unwrap_or(MIN_CLOCK), self.limits.clock_max.and_then(|lim| lim.max).unwrap_or(MAX_CLOCK)));
|
Some(max.clamp(self.limits.clock_max.and_then(|lim| lim.min).unwrap_or(MIN_CLOCK), self.limits.clock_max.and_then(|lim| lim.max).unwrap_or(MAX_CLOCK)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(mem_clock) = self.memory_clock {
|
||||||
|
self.memory_clock = Some(mem_clock.clamp(self.limits.memory_clock.and_then(|lim| lim.min).unwrap_or(MIN_MEMORY_CLOCK), self.limits.memory_clock.and_then(|lim| lim.max).unwrap_or(MAX_MEMORY_CLOCK)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +357,7 @@ impl Into<GpuJson> for Gpu {
|
||||||
tdp: None,
|
tdp: None,
|
||||||
tdp_boost: None,
|
tdp_boost: None,
|
||||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||||
slow_memory: self.slow_memory,
|
memory_clock: self.memory_clock,
|
||||||
root: self.sysfs_card.root().or(self.sysfs_hwmon.root()).and_then(|p| p.as_ref().to_str().map(|r| r.to_owned()))
|
root: self.sysfs_card.root().or(self.sysfs_hwmon.root()).and_then(|p| p.as_ref().to_str().map(|r| r.to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +370,7 @@ impl ProviderBuilder<GpuJson, GenericGpuLimit> for Gpu {
|
||||||
fast_ppt: persistent.fast_ppt,
|
fast_ppt: persistent.fast_ppt,
|
||||||
slow_ppt: persistent.slow_ppt,
|
slow_ppt: persistent.slow_ppt,
|
||||||
clock_limits: persistent.clock_limits.map(|x| min_max_from_json(x, version)),
|
clock_limits: persistent.clock_limits.map(|x| min_max_from_json(x, version)),
|
||||||
slow_memory: persistent.slow_memory,
|
memory_clock: persistent.memory_clock,
|
||||||
limits: limits,
|
limits: limits,
|
||||||
state: crate::state::steam_deck::Gpu::default(),
|
state: crate::state::steam_deck::Gpu::default(),
|
||||||
sysfs_card: Self::find_card_sysfs(persistent.root.clone()),
|
sysfs_card: Self::find_card_sysfs(persistent.root.clone()),
|
||||||
|
@ -329,7 +380,7 @@ impl ProviderBuilder<GpuJson, GenericGpuLimit> for Gpu {
|
||||||
fast_ppt: persistent.fast_ppt,
|
fast_ppt: persistent.fast_ppt,
|
||||||
slow_ppt: persistent.slow_ppt,
|
slow_ppt: persistent.slow_ppt,
|
||||||
clock_limits: persistent.clock_limits.map(|x| min_max_from_json(x, version)),
|
clock_limits: persistent.clock_limits.map(|x| min_max_from_json(x, version)),
|
||||||
slow_memory: persistent.slow_memory,
|
memory_clock: persistent.memory_clock,
|
||||||
limits: limits,
|
limits: limits,
|
||||||
state: crate::state::steam_deck::Gpu::default(),
|
state: crate::state::steam_deck::Gpu::default(),
|
||||||
sysfs_card: Self::find_card_sysfs(persistent.root.clone()),
|
sysfs_card: Self::find_card_sysfs(persistent.root.clone()),
|
||||||
|
@ -343,7 +394,7 @@ impl ProviderBuilder<GpuJson, GenericGpuLimit> for Gpu {
|
||||||
fast_ppt: None,
|
fast_ppt: None,
|
||||||
slow_ppt: None,
|
slow_ppt: None,
|
||||||
clock_limits: None,
|
clock_limits: None,
|
||||||
slow_memory: false,
|
memory_clock: None,
|
||||||
limits: limits,
|
limits: limits,
|
||||||
state: crate::state::steam_deck::Gpu::default(),
|
state: crate::state::steam_deck::Gpu::default(),
|
||||||
sysfs_card: Self::find_card_sysfs(None::<&'static str>),
|
sysfs_card: Self::find_card_sysfs(None::<&'static str>),
|
||||||
|
@ -393,7 +444,11 @@ impl TGpu for Gpu {
|
||||||
max: super::util::range_max_or_fallback(&self.limits.clock_max, MAX_CLOCK),
|
max: super::util::range_max_or_fallback(&self.limits.clock_max, MAX_CLOCK),
|
||||||
}),
|
}),
|
||||||
clock_step: self.limits.clock_step.unwrap_or(100),
|
clock_step: self.limits.clock_step.unwrap_or(100),
|
||||||
memory_control_capable: true,
|
memory_control: Some(RangeLimit {
|
||||||
|
min: super::util::range_min_or_fallback(&self.limits.memory_clock, MIN_MEMORY_CLOCK),
|
||||||
|
max: super::util::range_max_or_fallback(&self.limits.memory_clock, MAX_MEMORY_CLOCK),
|
||||||
|
}),
|
||||||
|
memory_step: self.limits.memory_clock_step.unwrap_or(400),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,11 +476,35 @@ impl TGpu for Gpu {
|
||||||
self.clock_limits.as_ref()
|
self.clock_limits.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slow_memory(&mut self) -> &mut bool {
|
fn memory_clock(&mut self, speed: Option<u64>) {
|
||||||
&mut self.slow_memory
|
self.memory_clock = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_memory_clock(&self) -> Option<u64> {
|
||||||
|
self.memory_clock
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
crate::persist::DriverJson::SteamDeck
|
crate::persist::DriverJson::SteamDeck
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_pp_dpm_fclk(s: &str) -> Vec<(usize, usize)> { // (value, MHz)
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for line in s.split('\n') {
|
||||||
|
if !line.is_empty() {
|
||||||
|
if let Some((val, freq_mess)) = line.split_once(':') {
|
||||||
|
if let Ok(val) = val.parse::<usize>() {
|
||||||
|
if let Some((freq, _unit)) = freq_mess.trim().split_once(|c: char| !c.is_digit(10)) {
|
||||||
|
if let Ok(freq) = freq.parse::<usize>() {
|
||||||
|
result.push((val, freq));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl PDFPLManager {
|
||||||
if let Ok(mode_now) =
|
if let Ok(mode_now) =
|
||||||
entity.attribute::<String, _>(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned())
|
entity.attribute::<String, _>(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned())
|
||||||
{
|
{
|
||||||
log::debug!("Mode for `{}` is now `{}`", path.display(), mode_now);
|
log::debug!("Mode for `{}` is now `{}` ({:#b})", path.display(), mode_now, self.get());
|
||||||
} else {
|
} else {
|
||||||
log::debug!("Error getting new mode for debugging purposes");
|
log::debug!("Error getting new mode for debugging purposes");
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,9 @@ pub trait TGpu: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
||||||
|
|
||||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>>;
|
fn get_clock_limits(&self) -> Option<&MinMax<u64>>;
|
||||||
|
|
||||||
fn slow_memory(&mut self) -> &mut bool;
|
fn memory_clock(&mut self, speed: Option<u64>);
|
||||||
|
|
||||||
|
fn get_memory_clock(&self) -> Option<u64>;
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
crate::persist::DriverJson::AutoDetect
|
crate::persist::DriverJson::AutoDetect
|
||||||
|
|
|
@ -8,13 +8,11 @@ use crate::settings::{TGpu, ProviderBuilder};
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Gpu {
|
pub struct Gpu {}
|
||||||
slow_memory: bool, // ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Gpu {
|
impl Gpu {
|
||||||
pub fn system_default() -> Self {
|
pub fn system_default() -> Self {
|
||||||
Self { slow_memory: false }
|
Self { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +35,7 @@ impl Into<GpuJson> for Gpu {
|
||||||
tdp: None,
|
tdp: None,
|
||||||
tdp_boost: None,
|
tdp_boost: None,
|
||||||
clock_limits: None,
|
clock_limits: None,
|
||||||
slow_memory: false,
|
memory_clock: None,
|
||||||
root: None,
|
root: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +67,8 @@ impl TGpu for Gpu {
|
||||||
clock_min_limits: None,
|
clock_min_limits: None,
|
||||||
clock_max_limits: None,
|
clock_max_limits: None,
|
||||||
clock_step: 100,
|
clock_step: 100,
|
||||||
memory_control_capable: false,
|
memory_control: None,
|
||||||
|
memory_step: 400,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +88,10 @@ impl TGpu for Gpu {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slow_memory(&mut self) -> &mut bool {
|
fn memory_clock(&mut self, _speed: Option<u64>) {}
|
||||||
&mut self.slow_memory
|
|
||||||
|
fn get_memory_clock(&self) -> Option<u64> {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
|
|
|
@ -90,7 +90,8 @@ export type GpuLimits = {
|
||||||
clock_min_limits: RangeLimit | null;
|
clock_min_limits: RangeLimit | null;
|
||||||
clock_max_limits: RangeLimit | null;
|
clock_max_limits: RangeLimit | null;
|
||||||
clock_step: number;
|
clock_step: number;
|
||||||
memory_control_capable: boolean;
|
memory_control: RangeLimit | null,
|
||||||
|
memory_step: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
@ -229,14 +230,18 @@ export async function unsetGpuClockLimits(): Promise<any[]> {
|
||||||
return (await call_backend("GPU_unset_clock_limits", []));
|
return (await call_backend("GPU_unset_clock_limits", []));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setGpuSlowMemory(val: boolean): Promise<boolean> {
|
export async function setGpuSlowMemory(clock: number): Promise<number> {
|
||||||
return (await call_backend("GPU_set_slow_memory", [val]))[0];
|
return (await call_backend("GPU_set_slow_memory", [clock]))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGpuSlowMemory(): Promise<boolean> {
|
export async function getGpuSlowMemory(): Promise<number> {
|
||||||
return (await call_backend("GPU_get_slow_memory", []))[0];
|
return (await call_backend("GPU_get_slow_memory", []))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function unsetGpuSlowMemory(): Promise<any[]> {
|
||||||
|
return (await call_backend("GPU_unset_slow_memory", []));
|
||||||
|
}
|
||||||
|
|
||||||
// general
|
// general
|
||||||
|
|
||||||
export async function setGeneralPersistent(val: boolean): Promise<boolean> {
|
export async function setGeneralPersistent(val: boolean): Promise<boolean> {
|
||||||
|
|
|
@ -180,16 +180,42 @@ export class Gpu extends Component<backend.IdcProps> {
|
||||||
}}
|
}}
|
||||||
/>}
|
/>}
|
||||||
</PanelSectionRow>
|
</PanelSectionRow>
|
||||||
{(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control_capable && <PanelSectionRow>
|
{((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control) && <PanelSectionRow>
|
||||||
<ToggleField
|
<ToggleField
|
||||||
checked={get_value(SLOW_MEMORY_GPU)}
|
checked={get_value(SLOW_MEMORY_GPU) != null}
|
||||||
label={tr("Downclock Memory")}
|
label={tr("Downclock Memory")}
|
||||||
description={tr("Force RAM into low-power mode")}
|
description={tr("Force RAM into low-power mode")}
|
||||||
onChange={(value: boolean) => {
|
onChange={(value: boolean) => {
|
||||||
backend.resolve(backend.setGpuSlowMemory(value), (val: boolean) => {
|
if (value) {
|
||||||
|
set_value(SLOW_MEMORY_GPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control!.max);
|
||||||
|
reloadGUI("GPUMemFreqToggle");
|
||||||
|
} else {
|
||||||
|
set_value(SLOW_MEMORY_GPU, null);
|
||||||
|
backend.resolve(backend.unsetGpuSlowMemory(), (_: any[]) => {
|
||||||
|
reloadGUI("GPUUnsetMemFreq");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PanelSectionRow>}
|
||||||
|
{get_value(SLOW_MEMORY_GPU) != null && <PanelSectionRow>
|
||||||
|
<SliderField
|
||||||
|
label={tr("Maximum (MHz)")}
|
||||||
|
value={get_value(SLOW_MEMORY_GPU)}
|
||||||
|
max={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control!.max}
|
||||||
|
min={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_control!.min}
|
||||||
|
step={(get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.memory_step}
|
||||||
|
showValue={true}
|
||||||
|
disabled={get_value(SLOW_MEMORY_GPU) == null}
|
||||||
|
onChange={(val: number) => {
|
||||||
|
backend.log(backend.LogLevel.Debug, "GPU memory clock Max is now " + val.toString());
|
||||||
|
backend.resolve(
|
||||||
|
backend.setGpuSlowMemory(val),
|
||||||
|
(val: number) => {
|
||||||
set_value(SLOW_MEMORY_GPU, val);
|
set_value(SLOW_MEMORY_GPU, val);
|
||||||
reloadGUI("GPUSlowMemory");
|
reloadGUI("GPUSetMemFreq");
|
||||||
})
|
}
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</PanelSectionRow>}
|
</PanelSectionRow>}
|
||||||
|
|
|
@ -170,7 +170,7 @@ const reload = function() {
|
||||||
set_value(CLOCK_MIN_GPU, limits[0]);
|
set_value(CLOCK_MIN_GPU, limits[0]);
|
||||||
set_value(CLOCK_MAX_GPU, limits[1]);
|
set_value(CLOCK_MAX_GPU, limits[1]);
|
||||||
});
|
});
|
||||||
backend.resolve(backend.getGpuSlowMemory(), (status: boolean) => { set_value(SLOW_MEMORY_GPU, status) });
|
backend.resolve(backend.getGpuSlowMemory(), (status: number) => { set_value(SLOW_MEMORY_GPU, status) });
|
||||||
|
|
||||||
backend.resolve(backend.getGeneralPersistent(), (value: boolean) => { set_value(PERSISTENT_GEN, value) });
|
backend.resolve(backend.getGeneralPersistent(), (value: boolean) => { set_value(PERSISTENT_GEN, value) });
|
||||||
backend.resolve(backend.getGeneralSettingsName(), (name: string) => { set_value(NAME_GEN, name) });
|
backend.resolve(backend.getGeneralSettingsName(), (name: string) => { set_value(NAME_GEN, name) });
|
||||||
|
|
Loading…
Reference in a new issue