1use std::sync::Arc;
4
5#[derive(Debug)]
6pub enum FrendererError {
7 NoUsableAdapter,
8}
9impl std::fmt::Display for FrendererError {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 match self {
12 FrendererError::NoUsableAdapter => {
13 f.write_str("No valid adapter found for GPU requirements")
14 }
15 }
16 }
17}
18impl std::error::Error for FrendererError {}
19
20#[allow(dead_code)]
22pub struct WGPU {
23 instance: Arc<wgpu::Instance>,
24 adapter: Arc<wgpu::Adapter>,
25 device: Arc<wgpu::Device>,
26 queue: Arc<wgpu::Queue>,
27}
28
29impl WGPU {
30 pub fn with_resources(
32 instance: Arc<wgpu::Instance>,
33 adapter: Arc<wgpu::Adapter>,
34 device: Arc<wgpu::Device>,
35 queue: Arc<wgpu::Queue>,
36 ) -> Self {
37 Self {
38 instance,
39 adapter,
40 device,
41 queue,
42 }
43 }
44 pub async fn new(
46 instance: Arc<wgpu::Instance>,
47 surface: Option<&wgpu::Surface<'static>>,
48 ) -> Result<Self, Box<dyn std::error::Error>> {
49 let adapter = instance
50 .request_adapter(&wgpu::RequestAdapterOptions {
51 power_preference: wgpu::PowerPreference::default(),
52 force_fallback_adapter: false,
53 compatible_surface: surface,
55 })
56 .await
57 .ok_or(FrendererError::NoUsableAdapter)?;
58 let is_gl = adapter.get_info().backend == wgpu::Backend::Gl;
59 #[cfg(not(target_arch = "wasm32"))]
60 let is_web = false;
61 #[cfg(target_arch = "wasm32")]
62 let is_web = true;
63 let use_storage = !(is_web && is_gl);
64
65 let (device, queue) = adapter
67 .request_device(
68 &wgpu::DeviceDescriptor {
69 label: None,
70 required_features: wgpu::Features::empty(),
71 required_limits: if use_storage {
72 wgpu::Limits::downlevel_defaults()
73 } else {
74 wgpu::Limits::downlevel_webgl2_defaults()
75 }
76 .using_resolution(adapter.limits()),
77 },
78 None,
79 )
80 .await?;
81 Ok(Self::with_resources(
82 instance,
83 Arc::new(adapter),
84 Arc::new(device),
85 Arc::new(queue),
86 ))
87 }
88 pub fn is_gl(&self) -> bool {
90 self.adapter.get_info().backend == wgpu::Backend::Gl
91 }
92 #[cfg(target_arch = "wasm32")]
94 pub fn is_web(&self) -> bool {
95 true
96 }
97 #[cfg(not(target_arch = "wasm32"))]
98 pub fn is_web(&self) -> bool {
99 false
100 }
101 pub fn supports_storage(&self) -> bool {
103 !(self.is_gl() && self.is_web())
104 && self
105 .adapter
106 .get_downlevel_capabilities()
107 .flags
108 .contains(wgpu::DownlevelFlags::VERTEX_STORAGE)
109 && self.device.limits().max_storage_buffers_per_shader_stage > 0
110 }
111 pub fn instance(&self) -> &wgpu::Instance {
113 &self.instance
114 }
115
116 pub fn adapter(&self) -> &wgpu::Adapter {
118 &self.adapter
119 }
120 pub fn device(&self) -> &wgpu::Device {
122 &self.device
123 }
124 pub fn queue(&self) -> &wgpu::Queue {
126 &self.queue
127 }
128}