1use crate::front::wgsl::parse::directive::enable_extension::{
2 EnableExtensions, ImplementedEnableExtension,
3};
4use crate::front::wgsl::{Error, Result, Scalar};
5use crate::Span;
6
7use alloc::boxed::Box;
8
9pub fn map_address_space(word: &str, span: Span) -> Result<'_, crate::AddressSpace> {
10 match word {
11 "private" => Ok(crate::AddressSpace::Private),
12 "workgroup" => Ok(crate::AddressSpace::WorkGroup),
13 "uniform" => Ok(crate::AddressSpace::Uniform),
14 "storage" => Ok(crate::AddressSpace::Storage {
15 access: crate::StorageAccess::default(),
16 }),
17 "push_constant" => Ok(crate::AddressSpace::PushConstant),
18 "function" => Ok(crate::AddressSpace::Function),
19 _ => Err(Box::new(Error::UnknownAddressSpace(span))),
20 }
21}
22
23pub fn map_built_in(word: &str, span: Span) -> Result<'_, crate::BuiltIn> {
24 Ok(match word {
25 "position" => crate::BuiltIn::Position { invariant: false },
26 "vertex_index" => crate::BuiltIn::VertexIndex,
28 "instance_index" => crate::BuiltIn::InstanceIndex,
29 "view_index" => crate::BuiltIn::ViewIndex,
30 "front_facing" => crate::BuiltIn::FrontFacing,
32 "frag_depth" => crate::BuiltIn::FragDepth,
33 "primitive_index" => crate::BuiltIn::PrimitiveIndex,
34 "sample_index" => crate::BuiltIn::SampleIndex,
35 "sample_mask" => crate::BuiltIn::SampleMask,
36 "global_invocation_id" => crate::BuiltIn::GlobalInvocationId,
38 "local_invocation_id" => crate::BuiltIn::LocalInvocationId,
39 "local_invocation_index" => crate::BuiltIn::LocalInvocationIndex,
40 "workgroup_id" => crate::BuiltIn::WorkGroupId,
41 "num_workgroups" => crate::BuiltIn::NumWorkGroups,
42 "num_subgroups" => crate::BuiltIn::NumSubgroups,
44 "subgroup_id" => crate::BuiltIn::SubgroupId,
45 "subgroup_size" => crate::BuiltIn::SubgroupSize,
46 "subgroup_invocation_id" => crate::BuiltIn::SubgroupInvocationId,
47 _ => return Err(Box::new(Error::UnknownBuiltin(span))),
48 })
49}
50
51pub fn map_interpolation(word: &str, span: Span) -> Result<'_, crate::Interpolation> {
52 match word {
53 "linear" => Ok(crate::Interpolation::Linear),
54 "flat" => Ok(crate::Interpolation::Flat),
55 "perspective" => Ok(crate::Interpolation::Perspective),
56 _ => Err(Box::new(Error::UnknownAttribute(span))),
57 }
58}
59
60pub fn map_sampling(word: &str, span: Span) -> Result<'_, crate::Sampling> {
61 match word {
62 "center" => Ok(crate::Sampling::Center),
63 "centroid" => Ok(crate::Sampling::Centroid),
64 "sample" => Ok(crate::Sampling::Sample),
65 "first" => Ok(crate::Sampling::First),
66 "either" => Ok(crate::Sampling::Either),
67 _ => Err(Box::new(Error::UnknownAttribute(span))),
68 }
69}
70
71pub fn map_storage_format(word: &str, span: Span) -> Result<'_, crate::StorageFormat> {
72 use crate::StorageFormat as Sf;
73 Ok(match word {
74 "r8unorm" => Sf::R8Unorm,
75 "r8snorm" => Sf::R8Snorm,
76 "r8uint" => Sf::R8Uint,
77 "r8sint" => Sf::R8Sint,
78 "r16unorm" => Sf::R16Unorm,
79 "r16snorm" => Sf::R16Snorm,
80 "r16uint" => Sf::R16Uint,
81 "r16sint" => Sf::R16Sint,
82 "r16float" => Sf::R16Float,
83 "rg8unorm" => Sf::Rg8Unorm,
84 "rg8snorm" => Sf::Rg8Snorm,
85 "rg8uint" => Sf::Rg8Uint,
86 "rg8sint" => Sf::Rg8Sint,
87 "r32uint" => Sf::R32Uint,
88 "r32sint" => Sf::R32Sint,
89 "r32float" => Sf::R32Float,
90 "rg16unorm" => Sf::Rg16Unorm,
91 "rg16snorm" => Sf::Rg16Snorm,
92 "rg16uint" => Sf::Rg16Uint,
93 "rg16sint" => Sf::Rg16Sint,
94 "rg16float" => Sf::Rg16Float,
95 "rgba8unorm" => Sf::Rgba8Unorm,
96 "rgba8snorm" => Sf::Rgba8Snorm,
97 "rgba8uint" => Sf::Rgba8Uint,
98 "rgba8sint" => Sf::Rgba8Sint,
99 "rgb10a2uint" => Sf::Rgb10a2Uint,
100 "rgb10a2unorm" => Sf::Rgb10a2Unorm,
101 "rg11b10float" => Sf::Rg11b10Ufloat,
102 "r64uint" => Sf::R64Uint,
103 "rg32uint" => Sf::Rg32Uint,
104 "rg32sint" => Sf::Rg32Sint,
105 "rg32float" => Sf::Rg32Float,
106 "rgba16unorm" => Sf::Rgba16Unorm,
107 "rgba16snorm" => Sf::Rgba16Snorm,
108 "rgba16uint" => Sf::Rgba16Uint,
109 "rgba16sint" => Sf::Rgba16Sint,
110 "rgba16float" => Sf::Rgba16Float,
111 "rgba32uint" => Sf::Rgba32Uint,
112 "rgba32sint" => Sf::Rgba32Sint,
113 "rgba32float" => Sf::Rgba32Float,
114 "bgra8unorm" => Sf::Bgra8Unorm,
115 _ => return Err(Box::new(Error::UnknownStorageFormat(span))),
116 })
117}
118
119pub fn get_scalar_type(
120 enable_extensions: &EnableExtensions,
121 span: Span,
122 word: &str,
123) -> Result<'static, Option<Scalar>> {
124 use crate::ScalarKind as Sk;
125 let scalar = match word {
126 "f16" => Some(Scalar {
127 kind: Sk::Float,
128 width: 2,
129 }),
130 "f32" => Some(Scalar {
131 kind: Sk::Float,
132 width: 4,
133 }),
134 "f64" => Some(Scalar {
135 kind: Sk::Float,
136 width: 8,
137 }),
138 "i32" => Some(Scalar {
139 kind: Sk::Sint,
140 width: 4,
141 }),
142 "u32" => Some(Scalar {
143 kind: Sk::Uint,
144 width: 4,
145 }),
146 "i64" => Some(Scalar {
147 kind: Sk::Sint,
148 width: 8,
149 }),
150 "u64" => Some(Scalar {
151 kind: Sk::Uint,
152 width: 8,
153 }),
154 "bool" => Some(Scalar {
155 kind: Sk::Bool,
156 width: crate::BOOL_WIDTH,
157 }),
158 _ => None,
159 };
160
161 if matches!(scalar, Some(Scalar::F16))
162 && !enable_extensions.contains(ImplementedEnableExtension::F16)
163 {
164 return Err(Box::new(Error::EnableExtensionNotEnabled {
165 span,
166 kind: ImplementedEnableExtension::F16.into(),
167 }));
168 }
169
170 Ok(scalar)
171}
172
173pub fn map_derivative(word: &str) -> Option<(crate::DerivativeAxis, crate::DerivativeControl)> {
174 use crate::{DerivativeAxis as Axis, DerivativeControl as Ctrl};
175 match word {
176 "dpdxCoarse" => Some((Axis::X, Ctrl::Coarse)),
177 "dpdyCoarse" => Some((Axis::Y, Ctrl::Coarse)),
178 "fwidthCoarse" => Some((Axis::Width, Ctrl::Coarse)),
179 "dpdxFine" => Some((Axis::X, Ctrl::Fine)),
180 "dpdyFine" => Some((Axis::Y, Ctrl::Fine)),
181 "fwidthFine" => Some((Axis::Width, Ctrl::Fine)),
182 "dpdx" => Some((Axis::X, Ctrl::None)),
183 "dpdy" => Some((Axis::Y, Ctrl::None)),
184 "fwidth" => Some((Axis::Width, Ctrl::None)),
185 _ => None,
186 }
187}
188
189pub fn map_relational_fun(word: &str) -> Option<crate::RelationalFunction> {
190 match word {
191 "any" => Some(crate::RelationalFunction::Any),
192 "all" => Some(crate::RelationalFunction::All),
193 _ => None,
194 }
195}
196
197pub fn map_standard_fun(word: &str) -> Option<crate::MathFunction> {
198 use crate::MathFunction as Mf;
199 Some(match word {
200 "abs" => Mf::Abs,
202 "min" => Mf::Min,
203 "max" => Mf::Max,
204 "clamp" => Mf::Clamp,
205 "saturate" => Mf::Saturate,
206 "cos" => Mf::Cos,
208 "cosh" => Mf::Cosh,
209 "sin" => Mf::Sin,
210 "sinh" => Mf::Sinh,
211 "tan" => Mf::Tan,
212 "tanh" => Mf::Tanh,
213 "acos" => Mf::Acos,
214 "acosh" => Mf::Acosh,
215 "asin" => Mf::Asin,
216 "asinh" => Mf::Asinh,
217 "atan" => Mf::Atan,
218 "atanh" => Mf::Atanh,
219 "atan2" => Mf::Atan2,
220 "radians" => Mf::Radians,
221 "degrees" => Mf::Degrees,
222 "ceil" => Mf::Ceil,
224 "floor" => Mf::Floor,
225 "round" => Mf::Round,
226 "fract" => Mf::Fract,
227 "trunc" => Mf::Trunc,
228 "modf" => Mf::Modf,
229 "frexp" => Mf::Frexp,
230 "ldexp" => Mf::Ldexp,
231 "exp" => Mf::Exp,
233 "exp2" => Mf::Exp2,
234 "log" => Mf::Log,
235 "log2" => Mf::Log2,
236 "pow" => Mf::Pow,
237 "dot" => Mf::Dot,
239 "cross" => Mf::Cross,
240 "distance" => Mf::Distance,
241 "length" => Mf::Length,
242 "normalize" => Mf::Normalize,
243 "faceForward" => Mf::FaceForward,
244 "reflect" => Mf::Reflect,
245 "refract" => Mf::Refract,
246 "sign" => Mf::Sign,
248 "fma" => Mf::Fma,
249 "mix" => Mf::Mix,
250 "step" => Mf::Step,
251 "smoothstep" => Mf::SmoothStep,
252 "sqrt" => Mf::Sqrt,
253 "inverseSqrt" => Mf::InverseSqrt,
254 "transpose" => Mf::Transpose,
255 "determinant" => Mf::Determinant,
256 "quantizeToF16" => Mf::QuantizeToF16,
257 "countTrailingZeros" => Mf::CountTrailingZeros,
259 "countLeadingZeros" => Mf::CountLeadingZeros,
260 "countOneBits" => Mf::CountOneBits,
261 "reverseBits" => Mf::ReverseBits,
262 "extractBits" => Mf::ExtractBits,
263 "insertBits" => Mf::InsertBits,
264 "firstTrailingBit" => Mf::FirstTrailingBit,
265 "firstLeadingBit" => Mf::FirstLeadingBit,
266 "pack4x8snorm" => Mf::Pack4x8snorm,
268 "pack4x8unorm" => Mf::Pack4x8unorm,
269 "pack2x16snorm" => Mf::Pack2x16snorm,
270 "pack2x16unorm" => Mf::Pack2x16unorm,
271 "pack2x16float" => Mf::Pack2x16float,
272 "pack4xI8" => Mf::Pack4xI8,
273 "pack4xU8" => Mf::Pack4xU8,
274 "unpack4x8snorm" => Mf::Unpack4x8snorm,
276 "unpack4x8unorm" => Mf::Unpack4x8unorm,
277 "unpack2x16snorm" => Mf::Unpack2x16snorm,
278 "unpack2x16unorm" => Mf::Unpack2x16unorm,
279 "unpack2x16float" => Mf::Unpack2x16float,
280 "unpack4xI8" => Mf::Unpack4xI8,
281 "unpack4xU8" => Mf::Unpack4xU8,
282 _ => return None,
283 })
284}
285
286pub fn map_conservative_depth(word: &str, span: Span) -> Result<'_, crate::ConservativeDepth> {
287 use crate::ConservativeDepth as Cd;
288 match word {
289 "greater_equal" => Ok(Cd::GreaterEqual),
290 "less_equal" => Ok(Cd::LessEqual),
291 "unchanged" => Ok(Cd::Unchanged),
292 _ => Err(Box::new(Error::UnknownConservativeDepth(span))),
293 }
294}
295
296pub fn map_subgroup_operation(
297 word: &str,
298) -> Option<(crate::SubgroupOperation, crate::CollectiveOperation)> {
299 use crate::CollectiveOperation as co;
300 use crate::SubgroupOperation as sg;
301 Some(match word {
302 "subgroupAll" => (sg::All, co::Reduce),
303 "subgroupAny" => (sg::Any, co::Reduce),
304 "subgroupAdd" => (sg::Add, co::Reduce),
305 "subgroupMul" => (sg::Mul, co::Reduce),
306 "subgroupMin" => (sg::Min, co::Reduce),
307 "subgroupMax" => (sg::Max, co::Reduce),
308 "subgroupAnd" => (sg::And, co::Reduce),
309 "subgroupOr" => (sg::Or, co::Reduce),
310 "subgroupXor" => (sg::Xor, co::Reduce),
311 "subgroupExclusiveAdd" => (sg::Add, co::ExclusiveScan),
312 "subgroupExclusiveMul" => (sg::Mul, co::ExclusiveScan),
313 "subgroupInclusiveAdd" => (sg::Add, co::InclusiveScan),
314 "subgroupInclusiveMul" => (sg::Mul, co::InclusiveScan),
315 _ => return None,
316 })
317}