Add general quirk support and specific quirk for SD mem clock bug

This commit is contained in:
NGnius (Graham) 2024-02-01 19:39:29 -05:00
parent 59a0727f88
commit 32a36f8627
10 changed files with 120 additions and 41 deletions

View file

@ -8,6 +8,8 @@ pub struct Base {
pub configs: Vec<super::Config>, pub configs: Vec<super::Config>,
/// Server messages /// Server messages
pub messages: Vec<super::DeveloperMessage>, pub messages: Vec<super::DeveloperMessage>,
/// Base URL for the config store
pub store: String,
/// URL from which to grab the next update /// URL from which to grab the next update
pub refresh: Option<String>, pub refresh: Option<String>,
} }
@ -110,7 +112,7 @@ impl Default for Base {
..Default::default() ..Default::default()
}; 4], }; 4],
global_governors: true, global_governors: true,
experiments: false, ..Default::default()
} }
}, },
gpu: super::GpuLimit { gpu: super::GpuLimit {
@ -154,7 +156,7 @@ impl Default for Base {
..Default::default() ..Default::default()
}; 12], // 6 cores with SMTx2 }; 12], // 6 cores with SMTx2
global_governors: true, global_governors: true,
experiments: false, ..Default::default()
} }
}, },
gpu: super::GpuLimit { gpu: super::GpuLimit {
@ -198,7 +200,7 @@ impl Default for Base {
..Default::default() ..Default::default()
}; 16], // 8 cores with SMTx2 }; 16], // 8 cores with SMTx2
global_governors: true, global_governors: true,
experiments: false, ..Default::default()
} }
}, },
gpu: super::GpuLimit { gpu: super::GpuLimit {
@ -242,7 +244,7 @@ impl Default for Base {
..Default::default() ..Default::default()
}; 16], // 8 cores with SMTx2 }; 16], // 8 cores with SMTx2
global_governors: true, global_governors: true,
experiments: false, ..Default::default()
} }
}, },
gpu: super::GpuLimit { gpu: super::GpuLimit {
@ -286,7 +288,7 @@ impl Default for Base {
..Default::default() ..Default::default()
}; 16], // 8 cores with SMTx2 }; 16], // 8 cores with SMTx2
global_governors: true, global_governors: true,
experiments: false, ..Default::default()
} }
}, },
gpu: super::GpuLimit { gpu: super::GpuLimit {
@ -341,6 +343,7 @@ impl Default for Base {
url: Some("https://git.ngni.us/NG-SD-Plugins/PowerTools/wiki".to_owned()), url: Some("https://git.ngni.us/NG-SD-Plugins/PowerTools/wiki".to_owned()),
} }
], ],
store: "https://powertools.ngni.us".to_owned(),
refresh: Some("http://limits.ngni.us:45000/powertools/v2".to_owned()) refresh: Some("http://limits.ngni.us:45000/powertools/v2".to_owned())
} }
} }

View file

@ -19,7 +19,7 @@ pub struct GenericBatteryLimit {
pub charge_modes: Vec<String>, pub charge_modes: Vec<String>,
pub charge_limit: Option<RangeLimit<f64>>, // battery charge % pub charge_limit: Option<RangeLimit<f64>>, // battery charge %
pub extra_readouts: bool, pub extra_readouts: bool,
pub experiments: bool, pub extras: super::LimitExtras,
} }
impl GenericBatteryLimit { impl GenericBatteryLimit {
@ -47,7 +47,7 @@ impl GenericBatteryLimit {
max: Some(90.0), max: Some(90.0),
}), }),
extra_readouts: false, extra_readouts: false,
experiments: false, extras: Default::default(),
} }
} }
@ -67,7 +67,10 @@ impl GenericBatteryLimit {
max: Some(99.0), max: Some(99.0),
}), }),
extra_readouts: true, extra_readouts: true,
extras: super::LimitExtras {
experiments: true, experiments: true,
quirks: vec!["".to_owned()].into_iter().collect(),
},
} }
} }
@ -91,6 +94,6 @@ impl GenericBatteryLimit {
} }
} }
self.extra_readouts = limit_override.extra_readouts; self.extra_readouts = limit_override.extra_readouts;
self.experiments = limit_override.experiments; self.extras = limit_override.extras;
} }
} }

View file

@ -19,7 +19,7 @@ pub enum CpuLimitType {
pub struct GenericCpusLimit { pub struct GenericCpusLimit {
pub cpus: Vec<GenericCpuLimit>, pub cpus: Vec<GenericCpuLimit>,
pub global_governors: bool, pub global_governors: bool,
pub experiments: bool, pub extras: super::LimitExtras,
} }
impl GenericCpusLimit { impl GenericCpusLimit {
@ -29,14 +29,17 @@ impl GenericCpusLimit {
Self { Self {
cpus: [(); 8].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(), cpus: [(); 8].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(),
global_governors: true, global_governors: true,
experiments: false, extras: Default::default(),
} }
}, },
CpuLimitType::DevMode => { CpuLimitType::DevMode => {
Self { Self {
cpus: [(); 11].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(), cpus: [(); 11].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(),
global_governors: true, global_governors: true,
extras: super::LimitExtras {
experiments: true, experiments: true,
quirks: vec!["".to_owned()].into_iter().collect(),
},
} }
}, },
t => { t => {
@ -48,7 +51,7 @@ impl GenericCpusLimit {
Self { Self {
cpus, cpus,
global_governors: true, global_governors: true,
experiments: false, extras: Default::default(),
} }
} }
} }
@ -76,7 +79,7 @@ impl GenericCpusLimit {
.for_each(|(cpu, limit_override)| cpu.apply_override(limit_override)); .for_each(|(cpu, limit_override)| cpu.apply_override(limit_override));
} }
self.global_governors = limit_override.global_governors; self.global_governors = limit_override.global_governors;
self.experiments = limit_override.experiments; self.extras = limit_override.extras;
} }
} }

View file

@ -32,7 +32,7 @@ pub struct GenericGpuLimit {
pub memory_clock: Option<RangeLimit<u64>>, pub memory_clock: Option<RangeLimit<u64>>,
pub memory_clock_step: Option<u64>, pub memory_clock_step: Option<u64>,
pub skip_resume_reclock: bool, pub skip_resume_reclock: bool,
pub experiments: bool, pub extras: super::LimitExtras,
} }
impl GenericGpuLimit { impl GenericGpuLimit {
@ -72,16 +72,21 @@ 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 // LCD version is a bit broken on sysfs, but it's ok
/*memory_clock: Some(RangeLimit { memory_clock: Some(RangeLimit {
min: Some(400), min: Some(400),
max: Some(800), max: Some(800),
}), }),
memory_clock_step: Some(400),*/ memory_clock_step: Some(400),
memory_clock: None,
memory_clock_step: None,
skip_resume_reclock: false, skip_resume_reclock: false,
extras: super::LimitExtras {
experiments: false, experiments: false,
quirks: vec![
"pp_dpm_fclk-reversed".to_owned(),
"pp_dpm_fclk-not-updated-on-LCD".to_owned(),
//"pp_dpm_fclk-static".to_owned(),
].into_iter().collect(),
}
} }
} }
@ -124,7 +129,10 @@ impl GenericGpuLimit {
}), }),
memory_clock_step: Some(100), memory_clock_step: Some(100),
skip_resume_reclock: false, skip_resume_reclock: false,
extras: super::LimitExtras {
experiments: true, experiments: true,
quirks: vec!["dev".to_owned()].into_iter().collect(),
},
} }
} }
@ -190,6 +198,6 @@ impl GenericGpuLimit {
self.clock_step = Some(val); self.clock_step = Some(val);
} }
self.skip_resume_reclock = limit_override.skip_resume_reclock; self.skip_resume_reclock = limit_override.skip_resume_reclock;
self.experiments = limit_override.experiments; self.extras = limit_override.extras;
} }
} }

View file

@ -26,3 +26,9 @@ pub struct Limit<P, L> {
pub type CpuLimit = Limit<super::CpuLimitType, super::GenericCpusLimit>; pub type CpuLimit = Limit<super::CpuLimitType, super::GenericCpusLimit>;
pub type GpuLimit = Limit<super::GpuLimitType, super::GenericGpuLimit>; pub type GpuLimit = Limit<super::GpuLimitType, super::GenericGpuLimit>;
pub type BatteryLimit = Limit<super::BatteryLimitType, super::GenericBatteryLimit>; pub type BatteryLimit = Limit<super::BatteryLimitType, super::GenericBatteryLimit>;
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct LimitExtras {
pub experiments: bool,
pub quirks: std::collections::HashSet<String>,
}

View file

@ -16,6 +16,6 @@ pub use cpu_limit::{CpuLimitType, GenericCpusLimit, GenericCpuLimit};
pub use devel_message::DeveloperMessage; pub use devel_message::DeveloperMessage;
pub use gpu_limit::{GpuLimitType, GenericGpuLimit}; pub use gpu_limit::{GpuLimitType, GenericGpuLimit};
pub use config::Config; pub use config::Config;
pub use limits::{Limits, Limit, CpuLimit, GpuLimit, BatteryLimit}; pub use limits::{Limits, Limit, CpuLimit, GpuLimit, BatteryLimit, LimitExtras};
pub use range::RangeLimit; pub use range::RangeLimit;
pub use target::Target; pub use target::Target;

View file

@ -1,17 +1,40 @@
use std::sync::mpsc::{self, Sender}; use std::sync::mpsc::{self, Sender};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex, RwLock};
use usdpl_back::core::serdes::Primitive; use usdpl_back::core::serdes::Primitive;
use usdpl_back::AsyncCallable; use usdpl_back::AsyncCallable;
use super::handler::{ApiMessage, GeneralMessage}; use super::handler::{ApiMessage, GeneralMessage};
const BASE_URL: &'static str = "http://powertools.ngni.us"; const BASE_URL_FALLBACK: &'static str = "https://powertools.ngni.us";
static BASE_URL: RwLock<Option<String>> = RwLock::new(None);
pub fn set_base_url(base_url: String) {
*BASE_URL.write().expect("Failed to acquire write lock for store base url") = Some(base_url);
}
fn get_base_url() -> String {
BASE_URL.read().expect("Failed to acquire read lock for store base url")
.clone()
.unwrap_or_else(|| BASE_URL_FALLBACK.to_owned())
}
fn url_search_by_app_id(steam_app_id: u32) -> String {
format!("{}/api/setting/by_app_id/{}", get_base_url(), steam_app_id)
}
fn url_download_config_by_id(id: u128) -> String {
format!("{}/api/setting/by_id/{}", get_base_url(), id)
}
fn url_upload_config() -> String {
format!("{}/api/setting", get_base_url())
}
/// Get search results web method /// Get search results web method
pub fn search_by_app_id() -> impl AsyncCallable { pub fn search_by_app_id() -> impl AsyncCallable {
let getter = move || { let getter = move || {
move |steam_app_id: u32| { move |steam_app_id: u32| {
let req_url = format!("{}/api/setting/by_app_id/{}", BASE_URL, steam_app_id); let req_url = url_search_by_app_id(steam_app_id);
match ureq::get(&req_url).call() { match ureq::get(&req_url).call() {
Ok(response) => { Ok(response) => {
let json_res: std::io::Result<Vec<community_settings_core::v1::Metadata>> = let json_res: std::io::Result<Vec<community_settings_core::v1::Metadata>> =
@ -110,7 +133,7 @@ fn web_config_to_settings_json(
} }
fn download_config(id: u128) -> std::io::Result<community_settings_core::v1::Metadata> { fn download_config(id: u128) -> std::io::Result<community_settings_core::v1::Metadata> {
let req_url = format!("{}/api/setting/by_id/{}", BASE_URL, id); let req_url = url_download_config_by_id(id);
let response = ureq::get(&req_url).call().map_err(|e| { let response = ureq::get(&req_url).call().map_err(|e| {
log::warn!("GET to {} failed: {}", req_url, e); log::warn!("GET to {} failed: {}", req_url, e);
std::io::Error::new(std::io::ErrorKind::ConnectionAborted, e) std::io::Error::new(std::io::ErrorKind::ConnectionAborted, e)
@ -207,7 +230,7 @@ fn settings_to_web_config(
} }
fn upload_config(config: community_settings_core::v1::Metadata) -> std::io::Result<()> { fn upload_config(config: community_settings_core::v1::Metadata) -> std::io::Result<()> {
let req_url = format!("{}/api/setting", BASE_URL); let req_url = url_upload_config();
ureq::post(&req_url) ureq::post(&req_url)
.send_json(&config) .send_json(&config)
.map_err(|e| { .map_err(|e| {

View file

@ -32,6 +32,7 @@ pub fn spawn() -> JoinHandle<()> {
save_base(&base, &limits_path); save_base(&base, &limits_path);
base base
}; };
crate::api::web::set_base_url(base.store);
if let Some(refresh) = &base.refresh { if let Some(refresh) = &base.refresh {
// try to retrieve newer version // try to retrieve newer version
match ureq::get(refresh).call() { match ureq::get(refresh).call() {

View file

@ -192,6 +192,37 @@ impl Gpu {
fn build_memory_clock_payload(&self, clock: u64) -> String { fn build_memory_clock_payload(&self, clock: u64) -> String {
let max_val = self.quantize_memory_clock(clock); let max_val = self.quantize_memory_clock(clock);
let is_oled = matches!(self.variant, super::Model::OLED);
let is_lcd = matches!(self.variant, super::Model::LCD);
let is_lock_feature_enabled = self.limits.extras.quirks.contains("pp_dpm_fclk-static");
if (is_oled && self.limits.extras.quirks.contains("pp_dpm_fclk-reversed-on-OLED"))
|| (is_lcd && self.limits.extras.quirks.contains("pp_dpm_fclk-reversed-on-LCD"))
|| self.limits.extras.quirks.contains("pp_dpm_fclk-reversed") {
let options_count = self
.sysfs_card
.read_value(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned())
.map(|b| parse_pp_dpm_fclk(&String::from_utf8_lossy(&b)).len())
.unwrap_or_else(|_| if is_oled { 4 } else { 2 });
let modifier = (options_count - 1) as u64;
if is_lock_feature_enabled {
format!("{}\n", modifier - max_val)
} else {
if max_val == 0 as u64 {
format!("{}\n", modifier)
} else {
use std::fmt::Write;
let mut payload = format!("{}", modifier - max_val);
for i in (0..max_val).rev(/* rev() isn't necessary but it creates a nicer (ascending) order */) {
write!(payload, " {}", modifier - i)
.expect("Failed to write to memory payload (should be infallible!?)");
}
write!(payload, "\n")
.expect("Failed to write to memory payload (should be infallible!?)");
payload
}
}
} else {
match max_val { match max_val {
0 => "0\n".to_owned(), 0 => "0\n".to_owned(),
max_val => { max_val => {
@ -207,6 +238,7 @@ impl Gpu {
} }
} }
} }
}
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();

View file

@ -23,7 +23,7 @@ import {
//joinClassNames, //joinClassNames,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import { VFC, useState } from "react"; import { VFC, useState } from "react";
import { GiDrill, GiTimeBomb, GiTimeTrap, GiDynamite } from "react-icons/gi"; import { GiDrill, GiFireExtinguisher, GiFireBomb, GiMineExplosion } from "react-icons/gi";
import { HiRefresh, HiTrash, HiPlus, HiUpload } from "react-icons/hi"; import { HiRefresh, HiTrash, HiPlus, HiUpload } from "react-icons/hi";
import { TbWorldPlus } from "react-icons/tb"; import { TbWorldPlus } from "react-icons/tb";
@ -532,7 +532,7 @@ export default definePlugin((serverApi: ServerAPI) => {
let ico = <GiDrill />; let ico = <GiDrill />;
let now = new Date(); let now = new Date();
if (now.getDate() == 1 && now.getMonth() == 3) { if (now.getDate() == 1 && now.getMonth() == 3) {
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>; ico = <span><GiFireExtinguisher /><GiFireBomb /><GiMineExplosion /></span>;
} }
//registerCallbacks(false); //registerCallbacks(false);
serverApi.routerHook.addRoute(STORE_RESULTS_URI, StoreResultsPage); serverApi.routerHook.addRoute(STORE_RESULTS_URI, StoreResultsPage);