Skip to main content

naga/ir/
mod.rs

1/*!
2The Intermediate Representation shared by all frontends and backends.
3
4The central structure of the IR, and the crate, is [`Module`]. A `Module` contains:
5
6- [`Function`]s, which have arguments, a return type, local variables, and a body,
7
8- [`EntryPoint`]s, which are specialized functions that can serve as the entry
9  point for pipeline stages like vertex shading or fragment shading,
10
11- [`Constant`]s and [`GlobalVariable`]s used by `EntryPoint`s and `Function`s, and
12
13- [`Type`]s used by the above.
14
15The body of an `EntryPoint` or `Function` is represented using two types:
16
17- An [`Expression`] produces a value, but has no side effects or control flow.
18  `Expressions` include variable references, unary and binary operators, and so
19  on.
20
21- A [`Statement`] can have side effects and structured control flow.
22  `Statement`s do not produce a value, other than by storing one in some
23  designated place. `Statements` include blocks, conditionals, and loops, but also
24  operations that have side effects, like stores and function calls.
25
26`Statement`s form a tree, with pointers into the DAG of `Expression`s.
27
28Restricting side effects to statements simplifies analysis and code generation.
29A Naga backend can generate code to evaluate an `Expression` however and
30whenever it pleases, as long as it is certain to observe the side effects of all
31previously executed `Statement`s.
32
33Many `Statement` variants use the [`Block`] type, which is `Vec<Statement>`,
34with optional span info, representing a series of statements executed in order. The body of an
35`EntryPoint`s or `Function` is a `Block`, and `Statement` has a
36[`Block`][Statement::Block] variant.
37
38## Function Calls
39
40Naga's representation of function calls is unusual. Most languages treat
41function calls as expressions, but because calls may have side effects, Naga
42represents them as a kind of statement, [`Statement::Call`]. If the function
43returns a value, a call statement designates a particular [`Expression::CallResult`]
44expression to represent its return value, for use by subsequent statements and
45expressions.
46
47## `Expression` evaluation time
48
49It is essential to know when an [`Expression`] should be evaluated, because its
50value may depend on previous [`Statement`]s' effects. But whereas the order of
51execution for a tree of `Statement`s is apparent from its structure, it is not
52so clear for `Expressions`, since an expression may be referred to by any number
53of `Statement`s and other `Expression`s.
54
55Naga's rules for when `Expression`s are evaluated are as follows:
56
57-   [`Literal`], [`Constant`], and [`ZeroValue`] expressions are
58    considered to be implicitly evaluated before execution begins.
59
60-   [`FunctionArgument`] and [`LocalVariable`] expressions are considered
61    implicitly evaluated upon entry to the function to which they belong.
62    Function arguments cannot be assigned to, and `LocalVariable` expressions
63    produce a *pointer to* the variable's value (for use with [`Load`] and
64    [`Store`]). Neither varies while the function executes, so it suffices to
65    consider these expressions evaluated once on entry.
66
67-   Similarly, [`GlobalVariable`] expressions are considered implicitly
68    evaluated before execution begins, since their value does not change while
69    code executes, for one of two reasons:
70
71    -   Most `GlobalVariable` expressions produce a pointer to the variable's
72        value, for use with [`Load`] and [`Store`], as `LocalVariable`
73        expressions do. Although the variable's value may change, its address
74        does not.
75
76    -   A `GlobalVariable` expression referring to a global in the
77        [`AddressSpace::Handle`] address space produces the value directly, not
78        a pointer. Such global variables hold opaque types like shaders or
79        images, and cannot be assigned to.
80
81-   A [`CallResult`] expression that is the `result` of a [`Statement::Call`],
82    representing the call's return value, is evaluated when the `Call` statement
83    is executed.
84
85-   Similarly, an [`AtomicResult`] expression that is the `result` of an
86    [`Atomic`] statement, representing the result of the atomic operation, is
87    evaluated when the `Atomic` statement is executed.
88
89-   A [`RayQueryProceedResult`] expression, which is a boolean
90    indicating if the ray query is finished, is evaluated when the
91    [`RayQuery`] statement whose [`Proceed::result`] points to it is
92    executed.
93
94-   A [`SubgroupBallotResult`] expression is evaluated when the
95    [`SubgroupBallot`] statement whose [`result`][Statement::SubgroupBallot::result]
96    field points to it is executed.
97
98-   A [`SubgroupOperationResult`] expression is evaluated when the
99    [`SubgroupCollectiveOperation`] statement whose
100    [`result`][Statement::SubgroupCollectiveOperation::result]
101    field points to it is executed.
102
103-   All other expressions are evaluated when the (unique) [`Statement::Emit`]
104    statement that covers them is executed.
105
106Now, strictly speaking, not all `Expression` variants actually care when they're
107evaluated. For example, you can evaluate a [`BinaryOperator::Add`] expression
108any time you like, as long as you give it the right operands. It's really only a
109very small set of expressions that are affected by timing:
110
111-   [`Load`], [`ImageSample`], and [`ImageLoad`] expressions are influenced by
112    stores to the variables or images they access, and must execute at the
113    proper time relative to them.
114
115-   [`Derivative`] expressions are sensitive to control flow uniformity: they
116    must not be moved out of an area of uniform control flow into a non-uniform
117    area.
118
119-   More generally, any expression that's used by more than one other expression
120    or statement should probably be evaluated only once, and then stored in a
121    variable to be cited at each point of use.
122
123Naga tries to help back ends handle all these cases correctly in a somewhat
124circuitous way. The [`ModuleInfo`] structure returned by [`Validator::validate`]
125provides a reference count for each expression in each function in the module.
126Naturally, any expression with a reference count of two or more deserves to be
127evaluated and stored in a temporary variable at the point that the `Emit`
128statement covering it is executed. But if we selectively lower the reference
129count threshold to _one_ for the sensitive expression types listed above, so
130that we _always_ generate a temporary variable and save their value, then the
131same code that manages multiply referenced expressions will take care of
132introducing temporaries for time-sensitive expressions as well. The
133`Expression::bake_ref_count` method (private to the back ends) is meant to help
134with this.
135
136## `Expression` scope
137
138Each `Expression` has a *scope*, which is the region of the function within
139which it can be used by `Statement`s and other `Expression`s. It is a validation
140error to use an `Expression` outside its scope.
141
142An expression's scope is defined as follows:
143
144-   The scope of a [`Constant`], [`GlobalVariable`], [`FunctionArgument`] or
145    [`LocalVariable`] expression covers the entire `Function` in which it
146    occurs.
147
148-   The scope of an expression evaluated by an [`Emit`] statement covers the
149    subsequent expressions in that `Emit`, the subsequent statements in the `Block`
150    to which that `Emit` belongs (if any) and their sub-statements (if any).
151
152-   The `result` expression of a [`Call`] or [`Atomic`] statement has a scope
153    covering the subsequent statements in the `Block` in which the statement
154    occurs (if any) and their sub-statements (if any).
155
156For example, this implies that an expression evaluated by some statement in a
157nested `Block` is not available in the `Block`'s parents. Such a value would
158need to be stored in a local variable to be carried upwards in the statement
159tree.
160
161## Constant expressions
162
163A Naga *constant expression* is one of the following [`Expression`]
164variants, whose operands (if any) are also constant expressions:
165- [`Literal`]
166- [`Constant`], for [`Constant`]s
167- [`ZeroValue`], for fixed-size types
168- [`Compose`]
169- [`Access`]
170- [`AccessIndex`]
171- [`Splat`]
172- [`Swizzle`]
173- [`Unary`]
174- [`Binary`]
175- [`Select`]
176- [`Relational`]
177- [`Math`]
178- [`As`]
179
180A constant expression can be evaluated at module translation time.
181
182## Override expressions
183
184A Naga *override expression* is the same as a [constant expression],
185except that it is also allowed to reference other [`Override`]s.
186
187An override expression can be evaluated at pipeline creation time.
188
189[`AtomicResult`]: Expression::AtomicResult
190[`RayQueryProceedResult`]: Expression::RayQueryProceedResult
191[`SubgroupBallotResult`]: Expression::SubgroupBallotResult
192[`SubgroupOperationResult`]: Expression::SubgroupOperationResult
193[`CallResult`]: Expression::CallResult
194[`Constant`]: Expression::Constant
195[`ZeroValue`]: Expression::ZeroValue
196[`Literal`]: Expression::Literal
197[`Derivative`]: Expression::Derivative
198[`FunctionArgument`]: Expression::FunctionArgument
199[`GlobalVariable`]: Expression::GlobalVariable
200[`ImageLoad`]: Expression::ImageLoad
201[`ImageSample`]: Expression::ImageSample
202[`Load`]: Expression::Load
203[`LocalVariable`]: Expression::LocalVariable
204
205[`Atomic`]: Statement::Atomic
206[`Call`]: Statement::Call
207[`Emit`]: Statement::Emit
208[`Store`]: Statement::Store
209[`RayQuery`]: Statement::RayQuery
210[`SubgroupBallot`]: Statement::SubgroupBallot
211[`SubgroupCollectiveOperation`]: Statement::SubgroupCollectiveOperation
212
213[`Proceed::result`]: RayQueryFunction::Proceed::result
214
215[`Validator::validate`]: crate::valid::Validator::validate
216[`ModuleInfo`]: crate::valid::ModuleInfo
217
218[`Literal`]: Expression::Literal
219[`ZeroValue`]: Expression::ZeroValue
220[`Compose`]: Expression::Compose
221[`Access`]: Expression::Access
222[`AccessIndex`]: Expression::AccessIndex
223[`Splat`]: Expression::Splat
224[`Swizzle`]: Expression::Swizzle
225[`Unary`]: Expression::Unary
226[`Binary`]: Expression::Binary
227[`Select`]: Expression::Select
228[`Relational`]: Expression::Relational
229[`Math`]: Expression::Math
230[`As`]: Expression::As
231
232[constant expression]: #constant-expressions
233*/
234
235mod block;
236
237use alloc::{boxed::Box, string::String, vec::Vec};
238
239#[cfg(feature = "arbitrary")]
240use arbitrary::Arbitrary;
241use half::f16;
242#[cfg(feature = "deserialize")]
243use serde::Deserialize;
244#[cfg(feature = "serialize")]
245use serde::Serialize;
246
247use crate::arena::{Arena, Handle, Range, UniqueArena};
248use crate::diagnostic_filter::DiagnosticFilterNode;
249use crate::{FastIndexMap, NamedExpressions};
250
251pub use block::Block;
252pub use naga_types::{ResourceBinding, ShaderStage};
253
254/// Explicitly allows early depth/stencil tests.
255///
256/// Normally, depth/stencil tests are performed after fragment shading. However, as an optimization,
257/// most drivers will move the depth/stencil tests before fragment shading if this does not
258/// have any observable consequences. This optimization is disabled under the following
259/// circumstances:
260///   - `discard` is called in the fragment shader.
261///   - The fragment shader writes to the depth buffer.
262///   - The fragment shader writes to any storage bindings.
263///
264/// When `EarlyDepthTest` is set, it is allowed to perform an early depth/stencil test even if the
265/// above conditions are not met. When [`EarlyDepthTest::Force`] is used, depth/stencil tests
266/// **must** be performed before fragment shading.
267///
268/// To force early depth/stencil tests in a shader:
269///   - GLSL: `layout(early_fragment_tests) in;`
270///   - HLSL: `Attribute earlydepthstencil`
271///   - SPIR-V: `ExecutionMode EarlyFragmentTests`
272///   - WGSL: `@early_depth_test(force)`
273///
274/// This may also be enabled in a shader by specifying a [`ConservativeDepth`].
275///
276/// For more, see:
277///   - <https://www.khronos.org/opengl/wiki/Early_Fragment_Test#Explicit_specification>
278///   - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-earlydepthstencil>
279///   - <https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Execution_Mode>
280#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
281#[cfg_attr(feature = "serialize", derive(Serialize))]
282#[cfg_attr(feature = "deserialize", derive(Deserialize))]
283#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
284pub enum EarlyDepthTest {
285    /// Requires depth/stencil tests to be performed before fragment shading.
286    ///
287    /// This will disable depth/stencil tests after fragment shading, so discarding the fragment
288    /// or overwriting the fragment depth will have no effect.
289    Force,
290
291    /// Allows an additional depth/stencil test to be performed before fragment shading.
292    ///
293    /// It is up to the driver to decide whether early tests are performed. Unlike `Force`, this
294    /// does not disable depth/stencil tests after fragment shading.
295    Allow {
296        /// Specifies restrictions on how the depth value can be modified within the fragment
297        /// shader.
298        ///
299        /// This may be taken into account when deciding whether to perform early tests.
300        conservative: ConservativeDepth,
301    },
302}
303
304/// Enables adjusting depth without disabling early Z.
305///
306/// To use in a shader:
307///   - GLSL: `layout (depth_<greater/less/unchanged/any>) out float gl_FragDepth;`
308///     - `depth_any` option behaves as if the layout qualifier was not present.
309///   - HLSL: `SV_DepthGreaterEqual`/`SV_DepthLessEqual`/`SV_Depth`
310///   - SPIR-V: `ExecutionMode Depth<Greater/Less/Unchanged>`
311///   - WGSL: `@early_depth_test(greater_equal/less_equal/unchanged)`
312///
313/// For more, see:
314///   - <https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_conservative_depth.txt>
315///   - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics>
316///   - <https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Execution_Mode>
317#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
318#[cfg_attr(feature = "serialize", derive(Serialize))]
319#[cfg_attr(feature = "deserialize", derive(Deserialize))]
320#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
321pub enum ConservativeDepth {
322    /// Shader may rewrite depth only with a value greater than calculated.
323    GreaterEqual,
324
325    /// Shader may rewrite depth smaller than one that would have been written without the modification.
326    LessEqual,
327
328    /// Shader may not rewrite depth value.
329    Unchanged,
330}
331
332/// Addressing space of variables.
333#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
334#[cfg_attr(feature = "serialize", derive(Serialize))]
335#[cfg_attr(feature = "deserialize", derive(Deserialize))]
336#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
337pub enum AddressSpace {
338    /// Function locals.
339    Function,
340    /// Private data, per invocation, mutable.
341    Private,
342    /// Workgroup shared data, mutable.
343    WorkGroup,
344    /// Uniform buffer data.
345    Uniform,
346    /// Storage buffer data, potentially mutable.
347    Storage { access: StorageAccess },
348    /// Opaque handles, such as samplers and images.
349    Handle,
350
351    /// Immediate data.
352    ///
353    /// A [`Module`] may contain at most one [`GlobalVariable`] in
354    /// this address space. Its contents are provided not by a buffer
355    /// but by `SetImmediates` pass commands, allowing the CPU to
356    /// establish different values for each draw/dispatch.
357    ///
358    /// `Immediate` variables may not contain `f16` values, even if
359    /// the [`SHADER_FLOAT16`] capability is enabled.
360    ///
361    /// Backends generally place tight limits on the size of
362    /// `Immediate` variables.
363    ///
364    /// [`SHADER_FLOAT16`]: crate::valid::Capabilities::SHADER_FLOAT16
365    Immediate,
366    /// Task shader to mesh shader payload
367    TaskPayload,
368
369    /// Ray tracing payload, for inputting in TraceRays
370    RayPayload,
371    /// Ray tracing payload, for entrypoints invoked by a TraceRays call
372    ///
373    /// Each entrypoint may reference only one variable in this scope, as
374    /// only one may be passed as a payload.
375    IncomingRayPayload,
376}
377
378/// Built-in inputs and outputs.
379#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
380#[cfg_attr(feature = "serialize", derive(Serialize))]
381#[cfg_attr(feature = "deserialize", derive(Deserialize))]
382#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
383pub enum BuiltIn {
384    // This must be at the top so that it gets sorted to the top. PrimitiveIndex is considered a non SV
385    // by FXC so it must appear before any other SVs.
386    /// Read in fragment shaders, written in mesh shaders, read in any and closest hit shaders.
387    PrimitiveIndex,
388
389    /// Written in vertex/mesh shaders, read in fragment shaders
390    Position { invariant: bool },
391    /// Read in task, mesh, vertex, and fragment shaders
392    ViewIndex,
393
394    /// Read in vertex shaders
395    BaseInstance,
396    /// Read in vertex shaders
397    BaseVertex,
398    /// Written in vertex & mesh shaders
399    ClipDistances,
400    /// Written in vertex & mesh shaders
401    CullDistance,
402    /// Read in vertex, any- and closest-hit shaders
403    InstanceIndex,
404    /// Written in vertex & mesh shaders
405    PointSize,
406    /// Read in vertex shaders
407    VertexIndex,
408    /// Read in vertex & task shaders, or mesh shaders in pipelines without task shaders
409    DrawIndex,
410
411    /// Written in fragment shaders
412    FragDepth,
413    /// Read in fragment shaders
414    PointCoord,
415    /// Read in fragment shaders
416    FrontFacing,
417    /// Read in fragment shaders
418    Barycentric { perspective: bool },
419    /// Read in fragment shaders
420    SampleIndex,
421    /// Read or written in fragment shaders
422    SampleMask,
423
424    /// Read in compute, task, and mesh shaders
425    GlobalInvocationId,
426    /// Read in compute, task, and mesh shaders
427    LocalInvocationId,
428    /// Read in compute, task, and mesh shaders
429    LocalInvocationIndex,
430    /// Read in compute, task, and mesh shaders
431    WorkGroupId,
432    /// Read in compute, task, and mesh shaders
433    WorkGroupSize,
434    /// Read in compute, task, and mesh shaders
435    NumWorkGroups,
436
437    /// Read in compute, task, and mesh shaders
438    NumSubgroups,
439    /// Read in compute, task, and mesh shaders
440    SubgroupId,
441    /// Read in compute, fragment, task, and mesh shaders
442    SubgroupSize,
443    /// Read in compute, fragment, task, and mesh shaders
444    SubgroupInvocationId,
445
446    /// Written in task shaders
447    MeshTaskSize,
448    /// Written in mesh shaders
449    CullPrimitive,
450    /// Written in mesh shaders
451    PointIndex,
452    /// Written in mesh shaders
453    LineIndices,
454    /// Written in mesh shaders
455    TriangleIndices,
456
457    /// Written to a workgroup variable in mesh shaders
458    VertexCount,
459    /// Written to a workgroup variable in mesh shaders
460    Vertices,
461    /// Written to a workgroup variable in mesh shaders
462    PrimitiveCount,
463    /// Written to a workgroup variable in mesh shaders
464    Primitives,
465
466    /// Read in all ray tracing pipeline shaders, the id within the number of
467    /// rays that this current ray is.
468    RayInvocationId,
469    /// Read in all ray tracing pipeline shaders, the number of rays created.
470    NumRayInvocations,
471    /// Read in closest hit and any hit shaders, the custom data in the tlas
472    /// instance
473    InstanceCustomData,
474    /// Read in closest hit and any hit shaders, the index of the geometry in
475    /// the blas.
476    GeometryIndex,
477    /// Read in closest hit, any hit, and miss shaders, the origin of the ray.
478    WorldRayOrigin,
479    /// Read in closest hit, any hit, and miss shaders, the direction of the
480    /// ray.
481    WorldRayDirection,
482    /// Read in closest hit and any hit shaders, the direction of the ray in
483    /// object space.
484    ObjectRayOrigin,
485    /// Read in closest hit and any hit shaders, the direction of the ray in
486    /// object space.
487    ObjectRayDirection,
488    /// Read in closest hit, any hit, and miss shaders, the t min provided by
489    /// in the ray desc.
490    RayTmin,
491    /// Read in closest hit, any hit, and miss shaders, the final bounds at which
492    /// a hit is accepted (the closest committed hit if there is one otherwise, t
493    /// max provided in the ray desc).
494    RayTCurrentMax,
495    /// Read in closest hit and any hit shaders, the matrix for converting from
496    /// object space to world space
497    ObjectToWorld,
498    /// Read in closest hit and any hit shaders, the matrix for converting from
499    /// world space to object space
500    WorldToObject,
501    /// Read in closest hit and any hit shaders, the type of hit as provided by
502    /// the intersection function if any, otherwise this is 254 (0xFE) for a
503    /// front facing triangle and 255 (0xFF) for a back facing triangle
504    HitKind,
505    /// Read in closest hit and any hit shaders, the second and third barycentric
506    /// coordinates of the hit point on the triangle. The first can be computed as
507    /// `1.0 - x - y`. Only meaningful if the hit was a triangle.
508    HitBarycentrics,
509}
510
511/// Number of bytes per scalar.
512pub type Bytes = u8;
513
514/// Number of components in a vector.
515#[repr(u8)]
516#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
517#[cfg_attr(feature = "serialize", derive(Serialize))]
518#[cfg_attr(feature = "deserialize", derive(Deserialize))]
519#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
520pub enum VectorSize {
521    /// 2D vector
522    Bi = 2,
523    /// 3D vector
524    Tri = 3,
525    /// 4D vector
526    Quad = 4,
527}
528
529impl VectorSize {
530    pub const MAX: usize = Self::Quad as usize;
531}
532
533impl From<VectorSize> for u8 {
534    fn from(size: VectorSize) -> u8 {
535        size as u8
536    }
537}
538
539impl From<VectorSize> for u32 {
540    fn from(size: VectorSize) -> u32 {
541        size as u32
542    }
543}
544
545/// Number of components in a cooperative vector.
546#[repr(u8)]
547#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
548#[cfg_attr(feature = "serialize", derive(Serialize))]
549#[cfg_attr(feature = "deserialize", derive(Deserialize))]
550#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
551pub enum CooperativeSize {
552    Eight = 8,
553    Sixteen = 16,
554}
555
556/// Primitive type for a scalar.
557#[repr(u8)]
558#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
559#[cfg_attr(feature = "serialize", derive(Serialize))]
560#[cfg_attr(feature = "deserialize", derive(Deserialize))]
561#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
562pub enum ScalarKind {
563    /// Signed integer type.
564    Sint,
565    /// Unsigned integer type.
566    Uint,
567    /// Floating point type.
568    Float,
569    /// Boolean type.
570    Bool,
571
572    /// WGSL abstract integer type.
573    ///
574    /// These are forbidden by validation, and should never reach backends.
575    AbstractInt,
576
577    /// Abstract floating-point type.
578    ///
579    /// These are forbidden by validation, and should never reach backends.
580    AbstractFloat,
581}
582
583/// Role of a cooperative variable in the equation "A * B + C"
584#[repr(u8)]
585#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
586#[cfg_attr(feature = "serialize", derive(Serialize))]
587#[cfg_attr(feature = "deserialize", derive(Deserialize))]
588#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
589pub enum CooperativeRole {
590    A,
591    B,
592    C,
593}
594
595/// Characteristics of a scalar type.
596#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
597#[cfg_attr(feature = "serialize", derive(Serialize))]
598#[cfg_attr(feature = "deserialize", derive(Deserialize))]
599#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
600pub struct Scalar {
601    /// How the value's bits are to be interpreted.
602    pub kind: ScalarKind,
603
604    /// This size of the value in bytes.
605    pub width: Bytes,
606}
607
608/// Size of an array.
609#[repr(u8)]
610#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
611#[cfg_attr(feature = "serialize", derive(Serialize))]
612#[cfg_attr(feature = "deserialize", derive(Deserialize))]
613#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
614pub enum ArraySize {
615    /// The array size is constant.
616    Constant(core::num::NonZeroU32),
617    /// The array size is an override-expression.
618    Pending(Handle<Override>),
619    /// The array size can change at runtime.
620    Dynamic,
621}
622
623/// The interpolation qualifier of a binding or struct field.
624#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
625#[cfg_attr(feature = "serialize", derive(Serialize))]
626#[cfg_attr(feature = "deserialize", derive(Deserialize))]
627#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
628pub enum Interpolation {
629    /// The value will be interpolated in a perspective-correct fashion.
630    /// Also known as "smooth" in glsl.
631    Perspective,
632    /// Indicates that linear, non-perspective, correct
633    /// interpolation must be used.
634    /// Also known as "no_perspective" in glsl.
635    Linear,
636    /// Indicates that no interpolation will be performed.
637    Flat,
638    /// Indicates the fragment input binding holds an array of per-vertex values.
639    /// This is typically used with barycentrics.
640    PerVertex,
641}
642
643/// The sampling qualifiers of a binding or struct field.
644#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
645#[cfg_attr(feature = "serialize", derive(Serialize))]
646#[cfg_attr(feature = "deserialize", derive(Deserialize))]
647#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
648pub enum Sampling {
649    /// Interpolate the value at the center of the pixel.
650    Center,
651
652    /// Interpolate the value at a point that lies within all samples covered by
653    /// the fragment within the current primitive. In multisampling, use a
654    /// single value for all samples in the primitive.
655    Centroid,
656
657    /// Interpolate the value at each sample location. In multisampling, invoke
658    /// the fragment shader once per sample.
659    Sample,
660
661    /// Use the value provided by the first vertex of the current primitive.
662    First,
663
664    /// Use the value provided by the first or last vertex of the current primitive. The exact
665    /// choice is implementation-dependent.
666    Either,
667}
668
669/// Member of a user-defined structure.
670// Clone is used only for error reporting and is not intended for end users
671#[derive(Clone, Debug, Eq, Hash, PartialEq)]
672#[cfg_attr(feature = "serialize", derive(Serialize))]
673#[cfg_attr(feature = "deserialize", derive(Deserialize))]
674#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
675pub struct StructMember {
676    pub name: Option<String>,
677    /// Type of the field.
678    pub ty: Handle<Type>,
679    /// For I/O structs, defines the binding.
680    pub binding: Option<Binding>,
681    /// Offset from the beginning from the struct.
682    pub offset: u32,
683}
684
685/// The number of dimensions an image has.
686#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
687#[cfg_attr(feature = "serialize", derive(Serialize))]
688#[cfg_attr(feature = "deserialize", derive(Deserialize))]
689#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
690pub enum ImageDimension {
691    /// 1D image
692    D1,
693    /// 2D image
694    D2,
695    /// 3D image
696    D3,
697    /// Cube map
698    Cube,
699}
700
701bitflags::bitflags! {
702    /// Flags describing an image.
703    #[cfg_attr(feature = "serialize", derive(Serialize))]
704    #[cfg_attr(feature = "deserialize", derive(Deserialize))]
705    #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
706    #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
707    pub struct StorageAccess: u32 {
708        /// Storage can be used as a source for load ops.
709        const LOAD = 0x1;
710        /// Storage can be used as a target for store ops.
711        const STORE = 0x2;
712        /// Storage can be used as a target for atomic ops.
713        const ATOMIC = 0x4;
714    }
715}
716
717bitflags::bitflags! {
718    /// Memory decorations for global variables.
719    #[cfg_attr(feature = "serialize", derive(Serialize))]
720    #[cfg_attr(feature = "deserialize", derive(Deserialize))]
721    #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
722    #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
723    pub struct MemoryDecorations: u8 {
724        /// Reads and writes are automatically visible to other invocations
725        /// without explicit barriers.
726        const COHERENT = 0x1;
727        /// The variable may be modified by something external to the shader,
728        /// preventing certain compiler optimizations.
729        const VOLATILE = 0x2;
730    }
731}
732
733/// Image storage format.
734#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
735#[cfg_attr(feature = "serialize", derive(Serialize))]
736#[cfg_attr(feature = "deserialize", derive(Deserialize))]
737#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
738pub enum StorageFormat {
739    // 8-bit formats
740    R8Unorm,
741    R8Snorm,
742    R8Uint,
743    R8Sint,
744
745    // 16-bit formats
746    R16Uint,
747    R16Sint,
748    R16Float,
749    Rg8Unorm,
750    Rg8Snorm,
751    Rg8Uint,
752    Rg8Sint,
753
754    // 32-bit formats
755    R32Uint,
756    R32Sint,
757    R32Float,
758    Rg16Uint,
759    Rg16Sint,
760    Rg16Float,
761    Rgba8Unorm,
762    Rgba8Snorm,
763    Rgba8Uint,
764    Rgba8Sint,
765    Bgra8Unorm,
766
767    // Packed 32-bit formats
768    Rgb10a2Uint,
769    Rgb10a2Unorm,
770    Rg11b10Ufloat,
771
772    // 64-bit formats
773    R64Uint,
774    Rg32Uint,
775    Rg32Sint,
776    Rg32Float,
777    Rgba16Uint,
778    Rgba16Sint,
779    Rgba16Float,
780
781    // 128-bit formats
782    Rgba32Uint,
783    Rgba32Sint,
784    Rgba32Float,
785
786    // Normalized 16-bit per channel formats
787    R16Unorm,
788    R16Snorm,
789    Rg16Unorm,
790    Rg16Snorm,
791    Rgba16Unorm,
792    Rgba16Snorm,
793}
794
795/// Sub-class of the image type.
796#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
797#[cfg_attr(feature = "serialize", derive(Serialize))]
798#[cfg_attr(feature = "deserialize", derive(Deserialize))]
799#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
800pub enum ImageClass {
801    /// Regular sampled image.
802    Sampled {
803        /// Kind of values to sample.
804        kind: ScalarKind,
805        /// Multi-sampled image.
806        ///
807        /// A multi-sampled image holds several samples per texel. Multi-sampled
808        /// images cannot have mipmaps.
809        multi: bool,
810    },
811    /// Depth comparison image.
812    Depth {
813        /// Multi-sampled depth image.
814        multi: bool,
815    },
816    /// External texture.
817    External,
818    /// Storage image.
819    Storage {
820        format: StorageFormat,
821        access: StorageAccess,
822    },
823}
824
825/// A data type declared in the module.
826#[derive(Clone, Debug, Eq, Hash, PartialEq)]
827#[cfg_attr(feature = "serialize", derive(Serialize))]
828#[cfg_attr(feature = "deserialize", derive(Deserialize))]
829#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
830pub struct Type {
831    /// The name of the type, if any.
832    pub name: Option<String>,
833    /// Inner structure that depends on the kind of the type.
834    pub inner: TypeInner,
835}
836
837/// Enum with additional information, depending on the kind of type.
838///
839/// Comparison using `==` is not reliable in the case of [`Pointer`],
840/// [`ValuePointer`], or [`Struct`] variants. For these variants,
841/// use [`TypeInner::non_struct_equivalent`] or [`compare_types`].
842///
843/// [`compare_types`]: crate::proc::compare_types
844/// [`ValuePointer`]: TypeInner::ValuePointer
845/// [`Pointer`]: TypeInner::Pointer
846/// [`Struct`]: TypeInner::Struct
847#[derive(Clone, Debug, Eq, Hash, PartialEq)]
848#[cfg_attr(feature = "serialize", derive(Serialize))]
849#[cfg_attr(feature = "deserialize", derive(Deserialize))]
850#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
851pub enum TypeInner {
852    /// Number of integral or floating-point kind.
853    Scalar(Scalar),
854    /// Vector of numbers.
855    Vector { size: VectorSize, scalar: Scalar },
856    /// Matrix of numbers.
857    Matrix {
858        columns: VectorSize,
859        rows: VectorSize,
860        scalar: Scalar,
861    },
862    /// Matrix that is cooperatively processed by all the threads
863    /// in an opaque mapping.
864    CooperativeMatrix {
865        columns: CooperativeSize,
866        rows: CooperativeSize,
867        scalar: Scalar,
868        role: CooperativeRole,
869    },
870    /// Atomic scalar.
871    Atomic(Scalar),
872    /// Pointer to another type.
873    ///
874    /// Pointers to scalars and vectors should be treated as equivalent to
875    /// [`ValuePointer`] types. Use either [`TypeInner::non_struct_equivalent`]
876    /// or [`compare_types`] to compare types in a way that treats pointers
877    /// correctly.
878    ///
879    /// ## Pointers to non-`SIZED` types
880    ///
881    /// The `base` type of a pointer may be a non-[`SIZED`] type like a
882    /// dynamically-sized [`Array`], or a [`Struct`] whose last member is a
883    /// dynamically sized array. Such pointers occur as the types of
884    /// [`GlobalVariable`] or [`AccessIndex`] expressions referring to
885    /// dynamically-sized arrays.
886    ///
887    /// However, among pointers to non-`SIZED` types, only pointers to `Struct`s
888    /// are [`DATA`]. Pointers to dynamically sized `Array`s cannot be passed as
889    /// arguments, stored in variables, or held in arrays or structures. Their
890    /// only use is as the types of `AccessIndex` expressions.
891    ///
892    /// [`SIZED`]: crate::valid::TypeFlags::SIZED
893    /// [`DATA`]: crate::valid::TypeFlags::DATA
894    /// [`Array`]: TypeInner::Array
895    /// [`Struct`]: TypeInner::Struct
896    /// [`ValuePointer`]: TypeInner::ValuePointer
897    /// [`GlobalVariable`]: Expression::GlobalVariable
898    /// [`AccessIndex`]: Expression::AccessIndex
899    /// [`compare_types`]: crate::proc::compare_types
900    Pointer {
901        base: Handle<Type>,
902        space: AddressSpace,
903    },
904
905    /// Pointer to a scalar or vector.
906    ///
907    /// A `ValuePointer` type is equivalent to a `Pointer` whose `base` is a
908    /// `Scalar` or `Vector` type. This is for use in [`TypeResolution::Value`]
909    /// variants; see the documentation for [`TypeResolution`] for details.
910    ///
911    /// Use [`TypeInner::non_struct_equivalent`] or [`compare_types`] to compare
912    /// types that could be pointers, to ensure that `Pointer` and
913    /// `ValuePointer` types are recognized as equivalent.
914    ///
915    /// [`TypeResolution`]: crate::proc::TypeResolution
916    /// [`TypeResolution::Value`]: crate::proc::TypeResolution::Value
917    /// [`compare_types`]: crate::proc::compare_types
918    ValuePointer {
919        size: Option<VectorSize>,
920        scalar: Scalar,
921        space: AddressSpace,
922    },
923
924    /// Homogeneous list of elements.
925    ///
926    /// The `base` type must be a [`SIZED`], [`DATA`] type.
927    ///
928    /// ## Dynamically sized arrays
929    ///
930    /// An `Array` is [`SIZED`] unless its `size` is [`Dynamic`].
931    /// Dynamically-sized arrays may only appear in a few situations:
932    ///
933    /// -   They may appear as the type of a [`GlobalVariable`], or as the last
934    ///     member of a [`Struct`].
935    ///
936    /// -   They may appear as the base type of a [`Pointer`]. An
937    ///     [`AccessIndex`] expression referring to a struct's final
938    ///     unsized array member would have such a pointer type. However, such
939    ///     pointer types may only appear as the types of such intermediate
940    ///     expressions. They are not [`DATA`], and cannot be stored in
941    ///     variables, held in arrays or structs, or passed as parameters.
942    ///
943    /// [`SIZED`]: crate::valid::TypeFlags::SIZED
944    /// [`DATA`]: crate::valid::TypeFlags::DATA
945    /// [`Dynamic`]: ArraySize::Dynamic
946    /// [`Struct`]: TypeInner::Struct
947    /// [`Pointer`]: TypeInner::Pointer
948    /// [`AccessIndex`]: Expression::AccessIndex
949    Array {
950        base: Handle<Type>,
951        size: ArraySize,
952        stride: u32,
953    },
954
955    /// User-defined structure.
956    ///
957    /// There must always be at least one member.
958    ///
959    /// A `Struct` type is [`DATA`], and the types of its members must be
960    /// `DATA` as well.
961    ///
962    /// Member types must be [`SIZED`], except for the final member of a
963    /// struct, which may be a dynamically sized [`Array`]. The
964    /// `Struct` type itself is `SIZED` when all its members are `SIZED`.
965    ///
966    /// Two structure types with different names are not equivalent. Because
967    /// this variant does not contain the name, it is not possible to use it
968    /// to compare struct types. Use [`compare_types`] to compare two types
969    /// that may be structs.
970    ///
971    /// [`DATA`]: crate::valid::TypeFlags::DATA
972    /// [`SIZED`]: crate::∅TypeFlags::SIZED
973    /// [`Array`]: TypeInner::Array
974    /// [`compare_types`]: crate::proc::compare_types
975    Struct {
976        members: Vec<StructMember>,
977        //TODO: should this be unaligned?
978        span: u32,
979    },
980    /// Possibly multidimensional array of texels.
981    Image {
982        dim: ImageDimension,
983        arrayed: bool,
984        //TODO: consider moving `multisampled: bool` out
985        class: ImageClass,
986    },
987    /// Can be used to sample values from images.
988    Sampler { comparison: bool },
989
990    /// Opaque object representing an acceleration structure of geometry.
991    AccelerationStructure { vertex_return: bool },
992
993    /// Locally used handle for ray queries.
994    RayQuery { vertex_return: bool },
995
996    /// Array of bindings.
997    ///
998    /// A `BindingArray` represents an array where each element draws its value
999    /// from a separate bound resource. The array's element type `base` may be
1000    /// [`Image`], [`Sampler`], or any type that would be permitted for a global
1001    /// in the [`Uniform`] or [`Storage`] address spaces. Only global variables
1002    /// may be binding arrays; on the host side, their values are provided by
1003    /// [`TextureViewArray`], [`SamplerArray`], or [`BufferArray`]
1004    /// bindings.
1005    ///
1006    /// Since each element comes from a distinct resource, a binding array of
1007    /// images could have images of varying sizes (but not varying dimensions;
1008    /// they must all have the same `Image` type). Or, a binding array of
1009    /// buffers could have elements that are dynamically sized arrays, each with
1010    /// a different length.
1011    ///
1012    /// Binding arrays are in the same address spaces as their underlying type.
1013    /// As such, referring to an array of images produces an [`Image`] value
1014    /// directly (as opposed to a pointer). The only operation permitted on
1015    /// `BindingArray` values is indexing, which works transparently: indexing
1016    /// a binding array of samplers yields a [`Sampler`], indexing a pointer to the
1017    /// binding array of storage buffers produces a pointer to the storage struct.
1018    ///
1019    /// Unlike textures and samplers, binding arrays are not [`ARGUMENT`], so
1020    /// they cannot be passed as arguments to functions.
1021    ///
1022    /// Naga's WGSL front end supports binding arrays with the type syntax
1023    /// `binding_array<T, N>`.
1024    ///
1025    /// [`Image`]: TypeInner::Image
1026    /// [`Sampler`]: TypeInner::Sampler
1027    /// [`Uniform`]: AddressSpace::Uniform
1028    /// [`Storage`]: AddressSpace::Storage
1029    /// [`TextureViewArray`]: https://docs.rs/wgpu/latest/wgpu/enum.BindingResource.html#variant.TextureViewArray
1030    /// [`SamplerArray`]: https://docs.rs/wgpu/latest/wgpu/enum.BindingResource.html#variant.SamplerArray
1031    /// [`BufferArray`]: https://docs.rs/wgpu/latest/wgpu/enum.BindingResource.html#variant.BufferArray
1032    /// [`DATA`]: crate::valid::TypeFlags::DATA
1033    /// [`ARGUMENT`]: crate::valid::TypeFlags::ARGUMENT
1034    /// [naga#1864]: https://github.com/gfx-rs/naga/issues/1864
1035    BindingArray { base: Handle<Type>, size: ArraySize },
1036}
1037
1038#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
1039#[cfg_attr(feature = "serialize", derive(Serialize))]
1040#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1041#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1042pub enum Literal {
1043    /// May not be NaN or infinity.
1044    F64(f64),
1045    /// May not be NaN or infinity.
1046    F32(f32),
1047    /// May not be NaN or infinity.
1048    F16(f16),
1049    U16(u16),
1050    I16(i16),
1051    U32(u32),
1052    I32(i32),
1053    U64(u64),
1054    I64(i64),
1055    Bool(bool),
1056    AbstractInt(i64),
1057    AbstractFloat(f64),
1058}
1059
1060/// Pipeline-overridable constant.
1061#[derive(Clone, Debug, PartialEq)]
1062#[cfg_attr(feature = "serialize", derive(Serialize))]
1063#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1064#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1065pub struct Override {
1066    pub name: Option<String>,
1067    /// Pipeline Constant ID.
1068    pub id: Option<u16>,
1069    pub ty: Handle<Type>,
1070
1071    /// The default value of the pipeline-overridable constant.
1072    ///
1073    /// This [`Handle`] refers to [`Module::global_expressions`], not
1074    /// any [`Function::expressions`] arena.
1075    pub init: Option<Handle<Expression>>,
1076}
1077
1078/// Constant value.
1079#[derive(Clone, Debug, PartialEq)]
1080#[cfg_attr(feature = "serialize", derive(Serialize))]
1081#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1082#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1083pub struct Constant {
1084    pub name: Option<String>,
1085    pub ty: Handle<Type>,
1086
1087    /// The value of the constant.
1088    ///
1089    /// This [`Handle`] refers to [`Module::global_expressions`], not
1090    /// any [`Function::expressions`] arena.
1091    pub init: Handle<Expression>,
1092}
1093
1094/// Describes how an input/output variable is to be bound.
1095#[derive(Clone, Debug, Eq, PartialEq, Hash)]
1096#[cfg_attr(feature = "serialize", derive(Serialize))]
1097#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1098#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1099pub enum Binding {
1100    /// Built-in shader variable.
1101    BuiltIn(BuiltIn),
1102
1103    /// Indexed location.
1104    ///
1105    /// This is a value passed to a [`Fragment`] shader from a [`Vertex`] or
1106    /// [`Mesh`] shader.
1107    ///
1108    /// Values passed from the [`Vertex`] stage to the [`Fragment`] stage must
1109    /// have their `interpolation` defaulted (i.e. not `None`) by the front end
1110    /// as appropriate for that language.
1111    ///
1112    /// For other stages, we permit interpolations even though they're ignored.
1113    /// When a front end is parsing a struct type, it usually doesn't know what
1114    /// stages will be using it for IO, so it's easiest if it can apply the
1115    /// defaults to anything with a `Location` binding, just in case.
1116    ///
1117    /// For anything other than floating-point scalars and vectors, the
1118    /// interpolation must be `Flat`.
1119    ///
1120    /// [`Vertex`]: crate::ShaderStage::Vertex
1121    /// [`Mesh`]: crate::ShaderStage::Mesh
1122    /// [`Fragment`]: crate::ShaderStage::Fragment
1123    Location {
1124        location: u32,
1125        interpolation: Option<Interpolation>,
1126        sampling: Option<Sampling>,
1127
1128        /// Optional `blend_src` index used for dual source blending.
1129        /// See <https://www.w3.org/TR/WGSL/#attribute-blend_src>
1130        blend_src: Option<u32>,
1131
1132        /// Whether the binding is a per-primitive binding for use with mesh shaders.
1133        ///
1134        /// This must be `true` if this binding is a mesh shader primitive output, or such
1135        /// an output's corresponding fragment shader input. It must be `false` otherwise.
1136        ///
1137        /// A stage's outputs must all have unique `location` numbers, regardless of
1138        /// whether they are per-primitive; a mesh shader's per-vertex and per-primitive
1139        /// outputs share the same location numbering space.
1140        ///
1141        /// Per-primitive values are not interpolated at all and are not dependent on the
1142        /// vertices or pixel location. For example, it may be used to store a
1143        /// non-interpolated normal vector.
1144        per_primitive: bool,
1145    },
1146}
1147
1148/// Variable defined at module level.
1149#[derive(Clone, Debug, PartialEq)]
1150#[cfg_attr(feature = "serialize", derive(Serialize))]
1151#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1152#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1153pub struct GlobalVariable {
1154    /// Name of the variable, if any.
1155    pub name: Option<String>,
1156    /// How this variable is to be stored.
1157    pub space: AddressSpace,
1158    /// For resources, defines the binding point.
1159    pub binding: Option<ResourceBinding>,
1160    /// The type of this variable.
1161    pub ty: Handle<Type>,
1162    /// Initial value for this variable.
1163    ///
1164    /// This refers to an [`Expression`] in [`Module::global_expressions`].
1165    pub init: Option<Handle<Expression>>,
1166    /// Memory decorations for this variable.
1167    ///
1168    /// These are meaningful for storage address space variables in SPIR-V,
1169    /// where they map to SPIR-V memory decorations on the variable.
1170    ///
1171    /// In WGSL, these can be set with attributes like `@coherent` or `@volatile`.
1172    pub memory_decorations: MemoryDecorations,
1173}
1174
1175/// Variable defined at function level.
1176#[derive(Clone, Debug)]
1177#[cfg_attr(feature = "serialize", derive(Serialize))]
1178#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1179#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1180pub struct LocalVariable {
1181    /// Name of the variable, if any.
1182    pub name: Option<String>,
1183    /// The type of this variable.
1184    pub ty: Handle<Type>,
1185    /// Initial value for this variable.
1186    ///
1187    /// This handle refers to an expression in this `LocalVariable`'s function's
1188    /// [`expressions`] arena, but it is required to be an evaluated override
1189    /// expression.
1190    ///
1191    /// [`expressions`]: Function::expressions
1192    pub init: Option<Handle<Expression>>,
1193}
1194
1195/// Operation that can be applied on a single value.
1196#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1197#[cfg_attr(feature = "serialize", derive(Serialize))]
1198#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1199#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1200pub enum UnaryOperator {
1201    Negate,
1202    LogicalNot,
1203    BitwiseNot,
1204}
1205
1206/// Operation that can be applied on two values.
1207///
1208/// ## Arithmetic type rules
1209///
1210/// The arithmetic operations `Add`, `Subtract`, `Multiply`, `Divide`, and
1211/// `Modulo` can all be applied to [`Scalar`] types other than [`Bool`], or
1212/// [`Vector`]s thereof. Both operands must have the same type.
1213///
1214/// `Add` and `Subtract` can also be applied to [`Matrix`] values. Both operands
1215/// must have the same type.
1216///
1217/// `Multiply` supports additional cases:
1218///
1219/// -   A [`Matrix`] or [`Vector`] can be multiplied by a scalar [`Float`],
1220///     either on the left or the right.
1221///
1222/// -   A [`Matrix`] on the left can be multiplied by a [`Vector`] on the right
1223///     if the matrix has as many columns as the vector has components
1224///     (`matCxR * VecC`).
1225///
1226/// -   A [`Vector`] on the left can be multiplied by a [`Matrix`] on the right
1227///     if the matrix has as many rows as the vector has components
1228///     (`VecR * matCxR`).
1229///
1230/// -   Two matrices can be multiplied if the left operand has as many columns
1231///     as the right operand has rows (`matNxR * matCxN`).
1232///
1233/// In all the above `Multiply` cases, the byte widths of the underlying scalar
1234/// types of both operands must be the same.
1235///
1236/// Note that `Multiply` supports mixed vector and scalar operations directly,
1237/// whereas the other arithmetic operations require an explicit [`Splat`] for
1238/// mixed-type use.
1239///
1240/// [`Scalar`]: TypeInner::Scalar
1241/// [`Vector`]: TypeInner::Vector
1242/// [`Matrix`]: TypeInner::Matrix
1243/// [`Float`]: ScalarKind::Float
1244/// [`Bool`]: ScalarKind::Bool
1245/// [`Splat`]: Expression::Splat
1246#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1247#[cfg_attr(feature = "serialize", derive(Serialize))]
1248#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1249#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1250pub enum BinaryOperator {
1251    Add,
1252    Subtract,
1253    Multiply,
1254    Divide,
1255    /// Equivalent of the WGSL's `%` operator or SPIR-V's `OpFRem`
1256    Modulo,
1257    Equal,
1258    NotEqual,
1259    Less,
1260    LessEqual,
1261    Greater,
1262    GreaterEqual,
1263    And,
1264    ExclusiveOr,
1265    InclusiveOr,
1266    LogicalAnd,
1267    LogicalOr,
1268    ShiftLeft,
1269    /// Right shift carries the sign of signed integers only.
1270    ShiftRight,
1271}
1272
1273/// Function on an atomic value.
1274///
1275/// Note: these do not include load/store, which use the existing
1276/// [`Expression::Load`] and [`Statement::Store`].
1277///
1278/// All `Handle<Expression>` values here refer to an expression in
1279/// [`Function::expressions`].
1280#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1281#[cfg_attr(feature = "serialize", derive(Serialize))]
1282#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1283#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1284pub enum AtomicFunction {
1285    Add,
1286    Subtract,
1287    And,
1288    ExclusiveOr,
1289    InclusiveOr,
1290    Min,
1291    Max,
1292    Exchange { compare: Option<Handle<Expression>> },
1293}
1294
1295/// Hint at which precision to compute a derivative.
1296#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1297#[cfg_attr(feature = "serialize", derive(Serialize))]
1298#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1299#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1300pub enum DerivativeControl {
1301    Coarse,
1302    Fine,
1303    None,
1304}
1305
1306/// Axis on which to compute a derivative.
1307#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1308#[cfg_attr(feature = "serialize", derive(Serialize))]
1309#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1310#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1311pub enum DerivativeAxis {
1312    X,
1313    Y,
1314    Width,
1315}
1316
1317/// Built-in shader function for testing relation between values.
1318#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1319#[cfg_attr(feature = "serialize", derive(Serialize))]
1320#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1321#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1322pub enum RelationalFunction {
1323    All,
1324    Any,
1325    IsNan,
1326    IsInf,
1327}
1328
1329/// Built-in shader function for math.
1330#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1331#[cfg_attr(feature = "serialize", derive(Serialize))]
1332#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1333#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1334pub enum MathFunction {
1335    // comparison
1336    Abs,
1337    Min,
1338    Max,
1339    Clamp,
1340    Saturate,
1341    // trigonometry
1342    Cos,
1343    Cosh,
1344    Sin,
1345    Sinh,
1346    Tan,
1347    Tanh,
1348    Acos,
1349    Asin,
1350    Atan,
1351    Atan2,
1352    Asinh,
1353    Acosh,
1354    Atanh,
1355    Radians,
1356    Degrees,
1357    // decomposition
1358    Ceil,
1359    Floor,
1360    Round,
1361    Fract,
1362    Trunc,
1363    Modf,
1364    Frexp,
1365    Ldexp,
1366    // exponent
1367    Exp,
1368    Exp2,
1369    Log,
1370    Log2,
1371    Pow,
1372    // geometry
1373    Dot,
1374    Dot4I8Packed,
1375    Dot4U8Packed,
1376    Outer,
1377    Cross,
1378    Distance,
1379    Length,
1380    Normalize,
1381    FaceForward,
1382    Reflect,
1383    Refract,
1384    // computational
1385    Sign,
1386    Fma,
1387    Mix,
1388    Step,
1389    SmoothStep,
1390    Sqrt,
1391    InverseSqrt,
1392    Inverse,
1393    Transpose,
1394    Determinant,
1395    QuantizeToF16,
1396    // bits
1397    CountTrailingZeros,
1398    CountLeadingZeros,
1399    CountOneBits,
1400    ReverseBits,
1401    ExtractBits,
1402    InsertBits,
1403    FirstTrailingBit,
1404    FirstLeadingBit,
1405    // data packing
1406    Pack4x8snorm,
1407    Pack4x8unorm,
1408    Pack2x16snorm,
1409    Pack2x16unorm,
1410    Pack2x16float,
1411    Pack4xI8,
1412    Pack4xU8,
1413    Pack4xI8Clamp,
1414    Pack4xU8Clamp,
1415    // data unpacking
1416    Unpack4x8snorm,
1417    Unpack4x8unorm,
1418    Unpack2x16snorm,
1419    Unpack2x16unorm,
1420    Unpack2x16float,
1421    Unpack4xI8,
1422    Unpack4xU8,
1423}
1424
1425/// Sampling modifier to control the level of detail.
1426///
1427/// All `Handle<Expression>` values here refer to an expression in
1428/// [`Function::expressions`].
1429#[derive(Clone, Copy, Debug, PartialEq)]
1430#[cfg_attr(feature = "serialize", derive(Serialize))]
1431#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1432#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1433pub enum SampleLevel {
1434    Auto,
1435    Zero,
1436    Exact(Handle<Expression>),
1437    Bias(Handle<Expression>),
1438    Gradient {
1439        x: Handle<Expression>,
1440        y: Handle<Expression>,
1441    },
1442}
1443
1444/// Type of an image query.
1445///
1446/// All `Handle<Expression>` values here refer to an expression in
1447/// [`Function::expressions`].
1448#[derive(Clone, Copy, Debug, PartialEq)]
1449#[cfg_attr(feature = "serialize", derive(Serialize))]
1450#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1451#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1452pub enum ImageQuery {
1453    /// Get the size at the specified level.
1454    ///
1455    /// The return value is a `u32` for 1D images, and a `vecN<u32>`
1456    /// for an image with dimensions N > 2.
1457    Size {
1458        /// If `None`, the base level is considered.
1459        level: Option<Handle<Expression>>,
1460    },
1461    /// Get the number of mipmap levels, a `u32`.
1462    NumLevels,
1463    /// Get the number of array layers, a `u32`.
1464    NumLayers,
1465    /// Get the number of samples, a `u32`.
1466    NumSamples,
1467}
1468
1469/// Component selection for a vector swizzle.
1470#[repr(u8)]
1471#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
1472#[cfg_attr(feature = "serialize", derive(Serialize))]
1473#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1474#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1475pub enum SwizzleComponent {
1476    X = 0,
1477    Y = 1,
1478    Z = 2,
1479    W = 3,
1480}
1481
1482/// The specific behavior of a [`SubgroupGather`] statement.
1483///
1484/// All `Handle<Expression>` values here refer to an expression in
1485/// [`Function::expressions`].
1486///
1487/// [`SubgroupGather`]: Statement::SubgroupGather
1488#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1489#[cfg_attr(feature = "serialize", derive(Serialize))]
1490#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1491#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1492pub enum GatherMode {
1493    /// All gather from the active lane with the smallest index
1494    BroadcastFirst,
1495    /// All gather from the same lane at the index given by the expression
1496    Broadcast(Handle<Expression>),
1497    /// Each gathers from a different lane at the index given by the expression
1498    Shuffle(Handle<Expression>),
1499    /// Each gathers from their lane plus the shift given by the expression
1500    ShuffleDown(Handle<Expression>),
1501    /// Each gathers from their lane minus the shift given by the expression
1502    ShuffleUp(Handle<Expression>),
1503    /// Each gathers from their lane xored with the given by the expression
1504    ShuffleXor(Handle<Expression>),
1505    /// All gather from the same quad lane at the index given by the expression
1506    QuadBroadcast(Handle<Expression>),
1507    /// Each gathers from the opposite quad lane along the given direction
1508    QuadSwap(Direction),
1509}
1510
1511#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1512#[cfg_attr(feature = "serialize", derive(Serialize))]
1513#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1514#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1515pub enum Direction {
1516    X = 0,
1517    Y = 1,
1518    Diagonal = 2,
1519}
1520
1521#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1522#[cfg_attr(feature = "serialize", derive(Serialize))]
1523#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1524#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1525pub enum SubgroupOperation {
1526    All = 0,
1527    Any = 1,
1528    Add = 2,
1529    Mul = 3,
1530    Min = 4,
1531    Max = 5,
1532    And = 6,
1533    Or = 7,
1534    Xor = 8,
1535}
1536
1537#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1538#[cfg_attr(feature = "serialize", derive(Serialize))]
1539#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1540#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1541pub enum CollectiveOperation {
1542    Reduce = 0,
1543    InclusiveScan = 1,
1544    ExclusiveScan = 2,
1545}
1546
1547bitflags::bitflags! {
1548    /// Memory barrier flags.
1549    #[cfg_attr(feature = "serialize", derive(Serialize))]
1550    #[cfg_attr(feature = "deserialize", derive(Deserialize))]
1551    #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1552    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
1553    pub struct Barrier: u32 {
1554        /// Barrier affects all [`AddressSpace::Storage`] accesses.
1555        const STORAGE = 1 << 0;
1556        /// Barrier affects all [`AddressSpace::WorkGroup`] and [`AddressSpace::TaskPayload`] accesses.
1557        const WORK_GROUP = 1 << 1;
1558        /// Barrier synchronizes execution across all invocations within a subgroup that execute this instruction.
1559        const SUB_GROUP = 1 << 2;
1560        /// Barrier synchronizes texture memory accesses in a workgroup.
1561        const TEXTURE = 1 << 3;
1562    }
1563}
1564
1565#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
1566#[cfg_attr(feature = "serialize", derive(Serialize))]
1567#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1568#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1569pub struct CooperativeData {
1570    pub pointer: Handle<Expression>,
1571    pub stride: Handle<Expression>,
1572    pub row_major: bool,
1573}
1574
1575/// An expression that can be evaluated to obtain a value.
1576///
1577/// This is a Single Static Assignment (SSA) scheme similar to SPIR-V.
1578///
1579/// When an `Expression` variant holds `Handle<Expression>` fields, they refer
1580/// to another expression in the same arena, unless explicitly noted otherwise.
1581/// One `Arena<Expression>` may only refer to a different arena indirectly, via
1582/// [`Constant`] or [`Override`] expressions, which hold handles for their
1583/// respective types.
1584///
1585/// [`Constant`]: Expression::Constant
1586/// [`Override`]: Expression::Override
1587#[derive(Clone, Debug, PartialEq)]
1588#[cfg_attr(feature = "serialize", derive(Serialize))]
1589#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1590#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1591pub enum Expression {
1592    /// Literal.
1593    Literal(Literal),
1594    /// Constant value.
1595    Constant(Handle<Constant>),
1596    /// Pipeline-overridable constant.
1597    Override(Handle<Override>),
1598    /// Zero value of a type.
1599    ZeroValue(Handle<Type>),
1600    /// Composite expression.
1601    Compose {
1602        ty: Handle<Type>,
1603        components: Vec<Handle<Expression>>,
1604    },
1605
1606    /// Array access with a computed index.
1607    ///
1608    /// ## Typing rules
1609    ///
1610    /// The `base` operand must be some composite type: [`Vector`], [`Matrix`],
1611    /// [`Array`], a [`Pointer`] to one of those, or a [`ValuePointer`] with a
1612    /// `size`.
1613    ///
1614    /// The `index` operand must be an integer, signed or unsigned.
1615    ///
1616    /// Indexing a [`Vector`] or [`Array`] produces a value of its element type.
1617    /// Indexing a [`Matrix`] produces a [`Vector`].
1618    ///
1619    /// Indexing a [`Pointer`] to any of the above produces a pointer to the
1620    /// element/component type, in the same [`space`]. In the case of [`Array`],
1621    /// the result is an actual [`Pointer`], but for vectors and matrices, there
1622    /// may not be any type in the arena representing the component's type, so
1623    /// those produce [`ValuePointer`] types equivalent to the appropriate
1624    /// [`Pointer`].
1625    ///
1626    /// ## Dynamic indexing restrictions
1627    ///
1628    /// To accommodate restrictions in some of the shader languages that Naga
1629    /// targets, it is not permitted to subscript a matrix with a dynamically
1630    /// computed index unless that matrix appears behind a pointer. In other
1631    /// words, if the inner type of `base` is [`Matrix`], then `index` must be a
1632    /// constant. But if the type of `base` is a [`Pointer`] to an matrix, then
1633    /// the index may be any expression of integer type.
1634    ///
1635    /// You can use the [`Expression::is_dynamic_index`] method to determine
1636    /// whether a given index expression requires matrix base operands to be
1637    /// behind a pointer.
1638    ///
1639    /// (It would be simpler to always require the use of `AccessIndex` when
1640    /// subscripting matrices that are not behind pointers, but to accommodate
1641    /// existing front ends, Naga also permits `Access`, with a restricted
1642    /// `index`.)
1643    ///
1644    /// [`Vector`]: TypeInner::Vector
1645    /// [`Matrix`]: TypeInner::Matrix
1646    /// [`Array`]: TypeInner::Array
1647    /// [`Pointer`]: TypeInner::Pointer
1648    /// [`space`]: TypeInner::Pointer::space
1649    /// [`ValuePointer`]: TypeInner::ValuePointer
1650    /// [`Float`]: ScalarKind::Float
1651    Access {
1652        base: Handle<Expression>,
1653        index: Handle<Expression>,
1654    },
1655    /// Access the same types as [`Access`], plus [`Struct`] with a known index.
1656    ///
1657    /// [`Access`]: Expression::Access
1658    /// [`Struct`]: TypeInner::Struct
1659    AccessIndex {
1660        base: Handle<Expression>,
1661        index: u32,
1662    },
1663    /// Splat scalar into a vector.
1664    Splat {
1665        size: VectorSize,
1666        value: Handle<Expression>,
1667    },
1668    /// Vector swizzle.
1669    Swizzle {
1670        size: VectorSize,
1671        vector: Handle<Expression>,
1672        pattern: [SwizzleComponent; 4],
1673    },
1674
1675    /// Reference a function parameter, by its index.
1676    ///
1677    /// A `FunctionArgument` expression evaluates to the argument's value.
1678    FunctionArgument(u32),
1679
1680    /// Reference a global variable.
1681    ///
1682    /// If the given `GlobalVariable`'s [`space`] is [`AddressSpace::Handle`],
1683    /// then the variable stores some opaque type like a sampler or an image,
1684    /// and a `GlobalVariable` expression referring to it produces the
1685    /// variable's value directly.
1686    ///
1687    /// For any other address space, a `GlobalVariable` expression produces a
1688    /// pointer to the variable's value. You must use a [`Load`] expression to
1689    /// retrieve its value, or a [`Store`] statement to assign it a new value.
1690    ///
1691    /// [`space`]: GlobalVariable::space
1692    /// [`Load`]: Expression::Load
1693    /// [`Store`]: Statement::Store
1694    GlobalVariable(Handle<GlobalVariable>),
1695
1696    /// Reference a local variable.
1697    ///
1698    /// A `LocalVariable` expression evaluates to a pointer to the variable's value.
1699    /// You must use a [`Load`](Expression::Load) expression to retrieve its value,
1700    /// or a [`Store`](Statement::Store) statement to assign it a new value.
1701    LocalVariable(Handle<LocalVariable>),
1702
1703    /// Load a value indirectly.
1704    ///
1705    /// For [`TypeInner::Atomic`] the result is a corresponding scalar.
1706    /// For other types behind the `pointer<T>`, the result is `T`.
1707    Load { pointer: Handle<Expression> },
1708    /// Sample a point from a sampled or a depth image.
1709    ImageSample {
1710        image: Handle<Expression>,
1711        sampler: Handle<Expression>,
1712        /// If Some(), this operation is a gather operation
1713        /// on the selected component.
1714        gather: Option<SwizzleComponent>,
1715        coordinate: Handle<Expression>,
1716        array_index: Option<Handle<Expression>>,
1717        /// This must be a const-expression.
1718        offset: Option<Handle<Expression>>,
1719        level: SampleLevel,
1720        depth_ref: Option<Handle<Expression>>,
1721        /// Whether the sampling operation should clamp each component of
1722        /// `coordinate` to the range `[half_texel, 1 - half_texel]`, regardless
1723        /// of `sampler`.
1724        clamp_to_edge: bool,
1725    },
1726
1727    /// Load a texel from an image.
1728    ///
1729    /// For most images, this returns a four-element vector of the same
1730    /// [`ScalarKind`] as the image. If the format of the image does not have
1731    /// four components, default values are provided: the first three components
1732    /// (typically R, G, and B) default to zero, and the final component
1733    /// (typically alpha) defaults to one.
1734    ///
1735    /// However, if the image's [`class`] is [`Depth`], then this returns a
1736    /// [`Float`] scalar value.
1737    ///
1738    /// [`ScalarKind`]: ScalarKind
1739    /// [`class`]: TypeInner::Image::class
1740    /// [`Depth`]: ImageClass::Depth
1741    /// [`Float`]: ScalarKind::Float
1742    ImageLoad {
1743        /// The image to load a texel from. This must have type [`Image`]. (This
1744        /// will necessarily be a [`GlobalVariable`] or [`FunctionArgument`]
1745        /// expression, since no other expressions are allowed to have that
1746        /// type.)
1747        ///
1748        /// [`Image`]: TypeInner::Image
1749        /// [`GlobalVariable`]: Expression::GlobalVariable
1750        /// [`FunctionArgument`]: Expression::FunctionArgument
1751        image: Handle<Expression>,
1752
1753        /// The coordinate of the texel we wish to load. This must be a scalar
1754        /// for [`D1`] images, a [`Bi`] vector for [`D2`] images, and a [`Tri`]
1755        /// vector for [`D3`] images. (Array indices, sample indices, and
1756        /// explicit level-of-detail values are supplied separately.) Its
1757        /// component type must be [`Sint`].
1758        ///
1759        /// [`D1`]: ImageDimension::D1
1760        /// [`D2`]: ImageDimension::D2
1761        /// [`D3`]: ImageDimension::D3
1762        /// [`Bi`]: VectorSize::Bi
1763        /// [`Tri`]: VectorSize::Tri
1764        /// [`Sint`]: ScalarKind::Sint
1765        coordinate: Handle<Expression>,
1766
1767        /// The index into an arrayed image. If the [`arrayed`] flag in
1768        /// `image`'s type is `true`, then this must be `Some(expr)`, where
1769        /// `expr` is a [`Sint`] scalar. Otherwise, it must be `None`.
1770        ///
1771        /// [`arrayed`]: TypeInner::Image::arrayed
1772        /// [`Sint`]: ScalarKind::Sint
1773        array_index: Option<Handle<Expression>>,
1774
1775        /// A sample index, for multisampled [`Sampled`] and [`Depth`] images.
1776        ///
1777        /// [`Sampled`]: ImageClass::Sampled
1778        /// [`Depth`]: ImageClass::Depth
1779        sample: Option<Handle<Expression>>,
1780
1781        /// A level of detail, for mipmapped images.
1782        ///
1783        /// This must be present when accessing non-multisampled
1784        /// [`Sampled`] and [`Depth`] images, even if only the
1785        /// full-resolution level is present (in which case the only
1786        /// valid level is zero).
1787        ///
1788        /// [`Sampled`]: ImageClass::Sampled
1789        /// [`Depth`]: ImageClass::Depth
1790        level: Option<Handle<Expression>>,
1791    },
1792
1793    /// Query information from an image.
1794    ImageQuery {
1795        image: Handle<Expression>,
1796        query: ImageQuery,
1797    },
1798    /// Apply an unary operator.
1799    Unary {
1800        op: UnaryOperator,
1801        expr: Handle<Expression>,
1802    },
1803    /// Apply a binary operator.
1804    Binary {
1805        op: BinaryOperator,
1806        left: Handle<Expression>,
1807        right: Handle<Expression>,
1808    },
1809    /// Select between two values based on a condition.
1810    ///
1811    /// Note that, because expressions have no side effects, it is unobservable
1812    /// whether the non-selected branch is evaluated.
1813    Select {
1814        /// Boolean expression
1815        condition: Handle<Expression>,
1816        accept: Handle<Expression>,
1817        reject: Handle<Expression>,
1818    },
1819    /// Compute the derivative on an axis.
1820    Derivative {
1821        axis: DerivativeAxis,
1822        ctrl: DerivativeControl,
1823        expr: Handle<Expression>,
1824    },
1825    /// Call a relational function.
1826    Relational {
1827        fun: RelationalFunction,
1828        argument: Handle<Expression>,
1829    },
1830    /// Call a math function
1831    Math {
1832        fun: MathFunction,
1833        arg: Handle<Expression>,
1834        arg1: Option<Handle<Expression>>,
1835        arg2: Option<Handle<Expression>>,
1836        arg3: Option<Handle<Expression>>,
1837    },
1838    /// Cast a simple type to another kind.
1839    As {
1840        /// Source expression, which can only be a scalar or a vector.
1841        expr: Handle<Expression>,
1842        /// Target scalar kind.
1843        kind: ScalarKind,
1844        /// If provided, converts to the specified byte width.
1845        /// Otherwise, bitcast.
1846        convert: Option<Bytes>,
1847    },
1848    /// Result of calling another function.
1849    CallResult(Handle<Function>),
1850
1851    /// Result of an atomic operation.
1852    ///
1853    /// This expression must be referred to by the [`result`] field of exactly one
1854    /// [`Atomic`][stmt] statement somewhere in the same function. Let `T` be the
1855    /// scalar type contained by the [`Atomic`][type] value that the statement
1856    /// operates on.
1857    ///
1858    /// If `comparison` is `false`, then `ty` must be the scalar type `T`.
1859    ///
1860    /// If `comparison` is `true`, then `ty` must be a [`Struct`] with two members:
1861    ///
1862    /// - A member named `old_value`, whose type is `T`, and
1863    ///
1864    /// - A member named `exchanged`, of type [`BOOL`].
1865    ///
1866    /// [`result`]: Statement::Atomic::result
1867    /// [stmt]: Statement::Atomic
1868    /// [type]: TypeInner::Atomic
1869    /// [`Struct`]: TypeInner::Struct
1870    /// [`BOOL`]: Scalar::BOOL
1871    AtomicResult { ty: Handle<Type>, comparison: bool },
1872
1873    /// Result of a [`WorkGroupUniformLoad`] statement.
1874    ///
1875    /// [`WorkGroupUniformLoad`]: Statement::WorkGroupUniformLoad
1876    WorkGroupUniformLoadResult {
1877        /// The type of the result
1878        ty: Handle<Type>,
1879    },
1880    /// Get the length of an array.
1881    /// The expression must resolve to a pointer to an array with a dynamic size.
1882    ///
1883    /// This doesn't match the semantics of spirv's `OpArrayLength`, which must be passed
1884    /// a pointer to a structure containing a runtime array in its' last field.
1885    ArrayLength(Handle<Expression>),
1886
1887    /// Get the Positions of the triangle hit by the [`RayQuery`]
1888    ///
1889    /// [`RayQuery`]: Statement::RayQuery
1890    RayQueryVertexPositions {
1891        query: Handle<Expression>,
1892        committed: bool,
1893    },
1894
1895    /// Result of a [`Proceed`] [`RayQuery`] statement.
1896    ///
1897    /// [`Proceed`]: RayQueryFunction::Proceed
1898    /// [`RayQuery`]: Statement::RayQuery
1899    RayQueryProceedResult,
1900
1901    /// Return an intersection found by `query`.
1902    ///
1903    /// If `committed` is true, return the committed result available when
1904    RayQueryGetIntersection {
1905        query: Handle<Expression>,
1906        committed: bool,
1907    },
1908
1909    /// Result of a [`SubgroupBallot`] statement.
1910    ///
1911    /// [`SubgroupBallot`]: Statement::SubgroupBallot
1912    SubgroupBallotResult,
1913
1914    /// Result of a [`SubgroupCollectiveOperation`] or [`SubgroupGather`] statement.
1915    ///
1916    /// [`SubgroupCollectiveOperation`]: Statement::SubgroupCollectiveOperation
1917    /// [`SubgroupGather`]: Statement::SubgroupGather
1918    SubgroupOperationResult { ty: Handle<Type> },
1919
1920    /// Load a cooperative primitive from memory.
1921    CooperativeLoad {
1922        columns: CooperativeSize,
1923        rows: CooperativeSize,
1924        role: CooperativeRole,
1925        data: CooperativeData,
1926    },
1927    /// Compute `a * b + c`
1928    CooperativeMultiplyAdd {
1929        a: Handle<Expression>,
1930        b: Handle<Expression>,
1931        c: Handle<Expression>,
1932    },
1933}
1934
1935/// The value of the switch case.
1936#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1937#[cfg_attr(feature = "serialize", derive(Serialize))]
1938#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1939#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1940pub enum SwitchValue {
1941    I32(i32),
1942    U32(u32),
1943    Default,
1944}
1945
1946/// A case for a switch statement.
1947// Clone is used only for error reporting and is not intended for end users
1948#[derive(Clone, Debug)]
1949#[cfg_attr(feature = "serialize", derive(Serialize))]
1950#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1951#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1952pub struct SwitchCase {
1953    /// Value, upon which the case is considered true.
1954    pub value: SwitchValue,
1955    /// Body of the case.
1956    pub body: Block,
1957    /// If true, the control flow continues to the next case in the list,
1958    /// or default.
1959    pub fall_through: bool,
1960}
1961
1962/// An operation that a [`RayQuery` statement] applies to its [`query`] operand.
1963///
1964/// [`RayQuery` statement]: Statement::RayQuery
1965/// [`query`]: Statement::RayQuery::query
1966#[derive(Clone, Debug)]
1967#[cfg_attr(feature = "serialize", derive(Serialize))]
1968#[cfg_attr(feature = "deserialize", derive(Deserialize))]
1969#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
1970pub enum RayQueryFunction {
1971    /// Initialize the `RayQuery` object.
1972    Initialize {
1973        /// The acceleration structure within which this query should search for hits.
1974        ///
1975        /// The expression must be an [`AccelerationStructure`].
1976        ///
1977        /// [`AccelerationStructure`]: TypeInner::AccelerationStructure
1978        acceleration_structure: Handle<Expression>,
1979
1980        #[allow(rustdoc::private_intra_doc_links)]
1981        /// A struct of detailed parameters for the ray query.
1982        ///
1983        /// This expression should have the struct type given in
1984        /// [`SpecialTypes::ray_desc`]. This is available in the WGSL
1985        /// front end as the `RayDesc` type.
1986        descriptor: Handle<Expression>,
1987    },
1988
1989    /// Start or continue the query given by the statement's [`query`] operand.
1990    ///
1991    /// After executing this statement, the `result` expression is a
1992    /// [`Bool`] scalar indicating whether there are more intersection
1993    /// candidates to consider.
1994    ///
1995    /// [`query`]: Statement::RayQuery::query
1996    /// [`Bool`]: ScalarKind::Bool
1997    Proceed {
1998        result: Handle<Expression>,
1999    },
2000
2001    /// Add a candidate generated intersection to be included
2002    /// in the determination of the closest hit for a ray query.
2003    GenerateIntersection {
2004        hit_t: Handle<Expression>,
2005    },
2006
2007    /// Confirm a triangle intersection to be included in the determination of
2008    /// the closest hit for a ray query.
2009    ConfirmIntersection,
2010
2011    Terminate,
2012
2013    /// Resets a variable's to appear as though it was previously unused.
2014    ///
2015    /// For most types in variables which don't have initialisers, a zero store
2016    /// is fine when resetting a variable in a loop (as functions always have
2017    /// their variables outside all blocks while wgsl and others can have blocks
2018    /// in loops) but ray queries cannot be stored to nor can be zero initialized.
2019    Begin,
2020}
2021
2022//TODO: consider removing `Clone`. It's not valid to clone `Statement::Emit` anyway.
2023/// Instructions which make up an executable block.
2024///
2025/// `Handle<Expression>` and `Range<Expression>` values in `Statement` variants
2026/// refer to expressions in [`Function::expressions`], unless otherwise noted.
2027// Clone is used only for error reporting and is not intended for end users
2028#[derive(Clone, Debug)]
2029#[cfg_attr(feature = "serialize", derive(Serialize))]
2030#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2031#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2032pub enum Statement {
2033    /// Emit a range of expressions, visible to all statements that follow in this block.
2034    ///
2035    /// See the [module-level documentation][emit] for details.
2036    ///
2037    /// [emit]: index.html#expression-evaluation-time
2038    Emit(Range<Expression>),
2039    /// A block containing more statements, to be executed sequentially.
2040    Block(Block),
2041    /// Conditionally executes one of two blocks, based on the value of the condition.
2042    ///
2043    /// Naga IR does not have "phi" instructions. If you need to use
2044    /// values computed in an `accept` or `reject` block after the `If`,
2045    /// store them in a [`LocalVariable`].
2046    If {
2047        condition: Handle<Expression>, //bool
2048        accept: Block,
2049        reject: Block,
2050    },
2051    /// Conditionally executes one of multiple blocks, based on the value of the selector.
2052    ///
2053    /// Each case must have a distinct [`value`], exactly one of which must be
2054    /// [`Default`]. The `Default` may appear at any position, and covers all
2055    /// values not explicitly appearing in other cases. A `Default` appearing in
2056    /// the midst of the list of cases does not shadow the cases that follow.
2057    ///
2058    /// Some backend languages don't support fallthrough (HLSL due to FXC,
2059    /// WGSL), and may translate fallthrough cases in the IR by duplicating
2060    /// code. However, all backend languages do support cases selected by
2061    /// multiple values, like `case 1: case 2: case 3: { ... }`. This is
2062    /// represented in the IR as a series of fallthrough cases with empty
2063    /// bodies, except for the last.
2064    ///
2065    /// Naga IR does not have "phi" instructions. If you need to use
2066    /// values computed in a [`SwitchCase::body`] block after the `Switch`,
2067    /// store them in a [`LocalVariable`].
2068    ///
2069    /// [`value`]: SwitchCase::value
2070    /// [`body`]: SwitchCase::body
2071    /// [`Default`]: SwitchValue::Default
2072    Switch {
2073        selector: Handle<Expression>,
2074        cases: Vec<SwitchCase>,
2075    },
2076
2077    /// Executes a block repeatedly.
2078    ///
2079    /// Each iteration of the loop executes the `body` block, followed by the
2080    /// `continuing` block.
2081    ///
2082    /// Executing a [`Break`], [`Return`] or [`Kill`] statement exits the loop.
2083    ///
2084    /// A [`Continue`] statement in `body` jumps to the `continuing` block. The
2085    /// `continuing` block is meant to be used to represent structures like the
2086    /// third expression of a C-style `for` loop head, to which `continue`
2087    /// statements in the loop's body jump.
2088    ///
2089    /// The `continuing` block and its substatements must not contain `Return`
2090    /// or `Kill` statements, or any `Break` or `Continue` statements targeting
2091    /// this loop. (It may have `Break` and `Continue` statements targeting
2092    /// loops or switches nested within the `continuing` block.) Expressions
2093    /// emitted in `body` are in scope in `continuing`.
2094    ///
2095    /// If present, `break_if` is an expression which is evaluated after the
2096    /// continuing block. Expressions emitted in `body` or `continuing` are
2097    /// considered to be in scope. If the expression's value is true, control
2098    /// continues after the `Loop` statement, rather than branching back to the
2099    /// top of body as usual. The `break_if` expression corresponds to a "break
2100    /// if" statement in WGSL, or a loop whose back edge is an
2101    /// `OpBranchConditional` instruction in SPIR-V.
2102    ///
2103    /// Naga IR does not have "phi" instructions. If you need to use
2104    /// values computed in a `body` or `continuing` block after the
2105    /// `Loop`, store them in a [`LocalVariable`].
2106    ///
2107    /// [`Break`]: Statement::Break
2108    /// [`Continue`]: Statement::Continue
2109    /// [`Kill`]: Statement::Kill
2110    /// [`Return`]: Statement::Return
2111    /// [`break if`]: Self::Loop::break_if
2112    Loop {
2113        body: Block,
2114        continuing: Block,
2115        break_if: Option<Handle<Expression>>,
2116    },
2117
2118    /// Exits the innermost enclosing [`Loop`] or [`Switch`].
2119    ///
2120    /// A `Break` statement may only appear within a [`Loop`] or [`Switch`]
2121    /// statement. It may not break out of a [`Loop`] from within the loop's
2122    /// `continuing` block.
2123    ///
2124    /// [`Loop`]: Statement::Loop
2125    /// [`Switch`]: Statement::Switch
2126    Break,
2127
2128    /// Skips to the `continuing` block of the innermost enclosing [`Loop`].
2129    ///
2130    /// A `Continue` statement may only appear within the `body` block of the
2131    /// innermost enclosing [`Loop`] statement. It must not appear within that
2132    /// loop's `continuing` block.
2133    ///
2134    /// [`Loop`]: Statement::Loop
2135    Continue,
2136
2137    /// Returns from the function (possibly with a value).
2138    ///
2139    /// `Return` statements are forbidden within the `continuing` block of a
2140    /// [`Loop`] statement.
2141    ///
2142    /// [`Loop`]: Statement::Loop
2143    Return { value: Option<Handle<Expression>> },
2144
2145    /// Aborts the current shader execution.
2146    ///
2147    /// `Kill` statements are forbidden within the `continuing` block of a
2148    /// [`Loop`] statement.
2149    ///
2150    /// [`Loop`]: Statement::Loop
2151    Kill,
2152
2153    /// Synchronize invocations within the work group.
2154    /// The `Barrier` flags control which memory accesses should be synchronized.
2155    /// If empty, this becomes purely an execution barrier.
2156    ControlBarrier(Barrier),
2157
2158    /// Synchronize invocations within the work group.
2159    /// The `Barrier` flags control which memory accesses should be synchronized.
2160    MemoryBarrier(Barrier),
2161
2162    /// Stores a value at an address.
2163    ///
2164    /// For [`TypeInner::Atomic`] type behind the pointer, the value
2165    /// has to be a corresponding scalar.
2166    /// For other types behind the `pointer<T>`, the value is `T`.
2167    ///
2168    /// This statement is a barrier for any operations on the
2169    /// `Expression::LocalVariable` or `Expression::GlobalVariable`
2170    /// that is the destination of an access chain, started
2171    /// from the `pointer`.
2172    Store {
2173        pointer: Handle<Expression>,
2174        value: Handle<Expression>,
2175    },
2176    /// Stores a texel value to an image.
2177    ///
2178    /// The `image`, `coordinate`, and `array_index` fields have the same
2179    /// meanings as the corresponding operands of an [`ImageLoad`] expression;
2180    /// see that documentation for details. Storing into multisampled images or
2181    /// images with mipmaps is not supported, so there are no `level` or
2182    /// `sample` operands.
2183    ///
2184    /// This statement is a barrier for any operations on the corresponding
2185    /// [`Expression::GlobalVariable`] for this image.
2186    ///
2187    /// [`ImageLoad`]: Expression::ImageLoad
2188    ImageStore {
2189        image: Handle<Expression>,
2190        coordinate: Handle<Expression>,
2191        array_index: Option<Handle<Expression>>,
2192        value: Handle<Expression>,
2193    },
2194    /// Atomic function.
2195    Atomic {
2196        /// Pointer to an atomic value.
2197        ///
2198        /// This must be a [`Pointer`] to an [`Atomic`] value. The atomic's
2199        /// scalar type may be [`I32`] or [`U32`].
2200        ///
2201        /// If [`SHADER_INT64_ATOMIC_MIN_MAX`] or [`SHADER_INT64_ATOMIC_ALL_OPS`] are
2202        /// enabled, this may also be [`I64`] or [`U64`].
2203        ///
2204        /// If [`SHADER_FLOAT32_ATOMIC`] is enabled, this may be [`F32`].
2205        ///
2206        /// [`Pointer`]: TypeInner::Pointer
2207        /// [`Atomic`]: TypeInner::Atomic
2208        /// [`I32`]: Scalar::I32
2209        /// [`U32`]: Scalar::U32
2210        /// [`SHADER_INT64_ATOMIC_MIN_MAX`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_MIN_MAX
2211        /// [`SHADER_INT64_ATOMIC_ALL_OPS`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_ALL_OPS
2212        /// [`SHADER_FLOAT32_ATOMIC`]: crate::valid::Capabilities::SHADER_FLOAT32_ATOMIC
2213        /// [`I64`]: Scalar::I64
2214        /// [`U64`]: Scalar::U64
2215        /// [`F32`]: Scalar::F32
2216        pointer: Handle<Expression>,
2217
2218        /// Function to run on the atomic value.
2219        ///
2220        /// If [`pointer`] refers to a 64-bit atomic value, then:
2221        ///
2222        /// - The [`SHADER_INT64_ATOMIC_ALL_OPS`] capability allows any [`AtomicFunction`]
2223        ///   value here.
2224        ///
2225        /// - The [`SHADER_INT64_ATOMIC_MIN_MAX`] capability allows
2226        ///   [`AtomicFunction::Min`] and [`AtomicFunction::Max`]
2227        ///   in the [`Storage`] address space here.
2228        ///
2229        /// - If neither of those capabilities are present, then 64-bit scalar
2230        ///   atomics are not allowed.
2231        ///
2232        /// If [`pointer`] refers to a 32-bit floating-point atomic value, then:
2233        ///
2234        /// - The [`SHADER_FLOAT32_ATOMIC`] capability allows [`AtomicFunction::Add`],
2235        ///   [`AtomicFunction::Subtract`], and [`AtomicFunction::Exchange { compare: None }`]
2236        ///   in the [`Storage`] address space here.
2237        ///
2238        /// [`AtomicFunction::Exchange { compare: None }`]: AtomicFunction::Exchange
2239        /// [`pointer`]: Statement::Atomic::pointer
2240        /// [`Storage`]: AddressSpace::Storage
2241        /// [`SHADER_INT64_ATOMIC_MIN_MAX`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_MIN_MAX
2242        /// [`SHADER_INT64_ATOMIC_ALL_OPS`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_ALL_OPS
2243        /// [`SHADER_FLOAT32_ATOMIC`]: crate::valid::Capabilities::SHADER_FLOAT32_ATOMIC
2244        fun: AtomicFunction,
2245
2246        /// Value to use in the function.
2247        ///
2248        /// This must be a scalar of the same type as [`pointer`]'s atomic's scalar type.
2249        ///
2250        /// [`pointer`]: Statement::Atomic::pointer
2251        value: Handle<Expression>,
2252
2253        /// [`AtomicResult`] expression representing this function's result.
2254        ///
2255        /// If [`fun`] is [`Exchange { compare: None }`], this must be `Some`,
2256        /// as otherwise that operation would be equivalent to a simple [`Store`]
2257        /// to the atomic.
2258        ///
2259        /// Otherwise, this may be `None` if the return value of the operation is not needed.
2260        ///
2261        /// If `pointer` refers to a 64-bit atomic value, [`SHADER_INT64_ATOMIC_MIN_MAX`]
2262        /// is enabled, and [`SHADER_INT64_ATOMIC_ALL_OPS`] is not, this must be `None`.
2263        ///
2264        /// [`AtomicResult`]: crate::Expression::AtomicResult
2265        /// [`fun`]: Statement::Atomic::fun
2266        /// [`Store`]: Statement::Store
2267        /// [`Exchange { compare: None }`]: AtomicFunction::Exchange
2268        /// [`SHADER_INT64_ATOMIC_MIN_MAX`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_MIN_MAX
2269        /// [`SHADER_INT64_ATOMIC_ALL_OPS`]: crate::valid::Capabilities::SHADER_INT64_ATOMIC_ALL_OPS
2270        result: Option<Handle<Expression>>,
2271    },
2272    /// Performs an atomic operation on a texel value of an image.
2273    ///
2274    /// Doing atomics on images with mipmaps is not supported, so there is no
2275    /// `level` operand.
2276    ImageAtomic {
2277        /// The image to perform an atomic operation on. This must have type
2278        /// [`Image`]. (This will necessarily be a [`GlobalVariable`] or
2279        /// [`FunctionArgument`] expression, since no other expressions are
2280        /// allowed to have that type.)
2281        ///
2282        /// [`Image`]: TypeInner::Image
2283        /// [`GlobalVariable`]: Expression::GlobalVariable
2284        /// [`FunctionArgument`]: Expression::FunctionArgument
2285        image: Handle<Expression>,
2286
2287        /// The coordinate of the texel we wish to load. This must be a scalar
2288        /// for [`D1`] images, a [`Bi`] vector for [`D2`] images, and a [`Tri`]
2289        /// vector for [`D3`] images. (Array indices, sample indices, and
2290        /// explicit level-of-detail values are supplied separately.) Its
2291        /// component type must be [`Sint`].
2292        ///
2293        /// [`D1`]: ImageDimension::D1
2294        /// [`D2`]: ImageDimension::D2
2295        /// [`D3`]: ImageDimension::D3
2296        /// [`Bi`]: VectorSize::Bi
2297        /// [`Tri`]: VectorSize::Tri
2298        /// [`Sint`]: ScalarKind::Sint
2299        coordinate: Handle<Expression>,
2300
2301        /// The index into an arrayed image. If the [`arrayed`] flag in
2302        /// `image`'s type is `true`, then this must be `Some(expr)`, where
2303        /// `expr` is a [`Sint`] scalar. Otherwise, it must be `None`.
2304        ///
2305        /// [`arrayed`]: TypeInner::Image::arrayed
2306        /// [`Sint`]: ScalarKind::Sint
2307        array_index: Option<Handle<Expression>>,
2308
2309        /// The kind of atomic operation to perform on the texel.
2310        fun: AtomicFunction,
2311
2312        /// The value with which to perform the atomic operation.
2313        value: Handle<Expression>,
2314    },
2315    /// Load uniformly from a uniform pointer in the workgroup address space.
2316    ///
2317    /// Corresponds to the [`workgroupUniformLoad`](https://www.w3.org/TR/WGSL/#workgroupUniformLoad-builtin)
2318    /// built-in function of wgsl, and has the same barrier semantics
2319    WorkGroupUniformLoad {
2320        /// This must be of type [`Pointer`] in the [`WorkGroup`] address space
2321        ///
2322        /// [`Pointer`]: TypeInner::Pointer
2323        /// [`WorkGroup`]: AddressSpace::WorkGroup
2324        pointer: Handle<Expression>,
2325        /// The [`WorkGroupUniformLoadResult`] expression representing this load's result.
2326        ///
2327        /// [`WorkGroupUniformLoadResult`]: Expression::WorkGroupUniformLoadResult
2328        result: Handle<Expression>,
2329    },
2330    /// Calls a function.
2331    ///
2332    /// If the `result` is `Some`, the corresponding expression has to be
2333    /// `Expression::CallResult`, and this statement serves as a barrier for any
2334    /// operations on that expression.
2335    Call {
2336        function: Handle<Function>,
2337        arguments: Vec<Handle<Expression>>,
2338        result: Option<Handle<Expression>>,
2339    },
2340    RayQuery {
2341        /// The [`RayQuery`] object this statement operates on.
2342        ///
2343        /// [`RayQuery`]: TypeInner::RayQuery
2344        query: Handle<Expression>,
2345
2346        /// The specific operation we're performing on `query`.
2347        fun: RayQueryFunction,
2348    },
2349    /// A ray tracing pipeline shader intrinsic.
2350    RayPipelineFunction(RayPipelineFunction),
2351    /// Calculate a bitmask using a boolean from each active thread in the subgroup
2352    SubgroupBallot {
2353        /// The [`SubgroupBallotResult`] expression representing this load's result.
2354        ///
2355        /// [`SubgroupBallotResult`]: Expression::SubgroupBallotResult
2356        result: Handle<Expression>,
2357        /// The value from this thread to store in the ballot
2358        predicate: Option<Handle<Expression>>,
2359    },
2360    /// Gather a value from another active thread in the subgroup
2361    SubgroupGather {
2362        /// Specifies which thread to gather from
2363        mode: GatherMode,
2364        /// The value to broadcast over
2365        argument: Handle<Expression>,
2366        /// The [`SubgroupOperationResult`] expression representing this load's result.
2367        ///
2368        /// [`SubgroupOperationResult`]: Expression::SubgroupOperationResult
2369        result: Handle<Expression>,
2370    },
2371    /// Compute a collective operation across all active threads in the subgroup
2372    SubgroupCollectiveOperation {
2373        /// What operation to compute
2374        op: SubgroupOperation,
2375        /// How to combine the results
2376        collective_op: CollectiveOperation,
2377        /// The value to compute over
2378        argument: Handle<Expression>,
2379        /// The [`SubgroupOperationResult`] expression representing this load's result.
2380        ///
2381        /// [`SubgroupOperationResult`]: Expression::SubgroupOperationResult
2382        result: Handle<Expression>,
2383    },
2384    /// Store a cooperative primitive into memory.
2385    CooperativeStore {
2386        target: Handle<Expression>,
2387        data: CooperativeData,
2388    },
2389    /// This corresponds to `debugPrintf` in WGSL when the `wgpu_debug_printf` extension is enabled.
2390    DebugPrintf {
2391        format: String,
2392        arguments: Vec<Handle<Expression>>,
2393    },
2394}
2395
2396/// A function argument.
2397#[derive(Clone, Debug)]
2398#[cfg_attr(feature = "serialize", derive(Serialize))]
2399#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2400#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2401pub struct FunctionArgument {
2402    /// Name of the argument, if any.
2403    pub name: Option<String>,
2404    /// Type of the argument.
2405    pub ty: Handle<Type>,
2406    /// For entry points, an argument has to have a binding
2407    /// unless it's a structure.
2408    pub binding: Option<Binding>,
2409}
2410
2411/// A function result.
2412#[derive(Clone, Debug)]
2413#[cfg_attr(feature = "serialize", derive(Serialize))]
2414#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2415#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2416pub struct FunctionResult {
2417    /// Type of the result.
2418    pub ty: Handle<Type>,
2419    /// For entry points, the result has to have a binding
2420    /// unless it's a structure.
2421    pub binding: Option<Binding>,
2422}
2423
2424/// A function defined in the module.
2425#[derive(Debug, Default, Clone)]
2426#[cfg_attr(feature = "serialize", derive(Serialize))]
2427#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2428#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2429pub struct Function {
2430    /// Name of the function, if any.
2431    ///
2432    /// Unlike WGSL, Naga IR allows a module to have multiple functions with the
2433    /// same name. Since functions are generally identified by handle, the name
2434    /// is mostly needed for diagnostics and as a hint to [`Namer`].
2435    ///
2436    /// [`Namer`]: crate::proc::Namer
2437    pub name: Option<String>,
2438    /// Information about function argument.
2439    pub arguments: Vec<FunctionArgument>,
2440    /// The result of this function, if any.
2441    pub result: Option<FunctionResult>,
2442    /// Local variables defined and used in the function.
2443    pub local_variables: Arena<LocalVariable>,
2444    /// Expressions used inside this function.
2445    ///
2446    /// Unless explicitly stated otherwise, if an [`Expression`] is in this
2447    /// arena, then its subexpressions are in this arena too. In other words,
2448    /// every `Handle<Expression>` in this arena refers to an [`Expression`] in
2449    /// this arena too.
2450    ///
2451    /// The main ways this arena refers to [`Module::global_expressions`] are:
2452    ///
2453    /// - [`Constant`], [`Override`], and [`GlobalVariable`] expressions hold
2454    ///   handles for their respective types, whose initializer expressions are
2455    ///   in [`Module::global_expressions`].
2456    ///
2457    /// - Various expressions hold [`Type`] handles, and [`Type`]s may refer to
2458    ///   global expressions, for things like array lengths.
2459    ///
2460    /// An [`Expression`] must occur before all other [`Expression`]s that use
2461    /// its value.
2462    ///
2463    /// [`Constant`]: Expression::Constant
2464    /// [`Override`]: Expression::Override
2465    /// [`GlobalVariable`]: Expression::GlobalVariable
2466    pub expressions: Arena<Expression>,
2467    /// Map of expressions that have associated variable names
2468    pub named_expressions: NamedExpressions,
2469    /// Block of instructions comprising the body of the function.
2470    pub body: Block,
2471    /// The leaf of all diagnostic filter rules tree (stored in [`Module::diagnostic_filters`])
2472    /// parsed on this function.
2473    ///
2474    /// In WGSL, this corresponds to `@diagnostic(…)` attributes.
2475    ///
2476    /// See [`DiagnosticFilterNode`] for details on how the tree is represented and used in
2477    /// validation.
2478    pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
2479}
2480
2481/// The main function for a pipeline stage.
2482///
2483/// An [`EntryPoint`] is a [`Function`] that serves as the main function for a
2484/// graphics or compute pipeline stage. For example, an `EntryPoint` whose
2485/// [`stage`] is [`ShaderStage::Vertex`] can serve as a graphics pipeline's
2486/// vertex shader.
2487///
2488/// Since an entry point is called directly by the graphics or compute pipeline,
2489/// not by other WGSL functions, you must specify what the pipeline should pass
2490/// as the entry point's arguments, and what values it will return. For example,
2491/// a vertex shader needs a vertex's attributes as its arguments, but if it's
2492/// used for instanced draw calls, it will also want to know the instance id.
2493/// The vertex shader's return value will usually include an output vertex
2494/// position, and possibly other attributes to be interpolated and passed along
2495/// to a fragment shader.
2496///
2497/// To specify this, the arguments and result of an `EntryPoint`'s [`function`]
2498/// must each have a [`Binding`], or be structs whose members all have
2499/// `Binding`s. This associates every value passed to or returned from the entry
2500/// point with either a [`BuiltIn`] or a [`Location`]:
2501///
2502/// -   A [`BuiltIn`] has special semantics, usually specific to its pipeline
2503///     stage. For example, the result of a vertex shader can include a
2504///     [`BuiltIn::Position`] value, which determines the position of a vertex
2505///     of a rendered primitive. Or, a compute shader might take an argument
2506///     whose binding is [`BuiltIn::WorkGroupSize`], through which the compute
2507///     pipeline would pass the number of invocations in your workgroup.
2508///
2509/// -   A [`Location`] indicates user-defined IO to be passed from one pipeline
2510///     stage to the next. For example, a vertex shader might also produce a
2511///     `uv` texture location as a user-defined IO value.
2512///
2513/// In other words, the pipeline stage's input and output interface are
2514/// determined by the bindings of the arguments and result of the `EntryPoint`'s
2515/// [`function`].
2516///
2517/// [`Function`]: crate::Function
2518/// [`Location`]: Binding::Location
2519/// [`function`]: EntryPoint::function
2520/// [`stage`]: EntryPoint::stage
2521#[derive(Debug, Clone)]
2522#[cfg_attr(feature = "serialize", derive(Serialize))]
2523#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2524#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2525pub struct EntryPoint {
2526    /// Name of this entry point, visible externally.
2527    ///
2528    /// Unlike WGSL, Naga IR allows a module to have multiple entry points with
2529    /// the same name, as long as they are for different shader stages. That is,
2530    /// `(name, stage)` pairs must be distinct within a module.
2531    pub name: String,
2532    /// Shader stage.
2533    pub stage: ShaderStage,
2534    /// Early depth test for fragment stages.
2535    pub early_depth_test: Option<EarlyDepthTest>,
2536    /// Workgroup size for compute stages
2537    pub workgroup_size: [u32; 3],
2538    /// Override expressions for workgroup size in the global_expressions arena
2539    pub workgroup_size_overrides: Option<[Option<Handle<Expression>>; 3]>,
2540    /// The entrance function.
2541    pub function: Function,
2542    /// Information for [`Mesh`] shaders.
2543    ///
2544    /// [`Mesh`]: ShaderStage::Mesh
2545    pub mesh_info: Option<MeshStageInfo>,
2546    /// The unique global variable used as a task payload from task shader to mesh shader
2547    pub task_payload: Option<Handle<GlobalVariable>>,
2548    /// The unique global variable used as an incoming ray payload going into any hit, closest hit and miss shaders.
2549    /// Unlike the outgoing ray payload, an incoming ray payload must be unique
2550    pub incoming_ray_payload: Option<Handle<GlobalVariable>>,
2551}
2552
2553/// Return types predeclared for the frexp, modf, and atomicCompareExchangeWeak built-in functions.
2554///
2555/// These cannot be spelled in WGSL source.
2556///
2557/// Stored in [`SpecialTypes::predeclared_types`] and created by [`Module::generate_predeclared_type`].
2558#[derive(Debug, PartialEq, Eq, Hash, Clone)]
2559#[cfg_attr(feature = "serialize", derive(Serialize))]
2560#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2561#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2562pub enum PredeclaredType {
2563    AtomicCompareExchangeWeakResult(Scalar),
2564    ModfResult {
2565        size: Option<VectorSize>,
2566        scalar: Scalar,
2567    },
2568    FrexpResult {
2569        size: Option<VectorSize>,
2570        scalar: Scalar,
2571    },
2572}
2573
2574/// Set of special types that can be optionally generated by the frontends.
2575#[derive(Debug, Default, Clone)]
2576#[cfg_attr(feature = "serialize", derive(Serialize))]
2577#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2578#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2579pub struct SpecialTypes {
2580    /// Type for `RayDesc`.
2581    ///
2582    /// Call [`Module::generate_ray_desc_type`] to populate this if
2583    /// needed and return the handle.
2584    pub ray_desc: Option<Handle<Type>>,
2585
2586    /// Type for `RayIntersection`.
2587    ///
2588    /// Call [`Module::generate_ray_intersection_type`] to populate
2589    /// this if needed and return the handle.
2590    pub ray_intersection: Option<Handle<Type>>,
2591
2592    /// Type for `RayVertexReturn`.
2593    ///
2594    /// Call [`Module::generate_vertex_return_type`]
2595    pub ray_vertex_return: Option<Handle<Type>>,
2596
2597    /// Struct containing parameters required by some backends to emit code for
2598    /// [`ImageClass::External`] textures.
2599    ///
2600    /// See `wgpu_core::device::resource::ExternalTextureParams` for the
2601    /// documentation of each field.
2602    ///
2603    /// In WGSL, this type would be:
2604    ///
2605    /// ```ignore
2606    /// struct NagaExternalTextureParams {         // align size offset
2607    ///     yuv_conversion_matrix: mat4x4<f32>,    //    16   64      0
2608    ///     gamut_conversion_matrix: mat3x3<f32>,  //    16   48     64
2609    ///     src_tf: NagaExternalTextureTransferFn, //     4   16    112
2610    ///     dst_tf: NagaExternalTextureTransferFn, //     4   16    128
2611    ///     sample_transform: mat3x2<f32>,         //     8   24    144
2612    ///     load_transform: mat3x2<f32>,           //     8   24    168
2613    ///     size: vec2<u32>,                       //     8    8    192
2614    ///     num_planes: u32,                       //     4    4    200
2615    /// }                            // whole struct:    16  208
2616    /// ```
2617    ///
2618    /// Call [`Module::generate_external_texture_types`] to populate this if
2619    /// needed.
2620    pub external_texture_params: Option<Handle<Type>>,
2621
2622    /// Struct describing a gamma encoding transfer function. Member of
2623    /// `NagaExternalTextureParams`, describing how the backend should perform
2624    /// color space conversion when sampling from [`ImageClass::External`]
2625    /// textures.
2626    ///
2627    /// In WGSL, this type would be:
2628    ///
2629    /// ```ignore
2630    /// struct NagaExternalTextureTransferFn { // align size offset
2631    ///     a: f32,                            //     4    4      0
2632    ///     b: f32,                            //     4    4      4
2633    ///     g: f32,                            //     4    4      8
2634    ///     k: f32,                            //     4    4     12
2635    /// }                         // whole struct:    4   16
2636    /// ```
2637    ///
2638    /// Call [`Module::generate_external_texture_types`] to populate this if
2639    /// needed.
2640    pub external_texture_transfer_function: Option<Handle<Type>>,
2641
2642    /// Types for predeclared wgsl types instantiated on demand.
2643    ///
2644    /// Call [`Module::generate_predeclared_type`] to populate this if
2645    /// needed and return the handle.
2646    pub predeclared_types: FastIndexMap<PredeclaredType, Handle<Type>>,
2647}
2648
2649bitflags::bitflags! {
2650    /// Ray flags used when casting rays.
2651    /// Matching vulkan constants can be found in
2652    /// https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/ray_common/ray_flags_section.txt
2653    #[cfg_attr(feature = "serialize", derive(Serialize))]
2654    #[cfg_attr(feature = "deserialize", derive(Deserialize))]
2655    #[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2656    #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
2657    pub struct RayFlag: u32 {
2658        /// Force all intersections to be treated as opaque.
2659        const FORCE_OPAQUE = 0x1;
2660        /// Force all intersections to be treated as non-opaque.
2661        const FORCE_NO_OPAQUE = 0x2;
2662        /// Stop traversal after the first hit.
2663        const TERMINATE_ON_FIRST_HIT = 0x4;
2664        /// Don't execute the closest hit shader.
2665        const SKIP_CLOSEST_HIT_SHADER = 0x8;
2666        /// Cull back facing geometry.
2667        const CULL_BACK_FACING = 0x10;
2668        /// Cull front facing geometry.
2669        const CULL_FRONT_FACING = 0x20;
2670        /// Cull opaque geometry.
2671        const CULL_OPAQUE = 0x40;
2672        /// Cull non-opaque geometry.
2673        const CULL_NO_OPAQUE = 0x80;
2674        /// Skip triangular geometry.
2675        const SKIP_TRIANGLES = 0x100;
2676        /// Skip axis-aligned bounding boxes.
2677        const SKIP_AABBS = 0x200;
2678    }
2679}
2680
2681/// Type of a ray query intersection.
2682/// Matching vulkan constants can be found in
2683/// <https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_ray_query.asciidoc>
2684/// but the actual values are different for candidate intersections.
2685#[cfg_attr(feature = "serialize", derive(Serialize))]
2686#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2687#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2688#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
2689pub enum RayQueryIntersection {
2690    /// No intersection found.
2691    /// Matches `RayQueryCommittedIntersectionNoneKHR`.
2692    #[default]
2693    None = 0,
2694    /// Intersecting with triangles.
2695    /// Matches `RayQueryCommittedIntersectionTriangleKHR` and `RayQueryCandidateIntersectionTriangleKHR`.
2696    Triangle = 1,
2697    /// Intersecting with generated primitives.
2698    /// Matches `RayQueryCommittedIntersectionGeneratedKHR`.
2699    Generated = 2,
2700    /// Intersecting with Axis Aligned Bounding Boxes.
2701    /// Matches `RayQueryCandidateIntersectionAABBKHR`.
2702    Aabb = 3,
2703}
2704
2705/// Doc comments preceding items.
2706///
2707/// These can be used to generate automated documentation,
2708/// IDE hover information or translate shaders with their context comments.
2709#[derive(Debug, Default, Clone)]
2710#[cfg_attr(feature = "serialize", derive(Serialize))]
2711#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2712#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2713pub struct DocComments {
2714    pub types: FastIndexMap<Handle<Type>, Vec<String>>,
2715    // The key is:
2716    // - key.0: the handle to the Struct
2717    // - key.1: the index of the `StructMember`.
2718    pub struct_members: FastIndexMap<(Handle<Type>, usize), Vec<String>>,
2719    pub entry_points: FastIndexMap<usize, Vec<String>>,
2720    pub functions: FastIndexMap<Handle<Function>, Vec<String>>,
2721    pub constants: FastIndexMap<Handle<Constant>, Vec<String>>,
2722    pub global_variables: FastIndexMap<Handle<GlobalVariable>, Vec<String>>,
2723    // Top level comments, appearing before any space.
2724    pub module: Vec<String>,
2725}
2726
2727/// The output topology for a mesh shader. Note that mesh shaders don't allow things like triangle-strips.
2728#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2729#[cfg_attr(feature = "serialize", derive(Serialize))]
2730#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2731#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2732pub enum MeshOutputTopology {
2733    /// Outputs individual vertices to be rendered as points.
2734    Points,
2735    /// Outputs groups of 2 vertices to be renderedas lines .
2736    Lines,
2737    /// Outputs groups of 3 vertices to be rendered as triangles.
2738    Triangles,
2739}
2740
2741/// Information specific to mesh shader entry points.
2742#[derive(Debug, Clone, PartialEq, Eq)]
2743#[cfg_attr(feature = "serialize", derive(Serialize))]
2744#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2745#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2746#[allow(dead_code)]
2747pub struct MeshStageInfo {
2748    /// The type of primitive outputted.
2749    pub topology: MeshOutputTopology,
2750    /// The maximum number of vertices a mesh shader may output.
2751    pub max_vertices: u32,
2752    /// If pipeline constants are used, the expressions that override `max_vertices`
2753    pub max_vertices_override: Option<Handle<Expression>>,
2754    /// The maximum number of primitives a mesh shader may output.
2755    pub max_primitives: u32,
2756    /// If pipeline constants are used, the expressions that override `max_primitives`
2757    pub max_primitives_override: Option<Handle<Expression>>,
2758    /// The type used by vertex outputs, i.e. what is passed to `setVertex`.
2759    pub vertex_output_type: Handle<Type>,
2760    /// The type used by primitive outputs, i.e. what is passed to `setPrimitive`.
2761    pub primitive_output_type: Handle<Type>,
2762    /// The global variable holding the outputted vertices, primitives, and counts
2763    pub output_variable: Handle<GlobalVariable>,
2764}
2765
2766/// Ray tracing pipeline intrinsics
2767#[derive(Debug, Clone, Copy)]
2768#[cfg_attr(feature = "serialize", derive(Serialize))]
2769#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2770#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2771pub enum RayPipelineFunction {
2772    /// Traces a ray through the given acceleration structure
2773    TraceRay {
2774        /// The acceleration structure within which this ray should search for hits.
2775        ///
2776        /// The expression must be an [`AccelerationStructure`].
2777        ///
2778        /// [`AccelerationStructure`]: TypeInner::AccelerationStructure
2779        acceleration_structure: Handle<Expression>,
2780
2781        #[allow(rustdoc::private_intra_doc_links)]
2782        /// A struct of detailed parameters for the ray query.
2783        ///
2784        /// This expression should have the struct type given in
2785        /// [`SpecialTypes::ray_desc`]. This is available in the WGSL
2786        /// front end as the `RayDesc` type.
2787        descriptor: Handle<Expression>,
2788
2789        /// A pointer in the ray_payload or incoming_ray_payload address spaces
2790        payload: Handle<Expression>,
2791        // Do we want miss index? What about sbt offset and sbt stride (could be hard to validate)?
2792        // https://github.com/gfx-rs/wgpu/issues/8894
2793    },
2794}
2795
2796/// Shader module.
2797///
2798/// A module is a set of constants, global variables and functions, as well as
2799/// the types required to define them.
2800///
2801/// Some functions are marked as entry points, to be used in a certain shader stage.
2802///
2803/// To create a new module, use the `Default` implementation.
2804/// Alternatively, you can load an existing shader using one of the [available front ends].
2805///
2806/// When finished, you can export modules using one of the [available backends].
2807///
2808/// ## Module arenas
2809///
2810/// Most module contents are stored in [`Arena`]s. In a valid module, arena
2811/// elements only refer to prior arena elements. That is, whenever an element in
2812/// some `Arena<T>` contains a `Handle<T>` referring to another element the same
2813/// arena, the handle's referent always precedes the element containing the
2814/// handle.
2815///
2816/// The elements of [`Module::types`] may refer to [`Expression`]s in
2817/// [`Module::global_expressions`], and those expressions may in turn refer back
2818/// to [`Type`]s in [`Module::types`]. In a valid module, there exists an order
2819/// in which all types and global expressions can be visited such that:
2820///
2821/// - types and expressions are visited in the order in which they appear in
2822///   their arenas, and
2823///
2824/// - every element refers only to previously visited elements.
2825///
2826/// This implies that the graph of types and global expressions is acyclic.
2827/// (However, it is a stronger condition: there are cycle-free arrangements of
2828/// types and expressions for which an order like the one described above does
2829/// not exist. Modules arranged in such a way are not valid.)
2830///
2831/// [available front ends]: crate::front
2832/// [available backends]: crate::back
2833#[derive(Debug, Default, Clone)]
2834#[cfg_attr(feature = "serialize", derive(Serialize))]
2835#[cfg_attr(feature = "deserialize", derive(Deserialize))]
2836#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
2837pub struct Module {
2838    /// Arena for the types defined in this module.
2839    ///
2840    /// See the [`Module`] docs for more details about this field.
2841    pub types: UniqueArena<Type>,
2842    /// Dictionary of special type handles.
2843    pub special_types: SpecialTypes,
2844    /// Arena for the constants defined in this module.
2845    pub constants: Arena<Constant>,
2846    /// Arena for the pipeline-overridable constants defined in this module.
2847    pub overrides: Arena<Override>,
2848    /// Arena for the global variables defined in this module.
2849    pub global_variables: Arena<GlobalVariable>,
2850    /// [Constant expressions] and [override expressions] used by this module.
2851    ///
2852    /// If an expression is in this arena, then its subexpressions are in this
2853    /// arena too. In other words, every `Handle<Expression>` in this arena
2854    /// refers to an [`Expression`] in this arena too.
2855    ///
2856    /// See the [`Module`] docs for more details about this field.
2857    ///
2858    /// [Constant expressions]: index.html#constant-expressions
2859    /// [override expressions]: index.html#override-expressions
2860    pub global_expressions: Arena<Expression>,
2861    /// Arena for the functions defined in this module.
2862    ///
2863    /// Each function must appear in this arena strictly before all its callers.
2864    /// Recursion is not supported.
2865    pub functions: Arena<Function>,
2866    /// Entry points.
2867    pub entry_points: Vec<EntryPoint>,
2868    /// Arena for all diagnostic filter rules parsed in this module, including those in functions
2869    /// and statements.
2870    ///
2871    /// This arena contains elements of a _tree_ of diagnostic filter rules. When nodes are built
2872    /// by a front-end, they refer to a parent scope
2873    pub diagnostic_filters: Arena<DiagnosticFilterNode>,
2874    /// The leaf of all diagnostic filter rules tree parsed from directives in this module.
2875    ///
2876    /// In WGSL, this corresponds to `diagnostic(…);` directives.
2877    ///
2878    /// See [`DiagnosticFilterNode`] for details on how the tree is represented and used in
2879    /// validation.
2880    pub diagnostic_filter_leaf: Option<Handle<DiagnosticFilterNode>>,
2881    /// Doc comments.
2882    pub doc_comments: Option<Box<DocComments>>,
2883}