1use wgt::{Backends, PowerPreference, RequestAdapterOptions};
2
3use crate::{Adapter, Instance, Surface};
4
5#[cfg(wgpu_core)]
6#[cfg_attr(docsrs, doc(cfg(all())))]
7pub use wgc::instance::parse_backends_from_comma_list;
8#[cfg(not(wgpu_core))]
10pub fn parse_backends_from_comma_list(_string: &str) -> Backends {
11 Backends::all()
12}
13
14pub fn backend_bits_from_env() -> Option<Backends> {
16 std::env::var("WGPU_BACKEND")
17 .as_deref()
18 .map(str::to_lowercase)
19 .ok()
20 .as_deref()
21 .map(parse_backends_from_comma_list)
22}
23
24pub fn power_preference_from_env() -> Option<PowerPreference> {
26 Some(
27 match std::env::var("WGPU_POWER_PREF")
28 .as_deref()
29 .map(str::to_lowercase)
30 .as_deref()
31 {
32 Ok("low") => PowerPreference::LowPower,
33 Ok("high") => PowerPreference::HighPerformance,
34 Ok("none") => PowerPreference::None,
35 _ => return None,
36 },
37 )
38}
39
40#[cfg(native)]
42pub fn initialize_adapter_from_env(
43 instance: &Instance,
44 compatible_surface: Option<&Surface<'_>>,
45) -> Option<Adapter> {
46 let desired_adapter_name = std::env::var("WGPU_ADAPTER_NAME")
47 .as_deref()
48 .map(str::to_lowercase)
49 .ok()?;
50
51 let adapters = instance.enumerate_adapters(Backends::all());
52
53 let mut chosen_adapter = None;
54 for adapter in adapters {
55 let info = adapter.get_info();
56
57 if let Some(surface) = compatible_surface {
58 if !adapter.is_surface_supported(surface) {
59 continue;
60 }
61 }
62
63 if info.name.to_lowercase().contains(&desired_adapter_name) {
64 chosen_adapter = Some(adapter);
65 break;
66 }
67 }
68
69 Some(chosen_adapter.expect("WGPU_ADAPTER_NAME set but no matching adapter found!"))
70}
71
72#[cfg(not(native))]
74pub fn initialize_adapter_from_env(
75 _instance: &Instance,
76 _compatible_surface: Option<&Surface<'_>>,
77) -> Option<Adapter> {
78 None
79}
80
81pub async fn initialize_adapter_from_env_or_default(
83 instance: &Instance,
84 compatible_surface: Option<&Surface<'_>>,
85) -> Option<Adapter> {
86 match initialize_adapter_from_env(instance, compatible_surface) {
87 Some(a) => Some(a),
88 None => {
89 instance
90 .request_adapter(&RequestAdapterOptions {
91 power_preference: power_preference_from_env().unwrap_or_default(),
92 force_fallback_adapter: false,
93 compatible_surface,
94 })
95 .await
96 }
97 }
98}
99
100pub fn dx12_shader_compiler_from_env() -> Option<wgt::Dx12Compiler> {
104 Some(
105 match std::env::var("WGPU_DX12_COMPILER")
106 .as_deref()
107 .map(str::to_lowercase)
108 .as_deref()
109 {
110 Ok("dxc") => wgt::Dx12Compiler::Dxc {
111 dxil_path: None,
112 dxc_path: None,
113 },
114 Ok("fxc") => wgt::Dx12Compiler::Fxc,
115 _ => return None,
116 },
117 )
118}
119
120pub fn gles_minor_version_from_env() -> Option<wgt::Gles3MinorVersion> {
124 Some(
125 match std::env::var("WGPU_GLES_MINOR_VERSION")
126 .as_deref()
127 .map(str::to_lowercase)
128 .as_deref()
129 {
130 Ok("automatic") => wgt::Gles3MinorVersion::Automatic,
131 Ok("0") => wgt::Gles3MinorVersion::Version0,
132 Ok("1") => wgt::Gles3MinorVersion::Version1,
133 Ok("2") => wgt::Gles3MinorVersion::Version2,
134 _ => return None,
135 },
136 )
137}
138
139pub async fn is_browser_webgpu_supported() -> bool {
144 #[cfg(webgpu)]
145 {
146 let gpu = crate::backend::get_browser_gpu_property();
148 let Ok(Some(gpu)) = gpu else {
149 return false;
150 };
151
152 let adapter_promise = gpu.request_adapter();
155 wasm_bindgen_futures::JsFuture::from(adapter_promise)
156 .await
157 .map_or(false, |adapter| {
158 !adapter.is_undefined() && !adapter.is_null()
159 })
160 }
161 #[cfg(not(webgpu))]
162 {
163 false
164 }
165}
166
167#[allow(unused_mut)]
183pub async fn new_instance_with_webgpu_detection(
184 mut instance_desc: wgt::InstanceDescriptor,
185) -> crate::Instance {
186 if instance_desc
187 .backends
188 .contains(wgt::Backends::BROWSER_WEBGPU)
189 && !is_browser_webgpu_supported().await
190 {
191 instance_desc.backends.remove(wgt::Backends::BROWSER_WEBGPU);
192 }
193
194 crate::Instance::new(instance_desc)
195}