Skip to main content

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