mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Changed enumerate_adapters to be able to work with custom backends (#8230)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
parent
1072b87894
commit
4652ea4189
15
CHANGELOG.md
15
CHANGELOG.md
@ -40,6 +40,20 @@ Bottom level categories:
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
#### 'wgpu::Instance::enumerate_adapters` is now `async` & available on WebGPU
|
||||||
|
|
||||||
|
Making `enumerate_adapters` async allows custom backends to use it along with elimnating some native/non-native distinctions
|
||||||
|
|
||||||
|
This is a breaking change
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- pub fn enumerate_adapters(&self, backends: Backends) -> Vec<Adapter> {
|
||||||
|
+ pub fn enumerate_adapters(&self, backends: Backends) -> impl Future<Output = Vec<Adapter>> {
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
By @R-Cramer4 in [#8230](https://github.com/gfx-rs/wgpu/pull/8230)
|
||||||
|
|
||||||
## v27.0.2 (2025-10-03)
|
## v27.0.2 (2025-10-03)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
@ -175,7 +189,6 @@ by if the `Feature::MULTI_DRAW_INDIRECT_COUNT` feature is available on the devic
|
|||||||
|
|
||||||
By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
|
By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
|
||||||
|
|
||||||
|
|
||||||
#### `wgpu::PollType::Wait` has now an optional timeout
|
#### `wgpu::PollType::Wait` has now an optional timeout
|
||||||
|
|
||||||
We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts.
|
We removed `wgpu::PollType::WaitForSubmissionIndex` and added fields to `wgpu::PollType::Wait` in order to express timeouts.
|
||||||
|
|||||||
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -120,9 +120,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.20"
|
version = "0.6.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
|
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"anstyle-parse",
|
"anstyle-parse",
|
||||||
@ -600,9 +600,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.39"
|
version = "1.2.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f"
|
checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
@ -1438,9 +1438,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
|
checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fixedbitset"
|
name = "fixedbitset"
|
||||||
@ -5012,6 +5012,7 @@ dependencies = [
|
|||||||
"env_logger",
|
"env_logger",
|
||||||
"hashbrown 0.16.0",
|
"hashbrown 0.16.0",
|
||||||
"pico-args",
|
"pico-args",
|
||||||
|
"pollster",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
|
|||||||
@ -203,7 +203,7 @@ pub(crate) async fn get_adapter_with_capabilities_or_from_env(
|
|||||||
);
|
);
|
||||||
adapter
|
adapter
|
||||||
} else {
|
} else {
|
||||||
let adapters = instance.enumerate_adapters(Backends::all());
|
let adapters = instance.enumerate_adapters(Backends::all()).await;
|
||||||
|
|
||||||
let mut chosen_adapter = None;
|
let mut chosen_adapter = None;
|
||||||
for adapter in adapters {
|
for adapter in adapters {
|
||||||
|
|||||||
@ -55,6 +55,13 @@ impl InstanceInterface for CustomInstance {
|
|||||||
fn wgsl_language_features(&self) -> wgpu::WgslLanguageFeatures {
|
fn wgsl_language_features(&self) -> wgpu::WgslLanguageFeatures {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enumerate_adapters(
|
||||||
|
&self,
|
||||||
|
_backends: wgpu::Backends,
|
||||||
|
) -> Pin<Box<dyn wgpu::custom::EnumerateAdapterFuture>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@ -122,7 +122,7 @@ pub async fn initialize_adapter(
|
|||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(not(target_arch = "wasm32"))] {
|
if #[cfg(not(target_arch = "wasm32"))] {
|
||||||
let adapter_iter = instance.enumerate_adapters(backends);
|
let adapter_iter = instance.enumerate_adapters(backends).await;
|
||||||
let adapter = adapter_iter.into_iter()
|
let adapter = adapter_iter.into_iter()
|
||||||
// If we have a report, we only want to match the adapter with the same info.
|
// If we have a report, we only want to match the adapter with the same info.
|
||||||
//
|
//
|
||||||
@ -136,7 +136,7 @@ pub async fn initialize_adapter(
|
|||||||
panic!(
|
panic!(
|
||||||
"Could not find adapter with info {:#?} in {:#?}",
|
"Could not find adapter with info {:#?} in {:#?}",
|
||||||
adapter_report.map(|r| &r.info),
|
adapter_report.map(|r| &r.info),
|
||||||
instance.enumerate_adapters(backends).into_iter().map(|a| a.get_info()).collect::<Vec<_>>(),
|
instance.enumerate_adapters(backends).await.into_iter().map(|a| a.get_info()).collect::<Vec<_>>(),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ bitflags.workspace = true
|
|||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
hashbrown = { workspace = true, features = ["serde"] }
|
hashbrown = { workspace = true, features = ["serde"] }
|
||||||
pico-args.workspace = true
|
pico-args.workspace = true
|
||||||
|
pollster.workspace = true
|
||||||
serde = { workspace = true, features = ["default"] }
|
serde = { workspace = true, features = ["default"] }
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
wgpu.workspace = true
|
wgpu.workspace = true
|
||||||
|
|||||||
@ -25,7 +25,8 @@ impl GpuReport {
|
|||||||
desc.flags = wgpu::InstanceFlags::debugging();
|
desc.flags = wgpu::InstanceFlags::debugging();
|
||||||
desc.with_env()
|
desc.with_env()
|
||||||
});
|
});
|
||||||
let adapters = instance.enumerate_adapters(wgpu::Backends::all());
|
|
||||||
|
let adapters = pollster::block_on(instance.enumerate_adapters(wgpu::Backends::all()));
|
||||||
|
|
||||||
let mut devices = Vec::with_capacity(adapters.len());
|
let mut devices = Vec::with_capacity(adapters.len());
|
||||||
for adapter in adapters {
|
for adapter in adapters {
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#[cfg(wgpu_core)]
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
|
|
||||||
@ -142,23 +141,18 @@ impl Instance {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// - `backends` - Backends from which to enumerate adapters.
|
/// - `backends` - Backends from which to enumerate adapters.
|
||||||
#[cfg(wgpu_core)]
|
pub fn enumerate_adapters(&self, backends: Backends) -> impl Future<Output = Vec<Adapter>> {
|
||||||
pub fn enumerate_adapters(&self, backends: Backends) -> Vec<Adapter> {
|
let future = self.inner.enumerate_adapters(backends);
|
||||||
let Some(core_instance) = self.inner.as_core_opt() else {
|
|
||||||
return Vec::new();
|
|
||||||
};
|
|
||||||
|
|
||||||
core_instance
|
async move {
|
||||||
.enumerate_adapters(backends)
|
future
|
||||||
.into_iter()
|
.await
|
||||||
.map(|adapter| {
|
.iter()
|
||||||
let core = backend::wgpu_core::CoreAdapter {
|
.map(|adapter| Adapter {
|
||||||
context: core_instance.clone(),
|
inner: adapter.clone(),
|
||||||
id: adapter,
|
})
|
||||||
};
|
.collect()
|
||||||
crate::Adapter { inner: core.into() }
|
}
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves an [`Adapter`] which matches the given [`RequestAdapterOptions`].
|
/// Retrieves an [`Adapter`] which matches the given [`RequestAdapterOptions`].
|
||||||
|
|||||||
@ -1569,6 +1569,20 @@ impl dispatch::InstanceInterface for ContextWebGpu {
|
|||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn enumerate_adapters(
|
||||||
|
&self,
|
||||||
|
_backends: crate::Backends,
|
||||||
|
) -> Pin<Box<dyn dispatch::EnumerateAdapterFuture>> {
|
||||||
|
let future = self.request_adapter(&crate::RequestAdapterOptions::default());
|
||||||
|
let enumerate_future = async move {
|
||||||
|
let adapter = future.await;
|
||||||
|
match adapter {
|
||||||
|
Ok(a) => vec![a],
|
||||||
|
Err(_) => vec![],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Box::pin(enumerate_future)
|
||||||
|
}
|
||||||
|
|
||||||
fn poll_all_devices(&self, _force_wait: bool) -> bool {
|
fn poll_all_devices(&self, _force_wait: bool) -> bool {
|
||||||
// Devices are automatically polled.
|
// Devices are automatically polled.
|
||||||
|
|||||||
@ -28,7 +28,6 @@ use wgt::{
|
|||||||
WasmNotSendSync,
|
WasmNotSendSync,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::util::Mutex;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api,
|
api,
|
||||||
dispatch::{self, BlasCompactCallback, BufferMappedRangeInterface},
|
dispatch::{self, BlasCompactCallback, BufferMappedRangeInterface},
|
||||||
@ -36,6 +35,7 @@ use crate::{
|
|||||||
CompilationMessageType, ErrorSource, Features, Label, LoadOp, MapMode, Operations,
|
CompilationMessageType, ErrorSource, Features, Label, LoadOp, MapMode, Operations,
|
||||||
ShaderSource, SurfaceTargetUnsafe, TextureDescriptor, Tlas,
|
ShaderSource, SurfaceTargetUnsafe, TextureDescriptor, Tlas,
|
||||||
};
|
};
|
||||||
|
use crate::{dispatch::DispatchAdapter, util::Mutex};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ContextWgpuCore(Arc<wgc::global::Global>);
|
pub struct ContextWgpuCore(Arc<wgc::global::Global>);
|
||||||
@ -902,6 +902,24 @@ impl dispatch::InstanceInterface for ContextWgpuCore {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enumerate_adapters(
|
||||||
|
&self,
|
||||||
|
backends: crate::Backends,
|
||||||
|
) -> Pin<Box<dyn dispatch::EnumerateAdapterFuture>> {
|
||||||
|
let adapters: Vec<DispatchAdapter> = self
|
||||||
|
.enumerate_adapters(backends)
|
||||||
|
.into_iter()
|
||||||
|
.map(|adapter| {
|
||||||
|
let core = crate::backend::wgpu_core::CoreAdapter {
|
||||||
|
context: self.clone(),
|
||||||
|
id: adapter,
|
||||||
|
};
|
||||||
|
core.into()
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Box::pin(ready(adapters))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl dispatch::AdapterInterface for CoreAdapter {
|
impl dispatch::AdapterInterface for CoreAdapter {
|
||||||
|
|||||||
@ -39,6 +39,7 @@ trait_alias!(RequestAdapterFuture: Future<Output = Result<DispatchAdapter, wgt::
|
|||||||
trait_alias!(RequestDeviceFuture: Future<Output = Result<(DispatchDevice, DispatchQueue), crate::RequestDeviceError>> + WasmNotSend + 'static);
|
trait_alias!(RequestDeviceFuture: Future<Output = Result<(DispatchDevice, DispatchQueue), crate::RequestDeviceError>> + WasmNotSend + 'static);
|
||||||
trait_alias!(PopErrorScopeFuture: Future<Output = Option<crate::Error>> + WasmNotSend + 'static);
|
trait_alias!(PopErrorScopeFuture: Future<Output = Option<crate::Error>> + WasmNotSend + 'static);
|
||||||
trait_alias!(ShaderCompilationInfoFuture: Future<Output = crate::CompilationInfo> + WasmNotSend + 'static);
|
trait_alias!(ShaderCompilationInfoFuture: Future<Output = crate::CompilationInfo> + WasmNotSend + 'static);
|
||||||
|
trait_alias!(EnumerateAdapterFuture: Future<Output = Vec<DispatchAdapter>> + WasmNotSend + 'static);
|
||||||
|
|
||||||
// We can't use trait aliases here, as you can't convert from a dyn Trait to dyn Supertrait _yet_.
|
// We can't use trait aliases here, as you can't convert from a dyn Trait to dyn Supertrait _yet_.
|
||||||
#[cfg(send_sync)]
|
#[cfg(send_sync)]
|
||||||
@ -93,6 +94,9 @@ pub trait InstanceInterface: CommonTraits {
|
|||||||
|
|
||||||
#[cfg(feature = "wgsl")]
|
#[cfg(feature = "wgsl")]
|
||||||
fn wgsl_language_features(&self) -> crate::WgslLanguageFeatures;
|
fn wgsl_language_features(&self) -> crate::WgslLanguageFeatures;
|
||||||
|
|
||||||
|
fn enumerate_adapters(&self, backends: crate::Backends)
|
||||||
|
-> Pin<Box<dyn EnumerateAdapterFuture>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AdapterInterface: CommonTraits {
|
pub trait AdapterInterface: CommonTraits {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::Backends;
|
|||||||
/// Initialize the adapter obeying the `WGPU_ADAPTER_NAME` environment variable.
|
/// Initialize the adapter obeying the `WGPU_ADAPTER_NAME` environment variable.
|
||||||
#[cfg(wgpu_core)]
|
#[cfg(wgpu_core)]
|
||||||
#[cfg_attr(not(std), expect(unused_variables, unreachable_code))]
|
#[cfg_attr(not(std), expect(unused_variables, unreachable_code))]
|
||||||
pub fn initialize_adapter_from_env(
|
pub async fn initialize_adapter_from_env(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
compatible_surface: Option<&Surface<'_>>,
|
compatible_surface: Option<&Surface<'_>>,
|
||||||
) -> Result<Adapter, wgt::RequestAdapterError> {
|
) -> Result<Adapter, wgt::RequestAdapterError> {
|
||||||
@ -23,7 +23,7 @@ pub fn initialize_adapter_from_env(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let adapters = instance.enumerate_adapters(crate::Backends::all());
|
let adapters = instance.enumerate_adapters(crate::Backends::all()).await;
|
||||||
|
|
||||||
let mut chosen_adapter = None;
|
let mut chosen_adapter = None;
|
||||||
for adapter in adapters {
|
for adapter in adapters {
|
||||||
@ -46,7 +46,7 @@ pub fn initialize_adapter_from_env(
|
|||||||
|
|
||||||
/// Initialize the adapter obeying the `WGPU_ADAPTER_NAME` environment variable.
|
/// Initialize the adapter obeying the `WGPU_ADAPTER_NAME` environment variable.
|
||||||
#[cfg(not(wgpu_core))]
|
#[cfg(not(wgpu_core))]
|
||||||
pub fn initialize_adapter_from_env(
|
pub async fn initialize_adapter_from_env(
|
||||||
_instance: &Instance,
|
_instance: &Instance,
|
||||||
_compatible_surface: Option<&Surface<'_>>,
|
_compatible_surface: Option<&Surface<'_>>,
|
||||||
) -> Result<Adapter, wgt::RequestAdapterError> {
|
) -> Result<Adapter, wgt::RequestAdapterError> {
|
||||||
@ -58,7 +58,7 @@ pub async fn initialize_adapter_from_env_or_default(
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
compatible_surface: Option<&Surface<'_>>,
|
compatible_surface: Option<&Surface<'_>>,
|
||||||
) -> Result<Adapter, wgt::RequestAdapterError> {
|
) -> Result<Adapter, wgt::RequestAdapterError> {
|
||||||
match initialize_adapter_from_env(instance, compatible_surface) {
|
match initialize_adapter_from_env(instance, compatible_surface).await {
|
||||||
Ok(a) => Ok(a),
|
Ok(a) => Ok(a),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
instance
|
instance
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user