1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Typed GPU errors with stable registry codes.
//!
//! A lost device or surface is a recoverable state the caller handles as a
//! value; nothing in the engine panics on a condition a caller could hit.
use crate::surface::SurfaceError;
use thiserror::Error;
/// Everything that can go wrong opening or driving a device.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum GpuError {
/// No adapter satisfied the device request.
#[error("no compatible GPU adapter found: {detail}")]
NoAdapter {
/// Backend selection diagnostics supplied by the active HAL.
detail: String,
},
/// A window or canvas could not be converted into a presentation surface.
#[error("GPU presentation surface creation failed: {detail}")]
SurfaceCreation {
/// Backend-reported creation failure.
detail: String,
},
/// An adapter was found but opening its logical device failed.
#[error("GPU device request failed: {detail}")]
DeviceRequest {
/// Backend-reported device negotiation failure.
detail: String,
},
/// The device was lost; recreate and retry.
#[error("device lost")]
DeviceLost,
/// The presentation surface is unavailable; reconfigure and skip the
/// frame.
#[error("surface unavailable")]
Surface(#[from] SurfaceError),
/// A requested capability is unavailable and no fallback applies.
#[error("capability {name:?} unavailable")]
Capability {
/// The capability that was required.
name: &'static str,
},
/// A requested resource exceeds a reported portable device limit.
#[error("resource {resource:?} exceeds device limit {limit}")]
LimitExceeded {
/// Resource class that exceeded the limit.
resource: &'static str,
/// Reported device ceiling.
limit: u64,
},
/// A shader failed to compile on this backend.
#[error("shader compilation failed in {label:?}: {detail}")]
ShaderCompile {
/// Which shader module.
label: String,
/// Backend-reported detail, including stage and location where
/// available.
detail: String,
},
/// A host-supplied device cannot run the renderer.
#[error("host GPU context is missing: {}", missing.join("; "))]
HostRequirements {
/// Every unmet requirement, one sentence each, naming the feature,
/// limit or format capability.
missing: Vec<String>,
},
/// A host-supplied texture cannot be rendered into.
#[error("host texture is unusable: {}", problems.join("; "))]
HostTarget {
/// Every problem found, one sentence each.
problems: Vec<String>,
},
/// A GPU operation failed validation or exhausted backend resources.
#[error("GPU runtime operation failed: {detail}")]
Runtime {
/// The first backend diagnostic, retained before secondary failures.
detail: String,
},
}
impl GpuError {
/// The stable registry code for this condition.
#[must_use]
pub fn code(&self) -> &'static str {
match self {
Self::NoAdapter { .. } => "MOLGFX-E0001",
Self::SurfaceCreation { .. } => "MOLGFX-E0004",
Self::DeviceRequest { .. } => "MOLGFX-E0005",
Self::DeviceLost => "MOLGFX-E0002",
Self::Surface(_) => "MOLGFX-E0003",
Self::Capability { .. } => "MOLGFX-E0010",
Self::LimitExceeded { .. } => "MOLGFX-E0011",
Self::HostRequirements { .. } => "MOLGFX-E0012",
Self::HostTarget { .. } => "MOLGFX-E0013",
Self::ShaderCompile { .. } => "MOLGFX-E0060",
Self::Runtime { .. } => "MOLGFX-E0061",
}
}
}
#[cfg(test)]
#[path = "error_tests.rs"]
mod tests;