protontweaks_api/
system.rs

1use std::collections::HashMap;
2
3use log::info;
4use serde::{Deserialize, Serialize};
5
6use crate::app::TweakSettings;
7
8#[derive(Debug, Deserialize, Serialize)]
9pub struct System {
10    pub gpu_driver: GpuDriver,
11}
12
13#[derive(Debug, Deserialize, Serialize)]
14pub struct GpuDriver {
15    pub amd: Option<SystemTweaks>,
16    pub nvidia: Option<SystemTweaks>,
17}
18
19#[derive(PartialEq, Debug, Deserialize, Serialize)]
20pub struct SystemTweaks {
21    pub tricks: Vec<String>,
22    pub env: HashMap<String, String>,
23    pub args: Vec<String>,
24    pub settings: TweakSettings,
25}
26
27#[derive(PartialEq, Debug)]
28pub enum GPU {
29    AMD,
30    NVIDIA,
31    UNKNOWN,
32}
33
34impl GPU {
35    pub fn as_str(&self) -> &'static str {
36        match self {
37            GPU::AMD => "amd",
38            GPU::NVIDIA => "nvidia",
39            GPU::UNKNOWN => "unknown",
40        }
41    }
42}
43
44pub struct SystemInfo {
45    pub driver: String,
46    pub driver_type: GPU,
47}
48
49pub async fn get_system_info() -> Option<SystemInfo> {
50    let instance = wgpu::Instance::default();
51
52    let adapter = instance
53        .request_adapter(&wgpu::RequestAdapterOptions::default())
54        .await?;
55
56    Some(SystemInfo {
57        driver: adapter.get_info().driver,
58        driver_type: match adapter.get_info().driver.as_ref() {
59            "NVIDIA" => GPU::NVIDIA,
60            // TODO: Need someone with an AMD GPU to verify this is correct
61            "AMD" => GPU::AMD,
62            _ => GPU::UNKNOWN,
63        },
64    })
65}
66
67impl GpuDriver {
68    async fn get_gpu_info(&self) -> GPU {
69        if let Some(system_info) = get_system_info().await {
70            system_info.driver_type
71        } else {
72            GPU::UNKNOWN
73        }
74    }
75
76    pub async fn get_tweaks(&self) -> &Option<SystemTweaks> {
77        match self.get_gpu_info().await {
78            GPU::UNKNOWN => &None,
79            gpu => {
80                info!("Detected gpu as '{}'", gpu.as_str());
81                self.get_tweaks_for_gpu(gpu)
82            }
83        }
84    }
85
86    pub fn get_tweaks_for_gpu(&self, gpu: GPU) -> &Option<SystemTweaks> {
87        match gpu {
88            GPU::AMD => &self.amd,
89            GPU::NVIDIA => &self.nvidia,
90            GPU::UNKNOWN => &None,
91        }
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[tokio::test]
100    async fn get_tweaks() {
101        let driver = GpuDriver {
102            amd: None,
103            nvidia: Some(SystemTweaks {
104                env: HashMap::new(),
105                tricks: vec![],
106                args: vec![],
107                settings: TweakSettings {
108                    gamemode: None,
109                    mangohud: None,
110                },
111            }),
112        };
113
114        assert_eq!(driver.get_tweaks_for_gpu(GPU::AMD), &None);
115        assert_eq!(driver.get_tweaks_for_gpu(GPU::NVIDIA), &driver.nvidia);
116    }
117}