forked from NG-SD-Plugins/PowerTools
Add general quirk support and specific quirk for SD mem clock bug
This commit is contained in:
parent
59a0727f88
commit
32a36f8627
10 changed files with 120 additions and 41 deletions
|
@ -8,6 +8,8 @@ pub struct Base {
|
|||
pub configs: Vec<super::Config>,
|
||||
/// Server messages
|
||||
pub messages: Vec<super::DeveloperMessage>,
|
||||
/// Base URL for the config store
|
||||
pub store: String,
|
||||
/// URL from which to grab the next update
|
||||
pub refresh: Option<String>,
|
||||
}
|
||||
|
@ -110,7 +112,7 @@ impl Default for Base {
|
|||
..Default::default()
|
||||
}; 4],
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
|
@ -154,7 +156,7 @@ impl Default for Base {
|
|||
..Default::default()
|
||||
}; 12], // 6 cores with SMTx2
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
|
@ -198,7 +200,7 @@ impl Default for Base {
|
|||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
|
@ -242,7 +244,7 @@ impl Default for Base {
|
|||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
|
@ -286,7 +288,7 @@ impl Default for Base {
|
|||
..Default::default()
|
||||
}; 16], // 8 cores with SMTx2
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
gpu: super::GpuLimit {
|
||||
|
@ -341,6 +343,7 @@ impl Default for Base {
|
|||
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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub struct GenericBatteryLimit {
|
|||
pub charge_modes: Vec<String>,
|
||||
pub charge_limit: Option<RangeLimit<f64>>, // battery charge %
|
||||
pub extra_readouts: bool,
|
||||
pub experiments: bool,
|
||||
pub extras: super::LimitExtras,
|
||||
}
|
||||
|
||||
impl GenericBatteryLimit {
|
||||
|
@ -47,7 +47,7 @@ impl GenericBatteryLimit {
|
|||
max: Some(90.0),
|
||||
}),
|
||||
extra_readouts: false,
|
||||
experiments: false,
|
||||
extras: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,10 @@ impl GenericBatteryLimit {
|
|||
max: Some(99.0),
|
||||
}),
|
||||
extra_readouts: true,
|
||||
experiments: true,
|
||||
extras: super::LimitExtras {
|
||||
experiments: true,
|
||||
quirks: vec!["".to_owned()].into_iter().collect(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,6 @@ impl GenericBatteryLimit {
|
|||
}
|
||||
}
|
||||
self.extra_readouts = limit_override.extra_readouts;
|
||||
self.experiments = limit_override.experiments;
|
||||
self.extras = limit_override.extras;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub enum CpuLimitType {
|
|||
pub struct GenericCpusLimit {
|
||||
pub cpus: Vec<GenericCpuLimit>,
|
||||
pub global_governors: bool,
|
||||
pub experiments: bool,
|
||||
pub extras: super::LimitExtras,
|
||||
}
|
||||
|
||||
impl GenericCpusLimit {
|
||||
|
@ -29,14 +29,17 @@ impl GenericCpusLimit {
|
|||
Self {
|
||||
cpus: [(); 8].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(),
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
extras: Default::default(),
|
||||
}
|
||||
},
|
||||
CpuLimitType::DevMode => {
|
||||
Self {
|
||||
cpus: [(); 11].iter().enumerate().map(|(i, _)| GenericCpuLimit::default_for(&t, i)).collect(),
|
||||
global_governors: true,
|
||||
experiments: true,
|
||||
extras: super::LimitExtras {
|
||||
experiments: true,
|
||||
quirks: vec!["".to_owned()].into_iter().collect(),
|
||||
},
|
||||
}
|
||||
},
|
||||
t => {
|
||||
|
@ -48,7 +51,7 @@ impl GenericCpusLimit {
|
|||
Self {
|
||||
cpus,
|
||||
global_governors: true,
|
||||
experiments: false,
|
||||
extras: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +79,7 @@ impl GenericCpusLimit {
|
|||
.for_each(|(cpu, limit_override)| cpu.apply_override(limit_override));
|
||||
}
|
||||
self.global_governors = limit_override.global_governors;
|
||||
self.experiments = limit_override.experiments;
|
||||
self.extras = limit_override.extras;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ pub struct GenericGpuLimit {
|
|||
pub memory_clock: Option<RangeLimit<u64>>,
|
||||
pub memory_clock_step: Option<u64>,
|
||||
pub skip_resume_reclock: bool,
|
||||
pub experiments: bool,
|
||||
pub extras: super::LimitExtras,
|
||||
}
|
||||
|
||||
impl GenericGpuLimit {
|
||||
|
@ -72,16 +72,21 @@ impl GenericGpuLimit {
|
|||
max: Some(1600),
|
||||
}),
|
||||
clock_step: Some(100),
|
||||
// Disabled for now since LCD version is a bit broken on sysfs right now
|
||||
/*memory_clock: Some(RangeLimit {
|
||||
// LCD version is a bit broken on sysfs, but it's ok
|
||||
memory_clock: Some(RangeLimit {
|
||||
min: Some(400),
|
||||
max: Some(800),
|
||||
}),
|
||||
memory_clock_step: Some(400),*/
|
||||
memory_clock: None,
|
||||
memory_clock_step: None,
|
||||
memory_clock_step: Some(400),
|
||||
skip_resume_reclock: false,
|
||||
experiments: false,
|
||||
extras: super::LimitExtras {
|
||||
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),
|
||||
skip_resume_reclock: false,
|
||||
experiments: true,
|
||||
extras: super::LimitExtras {
|
||||
experiments: true,
|
||||
quirks: vec!["dev".to_owned()].into_iter().collect(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,6 +198,6 @@ impl GenericGpuLimit {
|
|||
self.clock_step = Some(val);
|
||||
}
|
||||
self.skip_resume_reclock = limit_override.skip_resume_reclock;
|
||||
self.experiments = limit_override.experiments;
|
||||
self.extras = limit_override.extras;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,3 +26,9 @@ pub struct Limit<P, L> {
|
|||
pub type CpuLimit = Limit<super::CpuLimitType, super::GenericCpusLimit>;
|
||||
pub type GpuLimit = Limit<super::GpuLimitType, super::GenericGpuLimit>;
|
||||
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>,
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@ pub use cpu_limit::{CpuLimitType, GenericCpusLimit, GenericCpuLimit};
|
|||
pub use devel_message::DeveloperMessage;
|
||||
pub use gpu_limit::{GpuLimitType, GenericGpuLimit};
|
||||
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 target::Target;
|
||||
|
|
|
@ -1,17 +1,40 @@
|
|||
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::AsyncCallable;
|
||||
|
||||
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
|
||||
pub fn search_by_app_id() -> impl AsyncCallable {
|
||||
let getter = move || {
|
||||
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() {
|
||||
Ok(response) => {
|
||||
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> {
|
||||
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| {
|
||||
log::warn!("GET to {} failed: {}", req_url, 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<()> {
|
||||
let req_url = format!("{}/api/setting", BASE_URL);
|
||||
let req_url = url_upload_config();
|
||||
ureq::post(&req_url)
|
||||
.send_json(&config)
|
||||
.map_err(|e| {
|
||||
|
|
|
@ -32,6 +32,7 @@ pub fn spawn() -> JoinHandle<()> {
|
|||
save_base(&base, &limits_path);
|
||||
base
|
||||
};
|
||||
crate::api::web::set_base_url(base.store);
|
||||
if let Some(refresh) = &base.refresh {
|
||||
// try to retrieve newer version
|
||||
match ureq::get(refresh).call() {
|
||||
|
|
|
@ -192,18 +192,50 @@ impl Gpu {
|
|||
|
||||
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)
|
||||
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 {
|
||||
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
|
||||
}
|
||||
write!(payload, " {}\n", max_val)
|
||||
.expect("Failed to write to memory payload (should be infallible!?)");
|
||||
payload
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
//joinClassNames,
|
||||
} from "decky-frontend-lib";
|
||||
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 { TbWorldPlus } from "react-icons/tb";
|
||||
|
||||
|
@ -532,7 +532,7 @@ export default definePlugin((serverApi: ServerAPI) => {
|
|||
let ico = <GiDrill />;
|
||||
let now = new Date();
|
||||
if (now.getDate() == 1 && now.getMonth() == 3) {
|
||||
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>;
|
||||
ico = <span><GiFireExtinguisher /><GiFireBomb /><GiMineExplosion /></span>;
|
||||
}
|
||||
//registerCallbacks(false);
|
||||
serverApi.routerHook.addRoute(STORE_RESULTS_URI, StoreResultsPage);
|
||||
|
|
Loading…
Reference in a new issue