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>,
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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| {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue