/src/wgpu/naga/src/front/spv/error.rs
Line | Count | Source |
1 | | use alloc::{ |
2 | | format, |
3 | | string::{String, ToString}, |
4 | | }; |
5 | | |
6 | | use codespan_reporting::diagnostic::Diagnostic; |
7 | | use codespan_reporting::files::SimpleFile; |
8 | | use codespan_reporting::term; |
9 | | |
10 | | use super::ModuleState; |
11 | | use crate::{ |
12 | | arena::Handle, |
13 | | error::{replace_control_chars, ErrorWrite}, |
14 | | front::atomic_upgrade, |
15 | | }; |
16 | | |
17 | | #[derive(Clone, Debug, thiserror::Error)] |
18 | | pub enum Error { |
19 | | #[error("invalid header")] |
20 | | InvalidHeader, |
21 | | #[error("invalid word count")] |
22 | | InvalidWordCount, |
23 | | #[error("unknown instruction {0}")] |
24 | | UnknownInstruction(u16), |
25 | | #[error("unknown capability %{0}")] |
26 | | UnknownCapability(spirv::Word), |
27 | | #[error("unsupported instruction {1:?} at {0:?}")] |
28 | | UnsupportedInstruction(ModuleState, spirv::Op), |
29 | | #[error("unsupported capability {0:?}")] |
30 | | UnsupportedCapability(spirv::Capability), |
31 | | #[error("unsupported extension {0}")] |
32 | | UnsupportedExtension(String), |
33 | | #[error("unsupported extension set {0}")] |
34 | | UnsupportedExtSet(String), |
35 | | #[error("unsupported extension instantiation set %{0}")] |
36 | | UnsupportedExtInstSet(spirv::Word), |
37 | | #[error("unsupported extension instantiation %{0}")] |
38 | | UnsupportedExtInst(spirv::Word), |
39 | | #[error("unsupported type {0:?}")] |
40 | | UnsupportedType(Handle<crate::Type>), |
41 | | #[error("unsupported execution model %{0}")] |
42 | | UnsupportedExecutionModel(spirv::Word), |
43 | | #[error("unsupported execution mode %{0}")] |
44 | | UnsupportedExecutionMode(spirv::Word), |
45 | | #[error("unsupported storage class %{0}")] |
46 | | UnsupportedStorageClass(spirv::Word), |
47 | | #[error("unsupported image dimension %{0}")] |
48 | | UnsupportedImageDim(spirv::Word), |
49 | | #[error("unsupported image format %{0}")] |
50 | | UnsupportedImageFormat(spirv::Word), |
51 | | #[error("unsupported builtin %{0}")] |
52 | | UnsupportedBuiltIn(spirv::Word), |
53 | | #[error("unsupported control flow %{0}")] |
54 | | UnsupportedControlFlow(spirv::Word), |
55 | | #[error("unsupported binary operator %{0}")] |
56 | | UnsupportedBinaryOperator(spirv::Word), |
57 | | #[error("Naga supports OpTypeRuntimeArray in the StorageBuffer storage class only")] |
58 | | UnsupportedRuntimeArrayStorageClass, |
59 | | #[error( |
60 | | "unsupported matrix stride {} for a {}x{} matrix with scalar width={}", |
61 | | stride, |
62 | | columns, |
63 | | rows, |
64 | | width |
65 | | )] |
66 | | UnsupportedMatrixStride { |
67 | | stride: u32, |
68 | | columns: u8, |
69 | | rows: u8, |
70 | | width: u8, |
71 | | }, |
72 | | #[error("unknown binary operator {0:?}")] |
73 | | UnknownBinaryOperator(spirv::Op), |
74 | | #[error("unknown relational function {0:?}")] |
75 | | UnknownRelationalFunction(spirv::Op), |
76 | | #[error("unsupported group operation %{0}")] |
77 | | UnsupportedGroupOperation(spirv::Word), |
78 | | #[error("invalid parameter {0:?}")] |
79 | | InvalidParameter(spirv::Op), |
80 | | #[error("invalid operand count {1} for {0:?}")] |
81 | | InvalidOperandCount(spirv::Op, u16), |
82 | | #[error("invalid operand")] |
83 | | InvalidOperand, |
84 | | #[error("invalid id %{0}")] |
85 | | InvalidId(spirv::Word), |
86 | | #[error("invalid decoration %{0}")] |
87 | | InvalidDecoration(spirv::Word), |
88 | | #[error("invalid type width %{0}")] |
89 | | InvalidTypeWidth(spirv::Word), |
90 | | #[error("invalid sign %{0}")] |
91 | | InvalidSign(spirv::Word), |
92 | | #[error("invalid inner type %{0}")] |
93 | | InvalidInnerType(spirv::Word), |
94 | | #[error("invalid vector size %{0}")] |
95 | | InvalidVectorSize(spirv::Word), |
96 | | #[error("invalid access type %{0}")] |
97 | | InvalidAccessType(spirv::Word), |
98 | | #[error("invalid access {0:?}")] |
99 | | InvalidAccess(crate::Expression), |
100 | | #[error("invalid access index %{0}")] |
101 | | InvalidAccessIndex(spirv::Word), |
102 | | #[error("invalid index type %{0}")] |
103 | | InvalidIndexType(spirv::Word), |
104 | | #[error("invalid binding %{0}")] |
105 | | InvalidBinding(spirv::Word), |
106 | | #[error("invalid global var {0:?}")] |
107 | | InvalidGlobalVar(crate::Expression), |
108 | | #[error("invalid image/sampler expression {0:?}")] |
109 | | InvalidImageExpression(crate::Expression), |
110 | | #[error("image write without format is not currently supported. See https://github.com/gfx-rs/wgpu/issues/6797")] |
111 | | InvalidImageWriteType, |
112 | | #[error("invalid image base type {0:?}")] |
113 | | InvalidImageBaseType(Handle<crate::Type>), |
114 | | #[error("invalid image {0:?}")] |
115 | | InvalidImage(Handle<crate::Type>), |
116 | | #[error("invalid as type {0:?}")] |
117 | | InvalidAsType(Handle<crate::Type>), |
118 | | #[error("invalid vector type {0:?}")] |
119 | | InvalidVectorType(Handle<crate::Type>), |
120 | | #[error("inconsistent comparison sampling {0:?}")] |
121 | | InconsistentComparisonSampling(Handle<crate::GlobalVariable>), |
122 | | #[error("wrong function result type %{0}")] |
123 | | WrongFunctionResultType(spirv::Word), |
124 | | #[error("wrong function argument type %{0}")] |
125 | | WrongFunctionArgumentType(spirv::Word), |
126 | | #[error("missing decoration {0:?}")] |
127 | | MissingDecoration(spirv::Decoration), |
128 | | #[error("bad string")] |
129 | | BadString, |
130 | | #[error("incomplete data")] |
131 | | IncompleteData, |
132 | | #[error("invalid terminator")] |
133 | | InvalidTerminator, |
134 | | #[error("invalid edge classification")] |
135 | | InvalidEdgeClassification, |
136 | | #[error("cycle detected in the CFG during traversal at {0}")] |
137 | | ControlFlowGraphCycle(crate::front::spv::BlockId), |
138 | | #[error("recursive function call %{0}")] |
139 | | FunctionCallCycle(spirv::Word), |
140 | | #[error("invalid array size %{0}")] |
141 | | InvalidArraySize(spirv::Word), |
142 | | #[error("invalid barrier scope %{0}")] |
143 | | InvalidBarrierScope(spirv::Word), |
144 | | #[error("invalid barrier memory semantics %{0}")] |
145 | | InvalidBarrierMemorySemantics(spirv::Word), |
146 | | #[error( |
147 | | "arrays of images / samplers are supported only through bindings for \ |
148 | | now (i.e. you can't create an array of images or samplers that doesn't \ |
149 | | come from a binding)" |
150 | | )] |
151 | | NonBindingArrayOfImageOrSamplers, |
152 | | #[error("naga only supports specialization constant IDs up to 65535 but was given {0}")] |
153 | | SpecIdTooHigh(u32), |
154 | | |
155 | | #[error("atomic upgrade error: {0}")] |
156 | | AtomicUpgradeError(atomic_upgrade::Error), |
157 | | } |
158 | | |
159 | | impl Error { |
160 | 0 | pub fn emit_to_writer(&self, writer: &mut impl ErrorWrite, source: &str) { |
161 | 0 | self.emit_to_writer_with_path(writer, source, "glsl"); |
162 | 0 | } |
163 | | |
164 | 0 | pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) { |
165 | 0 | let path = path.to_string(); |
166 | 0 | let files = SimpleFile::new(path, replace_control_chars(source)); |
167 | 0 | let config = term::Config::default(); |
168 | 0 | let diagnostic = Diagnostic::error().with_message(format!("{self:?}")); |
169 | | |
170 | 0 | term::emit(writer, &config, &files, &diagnostic).expect("cannot write error"); |
171 | 0 | } |
172 | | |
173 | 0 | pub fn emit_to_string(&self, source: &str) -> String { |
174 | 0 | let mut writer = crate::error::DiagnosticBuffer::new(); |
175 | 0 | self.emit_to_writer(writer.inner_mut(), source); |
176 | 0 | writer.into_string() |
177 | 0 | } |
178 | | } |
179 | | |
180 | | impl From<atomic_upgrade::Error> for Error { |
181 | 0 | fn from(source: atomic_upgrade::Error) -> Self { |
182 | 0 | Error::AtomicUpgradeError(source) |
183 | 0 | } |
184 | | } |