1use crate::renderer::{
2 RenderAdapter, RenderAdapterInfo, RenderDevice, RenderInstance, RenderQueue,
3};
4use alloc::borrow::Cow;
5use std::path::PathBuf;
6
7pub use wgpu::{
8 Backends, Dx12Compiler, Features as WgpuFeatures, Gles3MinorVersion, InstanceFlags,
9 Limits as WgpuLimits, MemoryHints, PowerPreference,
10};
11
12#[derive(Clone)]
14pub enum WgpuSettingsPriority {
15 Compatibility,
17 Functionality,
19 WebGL2,
21}
22
23#[derive(Clone)]
33pub struct WgpuSettings {
34 pub device_label: Option<Cow<'static, str>>,
35 pub backends: Option<Backends>,
36 pub power_preference: PowerPreference,
37 pub priority: WgpuSettingsPriority,
38 pub features: WgpuFeatures,
41 pub disabled_features: Option<WgpuFeatures>,
43 pub limits: WgpuLimits,
45 pub constrained_limits: Option<WgpuLimits>,
47 pub dx12_shader_compiler: Dx12Compiler,
49 pub gles3_minor_version: Gles3MinorVersion,
52 pub instance_flags: InstanceFlags,
54 pub memory_hints: MemoryHints,
56 pub trace_path: Option<PathBuf>,
58}
59
60impl Default for WgpuSettings {
61 fn default() -> Self {
62 let default_backends = if cfg!(all(
63 feature = "webgl",
64 target_arch = "wasm32",
65 not(feature = "webgpu")
66 )) {
67 Backends::GL
68 } else if cfg!(all(feature = "webgpu", target_arch = "wasm32")) {
69 Backends::BROWSER_WEBGPU
70 } else {
71 Backends::all()
72 };
73
74 let backends = Some(wgpu::util::backend_bits_from_env().unwrap_or(default_backends));
75
76 let power_preference =
77 wgpu::util::power_preference_from_env().unwrap_or(PowerPreference::HighPerformance);
78
79 let priority = settings_priority_from_env().unwrap_or(WgpuSettingsPriority::Functionality);
80
81 let limits = if cfg!(all(
82 feature = "webgl",
83 target_arch = "wasm32",
84 not(feature = "webgpu")
85 )) || matches!(priority, WgpuSettingsPriority::WebGL2)
86 {
87 wgpu::Limits::downlevel_webgl2_defaults()
88 } else {
89 #[allow(unused_mut)]
90 let mut limits = wgpu::Limits::default();
91 #[cfg(feature = "ci_limits")]
92 {
93 limits.max_storage_textures_per_shader_stage = 4;
94 limits.max_texture_dimension_3d = 1024;
95 }
96 limits
97 };
98
99 let dx12_compiler =
100 wgpu::util::dx12_shader_compiler_from_env().unwrap_or(Dx12Compiler::Dxc {
101 dxil_path: None,
102 dxc_path: None,
103 });
104
105 let gles3_minor_version = wgpu::util::gles_minor_version_from_env().unwrap_or_default();
106
107 let instance_flags = InstanceFlags::default().with_env();
108
109 Self {
110 device_label: Default::default(),
111 backends,
112 power_preference,
113 priority,
114 features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
115 disabled_features: None,
116 limits,
117 constrained_limits: None,
118 dx12_shader_compiler: dx12_compiler,
119 gles3_minor_version,
120 instance_flags,
121 memory_hints: MemoryHints::default(),
122 trace_path: None,
123 }
124 }
125}
126
127pub enum RenderCreation {
129 Manual(
131 RenderDevice,
132 RenderQueue,
133 RenderAdapterInfo,
134 RenderAdapter,
135 RenderInstance,
136 ),
137 Automatic(WgpuSettings),
139}
140
141impl RenderCreation {
142 pub fn manual(
144 device: RenderDevice,
145 queue: RenderQueue,
146 adapter_info: RenderAdapterInfo,
147 adapter: RenderAdapter,
148 instance: RenderInstance,
149 ) -> Self {
150 Self::Manual(device, queue, adapter_info, adapter, instance)
151 }
152}
153
154impl Default for RenderCreation {
155 fn default() -> Self {
156 Self::Automatic(Default::default())
157 }
158}
159
160impl From<WgpuSettings> for RenderCreation {
161 fn from(value: WgpuSettings) -> Self {
162 Self::Automatic(value)
163 }
164}
165
166pub fn settings_priority_from_env() -> Option<WgpuSettingsPriority> {
168 Some(
169 match std::env::var("WGPU_SETTINGS_PRIO")
170 .as_deref()
171 .map(str::to_lowercase)
172 .as_deref()
173 {
174 Ok("compatibility") => WgpuSettingsPriority::Compatibility,
175 Ok("functionality") => WgpuSettingsPriority::Functionality,
176 Ok("webgl2") => WgpuSettingsPriority::WebGL2,
177 _ => return None,
178 },
179 )
180}