1use wgpu::{Adapter, Device, Instance, Queue};
6
7use crate::Error;
8use crate::scene::Stage;
9
10#[derive(Debug, Clone)]
12pub struct AppConfig {
13 pub width: u32,
15 pub height: u32,
17 pub power_preference: wgpu::PowerPreference,
19}
20
21impl Default for AppConfig {
22 fn default() -> Self {
23 Self {
24 width: 1280,
25 height: 720,
26 power_preference: wgpu::PowerPreference::HighPerformance,
27 }
28 }
29}
30
31pub struct Application {
38 config: AppConfig,
39 instance: Instance,
40 adapter: Adapter,
41 device: Device,
42 queue: Queue,
43 stage: Stage,
44}
45
46impl Application {
47 #[must_use]
53 pub fn from_wgpu(
54 instance: Instance,
55 adapter: Adapter,
56 device: Device,
57 queue: Queue,
58 config: AppConfig,
59 ) -> Self {
60 Self {
61 config,
62 instance,
63 adapter,
64 device,
65 queue,
66 stage: Stage::new(),
67 }
68 }
69
70 pub async fn new(config: AppConfig) -> Result<Self, Error> {
77 let instance = Instance::new(&wgpu::InstanceDescriptor::default());
78
79 let adapter = instance
80 .request_adapter(&wgpu::RequestAdapterOptions {
81 power_preference: config.power_preference,
82 compatible_surface: None,
83 force_fallback_adapter: false,
84 })
85 .await
86 .ok_or_else(|| Error::AdapterUnavailable("no compatible adapter found".to_owned()))?;
87
88 let (device, queue) = adapter
89 .request_device(
90 &wgpu::DeviceDescriptor {
91 label: Some("wisp::Application device"),
92 required_features: wgpu::Features::empty(),
93 required_limits: wgpu::Limits::default(),
94 memory_hints: wgpu::MemoryHints::Performance,
95 },
96 None,
97 )
98 .await
99 .map_err(|e| Error::DeviceRequest(e.to_string()))?;
100
101 let info = adapter.get_info();
102 tracing::info!(
103 adapter = %info.name,
104 backend = ?info.backend,
105 device_type = ?info.device_type,
106 "wgpu adapter selected"
107 );
108
109 Ok(Self {
110 config,
111 instance,
112 adapter,
113 device,
114 queue,
115 stage: Stage::new(),
116 })
117 }
118
119 #[must_use]
121 pub fn stage(&self) -> &Stage {
122 &self.stage
123 }
124
125 pub fn stage_mut(&mut self) -> &mut Stage {
127 &mut self.stage
128 }
129
130 #[must_use]
132 pub fn adapter_info(&self) -> wgpu::AdapterInfo {
133 self.adapter.get_info()
134 }
135
136 #[must_use]
138 pub fn instance(&self) -> &Instance {
139 &self.instance
140 }
141
142 #[must_use]
144 pub fn adapter(&self) -> &Adapter {
145 &self.adapter
146 }
147
148 #[must_use]
150 pub fn device(&self) -> &Device {
151 &self.device
152 }
153
154 #[must_use]
156 pub fn queue(&self) -> &Queue {
157 &self.queue
158 }
159
160 #[must_use]
162 pub fn width(&self) -> u32 {
163 self.config.width
164 }
165
166 #[must_use]
168 pub fn height(&self) -> u32 {
169 self.config.height
170 }
171}