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