diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 8cd5252b2c..9e99d34d1c 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -930,6 +930,14 @@ impl crate::Context for Context { .unwrap_pretty() } + fn device_on_uncaptured_error( + &self, + _device: &Self::DeviceId, + _handler: impl crate::UncapturedErrorHandler, + ) { + todo!(); + } + fn buffer_map_async( &self, buffer: &Self::BufferId, diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 804abe000c..680b0c81dd 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1148,6 +1148,14 @@ impl crate::Context for Context { // Device is polled automatically } + fn device_on_uncaptured_error( + &self, + _device: &Self::DeviceId, + _handler: impl crate::UncapturedErrorHandler, + ) { + // TODO: + } + fn buffer_map_async( &self, _buffer: &Self::BufferId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 5a21cf7e51..34d3e77178 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -262,6 +262,11 @@ trait Context: Debug + Send + Sized + Sync { ) -> Self::RenderBundleEncoderId; fn device_drop(&self, device: &Self::DeviceId); fn device_poll(&self, device: &Self::DeviceId, maintain: Maintain); + fn device_on_uncaptured_error( + &self, + device: &Self::DeviceId, + handler: impl UncapturedErrorHandler, + ); fn buffer_map_async( &self, @@ -1542,6 +1547,11 @@ impl Device { id: Context::device_create_swap_chain(&*self.context, &self.id, &surface.id, desc), } } + + /// Set a callback for errors that are not handled in error scopes. + pub fn on_uncaptured_error(&self, handler: impl UncapturedErrorHandler) { + self.context.device_on_uncaptured_error(&self.id, handler); + } } impl Drop for Device { @@ -2610,3 +2620,27 @@ impl SwapChain { } } } + +/// Type for the callback of uncaptured error handler +pub trait UncapturedErrorHandler: Fn(Error) + Send + Sync + 'static {} +impl UncapturedErrorHandler for T where T: Fn(Error) + Send + Sync + 'static {} + +/// Error type +#[derive(Debug)] +pub enum Error { + /// Out of memory error + OutOfMemoryError, + /// Validation error, signifying a bug in code or data + ValidationError { + /// + source: Box, + }, +} +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::OutOfMemoryError => f.write_str("Out of Memory"), + Error::ValidationError { source } => std::fmt::Display::fmt(source, f), + } + } +}