refactor(wgpu)!: use WebGpuError for error classification

This commit is contained in:
Erich Gubler 2025-06-12 15:16:28 +09:00
parent 43eee99b29
commit cc0f4ac4bf
5 changed files with 37 additions and 53 deletions

View File

@ -110,6 +110,7 @@ Bottom level categories:
### Changes
- Loosen Viewport validation requirements to match the [new specs](https://github.com/gpuweb/gpuweb/pull/5025). By @ebbdrop in [#7564](https://github.com/gfx-rs/wgpu/pull/7564)
- `wgpu` now uses `wgpu-types::error::WebGpuError` to classify errors. Any changes here are likely to be regressions; please report them if you find them! By @ErichDonGubler in [#6547](https://github.com/gfx-rs/wgpu/pull/6547).
#### General

View File

@ -108,6 +108,11 @@ pub fn did_fail<T>(device: &wgpu::Device, callback: impl FnOnce() -> T) -> (bool
did_fill_error_scope(device, callback, wgpu::ErrorFilter::Validation)
}
/// Returns true if the provided callback encounters an out-of-memory error.
pub fn did_oom<T>(device: &wgpu::Device, callback: impl FnOnce() -> T) -> (bool, T) {
did_fill_error_scope(device, callback, wgpu::ErrorFilter::OutOfMemory)
}
/// Adds the necessary main function for our gpu test harness.
#[macro_export]
macro_rules! gpu_test_main {

View File

@ -2,7 +2,7 @@
//!
//! Do some tests to ensure things are working correctly and nothing gets mad.
use wgpu_test::{did_fail, gpu_test, valid, GpuTestConfiguration, TestParameters, TestingContext};
use wgpu_test::{did_oom, gpu_test, valid, GpuTestConfiguration, TestParameters, TestingContext};
// A number large enough to likely cause sampler caches to run out of space
// on some devices.
@ -93,7 +93,7 @@ fn sampler_creation_failure(ctx: TestingContext) {
let mut sampler_storage = Vec::with_capacity(PROBABLY_PROBLEMATIC_SAMPLER_COUNT as usize);
for i in 0..PROBABLY_PROBLEMATIC_SAMPLER_COUNT {
let (failed, sampler) = did_fail(&ctx.device, || {
let (failed, sampler) = did_oom(&ctx.device, || {
ctx.device.create_sampler(&wgpu::SamplerDescriptor {
lod_min_clamp: i as f32 * 0.01,
..desc

View File

@ -52,7 +52,9 @@ static ARRAY_SIZE_OVERRIDES: GpuTestConfiguration = GpuTestConfiguration::new()
.run_async(move |ctx| async move {
array_size_overrides(&ctx, None, &[534], false).await;
array_size_overrides(&ctx, Some(14), &[286480122], false).await;
array_size_overrides(&ctx, Some(1), &[0], true).await;
// // TODO: Restore this with the resolution for
// // <https://github.com/gfx-rs/wgpu/issues/7806>.
// array_size_overrides(&ctx, Some(1), &[0], true).await;
});
async fn array_size_overrides(

View File

@ -15,7 +15,10 @@ use wgc::{
command::bundle_ffi::*, error::ContextErrorSource, pipeline::CreateShaderModuleError,
resource::BlasPrepareCompactResult,
};
use wgt::WasmNotSendSync;
use wgt::{
error::{ErrorType, WebGpuError},
WasmNotSendSync,
};
use crate::util::Mutex;
use crate::{
@ -304,62 +307,33 @@ impl ContextWgpuCore {
fn handle_error_inner(
&self,
sink_mutex: &Mutex<ErrorSinkRaw>,
error_type: ErrorType,
source: ContextErrorSource,
label: Label<'_>,
fn_ident: &'static str,
) {
let source_error: ErrorSource = Box::new(wgc::error::ContextError {
let source: ErrorSource = Box::new(wgc::error::ContextError {
fn_ident,
source,
label: label.unwrap_or_default().to_string(),
});
let mut sink = sink_mutex.lock();
let mut source_opt: Option<&(dyn Error + 'static)> = Some(&*source_error);
let error = loop {
if let Some(source) = source_opt {
if let Some(wgc::device::DeviceError::OutOfMemory) =
source.downcast_ref::<wgc::device::DeviceError>()
{
break crate::Error::OutOfMemory {
source: source_error,
};
let description = || self.format_error(&*source);
let error = match error_type {
ErrorType::Internal => {
let description = description();
crate::Error::Internal {
source,
description,
}
let device_error =
if let Some(wgc::resource::CreateTextureError::Device(device_error)) =
source.downcast_ref::<wgc::resource::CreateTextureError>()
{
Some(device_error)
} else if let Some(wgc::resource::CreateBufferError::Device(device_error)) =
source.downcast_ref::<wgc::resource::CreateBufferError>()
{
Some(device_error)
} else if let Some(wgc::resource::CreateQuerySetError::Device(device_error)) =
source.downcast_ref::<wgc::resource::CreateQuerySetError>()
{
Some(device_error)
} else if let Some(wgc::ray_tracing::CreateBlasError::Device(device_error)) =
source.downcast_ref::<wgc::ray_tracing::CreateBlasError>()
{
Some(device_error)
} else if let Some(wgc::ray_tracing::CreateTlasError::Device(device_error)) =
source.downcast_ref::<wgc::ray_tracing::CreateTlasError>()
{
Some(device_error)
} else {
None
};
if let Some(wgc::device::DeviceError::OutOfMemory) = device_error {
break crate::Error::OutOfMemory {
source: source_error,
};
}
ErrorType::OutOfMemory => crate::Error::OutOfMemory { source },
ErrorType::Validation => {
let description = description();
crate::Error::Validation {
source,
description,
}
source_opt = source.source();
} else {
// Otherwise, it is a validation error
break crate::Error::Validation {
description: self.format_error(&*source_error),
source: source_error,
};
}
ErrorType::DeviceLost { reason: _ } => return,
};
@ -371,11 +345,12 @@ impl ContextWgpuCore {
fn handle_error(
&self,
sink_mutex: &Mutex<ErrorSinkRaw>,
source: impl Error + WasmNotSendSync + 'static,
source: impl WebGpuError + WasmNotSendSync + 'static,
label: Label<'_>,
fn_ident: &'static str,
) {
self.handle_error_inner(sink_mutex, Box::new(source), label, fn_ident)
let error_type = source.webgpu_error_type();
self.handle_error_inner(sink_mutex, error_type, Box::new(source), label, fn_ident)
}
#[inline]
@ -383,10 +358,11 @@ impl ContextWgpuCore {
fn handle_error_nolabel(
&self,
sink_mutex: &Mutex<ErrorSinkRaw>,
source: impl Error + WasmNotSendSync + 'static,
source: impl WebGpuError + WasmNotSendSync + 'static,
fn_ident: &'static str,
) {
self.handle_error_inner(sink_mutex, Box::new(source), None, fn_ident)
let error_type = source.webgpu_error_type();
self.handle_error_inner(sink_mutex, error_type, Box::new(source), None, fn_ident)
}
#[track_caller]