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