mtl_gpu/error.rs
1//! Validation error types for Metal API.
2//!
3//! These errors are returned by safe wrapper methods that validate parameters
4//! before calling Metal APIs that would otherwise abort the process.
5
6use std::fmt;
7
8use mtl_foundation::UInteger;
9
10/// Validation error returned when resource creation would fail.
11///
12/// Metal's validation layer sometimes aborts the process instead of returning
13/// an error for certain invalid configurations. These safe wrapper methods
14/// validate parameters before calling Metal APIs and return this error type
15/// instead of allowing the process to abort.
16#[derive(Debug, Clone)]
17pub enum ValidationError {
18 // =========================================================================
19 // Render Pipeline Errors
20 // =========================================================================
21 /// Render pipeline descriptor is missing a required vertex function.
22 MissingVertexFunction,
23
24 /// The raster sample count is not supported by the device.
25 UnsupportedRasterSampleCount(UInteger),
26
27 // =========================================================================
28 // Compute Pipeline Errors
29 // =========================================================================
30 /// Compute pipeline descriptor is missing a required compute function.
31 MissingComputeFunction,
32
33 // =========================================================================
34 // Texture Errors
35 // =========================================================================
36 /// Texture dimensions are invalid (width, height, or depth is zero).
37 InvalidTextureDimensions {
38 width: UInteger,
39 height: UInteger,
40 depth: UInteger,
41 },
42
43 /// Requested mipmap count exceeds the maximum allowed for the texture dimensions.
44 InvalidMipmapCount {
45 requested: UInteger,
46 max_allowed: UInteger,
47 },
48
49 /// The texture sample count is not supported by the device.
50 UnsupportedTextureSampleCount(UInteger),
51
52 /// Array length is invalid (must be > 0 for array textures).
53 InvalidArrayLength,
54
55 // =========================================================================
56 // Sampler Errors
57 // =========================================================================
58 /// LOD clamp range is invalid (min must be <= max).
59 InvalidLodRange { min: f32, max: f32 },
60
61 /// Max anisotropy value is invalid (must be >= 1 and power of 2).
62 InvalidAnisotropy(UInteger),
63
64 // =========================================================================
65 // Heap Errors
66 // =========================================================================
67 /// Heap size is invalid (must be > 0).
68 InvalidHeapSize,
69
70 // =========================================================================
71 // Generic Errors
72 // =========================================================================
73 /// Metal failed to create the resource.
74 CreationFailed(Option<mtl_foundation::Error>),
75}
76
77impl fmt::Display for ValidationError {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 match self {
80 // Render Pipeline
81 ValidationError::MissingVertexFunction => {
82 write!(f, "render pipeline descriptor requires a vertex function")
83 }
84 ValidationError::UnsupportedRasterSampleCount(count) => {
85 write!(
86 f,
87 "raster sample count {} is not supported by device",
88 count
89 )
90 }
91
92 // Compute Pipeline
93 ValidationError::MissingComputeFunction => {
94 write!(f, "compute pipeline descriptor requires a compute function")
95 }
96
97 // Texture
98 ValidationError::InvalidTextureDimensions {
99 width,
100 height,
101 depth,
102 } => {
103 write!(
104 f,
105 "invalid texture dimensions: {}x{}x{} (dimensions must be > 0)",
106 width, height, depth
107 )
108 }
109 ValidationError::InvalidMipmapCount {
110 requested,
111 max_allowed,
112 } => {
113 write!(
114 f,
115 "invalid mipmap count: {} exceeds maximum {} for texture dimensions",
116 requested, max_allowed
117 )
118 }
119 ValidationError::UnsupportedTextureSampleCount(count) => {
120 write!(
121 f,
122 "texture sample count {} is not supported by device",
123 count
124 )
125 }
126 ValidationError::InvalidArrayLength => {
127 write!(f, "array length must be > 0 for array textures")
128 }
129
130 // Sampler
131 ValidationError::InvalidLodRange { min, max } => {
132 write!(
133 f,
134 "invalid LOD clamp range: min ({}) must be <= max ({})",
135 min, max
136 )
137 }
138 ValidationError::InvalidAnisotropy(value) => {
139 write!(
140 f,
141 "invalid max anisotropy {}: must be >= 1 and a power of 2",
142 value
143 )
144 }
145
146 // Heap
147 ValidationError::InvalidHeapSize => {
148 write!(f, "heap size must be > 0")
149 }
150
151 // Generic
152 ValidationError::CreationFailed(Some(err)) => {
153 write!(f, "resource creation failed: error code {}", err.code())
154 }
155 ValidationError::CreationFailed(None) => {
156 write!(f, "resource creation failed")
157 }
158 }
159 }
160}
161
162impl std::error::Error for ValidationError {
163 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
164 None
165 }
166}
167
168impl From<mtl_foundation::Error> for ValidationError {
169 fn from(err: mtl_foundation::Error) -> Self {
170 ValidationError::CreationFailed(Some(err))
171 }
172}