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