Skip to content

Commit 4652ea4

Browse files
R-Cramer4Wumpf
andauthored
Changed enumerate_adapters to be able to work with custom backends (#8230)
Co-authored-by: Andreas Reich <[email protected]>
1 parent 1072b87 commit 4652ea4

File tree

12 files changed

+87
-34
lines changed

12 files changed

+87
-34
lines changed

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ Bottom level categories:
4040

4141
## Unreleased
4242

43+
#### 'wgpu::Instance::enumerate_adapters` is now `async` & available on WebGPU
44+
45+
Making `enumerate_adapters` async allows custom backends to use it along with elimnating some native/non-native distinctions
46+
47+
This is a breaking change
48+
49+
```diff
50+
- pub fn enumerate_adapters(&self, backends: Backends) -> Vec<Adapter> {
51+
+ pub fn enumerate_adapters(&self, backends: Backends) -> impl Future<Output = Vec<Adapter>> {
52+
53+
```
54+
55+
By @R-Cramer4 in [#8230](https://github.com/gfx-rs/wgpu/pull/8230)
56+
4357
## v27.0.2 (2025-10-03)
4458

4559
### Bug Fixes
@@ -175,7 +189,6 @@ by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the devic
175189

176190
By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
177191

178-
179192
#### `wgpu::PollType::Wait` has now an optional timeout
180193

181194
We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts.

Cargo.lock

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/features/src/utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ pub(crate) async fn get_adapter_with_capabilities_or_from_env(
203203
);
204204
adapter
205205
} else {
206-
let adapters = instance.enumerate_adapters(Backends::all());
206+
let adapters = instance.enumerate_adapters(Backends::all()).await;
207207

208208
let mut chosen_adapter = None;
209209
for adapter in adapters {

examples/standalone/custom_backend/src/custom.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ impl InstanceInterface for CustomInstance {
5555
fn wgsl_language_features(&self) -> wgpu::WgslLanguageFeatures {
5656
unimplemented!()
5757
}
58+
59+
fn enumerate_adapters(
60+
&self,
61+
_backends: wgpu::Backends,
62+
) -> Pin<Box<dyn wgpu::custom::EnumerateAdapterFuture>> {
63+
unimplemented!()
64+
}
5865
}
5966

6067
#[derive(Debug)]

tests/src/init.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ pub async fn initialize_adapter(
122122

123123
cfg_if::cfg_if! {
124124
if #[cfg(not(target_arch = "wasm32"))] {
125-
let adapter_iter = instance.enumerate_adapters(backends);
125+
let adapter_iter = instance.enumerate_adapters(backends).await;
126126
let adapter = adapter_iter.into_iter()
127127
// If we have a report, we only want to match the adapter with the same info.
128128
//
@@ -136,7 +136,7 @@ pub async fn initialize_adapter(
136136
panic!(
137137
"Could not find adapter with info {:#?} in {:#?}",
138138
adapter_report.map(|r| &r.info),
139-
instance.enumerate_adapters(backends).into_iter().map(|a| a.get_info()).collect::<Vec<_>>(),
139+
instance.enumerate_adapters(backends).await.into_iter().map(|a| a.get_info()).collect::<Vec<_>>(),
140140
);
141141
};
142142
} else {

wgpu-info/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ bitflags.workspace = true
1616
env_logger.workspace = true
1717
hashbrown = { workspace = true, features = ["serde"] }
1818
pico-args.workspace = true
19+
pollster.workspace = true
1920
serde = { workspace = true, features = ["default"] }
2021
serde_json.workspace = true
2122
wgpu.workspace = true

wgpu-info/src/report.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ impl GpuReport {
2525
desc.flags = wgpu::InstanceFlags::debugging();
2626
desc.with_env()
2727
});
28-
let adapters = instance.enumerate_adapters(wgpu::Backends::all());
28+
29+
let adapters = pollster::block_on(instance.enumerate_adapters(wgpu::Backends::all()));
2930

3031
let mut devices = Vec::with_capacity(adapters.len());
3132
for adapter in adapters {

wgpu/src/api/instance.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#[cfg(wgpu_core)]
21
use alloc::vec::Vec;
32
use core::future::Future;
43

@@ -142,23 +141,18 @@ impl Instance {
142141
/// # Arguments
143142
///
144143
/// - `backends` - Backends from which to enumerate adapters.
145-
#[cfg(wgpu_core)]
146-
pub fn enumerate_adapters(&self, backends: Backends) -> Vec<Adapter> {
147-
let Some(core_instance) = self.inner.as_core_opt() else {
148-
return Vec::new();
149-
};
150-
151-
core_instance
152-
.enumerate_adapters(backends)
153-
.into_iter()
154-
.map(|adapter| {
155-
let core = backend::wgpu_core::CoreAdapter {
156-
context: core_instance.clone(),
157-
id: adapter,
158-
};
159-
crate::Adapter { inner: core.into() }
160-
})
161-
.collect()
144+
pub fn enumerate_adapters(&self, backends: Backends) -> impl Future<Output = Vec<Adapter>> {
145+
let future = self.inner.enumerate_adapters(backends);
146+
147+
async move {
148+
future
149+
.await
150+
.iter()
151+
.map(|adapter| Adapter {
152+
inner: adapter.clone(),
153+
})
154+
.collect()
155+
}
162156
}
163157

164158
/// Retrieves an [`Adapter`] which matches the given [`RequestAdapterOptions`].

wgpu/src/backend/webgpu.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,20 @@ impl dispatch::InstanceInterface for ContextWebGpu {
15691569
))))
15701570
}
15711571
}
1572+
fn enumerate_adapters(
1573+
&self,
1574+
_backends: crate::Backends,
1575+
) -> Pin<Box<dyn dispatch::EnumerateAdapterFuture>> {
1576+
let future = self.request_adapter(&crate::RequestAdapterOptions::default());
1577+
let enumerate_future = async move {
1578+
let adapter = future.await;
1579+
match adapter {
1580+
Ok(a) => vec![a],
1581+
Err(_) => vec![],
1582+
}
1583+
};
1584+
Box::pin(enumerate_future)
1585+
}
15721586

15731587
fn poll_all_devices(&self, _force_wait: bool) -> bool {
15741588
// Devices are automatically polled.

wgpu/src/backend/wgpu_core.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ use wgt::{
2828
WasmNotSendSync,
2929
};
3030

31-
use crate::util::Mutex;
3231
use crate::{
3332
api,
3433
dispatch::{self, BlasCompactCallback, BufferMappedRangeInterface},
3534
BindingResource, Blas, BufferBinding, BufferDescriptor, CompilationInfo, CompilationMessage,
3635
CompilationMessageType, ErrorSource, Features, Label, LoadOp, MapMode, Operations,
3736
ShaderSource, SurfaceTargetUnsafe, TextureDescriptor, Tlas,
3837
};
38+
use crate::{dispatch::DispatchAdapter, util::Mutex};
3939

4040
#[derive(Clone)]
4141
pub struct ContextWgpuCore(Arc<wgc::global::Global>);
@@ -902,6 +902,24 @@ impl dispatch::InstanceInterface for ContextWgpuCore {
902902
},
903903
)
904904
}
905+
906+
fn enumerate_adapters(
907+
&self,
908+
backends: crate::Backends,
909+
) -> Pin<Box<dyn dispatch::EnumerateAdapterFuture>> {
910+
let adapters: Vec<DispatchAdapter> = self
911+
.enumerate_adapters(backends)
912+
.into_iter()
913+
.map(|adapter| {
914+
let core = crate::backend::wgpu_core::CoreAdapter {
915+
context: self.clone(),
916+
id: adapter,
917+
};
918+
core.into()
919+
})
920+
.collect();
921+
Box::pin(ready(adapters))
922+
}
905923
}
906924

907925
impl dispatch::AdapterInterface for CoreAdapter {

0 commit comments

Comments
 (0)