naga/front/wgsl/parse/
conv.rs

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
27        "vertex_index" => crate::BuiltIn::VertexIndex,
28        "instance_index" => crate::BuiltIn::InstanceIndex,
29        "view_index" => crate::BuiltIn::ViewIndex,
30        // fragment
31        "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        // compute
37        "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        // subgroup
43        "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        // comparison
201        "abs" => Mf::Abs,
202        "min" => Mf::Min,
203        "max" => Mf::Max,
204        "clamp" => Mf::Clamp,
205        "saturate" => Mf::Saturate,
206        // trigonometry
207        "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        // decomposition
223        "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        // exponent
232        "exp" => Mf::Exp,
233        "exp2" => Mf::Exp2,
234        "log" => Mf::Log,
235        "log2" => Mf::Log2,
236        "pow" => Mf::Pow,
237        // geometry
238        "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        // computational
247        "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        // bits
258        "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        // data packing
267        "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        // data unpacking
275        "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}