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