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