mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Add details to RequestDeviceError. (#4145)
This commit is contained in:
parent
40cc2ee88a
commit
7c575a0b40
@ -75,7 +75,7 @@ By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402)
|
|||||||
- Omit texture store bound checks since they are no-ops if out of bounds on all APIs. By @teoxoy in [#3975](https://github.com/gfx-rs/wgpu/pull/3975)
|
- Omit texture store bound checks since they are no-ops if out of bounds on all APIs. By @teoxoy in [#3975](https://github.com/gfx-rs/wgpu/pull/3975)
|
||||||
- Validate `DownlevelFlags::READ_ONLY_DEPTH_STENCIL`. By @teoxoy in [#4031](https://github.com/gfx-rs/wgpu/pull/4031)
|
- Validate `DownlevelFlags::READ_ONLY_DEPTH_STENCIL`. By @teoxoy in [#4031](https://github.com/gfx-rs/wgpu/pull/4031)
|
||||||
- Add validation in accordance with WebGPU `setViewport` valid usage for `x`, `y` and `this.[[attachment_size]]`. By @James2022-rgb in [#4058](https://github.com/gfx-rs/wgpu/pull/4058)
|
- Add validation in accordance with WebGPU `setViewport` valid usage for `x`, `y` and `this.[[attachment_size]]`. By @James2022-rgb in [#4058](https://github.com/gfx-rs/wgpu/pull/4058)
|
||||||
- `wgpu::CreateSurfaceError` now gives details of the failure, but no longer implements `PartialEq`. By @kpreid in [#4066](https://github.com/gfx-rs/wgpu/pull/4066)
|
- `wgpu::CreateSurfaceError` and `wgpu::RequestDeviceError` now give details of the failure, but no longer implement `PartialEq` and cannot be constructed. By @kpreid in [#4066](https://github.com/gfx-rs/wgpu/pull/4066) and [#4145](https://github.com/gfx-rs/wgpu/pull/4145)
|
||||||
- Make `WGPU_POWER_PREF=none` a valid value. By @fornwall in [4076](https://github.com/gfx-rs/wgpu/pull/4076)
|
- Make `WGPU_POWER_PREF=none` a valid value. By @fornwall in [4076](https://github.com/gfx-rs/wgpu/pull/4076)
|
||||||
|
|
||||||
#### Vulkan
|
#### Vulkan
|
||||||
|
|||||||
@ -449,7 +449,7 @@ pub fn initialize_test(parameters: TestParameters, test_function: impl FnOnce(Te
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_adapter() -> (Adapter, Option<SurfaceGuard>) {
|
pub fn initialize_adapter() -> (Adapter, Option<SurfaceGuard>) {
|
||||||
let instance = initialize_instance();
|
let instance = initialize_instance();
|
||||||
let surface_guard: Option<SurfaceGuard>;
|
let surface_guard: Option<SurfaceGuard>;
|
||||||
let compatible_surface;
|
let compatible_surface;
|
||||||
|
|||||||
@ -40,3 +40,54 @@ fn device_mismatch() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))]
|
||||||
|
#[test]
|
||||||
|
fn request_device_error_on_native() {
|
||||||
|
pollster::block_on(request_device_error_message());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that `RequestDeviceError`s produced have some diagnostic information.
|
||||||
|
///
|
||||||
|
/// Note: this is a wasm *and* native test. On wasm it is run directly; on native, indirectly
|
||||||
|
#[wasm_bindgen_test::wasm_bindgen_test]
|
||||||
|
async fn request_device_error_message() {
|
||||||
|
// Not using initialize_test() because that doesn't let us catch the error
|
||||||
|
// nor .await anything
|
||||||
|
let (adapter, _surface_guard) = wgpu_test::initialize_adapter();
|
||||||
|
|
||||||
|
let device_error = adapter
|
||||||
|
.request_device(
|
||||||
|
&wgpu::DeviceDescriptor {
|
||||||
|
// Force a failure by requesting absurd limits.
|
||||||
|
features: wgpu::Features::all(),
|
||||||
|
limits: wgpu::Limits {
|
||||||
|
max_texture_dimension_1d: u32::MAX,
|
||||||
|
max_texture_dimension_2d: u32::MAX,
|
||||||
|
max_texture_dimension_3d: u32::MAX,
|
||||||
|
max_bind_groups: u32::MAX,
|
||||||
|
max_push_constant_size: u32::MAX,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
let device_error = device_error.to_string();
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(all(target_arch = "wasm32", not(feature = "webgl")))] {
|
||||||
|
// On WebGPU, so the error we get will be from the browser WebGPU API.
|
||||||
|
// Per the WebGPU specification this should be a `TypeError` when features are not
|
||||||
|
// available, <https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice>,
|
||||||
|
// and the stringification it goes through for Rust should put that in the message.
|
||||||
|
let expected = "TypeError";
|
||||||
|
} else {
|
||||||
|
// This message appears whenever wgpu-core is used as the implementation.
|
||||||
|
let expected = "Unsupported features were requested: Features(";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert!(device_error.contains(expected), "{device_error}");
|
||||||
|
}
|
||||||
|
|||||||
@ -622,8 +622,7 @@ impl crate::Context for Context {
|
|||||||
()
|
()
|
||||||
));
|
));
|
||||||
if let Some(err) = error {
|
if let Some(err) = error {
|
||||||
log::error!("Error in Adapter::request_device: {}", err);
|
return ready(Err(err.into()));
|
||||||
return ready(Err(crate::RequestDeviceError));
|
|
||||||
}
|
}
|
||||||
let error_sink = Arc::new(Mutex::new(ErrorSinkRaw::new()));
|
let error_sink = Arc::new(Mutex::new(ErrorSinkRaw::new()));
|
||||||
let device = Device {
|
let device = Device {
|
||||||
|
|||||||
@ -812,7 +812,9 @@ fn future_request_device(
|
|||||||
|
|
||||||
(device_id, device_data, queue_id, queue_data)
|
(device_id, device_data, queue_id, queue_data)
|
||||||
})
|
})
|
||||||
.map_err(|_| crate::RequestDeviceError)
|
.map_err(|error_value| crate::RequestDeviceError {
|
||||||
|
inner: crate::RequestDeviceErrorKind::Web(error_value),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn future_pop_error_scope(result: JsFutureResult) -> Option<crate::Error> {
|
fn future_pop_error_scope(result: JsFutureResult) -> Option<crate::Error> {
|
||||||
|
|||||||
@ -2738,18 +2738,103 @@ impl Drop for Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requesting a device failed.
|
/// Requesting a device from an [`Adapter`] failed.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RequestDeviceError;
|
pub struct RequestDeviceError {
|
||||||
|
inner: RequestDeviceErrorKind,
|
||||||
|
}
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
enum RequestDeviceErrorKind {
|
||||||
|
/// Error from [`wgpu_core`].
|
||||||
|
// must match dependency cfg
|
||||||
|
#[cfg(any(
|
||||||
|
not(target_arch = "wasm32"),
|
||||||
|
feature = "webgl",
|
||||||
|
target_os = "emscripten"
|
||||||
|
))]
|
||||||
|
Core(core::instance::RequestDeviceError),
|
||||||
|
|
||||||
|
/// Error from web API that was called by `wgpu` to request a device.
|
||||||
|
///
|
||||||
|
/// (This is currently never used by the webgl backend, but it could be.)
|
||||||
|
#[cfg(all(
|
||||||
|
target_arch = "wasm32",
|
||||||
|
not(any(target_os = "emscripten", feature = "webgl"))
|
||||||
|
))]
|
||||||
|
Web(wasm_bindgen::JsValue),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "fragile-send-sync-non-atomic-wasm",
|
||||||
|
not(target_feature = "atomics")
|
||||||
|
))]
|
||||||
|
unsafe impl Send for RequestDeviceErrorKind {}
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "fragile-send-sync-non-atomic-wasm",
|
||||||
|
not(target_feature = "atomics")
|
||||||
|
))]
|
||||||
|
unsafe impl Sync for RequestDeviceErrorKind {}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
not(target_arch = "wasm32"),
|
||||||
|
all(
|
||||||
|
feature = "fragile-send-sync-non-atomic-wasm",
|
||||||
|
not(target_feature = "atomics")
|
||||||
|
)
|
||||||
|
))]
|
||||||
static_assertions::assert_impl_all!(RequestDeviceError: Send, Sync);
|
static_assertions::assert_impl_all!(RequestDeviceError: Send, Sync);
|
||||||
|
|
||||||
impl fmt::Display for RequestDeviceError {
|
impl fmt::Display for RequestDeviceError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "Requesting a device failed")
|
match &self.inner {
|
||||||
|
#[cfg(any(
|
||||||
|
not(target_arch = "wasm32"),
|
||||||
|
feature = "webgl",
|
||||||
|
target_os = "emscripten"
|
||||||
|
))]
|
||||||
|
RequestDeviceErrorKind::Core(error) => error.fmt(f),
|
||||||
|
#[cfg(all(
|
||||||
|
target_arch = "wasm32",
|
||||||
|
not(any(target_os = "emscripten", feature = "webgl"))
|
||||||
|
))]
|
||||||
|
RequestDeviceErrorKind::Web(error_js_value) => {
|
||||||
|
// wasm-bindgen provides a reasonable error stringification via `Debug` impl
|
||||||
|
write!(f, "{error_js_value:?}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for RequestDeviceError {}
|
impl error::Error for RequestDeviceError {
|
||||||
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||||
|
match &self.inner {
|
||||||
|
#[cfg(any(
|
||||||
|
not(target_arch = "wasm32"),
|
||||||
|
feature = "webgl",
|
||||||
|
target_os = "emscripten"
|
||||||
|
))]
|
||||||
|
RequestDeviceErrorKind::Core(error) => error.source(),
|
||||||
|
#[cfg(all(
|
||||||
|
target_arch = "wasm32",
|
||||||
|
not(any(target_os = "emscripten", feature = "webgl"))
|
||||||
|
))]
|
||||||
|
RequestDeviceErrorKind::Web(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
not(target_arch = "wasm32"),
|
||||||
|
feature = "webgl",
|
||||||
|
target_os = "emscripten"
|
||||||
|
))]
|
||||||
|
impl From<core::instance::RequestDeviceError> for RequestDeviceError {
|
||||||
|
fn from(error: core::instance::RequestDeviceError) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: RequestDeviceErrorKind::Core(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// [`Instance::create_surface()`] or a related function failed.
|
/// [`Instance::create_surface()`] or a related function failed.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user