1use crate::display_backend::DisplayError;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum BudgetKind {
5 DrawPrimitives {
6 attempted: usize,
7 max: usize,
8 },
9 MeshesPerFrame {
10 attempted: usize,
11 max: usize,
12 },
13 TrianglesPerMesh {
14 attempted: usize,
15 max: usize,
16 },
17 VerticesPerMesh {
18 attempted: usize,
19 max: usize,
20 },
21 Textures {
22 attempted: usize,
23 max: usize,
24 },
25 FramebufferDimensions {
26 width: usize,
27 height: usize,
28 max_width: usize,
29 max_height: usize,
30 },
31 ZBufferLength {
32 expected: usize,
33 got: usize,
34 },
35}
36
37impl BudgetKind {
38 pub fn key(&self) -> &'static str {
39 match self {
40 BudgetKind::DrawPrimitives { .. } => "DrawPrimitives",
41 BudgetKind::MeshesPerFrame { .. } => "MeshesPerFrame",
42 BudgetKind::TrianglesPerMesh { .. } => "TrianglesPerMesh",
43 BudgetKind::VerticesPerMesh { .. } => "VerticesPerMesh",
44 BudgetKind::Textures { .. } => "Textures",
45 BudgetKind::FramebufferDimensions { .. } => "FramebufferDimensions",
46 BudgetKind::ZBufferLength { .. } => "ZBufferLength",
47 }
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum RenderError {
53 OutOfBudget(BudgetKind),
54 InvalidInput(&'static str),
55 Backend(DisplayError),
56 BackendFault(BackendFaultKind),
57 Stall(StallKind),
58 Recoverable {
59 fault: RuntimeFaultKind,
60 action: RecoveryAction,
61 },
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub enum BackendFaultKind {
66 DmaBusyTimeout,
67 TransferStartFailed,
68 InvalidBufferConfig,
69 DeviceUnavailable,
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73pub enum StallKind {
74 RecordStage,
75 ExecuteStage,
76 PresentStage,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub enum RuntimeFaultKind {
81 Backend(BackendFaultKind),
82 Budget(BudgetKind),
83 Stall(StallKind),
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum RecoveryAction {
88 Retry,
89 RetryWithFallback,
90 DropEffects,
91 ReduceQuality,
92 SkipFrame,
93 ResetBackend,
94}
95
96impl From<DisplayError> for RenderError {
97 fn from(value: DisplayError) -> Self {
98 match value {
99 DisplayError::Busy => Self::BackendFault(BackendFaultKind::DmaBusyTimeout),
100 DisplayError::HardwareError => {
101 Self::BackendFault(BackendFaultKind::TransferStartFailed)
102 }
103 DisplayError::InvalidBuffer => {
104 Self::BackendFault(BackendFaultKind::InvalidBufferConfig)
105 }
106 }
107 }
108}