wgsl_types/
syntax.rs

1//! Basic representations of WGSL syntactic elements, such as enums, operators, and
2//! context-dependent names.
3
4use std::{fmt::Display, str::FromStr};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8#[cfg(feature = "tokrepr")]
9use tokrepr::TokRepr;
10
11// ------------
12// ENUMERATIONS
13// ------------
14// reference: <https://www.w3.org/TR/WGSL/#enumeration-types>
15
16/// Address space enumeration.
17///
18/// Reference: <https://www.w3.org/TR/WGSL/#address-spaces>
19#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22pub enum AddressSpace {
23    Function,
24    Private,
25    Workgroup,
26    Uniform,
27    Storage,
28    Handle, // the handle address space cannot be spelled in WGSL.
29    #[cfg(feature = "naga-ext")]
30    PushConstant,
31}
32
33impl AddressSpace {
34    pub fn default_access_mode(&self) -> AccessMode {
35        match self {
36            AddressSpace::Function => AccessMode::ReadWrite,
37            AddressSpace::Private => AccessMode::ReadWrite,
38            AddressSpace::Workgroup => AccessMode::ReadWrite,
39            AddressSpace::Uniform => AccessMode::Read,
40            AddressSpace::Storage => AccessMode::Read,
41            AddressSpace::Handle => AccessMode::Read,
42            #[cfg(feature = "naga-ext")]
43            AddressSpace::PushConstant => AccessMode::Read,
44        }
45    }
46}
47
48/// Memory access mode enumeration.
49///
50/// Reference: <https://www.w3.org/TR/WGSL/#access-mode>
51#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
52#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
53#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
54pub enum AccessMode {
55    Read,
56    Write,
57    ReadWrite,
58    #[cfg(feature = "naga-ext")]
59    Atomic,
60}
61
62/// Texel format enumeration.
63///
64/// Reference: <https://www.w3.org/TR/WGSL/#texel-format>
65#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
66#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
67#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
68pub enum TexelFormat {
69    Rgba8Unorm,
70    Rgba8Snorm,
71    Rgba8Uint,
72    Rgba8Sint,
73    Rgba16Uint,
74    Rgba16Sint,
75    Rgba16Float,
76    R32Uint,
77    R32Sint,
78    R32Float,
79    Rg32Uint,
80    Rg32Sint,
81    Rg32Float,
82    Rgba32Uint,
83    Rgba32Sint,
84    Rgba32Float,
85    Bgra8Unorm,
86    #[cfg(feature = "naga-ext")]
87    R8Unorm,
88    #[cfg(feature = "naga-ext")]
89    R8Snorm,
90    #[cfg(feature = "naga-ext")]
91    R8Uint,
92    #[cfg(feature = "naga-ext")]
93    R8Sint,
94    #[cfg(feature = "naga-ext")]
95    R16Unorm,
96    #[cfg(feature = "naga-ext")]
97    R16Snorm,
98    #[cfg(feature = "naga-ext")]
99    R16Uint,
100    #[cfg(feature = "naga-ext")]
101    R16Sint,
102    #[cfg(feature = "naga-ext")]
103    R16Float,
104    #[cfg(feature = "naga-ext")]
105    Rg8Unorm,
106    #[cfg(feature = "naga-ext")]
107    Rg8Snorm,
108    #[cfg(feature = "naga-ext")]
109    Rg8Uint,
110    #[cfg(feature = "naga-ext")]
111    Rg8Sint,
112    #[cfg(feature = "naga-ext")]
113    Rg16Unorm,
114    #[cfg(feature = "naga-ext")]
115    Rg16Snorm,
116    #[cfg(feature = "naga-ext")]
117    Rg16Uint,
118    #[cfg(feature = "naga-ext")]
119    Rg16Sint,
120    #[cfg(feature = "naga-ext")]
121    Rg16Float,
122    #[cfg(feature = "naga-ext")]
123    Rgb10a2Uint,
124    #[cfg(feature = "naga-ext")]
125    Rgb10a2Unorm,
126    #[cfg(feature = "naga-ext")]
127    Rg11b10Float,
128    #[cfg(feature = "naga-ext")]
129    R64Uint,
130    #[cfg(feature = "naga-ext")]
131    Rgba16Unorm,
132    #[cfg(feature = "naga-ext")]
133    Rgba16Snorm,
134}
135
136/// Acceleration structure flags (naga extension)
137#[cfg(feature = "naga-ext")]
138#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
140#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
141pub enum AccelerationStructureFlags {
142    VertexReturn,
143}
144
145/// One of the predeclared enumerants.
146///
147/// Reference: <https://www.w3.org/TR/WGSL/#predeclared-enumerants>
148#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
149pub enum Enumerant {
150    AccessMode(AccessMode),
151    AddressSpace(AddressSpace),
152    TexelFormat(TexelFormat),
153    #[cfg(feature = "naga-ext")]
154    AccelerationStructureFlags(AccelerationStructureFlags),
155}
156
157impl FromStr for Enumerant {
158    type Err = ();
159
160    fn from_str(s: &str) -> Result<Self, Self::Err> {
161        let res = AccessMode::from_str(s)
162            .map(Enumerant::AccessMode)
163            .or_else(|()| AddressSpace::from_str(s).map(Enumerant::AddressSpace))
164            .or_else(|()| TexelFormat::from_str(s).map(Enumerant::TexelFormat));
165        #[cfg(feature = "naga-ext")]
166        let res = res.or_else(|()| {
167            AccelerationStructureFlags::from_str(s).map(Enumerant::AccelerationStructureFlags)
168        });
169        res
170    }
171}
172
173// -----------------------
174// CONTEXT-DEPENDENT NAMES
175// -----------------------
176// reference: <https://www.w3.org/TR/WGSL/#context-dependent-names>
177
178/// Built-in value names.
179///
180/// Context-dependent tokens.
181///
182/// Reference: <https://www.w3.org/TR/WGSL/#builtin-value-names>
183#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
184#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
185#[derive(Clone, Copy, Debug, PartialEq, Eq)]
186pub enum BuiltinValue {
187    VertexIndex,
188    InstanceIndex,
189    ClipDistances, // requires WGSL extension clip_distances
190    Position,
191    FrontFacing,
192    FragDepth,
193    SampleIndex,
194    SampleMask,
195    LocalInvocationId,
196    LocalInvocationIndex,
197    GlobalInvocationId,
198    WorkgroupId,
199    NumWorkgroups,
200    SubgroupInvocationId, // requires WGSL extension subgroups
201    SubgroupSize,         // requires WGSL extension subgroups
202    #[cfg(feature = "naga-ext")]
203    SubgroupId, // requires WGSL extension subgroups
204    #[cfg(feature = "naga-ext")]
205    NumSubgroups, // requires WGSL extension subgroups
206    #[cfg(feature = "naga-ext")]
207    PrimitiveIndex,
208    #[cfg(feature = "naga-ext")]
209    ViewIndex,
210}
211
212/// Diagnostic Severity Control Names.
213///
214/// Context-dependent tokens.
215///
216/// Reference: <https://www.w3.org/TR/WGSL/#diagnostic-severity-control-names>
217#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
219#[derive(Clone, Debug, PartialEq, Eq)]
220pub enum DiagnosticSeverity {
221    Error,
222    Warning,
223    Info,
224    Off,
225}
226
227///  Interpolation Type Names.
228///
229/// Context-dependent tokens.
230///
231/// Reference: <https://www.w3.org/TR/WGSL/#interpolation-type-names>
232#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
234#[derive(Clone, Copy, Debug, PartialEq, Eq)]
235pub enum InterpolationType {
236    Perspective,
237    Linear,
238    Flat,
239}
240
241/// Interpolation Sampling Names.
242///
243/// Context-dependent tokens.
244///
245/// Reference: <https://www.w3.org/TR/WGSL/#interpolation-sampling-names>
246#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
248#[derive(Clone, Copy, Debug, PartialEq, Eq)]
249pub enum InterpolationSampling {
250    Center,
251    Centroid,
252    Sample,
253    First,
254    Either,
255}
256
257/// Naga extension: Conservative Depth.
258#[cfg(feature = "naga-ext")]
259#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
260#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
261#[derive(Clone, Copy, Debug, PartialEq, Eq)]
262pub enum ConservativeDepth {
263    GreaterEqual,
264    LessEqual,
265    Unchanged,
266}
267
268// -----------------------
269// CONTEXT-DEPENDENT NAMES
270// -----------------------
271// reference: <https://www.w3.org/TR/WGSL/#context-dependent-names>
272
273#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
274#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
275#[derive(Clone, Copy, Debug, PartialEq, Eq)]
276pub enum UnaryOperator {
277    /// `!`
278    LogicalNegation,
279    /// `-`
280    Negation,
281    /// `~`
282    BitwiseComplement,
283    /// `&`
284    AddressOf,
285    /// `*`
286    Indirection,
287}
288
289#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
291#[derive(Clone, Copy, Debug, PartialEq, Eq)]
292pub enum BinaryOperator {
293    /// `||`
294    ShortCircuitOr,
295    /// `&&`
296    ShortCircuitAnd,
297    /// `+`
298    Addition,
299    /// `-`
300    Subtraction,
301    /// `*`
302    Multiplication,
303    /// `/`
304    Division,
305    /// `%`
306    Remainder,
307    /// `==`
308    Equality,
309    /// `!=`
310    Inequality,
311    /// `<`
312    LessThan,
313    /// `<=`
314    LessThanEqual,
315    /// `>`
316    GreaterThan,
317    /// `>=`
318    GreaterThanEqual,
319    /// `|`
320    /// Note: this is both the "bitwise OR" and "logical OR" operator.
321    BitwiseOr,
322    /// `&`
323    /// Note: this is both the "bitwise AND" and "logical AND" operator.
324    BitwiseAnd,
325    /// `^`
326    BitwiseXor,
327    /// `<<`
328    ShiftLeft,
329    /// `>>`
330    ShiftRight,
331}
332
333#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
334#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
335#[derive(Clone, Copy, Debug, PartialEq, Eq)]
336pub enum AssignmentOperator {
337    /// `=`
338    Equal,
339    /// `+=`
340    PlusEqual,
341    /// `-=`
342    MinusEqual,
343    /// `*=`
344    TimesEqual,
345    /// `/=`
346    DivisionEqual,
347    /// `%=`
348    ModuloEqual,
349    /// `&=`
350    AndEqual,
351    /// `|=`
352    OrEqual,
353    /// `^=`
354    XorEqual,
355    /// `>>=`
356    ShiftRightAssign,
357    /// `<<=`
358    ShiftLeftAssign,
359}
360
361// ---------------
362// Implementations
363// ---------------
364
365impl AccessMode {
366    /// Is [`Self::Read`] or [`Self::ReadWrite`]
367    pub fn is_read(&self) -> bool {
368        matches!(self, Self::Read | Self::ReadWrite)
369    }
370    /// Is [`Self::Write`] or [`Self::ReadWrite`]
371    pub fn is_write(&self) -> bool {
372        matches!(self, Self::Write | Self::ReadWrite)
373    }
374}
375
376#[cfg_attr(feature = "tokrepr", derive(TokRepr))]
377#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
378#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
379pub enum SampledType {
380    I32,
381    U32,
382    F32,
383}
384
385impl TexelFormat {
386    pub fn channel_type(&self) -> SampledType {
387        match self {
388            TexelFormat::Rgba8Unorm => SampledType::F32,
389            TexelFormat::Rgba8Snorm => SampledType::F32,
390            TexelFormat::Rgba8Uint => SampledType::U32,
391            TexelFormat::Rgba8Sint => SampledType::I32,
392            TexelFormat::Rgba16Uint => SampledType::U32,
393            TexelFormat::Rgba16Sint => SampledType::I32,
394            TexelFormat::Rgba16Float => SampledType::F32,
395            TexelFormat::R32Uint => SampledType::U32,
396            TexelFormat::R32Sint => SampledType::I32,
397            TexelFormat::R32Float => SampledType::F32,
398            TexelFormat::Rg32Uint => SampledType::U32,
399            TexelFormat::Rg32Sint => SampledType::I32,
400            TexelFormat::Rg32Float => SampledType::F32,
401            TexelFormat::Rgba32Uint => SampledType::U32,
402            TexelFormat::Rgba32Sint => SampledType::I32,
403            TexelFormat::Rgba32Float => SampledType::F32,
404            TexelFormat::Bgra8Unorm => SampledType::F32,
405            #[cfg(feature = "naga-ext")]
406            TexelFormat::R8Unorm => SampledType::F32,
407            #[cfg(feature = "naga-ext")]
408            TexelFormat::R8Snorm => SampledType::F32,
409            #[cfg(feature = "naga-ext")]
410            TexelFormat::R8Uint => SampledType::U32,
411            #[cfg(feature = "naga-ext")]
412            TexelFormat::R8Sint => SampledType::I32,
413            #[cfg(feature = "naga-ext")]
414            TexelFormat::R16Unorm => SampledType::F32,
415            #[cfg(feature = "naga-ext")]
416            TexelFormat::R16Snorm => SampledType::F32,
417            #[cfg(feature = "naga-ext")]
418            TexelFormat::R16Uint => SampledType::U32,
419            #[cfg(feature = "naga-ext")]
420            TexelFormat::R16Sint => SampledType::I32,
421            #[cfg(feature = "naga-ext")]
422            TexelFormat::R16Float => SampledType::F32,
423            #[cfg(feature = "naga-ext")]
424            TexelFormat::Rg8Unorm => SampledType::F32,
425            #[cfg(feature = "naga-ext")]
426            TexelFormat::Rg8Snorm => SampledType::F32,
427            #[cfg(feature = "naga-ext")]
428            TexelFormat::Rg8Uint => SampledType::U32,
429            #[cfg(feature = "naga-ext")]
430            TexelFormat::Rg8Sint => SampledType::I32,
431            #[cfg(feature = "naga-ext")]
432            TexelFormat::Rg16Unorm => SampledType::F32,
433            #[cfg(feature = "naga-ext")]
434            TexelFormat::Rg16Snorm => SampledType::F32,
435            #[cfg(feature = "naga-ext")]
436            TexelFormat::Rg16Uint => SampledType::U32,
437            #[cfg(feature = "naga-ext")]
438            TexelFormat::Rg16Sint => SampledType::I32,
439            #[cfg(feature = "naga-ext")]
440            TexelFormat::Rg16Float => SampledType::F32,
441            #[cfg(feature = "naga-ext")]
442            TexelFormat::Rgb10a2Uint => SampledType::U32,
443            #[cfg(feature = "naga-ext")]
444            TexelFormat::Rgb10a2Unorm => SampledType::F32,
445            #[cfg(feature = "naga-ext")]
446            TexelFormat::Rg11b10Float => SampledType::F32,
447            #[cfg(feature = "naga-ext")]
448            TexelFormat::R64Uint => SampledType::U32,
449            #[cfg(feature = "naga-ext")]
450            TexelFormat::Rgba16Unorm => SampledType::F32,
451            #[cfg(feature = "naga-ext")]
452            TexelFormat::Rgba16Snorm => SampledType::F32,
453        }
454    }
455
456    pub fn num_channels(&self) -> u32 {
457        match self {
458            TexelFormat::Rgba8Unorm => 4,
459            TexelFormat::Rgba8Snorm => 4,
460            TexelFormat::Rgba8Uint => 4,
461            TexelFormat::Rgba8Sint => 4,
462            TexelFormat::Rgba16Uint => 4,
463            TexelFormat::Rgba16Sint => 4,
464            TexelFormat::Rgba16Float => 4,
465            TexelFormat::R32Uint => 1,
466            TexelFormat::R32Sint => 1,
467            TexelFormat::R32Float => 1,
468            TexelFormat::Rg32Uint => 2,
469            TexelFormat::Rg32Sint => 2,
470            TexelFormat::Rg32Float => 2,
471            TexelFormat::Rgba32Uint => 4,
472            TexelFormat::Rgba32Sint => 4,
473            TexelFormat::Rgba32Float => 4,
474            TexelFormat::Bgra8Unorm => 4,
475            #[cfg(feature = "naga-ext")]
476            TexelFormat::R8Unorm => 1,
477            #[cfg(feature = "naga-ext")]
478            TexelFormat::R8Snorm => 1,
479            #[cfg(feature = "naga-ext")]
480            TexelFormat::R8Uint => 1,
481            #[cfg(feature = "naga-ext")]
482            TexelFormat::R8Sint => 1,
483            #[cfg(feature = "naga-ext")]
484            TexelFormat::R16Unorm => 1,
485            #[cfg(feature = "naga-ext")]
486            TexelFormat::R16Snorm => 1,
487            #[cfg(feature = "naga-ext")]
488            TexelFormat::R16Uint => 1,
489            #[cfg(feature = "naga-ext")]
490            TexelFormat::R16Sint => 1,
491            #[cfg(feature = "naga-ext")]
492            TexelFormat::R16Float => 1,
493            #[cfg(feature = "naga-ext")]
494            TexelFormat::Rg8Unorm => 2,
495            #[cfg(feature = "naga-ext")]
496            TexelFormat::Rg8Snorm => 2,
497            #[cfg(feature = "naga-ext")]
498            TexelFormat::Rg8Uint => 2,
499            #[cfg(feature = "naga-ext")]
500            TexelFormat::Rg8Sint => 2,
501            #[cfg(feature = "naga-ext")]
502            TexelFormat::Rg16Unorm => 2,
503            #[cfg(feature = "naga-ext")]
504            TexelFormat::Rg16Snorm => 2,
505            #[cfg(feature = "naga-ext")]
506            TexelFormat::Rg16Uint => 2,
507            #[cfg(feature = "naga-ext")]
508            TexelFormat::Rg16Sint => 2,
509            #[cfg(feature = "naga-ext")]
510            TexelFormat::Rg16Float => 2,
511            #[cfg(feature = "naga-ext")]
512            TexelFormat::Rgb10a2Uint => 4,
513            #[cfg(feature = "naga-ext")]
514            TexelFormat::Rgb10a2Unorm => 4,
515            #[cfg(feature = "naga-ext")]
516            TexelFormat::Rg11b10Float => 3,
517            #[cfg(feature = "naga-ext")]
518            TexelFormat::R64Uint => 1,
519            #[cfg(feature = "naga-ext")]
520            TexelFormat::Rgba16Unorm => 4,
521            #[cfg(feature = "naga-ext")]
522            TexelFormat::Rgba16Snorm => 4,
523        }
524    }
525}
526
527// -------------
528// FromStr impls
529// -------------
530
531impl FromStr for AddressSpace {
532    type Err = ();
533
534    fn from_str(s: &str) -> Result<Self, Self::Err> {
535        match s {
536            "function" => Ok(Self::Function),
537            "private" => Ok(Self::Private),
538            "workgroup" => Ok(Self::Workgroup),
539            "uniform" => Ok(Self::Uniform),
540            "storage" => Ok(Self::Storage),
541            #[cfg(feature = "naga-ext")]
542            "push_constant" => Ok(Self::PushConstant),
543            // "WGSL predeclares an enumerant for each address space, except for the handle address space."
544            // "handle" => Ok(Self::Handle),
545            _ => Err(()),
546        }
547    }
548}
549
550impl FromStr for AccessMode {
551    type Err = ();
552
553    fn from_str(s: &str) -> Result<Self, Self::Err> {
554        match s {
555            "read" => Ok(Self::Read),
556            "write" => Ok(Self::Write),
557            "read_write" => Ok(Self::ReadWrite),
558            #[cfg(feature = "naga-ext")]
559            "atomic" => Ok(Self::Atomic),
560            _ => Err(()),
561        }
562    }
563}
564
565impl FromStr for TexelFormat {
566    type Err = ();
567
568    fn from_str(s: &str) -> Result<Self, Self::Err> {
569        match s {
570            "rgba8unorm" => Ok(Self::Rgba8Unorm),
571            "rgba8snorm" => Ok(Self::Rgba8Snorm),
572            "rgba8uint" => Ok(Self::Rgba8Uint),
573            "rgba8sint" => Ok(Self::Rgba8Sint),
574            "rgba16uint" => Ok(Self::Rgba16Uint),
575            "rgba16sint" => Ok(Self::Rgba16Sint),
576            "rgba16float" => Ok(Self::Rgba16Float),
577            "r32uint" => Ok(Self::R32Uint),
578            "r32sint" => Ok(Self::R32Sint),
579            "r32float" => Ok(Self::R32Float),
580            "rg32uint" => Ok(Self::Rg32Uint),
581            "rg32sint" => Ok(Self::Rg32Sint),
582            "rg32float" => Ok(Self::Rg32Float),
583            "rgba32uint" => Ok(Self::Rgba32Uint),
584            "rgba32sint" => Ok(Self::Rgba32Sint),
585            "rgba32float" => Ok(Self::Rgba32Float),
586            "bgra8unorm" => Ok(Self::Bgra8Unorm),
587            #[cfg(feature = "naga-ext")]
588            "r8unorm" => Ok(Self::R8Unorm),
589            #[cfg(feature = "naga-ext")]
590            "r8snorm" => Ok(Self::R8Snorm),
591            #[cfg(feature = "naga-ext")]
592            "r8uint" => Ok(Self::R8Uint),
593            #[cfg(feature = "naga-ext")]
594            "r8sint" => Ok(Self::R8Sint),
595            #[cfg(feature = "naga-ext")]
596            "r16unorm" => Ok(Self::R16Unorm),
597            #[cfg(feature = "naga-ext")]
598            "r16snorm" => Ok(Self::R16Snorm),
599            #[cfg(feature = "naga-ext")]
600            "r16uint" => Ok(Self::R16Uint),
601            #[cfg(feature = "naga-ext")]
602            "r16sint" => Ok(Self::R16Sint),
603            #[cfg(feature = "naga-ext")]
604            "r16float" => Ok(Self::R16Float),
605            #[cfg(feature = "naga-ext")]
606            "rg8unorm" => Ok(Self::Rg8Unorm),
607            #[cfg(feature = "naga-ext")]
608            "rg8snorm" => Ok(Self::Rg8Snorm),
609            #[cfg(feature = "naga-ext")]
610            "rg8uint" => Ok(Self::Rg8Uint),
611            #[cfg(feature = "naga-ext")]
612            "rg8sint" => Ok(Self::Rg8Sint),
613            #[cfg(feature = "naga-ext")]
614            "rg16unorm" => Ok(Self::Rg16Unorm),
615            #[cfg(feature = "naga-ext")]
616            "rg16snorm" => Ok(Self::Rg16Snorm),
617            #[cfg(feature = "naga-ext")]
618            "rg16uint" => Ok(Self::Rg16Uint),
619            #[cfg(feature = "naga-ext")]
620            "rg16sint" => Ok(Self::Rg16Sint),
621            #[cfg(feature = "naga-ext")]
622            "rg16float" => Ok(Self::Rg16Float),
623            #[cfg(feature = "naga-ext")]
624            "rgb10a2uint" => Ok(Self::Rgb10a2Uint),
625            #[cfg(feature = "naga-ext")]
626            "rgb10a2unorm" => Ok(Self::Rgb10a2Unorm),
627            #[cfg(feature = "naga-ext")]
628            "rg11b10float" => Ok(Self::Rg11b10Float),
629            #[cfg(feature = "naga-ext")]
630            "r64uint" => Ok(Self::R64Uint),
631            #[cfg(feature = "naga-ext")]
632            "rgba16unorm" => Ok(Self::Rgba16Unorm),
633            #[cfg(feature = "naga-ext")]
634            "rgba16snorm" => Ok(Self::Rgba16Snorm),
635            _ => Err(()),
636        }
637    }
638}
639
640#[cfg(feature = "naga-ext")]
641impl FromStr for AccelerationStructureFlags {
642    type Err = ();
643
644    fn from_str(s: &str) -> Result<Self, Self::Err> {
645        match s {
646            "vertex_return" => Ok(Self::VertexReturn),
647            _ => Err(()),
648        }
649    }
650}
651
652impl FromStr for DiagnosticSeverity {
653    type Err = ();
654
655    fn from_str(s: &str) -> Result<Self, Self::Err> {
656        match s {
657            "error" => Ok(Self::Error),
658            "warning" => Ok(Self::Warning),
659            "info" => Ok(Self::Info),
660            "off" => Ok(Self::Off),
661            _ => Err(()),
662        }
663    }
664}
665
666impl FromStr for BuiltinValue {
667    type Err = ();
668
669    fn from_str(s: &str) -> Result<Self, Self::Err> {
670        match s {
671            "vertex_index" => Ok(Self::VertexIndex),
672            "instance_index" => Ok(Self::InstanceIndex),
673            "clip_distances" => Ok(Self::ClipDistances),
674            "position" => Ok(Self::Position),
675            "front_facing" => Ok(Self::FrontFacing),
676            "frag_depth" => Ok(Self::FragDepth),
677            "sample_index" => Ok(Self::SampleIndex),
678            "sample_mask" => Ok(Self::SampleMask),
679            "local_invocation_id" => Ok(Self::LocalInvocationId),
680            "local_invocation_index" => Ok(Self::LocalInvocationIndex),
681            "global_invocation_id" => Ok(Self::GlobalInvocationId),
682            "workgroup_id" => Ok(Self::WorkgroupId),
683            "num_workgroups" => Ok(Self::NumWorkgroups),
684            "subgroup_invocation_id" => Ok(Self::SubgroupInvocationId),
685            "subgroup_size" => Ok(Self::SubgroupSize),
686            #[cfg(feature = "naga-ext")]
687            "subgroup_id" => Ok(Self::SubgroupId),
688            #[cfg(feature = "naga-ext")]
689            "num_subgroups" => Ok(Self::NumSubgroups),
690            #[cfg(feature = "naga-ext")]
691            "primitive_index" => Ok(Self::PrimitiveIndex),
692            #[cfg(feature = "naga-ext")]
693            "view_index" => Ok(Self::ViewIndex),
694            _ => Err(()),
695        }
696    }
697}
698
699impl FromStr for InterpolationType {
700    type Err = ();
701
702    fn from_str(s: &str) -> Result<Self, Self::Err> {
703        match s {
704            "perspective" => Ok(Self::Perspective),
705            "linear" => Ok(Self::Linear),
706            "flat" => Ok(Self::Flat),
707            _ => Err(()),
708        }
709    }
710}
711
712impl FromStr for InterpolationSampling {
713    type Err = ();
714
715    fn from_str(s: &str) -> Result<Self, Self::Err> {
716        match s {
717            "center" => Ok(Self::Center),
718            "centroid" => Ok(Self::Centroid),
719            "sample" => Ok(Self::Sample),
720            "first" => Ok(Self::First),
721            "either" => Ok(Self::Either),
722            _ => Err(()),
723        }
724    }
725}
726
727#[cfg(feature = "naga-ext")]
728impl FromStr for ConservativeDepth {
729    type Err = ();
730
731    fn from_str(s: &str) -> Result<Self, Self::Err> {
732        match s {
733            "greater_equal" => Ok(Self::GreaterEqual),
734            "less_equal" => Ok(Self::LessEqual),
735            "unchanged" => Ok(Self::Unchanged),
736            _ => Err(()),
737        }
738    }
739}
740
741impl FromStr for SampledType {
742    type Err = ();
743
744    fn from_str(s: &str) -> Result<Self, Self::Err> {
745        match s {
746            "i32" => Ok(Self::I32),
747            "u32" => Ok(Self::U32),
748            "f32" => Ok(Self::F32),
749            _ => Err(()),
750        }
751    }
752}
753
754// -------------
755// Display impls
756// -------------
757
758impl Display for AddressSpace {
759    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
760        match self {
761            Self::Function => write!(f, "function"),
762            Self::Private => write!(f, "private"),
763            Self::Workgroup => write!(f, "workgroup"),
764            Self::Uniform => write!(f, "uniform"),
765            Self::Storage => write!(f, "storage"),
766            Self::Handle => write!(f, "handle"),
767            #[cfg(feature = "naga-ext")]
768            Self::PushConstant => write!(f, "push_constant"),
769        }
770    }
771}
772
773impl Display for AccessMode {
774    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
775        match self {
776            Self::Read => write!(f, "read"),
777            Self::Write => write!(f, "write"),
778            Self::ReadWrite => write!(f, "read_write"),
779            #[cfg(feature = "naga-ext")]
780            Self::Atomic => write!(f, "atomic"),
781        }
782    }
783}
784
785impl Display for TexelFormat {
786    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
787        match self {
788            TexelFormat::Rgba8Unorm => write!(f, "rgba8unorm"),
789            TexelFormat::Rgba8Snorm => write!(f, "rgba8snorm"),
790            TexelFormat::Rgba8Uint => write!(f, "rgba8uint"),
791            TexelFormat::Rgba8Sint => write!(f, "rgba8sint"),
792            TexelFormat::Rgba16Uint => write!(f, "rgba16uint"),
793            TexelFormat::Rgba16Sint => write!(f, "rgba16sint"),
794            TexelFormat::Rgba16Float => write!(f, "rgba16float"),
795            TexelFormat::R32Uint => write!(f, "r32uint"),
796            TexelFormat::R32Sint => write!(f, "r32sint"),
797            TexelFormat::R32Float => write!(f, "r32float"),
798            TexelFormat::Rg32Uint => write!(f, "rg32uint"),
799            TexelFormat::Rg32Sint => write!(f, "rg32sint"),
800            TexelFormat::Rg32Float => write!(f, "rg32float"),
801            TexelFormat::Rgba32Uint => write!(f, "rgba32uint"),
802            TexelFormat::Rgba32Sint => write!(f, "rgba32sint"),
803            TexelFormat::Rgba32Float => write!(f, "rgba32float"),
804            TexelFormat::Bgra8Unorm => write!(f, "bgra8unorm"),
805            #[cfg(feature = "naga-ext")]
806            TexelFormat::R8Unorm => write!(f, "r8unorm"),
807            #[cfg(feature = "naga-ext")]
808            TexelFormat::R8Snorm => write!(f, "r8snorm"),
809            #[cfg(feature = "naga-ext")]
810            TexelFormat::R8Uint => write!(f, "r8uint"),
811            #[cfg(feature = "naga-ext")]
812            TexelFormat::R8Sint => write!(f, "r8sint"),
813            #[cfg(feature = "naga-ext")]
814            TexelFormat::R16Unorm => write!(f, "r16unorm"),
815            #[cfg(feature = "naga-ext")]
816            TexelFormat::R16Snorm => write!(f, "r16snorm"),
817            #[cfg(feature = "naga-ext")]
818            TexelFormat::R16Uint => write!(f, "r16uint"),
819            #[cfg(feature = "naga-ext")]
820            TexelFormat::R16Sint => write!(f, "r16sint"),
821            #[cfg(feature = "naga-ext")]
822            TexelFormat::R16Float => write!(f, "r16float"),
823            #[cfg(feature = "naga-ext")]
824            TexelFormat::Rg8Unorm => write!(f, "rg8unorm"),
825            #[cfg(feature = "naga-ext")]
826            TexelFormat::Rg8Snorm => write!(f, "rg8snorm"),
827            #[cfg(feature = "naga-ext")]
828            TexelFormat::Rg8Uint => write!(f, "rg8uint"),
829            #[cfg(feature = "naga-ext")]
830            TexelFormat::Rg8Sint => write!(f, "rg8sint"),
831            #[cfg(feature = "naga-ext")]
832            TexelFormat::Rg16Unorm => write!(f, "rg16unorm"),
833            #[cfg(feature = "naga-ext")]
834            TexelFormat::Rg16Snorm => write!(f, "rg16snorm"),
835            #[cfg(feature = "naga-ext")]
836            TexelFormat::Rg16Uint => write!(f, "rg16uint"),
837            #[cfg(feature = "naga-ext")]
838            TexelFormat::Rg16Sint => write!(f, "rg16sint"),
839            #[cfg(feature = "naga-ext")]
840            TexelFormat::Rg16Float => write!(f, "rg16float"),
841            #[cfg(feature = "naga-ext")]
842            TexelFormat::Rgb10a2Uint => write!(f, "rgb10a2uint"),
843            #[cfg(feature = "naga-ext")]
844            TexelFormat::Rgb10a2Unorm => write!(f, "rgb10a2unorm"),
845            #[cfg(feature = "naga-ext")]
846            TexelFormat::Rg11b10Float => write!(f, "rg11b10float"),
847            #[cfg(feature = "naga-ext")]
848            TexelFormat::R64Uint => write!(f, "r64uint"),
849            #[cfg(feature = "naga-ext")]
850            TexelFormat::Rgba16Unorm => write!(f, "rgba16unorm"),
851            #[cfg(feature = "naga-ext")]
852            TexelFormat::Rgba16Snorm => write!(f, "rgba16snorm"),
853        }
854    }
855}
856
857#[cfg(feature = "naga-ext")]
858impl Display for AccelerationStructureFlags {
859    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
860        match self {
861            Self::VertexReturn => write!(f, "vertex_return"),
862        }
863    }
864}
865
866impl Display for BuiltinValue {
867    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
868        match self {
869            Self::VertexIndex => write!(f, "vertex_index"),
870            Self::InstanceIndex => write!(f, "instance_index"),
871            Self::ClipDistances => write!(f, "clip_distances"),
872            Self::Position => write!(f, "position"),
873            Self::FrontFacing => write!(f, "front_facing"),
874            Self::FragDepth => write!(f, "frag_depth"),
875            Self::SampleIndex => write!(f, "sample_index"),
876            Self::SampleMask => write!(f, "sample_mask"),
877            Self::LocalInvocationId => write!(f, "local_invocation_id"),
878            Self::LocalInvocationIndex => write!(f, "local_invocation_index"),
879            Self::GlobalInvocationId => write!(f, "global_invocation_id"),
880            Self::WorkgroupId => write!(f, "workgroup_id"),
881            Self::NumWorkgroups => write!(f, "num_workgroups"),
882            Self::SubgroupInvocationId => write!(f, "subgroup_invocation_id"),
883            Self::SubgroupSize => write!(f, "subgroup_size"),
884            #[cfg(feature = "naga-ext")]
885            Self::SubgroupId => write!(f, "subgroup_id"),
886            #[cfg(feature = "naga-ext")]
887            Self::NumSubgroups => write!(f, "num_subgroups"),
888            #[cfg(feature = "naga-ext")]
889            Self::PrimitiveIndex => write!(f, "primitive_index"),
890            #[cfg(feature = "naga-ext")]
891            Self::ViewIndex => write!(f, "view_index"),
892        }
893    }
894}
895
896impl Display for InterpolationType {
897    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
898        match self {
899            InterpolationType::Perspective => write!(f, "perspective"),
900            InterpolationType::Linear => write!(f, "linear"),
901            InterpolationType::Flat => write!(f, "flat"),
902        }
903    }
904}
905
906impl Display for InterpolationSampling {
907    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
908        match self {
909            Self::Center => write!(f, "center"),
910            Self::Centroid => write!(f, "centroid"),
911            Self::Sample => write!(f, "sample"),
912            Self::First => write!(f, "first"),
913            Self::Either => write!(f, "either"),
914        }
915    }
916}
917
918impl Display for UnaryOperator {
919    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
920        match self {
921            UnaryOperator::LogicalNegation => write!(f, "!"),
922            UnaryOperator::Negation => write!(f, "-"),
923            UnaryOperator::BitwiseComplement => write!(f, "~"),
924            UnaryOperator::AddressOf => write!(f, "&"),
925            UnaryOperator::Indirection => write!(f, "*"),
926        }
927    }
928}
929
930impl Display for BinaryOperator {
931    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
932        match self {
933            BinaryOperator::ShortCircuitOr => write!(f, "||"),
934            BinaryOperator::ShortCircuitAnd => write!(f, "&&"),
935            BinaryOperator::Addition => write!(f, "+"),
936            BinaryOperator::Subtraction => write!(f, "-"),
937            BinaryOperator::Multiplication => write!(f, "*"),
938            BinaryOperator::Division => write!(f, "/"),
939            BinaryOperator::Remainder => write!(f, "%"),
940            BinaryOperator::Equality => write!(f, "=="),
941            BinaryOperator::Inequality => write!(f, "!="),
942            BinaryOperator::LessThan => write!(f, "<"),
943            BinaryOperator::LessThanEqual => write!(f, "<="),
944            BinaryOperator::GreaterThan => write!(f, ">"),
945            BinaryOperator::GreaterThanEqual => write!(f, ">="),
946            BinaryOperator::BitwiseOr => write!(f, "|"),
947            BinaryOperator::BitwiseAnd => write!(f, "&"),
948            BinaryOperator::BitwiseXor => write!(f, "^"),
949            BinaryOperator::ShiftLeft => write!(f, "<<"),
950            BinaryOperator::ShiftRight => write!(f, ">>"),
951        }
952    }
953}
954
955impl Display for AssignmentOperator {
956    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
957        match self {
958            AssignmentOperator::Equal => write!(f, "="),
959            AssignmentOperator::PlusEqual => write!(f, "+="),
960            AssignmentOperator::MinusEqual => write!(f, "-="),
961            AssignmentOperator::TimesEqual => write!(f, "*="),
962            AssignmentOperator::DivisionEqual => write!(f, "/="),
963            AssignmentOperator::ModuloEqual => write!(f, "%="),
964            AssignmentOperator::AndEqual => write!(f, "&="),
965            AssignmentOperator::OrEqual => write!(f, "|="),
966            AssignmentOperator::XorEqual => write!(f, "^="),
967            AssignmentOperator::ShiftRightAssign => write!(f, ">>="),
968            AssignmentOperator::ShiftLeftAssign => write!(f, "<<="),
969        }
970    }
971}
972
973#[cfg(feature = "naga-ext")]
974impl Display for ConservativeDepth {
975    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
976        match self {
977            Self::GreaterEqual => write!(f, "Greater_equal"),
978            Self::LessEqual => write!(f, "less_equal"),
979            Self::Unchanged => write!(f, "unchanged"),
980        }
981    }
982}
983
984impl Display for DiagnosticSeverity {
985    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
986        match self {
987            Self::Error => write!(f, "error"),
988            Self::Warning => write!(f, "warning"),
989            Self::Info => write!(f, "info"),
990            Self::Off => write!(f, "off"),
991        }
992    }
993}
994
995impl Display for SampledType {
996    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
997        match self {
998            SampledType::I32 => write!(f, "i32"),
999            SampledType::U32 => write!(f, "u32"),
1000            SampledType::F32 => write!(f, "f32"),
1001        }
1002    }
1003}