webgpu_traits/
error.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Error scopes and GPUError types
6
7use std::fmt;
8
9use serde::{Deserialize, Serialize};
10use wgpu_core::device::DeviceError;
11
12/// <https://www.w3.org/TR/webgpu/#gpu-error-scope>
13#[derive(Clone, Debug, Eq, Hash, PartialEq)]
14pub struct ErrorScope {
15    pub errors: Vec<Error>,
16    pub filter: ErrorFilter,
17}
18
19impl ErrorScope {
20    pub fn new(filter: ErrorFilter) -> Self {
21        Self {
22            filter,
23            errors: Vec::new(),
24        }
25    }
26}
27
28/// <https://www.w3.org/TR/webgpu/#enumdef-gpuerrorfilter>
29#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
30pub enum ErrorFilter {
31    Validation,
32    OutOfMemory,
33    Internal,
34}
35
36/// <https://www.w3.org/TR/webgpu/#gpuerror>
37#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
38pub enum Error {
39    Validation(String),
40    OutOfMemory(String),
41    Internal(String),
42}
43
44impl std::error::Error for Error {
45    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
46        None
47    }
48}
49
50impl fmt::Display for Error {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        f.write_str(self.message())
53    }
54}
55
56impl Error {
57    pub fn filter(&self) -> ErrorFilter {
58        match self {
59            Error::Validation(_) => ErrorFilter::Validation,
60            Error::OutOfMemory(_) => ErrorFilter::OutOfMemory,
61            Error::Internal(_) => ErrorFilter::Internal,
62        }
63    }
64
65    pub fn message(&self) -> &str {
66        match self {
67            Error::Validation(m) => m,
68            Error::OutOfMemory(m) => m,
69            Error::Internal(m) => m,
70        }
71    }
72
73    // TODO: labels
74    // based on https://github.com/gfx-rs/wgpu/blob/trunk/wgpu/src/backend/wgpu_core.rs#L289
75    pub fn from_error<E: std::error::Error + 'static>(error: E) -> Self {
76        let mut source_opt: Option<&(dyn std::error::Error + 'static)> = Some(&error);
77        while let Some(source) = source_opt {
78            if let Some(DeviceError::OutOfMemory) = source.downcast_ref::<DeviceError>() {
79                return Self::OutOfMemory(error.to_string());
80            }
81            source_opt = source.source();
82        }
83        // TODO: This hack is needed because there are
84        // multiple OutOfMemory error variant in wgpu-core
85        // and even upstream does not handle them correctly
86        if format!("{error:?}").contains("OutOfMemory") {
87            return Self::OutOfMemory(error.to_string());
88        }
89        Self::Validation(error.to_string())
90    }
91}
92
93#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
94pub enum PopError {
95    Lost,
96    Empty,
97}