Remember power preerence and force fallback
This commit is contained in:
parent
05d00eee5a
commit
0a8663a010
|
|
@ -232,6 +232,9 @@ name = "arrayvec"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
|
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "as-raw-xcb-connection"
|
name = "as-raw-xcb-connection"
|
||||||
|
|
@ -1571,6 +1574,8 @@ dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"foldhash 0.2.0",
|
"foldhash 0.2.0",
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2238,6 +2243,22 @@ dependencies = [
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "macro_rules_attribute"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3ae8f6d608c795738406608304d30a2dfbdc8e58e44f7ba43236da5208ded3c"
|
||||||
|
dependencies = [
|
||||||
|
"macro_rules_attribute-proc_macro",
|
||||||
|
"pastey",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "macro_rules_attribute-proc_macro"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc04a4c58212d57930a24bf47d3fa87485264a3a054e9c10e042eb373573ad3c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -2999,6 +3020,12 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pastey"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pdb-addr2line"
|
name = "pdb-addr2line"
|
||||||
version = "0.11.2"
|
version = "0.11.2"
|
||||||
|
|
@ -5094,6 +5121,7 @@ dependencies = [
|
||||||
"hashbrown 0.16.1",
|
"hashbrown 0.16.1",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"log",
|
"log",
|
||||||
|
"macro_rules_attribute",
|
||||||
"naga",
|
"naga",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
|
|
@ -5101,6 +5129,7 @@ dependencies = [
|
||||||
"profiling",
|
"profiling",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"rustc-hash 1.1.0",
|
"rustc-hash 1.1.0",
|
||||||
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"wgpu-core-deps-apple",
|
"wgpu-core-deps-apple",
|
||||||
|
|
@ -5223,6 +5252,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
|
"serde",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ thread-priority = "3"
|
||||||
tokio = { version = "1", features = ["io-util", "macros", "net", "rt", "sync", "time"] }
|
tokio = { version = "1", features = ["io-util", "macros", "net", "rt", "sync", "time"] }
|
||||||
tracing = { version = "0.1", features = ["release_max_level_debug"] }
|
tracing = { version = "0.1", features = ["release_max_level_debug"] }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
wgpu = "29"
|
wgpu = { version = "29", features = ["serde"] }
|
||||||
wholesym = "0.8"
|
wholesym = "0.8"
|
||||||
winit = { version = "0.30", features = ["serde"] }
|
winit = { version = "0.30", features = ["serde"] }
|
||||||
|
|
||||||
|
|
|
||||||
15
src/app.rs
15
src/app.rs
|
|
@ -23,7 +23,7 @@ use winit::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::CliArgs,
|
config::{AppConfig, CliArgs},
|
||||||
controller::ControllerManager,
|
controller::ControllerManager,
|
||||||
emulator::{EmulatorClient, EmulatorCommand, SimId},
|
emulator::{EmulatorClient, EmulatorCommand, SimId},
|
||||||
images::ImageTextureLoader,
|
images::ImageTextureLoader,
|
||||||
|
|
@ -94,8 +94,9 @@ impl Application {
|
||||||
handle: OwnedDisplayHandle,
|
handle: OwnedDisplayHandle,
|
||||||
persistence: Persistence,
|
persistence: Persistence,
|
||||||
args: CliArgs,
|
args: CliArgs,
|
||||||
|
config: AppConfig,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let wgpu = WgpuState::new(handle);
|
let wgpu = WgpuState::new(handle, config);
|
||||||
let icon = load_icon().ok().map(Arc::new);
|
let icon = load_icon().ok().map(Arc::new);
|
||||||
let mappings = MappingProvider::new(persistence.clone(), args.player2_controller);
|
let mappings = MappingProvider::new(persistence.clone(), args.player2_controller);
|
||||||
let shortcuts = ShortcutProvider::new(persistence.clone());
|
let shortcuts = ShortcutProvider::new(persistence.clone());
|
||||||
|
|
@ -496,10 +497,11 @@ impl ApplicationHandler<UserEvent> for Application {
|
||||||
struct WgpuState {
|
struct WgpuState {
|
||||||
instance: wgpu::Instance,
|
instance: wgpu::Instance,
|
||||||
device_descriptor: Arc<dyn Fn(&wgpu::Adapter) -> wgpu::DeviceDescriptor<'static> + Send + Sync>,
|
device_descriptor: Arc<dyn Fn(&wgpu::Adapter) -> wgpu::DeviceDescriptor<'static> + Send + Sync>,
|
||||||
|
config: AppConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuState {
|
impl WgpuState {
|
||||||
fn new(handle: OwnedDisplayHandle) -> Self {
|
fn new(handle: OwnedDisplayHandle, config: AppConfig) -> Self {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
let egui_wgpu::WgpuSetupCreateNew {
|
let egui_wgpu::WgpuSetupCreateNew {
|
||||||
instance_descriptor: wgpu::InstanceDescriptor { backends, .. },
|
instance_descriptor: wgpu::InstanceDescriptor { backends, .. },
|
||||||
|
|
@ -517,16 +519,19 @@ impl WgpuState {
|
||||||
Self {
|
Self {
|
||||||
instance,
|
instance,
|
||||||
device_descriptor,
|
device_descriptor,
|
||||||
|
config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self, window: &Window) -> egui_wgpu::WgpuSetupExisting {
|
fn init(&mut self, window: &Window) -> egui_wgpu::WgpuSetupExisting {
|
||||||
let power_preference =
|
let power_preference =
|
||||||
wgpu::PowerPreference::from_env().unwrap_or(wgpu::PowerPreference::LowPower);
|
wgpu::PowerPreference::from_env().unwrap_or(self.config.power_preference);
|
||||||
debug!("power preference: {power_preference:?}");
|
debug!("power preference: {power_preference:?}");
|
||||||
|
|
||||||
let force_fallback_adapter = std::env::var("WGPU_FORCE_FALLBACK")
|
let force_fallback_adapter = std::env::var("WGPU_FORCE_FALLBACK")
|
||||||
.is_ok_and(|f| f.eq_ignore_ascii_case("true") || f.eq_ignore_ascii_case("1"));
|
.map_or(self.config.force_fallback, |f| {
|
||||||
|
f.eq_ignore_ascii_case("true") || f.eq_ignore_ascii_case("1")
|
||||||
|
});
|
||||||
debug!("force fallback: {force_fallback_adapter}");
|
debug!("force fallback: {force_fallback_adapter}");
|
||||||
|
|
||||||
let surface = self
|
let surface = self
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::{Parser, ValueEnum};
|
||||||
use egui::{Color32, Pos2, Vec2};
|
use egui::{Color32, Pos2, Vec2};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -47,6 +47,28 @@ pub struct CliArgs {
|
||||||
/// Map the first connected controller to Player 2
|
/// Map the first connected controller to Player 2
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub player2_controller: bool,
|
pub player2_controller: bool,
|
||||||
|
/// Force the application to render with CPU, rather than GPU.
|
||||||
|
#[arg(long)]
|
||||||
|
pub wgpu_force_fallback: Option<bool>,
|
||||||
|
/// Set a preference for whether to use a low-power or high-performance GPU adapter
|
||||||
|
#[arg(long)]
|
||||||
|
pub wgpu_power_preference: Option<PowerPreferenceWrapper>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Clone, Copy)]
|
||||||
|
pub enum PowerPreferenceWrapper {
|
||||||
|
Low,
|
||||||
|
High,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
impl From<PowerPreferenceWrapper> for wgpu::PowerPreference {
|
||||||
|
fn from(value: PowerPreferenceWrapper) -> Self {
|
||||||
|
match value {
|
||||||
|
PowerPreferenceWrapper::Low => wgpu::PowerPreference::LowPower,
|
||||||
|
PowerPreferenceWrapper::High => wgpu::PowerPreference::HighPerformance,
|
||||||
|
PowerPreferenceWrapper::None => wgpu::PowerPreference::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const COLOR_PRESETS: [[Color32; 2]; 3] = [
|
pub const COLOR_PRESETS: [[Color32; 2]; 3] = [
|
||||||
|
|
@ -64,6 +86,49 @@ pub const COLOR_PRESETS: [[Color32; 2]; 3] = [
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const fn default_power_preference() -> wgpu::PowerPreference {
|
||||||
|
wgpu::PowerPreference::LowPower
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct AppConfig {
|
||||||
|
#[serde(default = "default_power_preference")]
|
||||||
|
pub power_preference: wgpu::PowerPreference,
|
||||||
|
#[serde(default)]
|
||||||
|
pub force_fallback: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppConfig {
|
||||||
|
pub fn load(persistence: &Persistence) -> Self {
|
||||||
|
if let Ok(config) = persistence.load_config(APP_CONFIG_FILENAME) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
Self {
|
||||||
|
power_preference: default_power_preference(),
|
||||||
|
force_fallback: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self, persistence: &Persistence) -> Result<()> {
|
||||||
|
persistence.save_config(APP_CONFIG_FILENAME, &self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self, args: &CliArgs) -> bool {
|
||||||
|
let mut updated = false;
|
||||||
|
if let Some(pref) = args.wgpu_power_preference {
|
||||||
|
self.power_preference = pref.into();
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
if let Some(force_fallback) = args.wgpu_force_fallback {
|
||||||
|
self.force_fallback = force_fallback;
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const APP_CONFIG_FILENAME: &str = "config";
|
||||||
|
|
||||||
const fn default_audio_enabled() -> bool {
|
const fn default_audio_enabled() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +146,7 @@ pub struct SimConfig {
|
||||||
|
|
||||||
impl SimConfig {
|
impl SimConfig {
|
||||||
pub fn load(persistence: &Persistence, sim_id: SimId) -> Self {
|
pub fn load(persistence: &Persistence, sim_id: SimId) -> Self {
|
||||||
if let Ok(config) = persistence.load_config(config_filename(sim_id)) {
|
if let Ok(config) = persistence.load_config(sim_config_filename(sim_id)) {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -94,11 +159,11 @@ impl SimConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self, persistence: &Persistence, sim_id: SimId) -> Result<()> {
|
pub fn save(&self, persistence: &Persistence, sim_id: SimId) -> Result<()> {
|
||||||
persistence.save_config(config_filename(sim_id), self)
|
persistence.save_config(sim_config_filename(sim_id), self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_filename(sim_id: SimId) -> &'static str {
|
fn sim_config_filename(sim_id: SimId) -> &'static str {
|
||||||
match sim_id {
|
match sim_id {
|
||||||
SimId::Player1 => "config_p1",
|
SimId::Player1 => "config_p1",
|
||||||
SimId::Player2 => "config_p2",
|
SimId::Player2 => "config_p2",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::Subscribe
|
||||||
use winit::event_loop::{ControlFlow, EventLoop};
|
use winit::event_loop::{ControlFlow, EventLoop};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{CliArgs, SimConfig},
|
config::{AppConfig, CliArgs, SimConfig},
|
||||||
emulator::SimId,
|
emulator::SimId,
|
||||||
persistence::Persistence,
|
persistence::Persistence,
|
||||||
};
|
};
|
||||||
|
|
@ -110,6 +110,10 @@ fn main() -> Result<()> {
|
||||||
if args.profile {
|
if args.profile {
|
||||||
builder = builder.start_paused(true)
|
builder = builder.start_paused(true)
|
||||||
}
|
}
|
||||||
|
let mut config = AppConfig::load(&persistence);
|
||||||
|
if config.update(&args) {
|
||||||
|
let _ = config.save(&persistence);
|
||||||
|
}
|
||||||
let p1 = SimConfig::load(&persistence, SimId::Player1);
|
let p1 = SimConfig::load(&persistence, SimId::Player1);
|
||||||
let p2 = SimConfig::load(&persistence, SimId::Player2);
|
let p2 = SimConfig::load(&persistence, SimId::Player2);
|
||||||
|
|
||||||
|
|
@ -143,6 +147,7 @@ fn main() -> Result<()> {
|
||||||
handle,
|
handle,
|
||||||
persistence,
|
persistence,
|
||||||
args,
|
args,
|
||||||
|
config,
|
||||||
))?;
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue