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