ailloli_ui_render_wgpu/error.rs
1//! GPU renderer errors.
2
3use thiserror::Error;
4
5/// Rejected input to [`crate::Renderer::record_layered_to_target_scaled`].
6///
7/// These failures are detected before the encoder, atlas, or stencil cache is
8/// changed. GPU validation failures (for example, a view from another device)
9/// are reported by wgpu instead. This separate error type leaves the published
10/// [`RendererError`] variants unchanged for existing exhaustive matches.
11///
12/// # Examples
13///
14/// ```
15/// use ailloli_ui_render_wgpu::TargetRecordingError;
16/// let error = TargetRecordingError::FrameTextureUnavailable;
17/// assert!(error.to_string().contains("backing texture"));
18/// ```
19#[derive(Debug, Error)]
20#[non_exhaustive]
21pub enum TargetRecordingError {
22 /// Dimensions, format, scale, or the supplied texture violate the contract.
23 ///
24 /// The diagnostic explains which check failed; its wording is not a stable
25 /// identifier. Match the variant, not the diagnostic string.
26 #[error("wgpu: invalid borrowed render target: {0}")]
27 InvalidRenderTarget(&'static str),
28 /// A backdrop filter or destination blend needs the backing texture.
29 ///
30 /// Supply the texture corresponding to the view, with `COPY_SRC` usage.
31 #[error("wgpu: borrowed target requires a backing texture for destination effects")]
32 FrameTextureUnavailable,
33}
34
35/// Failure during adapter/device setup, surface configuration, or capture readback.
36///
37/// # Examples
38///
39/// ```
40/// use ailloli_ui_render_wgpu::RendererError;
41/// let error = RendererError::SurfaceAcquireTimeout;
42/// assert!(error.to_string().contains("Timeout"));
43/// ```
44#[derive(Debug, Error)]
45pub enum RendererError {
46 /// No adapter matching the requested backend and surface was available.
47 #[error("wgpu: request adapter failed")]
48 RequestAdapterFailed,
49 /// Device creation failed; the string contains wgpu's diagnostic.
50 #[error("wgpu: request device failed: {0}")]
51 RequestDeviceFailed(String),
52 /// The surface returned no usable capabilities for the named property.
53 #[error("wgpu: surface capabilities unavailable: {0}")]
54 SurfaceCapabilitiesUnavailable(&'static str),
55 /// A surface configuration could not be constructed.
56 #[error("wgpu: surface configuration failed")]
57 SurfaceConfigFailed,
58 /// The current renderer pipelines cannot be reused with the surface's new
59 /// preferred format. The presentation adapter must rebuild the renderer.
60 #[error("wgpu: surface presentation must be recreated: {0}")]
61 SurfaceRecreationRequired(&'static str),
62 /// No compatible adapter succeeded at `Surface::configure` (wgpu 0.20 may panic instead of returning an error).
63 #[error("wgpu: surface configure failed for every compatible adapter (try WGPU_BACKEND=gl or WINIT_UNIX_BACKEND=x11)")]
64 SurfaceConfigureExhausted,
65 /// Capture was requested from a format not handled by the RGBA readback path.
66 #[error("wgpu: capture unsupported surface format: {0:?}")]
67 CaptureUnsupportedFormat(wgpu::TextureFormat),
68 /// Mapping the GPU capture buffer failed.
69 #[error("wgpu: capture mapping failed: {0}")]
70 CaptureMapFailed(String),
71 /// A render target exposed only a view where a backing texture was required.
72 #[error("wgpu: frame texture unavailable for this render target")]
73 FrameTextureUnavailable,
74 /// The requested renderer mode has no compatible render target.
75 #[error("ailloli_ui: render target unavailable for this renderer mode ({0})")]
76 RenderTargetUnavailable(&'static str),
77 /// Frame acquisition failed with an untyped host diagnostic.
78 #[error("wgpu: failed to acquire current frame: {0}")]
79 SurfaceAcquireFailed(String),
80 /// Surface acquisition timed out; hosts may skip and retry a later frame.
81 #[error("wgpu: failed to acquire current frame: Timeout")]
82 SurfaceAcquireTimeout,
83 /// The surface was lost and should be recreated or reconfigured.
84 #[error("wgpu: failed to acquire current frame: Lost")]
85 SurfaceAcquireLost,
86 /// The surface is outdated and should be reconfigured before retrying.
87 #[error("wgpu: failed to acquire current frame: Outdated")]
88 SurfaceAcquireOutdated,
89 /// The GPU cannot allocate the frame; callers should terminate rendering.
90 #[error("wgpu: failed to acquire current frame: OutOfMemory")]
91 SurfaceAcquireOutOfMemory,
92 /// The surface exists but is not ready, commonly because one axis is zero.
93 #[error("wgpu: surface is not ready: {0}")]
94 SurfaceNotReady(String),
95}
96
97impl RendererError {
98 /// Converts wgpu's typed acquisition failure without string parsing.
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// use ailloli_ui_render_wgpu::RendererError;
104 /// let error = RendererError::from_surface_error(wgpu::SurfaceError::Lost);
105 /// assert!(matches!(error, RendererError::SurfaceAcquireLost));
106 /// ```
107 pub fn from_surface_error(error: wgpu::SurfaceError) -> Self {
108 match error {
109 wgpu::SurfaceError::Timeout => Self::SurfaceAcquireTimeout,
110 wgpu::SurfaceError::Lost => Self::SurfaceAcquireLost,
111 wgpu::SurfaceError::Outdated => Self::SurfaceAcquireOutdated,
112 wgpu::SurfaceError::OutOfMemory => Self::SurfaceAcquireOutOfMemory,
113 }
114 }
115}
116
117#[cfg(test)]
118/// Verifies typed surface-acquisition error conversion.
119mod tests {
120 use super::*;
121
122 #[test]
123 fn surface_acquire_errors_are_typed_without_string_parsing() {
124 assert!(matches!(
125 RendererError::from_surface_error(wgpu::SurfaceError::Timeout),
126 RendererError::SurfaceAcquireTimeout
127 ));
128 assert!(matches!(
129 RendererError::from_surface_error(wgpu::SurfaceError::Lost),
130 RendererError::SurfaceAcquireLost
131 ));
132 assert!(matches!(
133 RendererError::from_surface_error(wgpu::SurfaceError::Outdated),
134 RendererError::SurfaceAcquireOutdated
135 ));
136 assert!(matches!(
137 RendererError::from_surface_error(wgpu::SurfaceError::OutOfMemory),
138 RendererError::SurfaceAcquireOutOfMemory
139 ));
140 }
141}