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