naga/
lib.rs

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