Skip to main content

scry_gpu/
error.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Error types for scry-gpu.
3
4/// The Vulkan operation that failed.
5///
6/// Variant names mirror the Vulkan API call (e.g. `CreateBuffer` →
7/// `vkCreateBuffer`). Used inside [`GpuError::Backend`] for programmatic
8/// error matching.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[non_exhaustive]
11#[allow(missing_docs)]
12pub enum BackendOp {
13    CreateBuffer,
14    BindMemory,
15    CreateShaderModule,
16    CreatePipeline,
17    CreatePipelineLayout,
18    CreateDescriptorPool,
19    CreateDescriptorSetLayout,
20    CreateFence,
21    CreateCommandPool,
22    AllocCommandBuffer,
23    AllocDescriptorSet,
24    ResetDescriptorPool,
25    ResetCommandBuffer,
26    BeginCommandBuffer,
27    EndCommandBuffer,
28    ResetFence,
29    QueueSubmit,
30    WaitFence,
31    FreeMemory,
32    MapMemory,
33    CopyBuffer,
34    MutexPoisoned,
35    CreateInstance,
36    CreateDevice,
37    EnumerateDevices,
38    CreateAllocator,
39    // Fence polling
40    GetFenceStatus,
41    // CUDA-specific operations
42    CompileKernel,
43    LoadModule,
44    LoadFunction,
45    LaunchKernel,
46    StreamSync,
47    RecordEvent,
48    DeviceQuery,
49    CuBlas,
50}
51
52/// Helper to build a [`GpuError::Backend`] concisely.
53pub(crate) fn backend_err(op: BackendOp, e: impl std::fmt::Display) -> GpuError {
54    GpuError::Backend {
55        op,
56        detail: e.to_string(),
57    }
58}
59
60/// Errors that can occur during GPU operations.
61#[derive(Debug, thiserror::Error)]
62#[non_exhaustive]
63pub enum GpuError {
64    /// No suitable GPU device was found on this system.
65    #[error("no suitable GPU device found")]
66    NoDevice,
67
68    /// The requested backend is not available (e.g. Vulkan not installed).
69    #[error("backend not available: {0}")]
70    BackendUnavailable(String),
71
72    /// Buffer allocation failed — typically the device ran out of memory.
73    #[error("buffer allocation failed: requested {requested} bytes (device max: {device_max})")]
74    AllocationFailed {
75        /// Bytes requested.
76        requested: u64,
77        /// Device maximum allocation size.
78        device_max: u64,
79    },
80
81    /// Shader compilation failed.
82    #[error("shader compilation error: {0}")]
83    ShaderCompilation(String),
84
85    /// Shader is missing an entry point with the expected name.
86    #[error("entry point \"{name}\" not found in shader")]
87    MissingEntryPoint {
88        /// The entry point name that was expected.
89        name: String,
90    },
91
92    /// A dispatch or readback operation failed.
93    #[error("dispatch failed: {0}")]
94    Dispatch(String),
95
96    /// Readback from GPU buffer to CPU timed out.
97    #[error("readback timed out after {ms}ms")]
98    ReadbackTimeout {
99        /// Timeout duration in milliseconds.
100        ms: u64,
101    },
102
103    /// The provided buffer count does not match the shader's binding count.
104    #[error("binding mismatch: shader expects {expected} buffer(s), got {got}")]
105    BindingMismatch {
106        /// Bindings declared in the shader.
107        expected: usize,
108        /// Buffers provided by the caller.
109        got: usize,
110    },
111
112    /// Internal backend error (Vulkan, Metal, etc.).
113    #[error("backend error ({op:?}): {detail}")]
114    Backend {
115        /// The operation that failed.
116        op: BackendOp,
117        /// Human-readable detail string.
118        detail: String,
119    },
120}
121
122/// Convenience alias.
123pub type Result<T> = std::result::Result<T, GpuError>;