From 6035b07b786135f65cb4140f99cf67cc0381b4c3 Mon Sep 17 00:00:00 2001 From: SparkyPotato Date: Thu, 12 Jan 2023 09:26:28 -0800 Subject: [PATCH] [wgsl-in] Implement module-level scoping. Fixes #1745: Support out-of-order module scope declarations in WGSL Fixes #1044: Forbid local variable shadowing in WGSL Fixes #2076: [wgsl-in] no error for duplicated type definition Fixes #2071: Global item does not support 'const' Fixes #2105: [wgsl-in] Type aliases for a vecN doesn't work when constructing vec from a single argument Fixes #1775: Referencing a function without a return type yields an unknown identifier error. Fixes #2089: Error span reported on the declaration of a variable instead of its use Fixes #1996: [wgsl-in] Confusing error: "expected unsigned/signed integer literal, found '1'" Separate parsing from lowering by generating an AST, which desugars as much as possible down to something like Naga IR. The AST is then used to resolve identifiers while lowering to Naga IR. Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com> Co-authored-by: Jim Blandy --- src/back/wgsl/writer.rs | 4 +- src/front/glsl/parser_tests.rs | 2 +- src/front/glsl/types.rs | 15 +- src/front/mod.rs | 67 +- src/front/wgsl/ast.rs | 476 ++ src/front/wgsl/construction.rs | 1271 ++-- src/front/wgsl/conv.rs | 3 +- src/front/wgsl/index.rs | 192 + src/front/wgsl/lexer.rs | 88 +- src/front/wgsl/mod.rs | 5787 +++++++++-------- src/front/wgsl/tests.rs | 6 +- src/span.rs | 17 + tests/in/access.wgsl | 6 +- tests/in/atomicCompareExchange.wgsl | 2 +- tests/in/bitcast.wgsl | 8 +- tests/in/boids.wgsl | 2 +- tests/in/globals.wgsl | 6 +- tests/in/module-scope.wgsl | 26 + tests/in/operators.wgsl | 8 +- tests/in/quad.wgsl | 4 +- tests/in/shadow.wgsl | 4 +- tests/in/type-alias.wgsl | 13 + tests/out/analysis/collatz.info.ron | 110 +- tests/out/dot/quad.dot | 78 +- .../access.assign_through_ptr.Compute.glsl | 4 +- tests/out/glsl/access.atomics.Compute.glsl | 30 +- tests/out/glsl/access.foo_frag.Fragment.glsl | 4 +- tests/out/glsl/access.foo_vert.Vertex.glsl | 113 +- tests/out/glsl/bits.main.Compute.glsl | 2 + tests/out/glsl/boids.main.Compute.glsl | 159 +- ...age-restrict.fragment_shader.Fragment.glsl | 32 +- ...k-image-rzsw.fragment_shader.Fragment.glsl | 26 +- tests/out/glsl/globals.main.Compute.glsl | 43 +- tests/out/glsl/operators.main.Compute.glsl | 74 +- tests/out/glsl/padding.vertex.Vertex.glsl | 6 +- tests/out/glsl/shadow.fs_main.Fragment.glsl | 42 +- ...adow.fs_main_without_storage.Fragment.glsl | 42 +- tests/out/glsl/shadow.vs_main.Vertex.glsl | 12 +- tests/out/glsl/skybox.fs_main.Fragment.glsl | 4 +- tests/out/glsl/skybox.vs_main.Vertex.glsl | 16 +- tests/out/glsl/texture-arg.main.Fragment.glsl | 4 +- tests/out/hlsl/access.hlsl | 141 +- tests/out/hlsl/binding-arrays.hlsl | 236 +- tests/out/hlsl/boids.hlsl | 165 +- tests/out/hlsl/collatz.hlsl | 37 +- tests/out/hlsl/globals.hlsl | 47 +- tests/out/hlsl/interface.hlsl | 7 +- tests/out/hlsl/operators.hlsl | 74 +- tests/out/hlsl/padding.hlsl | 6 +- tests/out/hlsl/shadow.hlsl | 92 +- tests/out/hlsl/skybox.hlsl | 20 +- tests/out/hlsl/texture-arg.hlsl | 4 +- tests/out/ir/collatz.ron | 220 +- tests/out/msl/access.msl | 157 +- tests/out/msl/binding-arrays.msl | 236 +- tests/out/msl/bits.msl | 6 +- tests/out/msl/boids.msl | 165 +- tests/out/msl/bounds-check-image-restrict.msl | 48 +- tests/out/msl/bounds-check-image-rzsw.msl | 38 +- tests/out/msl/bounds-check-restrict.msl | 6 +- tests/out/msl/bounds-check-zero.msl | 6 +- tests/out/msl/collatz.msl | 37 +- tests/out/msl/globals.msl | 47 +- tests/out/msl/interface.msl | 7 +- tests/out/msl/math-functions.msl | 4 +- tests/out/msl/operators.msl | 118 +- tests/out/msl/padding.msl | 6 +- tests/out/msl/policy-mix.msl | 10 +- tests/out/msl/shadow.msl | 92 +- tests/out/msl/skybox.msl | 20 +- tests/out/msl/texture-arg.msl | 4 +- tests/out/spv/access.spvasm | 732 +-- tests/out/spv/atomicCompareExchange.spvasm | 264 +- tests/out/spv/binding-arrays.spvasm | 1032 +-- tests/out/spv/bits.spvasm | 398 +- tests/out/spv/boids.spvasm | 498 +- tests/out/spv/collatz.spvasm | 140 +- tests/out/spv/extra.spvasm | 96 +- tests/out/spv/functions.spvasm | 86 +- tests/out/spv/globals.spvasm | 234 +- tests/out/spv/image.spvasm | 718 +- .../spv/interface.vertex_two_structs.spvasm | 53 +- tests/out/spv/math-functions.spvasm | 38 +- tests/out/spv/operators.spvasm | 488 +- tests/out/spv/shadow.spvasm | 524 +- tests/out/wgsl/access.wgsl | 141 +- tests/out/wgsl/atomicCompareExchange.wgsl | 96 +- tests/out/wgsl/binding-arrays.wgsl | 260 +- tests/out/wgsl/bits.wgsl | 6 +- tests/out/wgsl/boids.wgsl | 167 +- tests/out/wgsl/collatz.wgsl | 37 +- tests/out/wgsl/globals.wgsl | 43 +- tests/out/wgsl/interface.wgsl | 7 +- tests/out/wgsl/lexical-scopes.wgsl | 11 +- tests/out/wgsl/module-scope.wgsl | 26 + tests/out/wgsl/operators.wgsl | 82 +- tests/out/wgsl/padding.wgsl | 6 +- tests/out/wgsl/quad.wgsl | 2 +- tests/out/wgsl/shadow.wgsl | 96 +- tests/out/wgsl/skybox.wgsl | 20 +- tests/out/wgsl/texture-arg.wgsl | 4 +- tests/out/wgsl/type-alias.wgsl | 9 + tests/snapshots.rs | 2 + tests/wgsl-errors.rs | 252 +- 104 files changed, 9624 insertions(+), 7808 deletions(-) create mode 100644 src/front/wgsl/ast.rs create mode 100644 src/front/wgsl/index.rs create mode 100644 tests/in/module-scope.wgsl create mode 100644 tests/in/type-alias.wgsl create mode 100644 tests/out/wgsl/module-scope.wgsl create mode 100644 tests/out/wgsl/type-alias.wgsl diff --git a/src/back/wgsl/writer.rs b/src/back/wgsl/writer.rs index f9e98e8cdc..51091f8be1 100644 --- a/src/back/wgsl/writer.rs +++ b/src/back/wgsl/writer.rs @@ -1850,7 +1850,7 @@ impl Writer { } => { let name = &self.names[&NameKey::Constant(handle)]; // First write only constant name - write!(self.out, "let {}: ", name)?; + write!(self.out, "const {}: ", name)?; // Next write constant type and value match *value { crate::ScalarValue::Sint(value) => { @@ -1874,7 +1874,7 @@ impl Writer { crate::ConstantInner::Composite { ty, ref components } => { let name = &self.names[&NameKey::Constant(handle)]; // First write only constant name - write!(self.out, "let {}: ", name)?; + write!(self.out, "const {}: ", name)?; // Next write constant type self.write_type(module, ty)?; diff --git a/src/front/glsl/parser_tests.rs b/src/front/glsl/parser_tests.rs index 5f865e9752..d6d831aaf6 100644 --- a/src/front/glsl/parser_tests.rs +++ b/src/front/glsl/parser_tests.rs @@ -796,7 +796,7 @@ fn expressions() { # version 450 void main() { uint index = 0; - + --index; ++index; } diff --git a/src/front/glsl/types.rs b/src/front/glsl/types.rs index 05c415eba0..427b0b27ba 100644 --- a/src/front/glsl/types.rs +++ b/src/front/glsl/types.rs @@ -300,20 +300,7 @@ impl Parser { meta: Span, ) -> Result> { self.typifier_grow(ctx, expr, meta)?; - let resolution = &ctx.typifier[expr]; - Ok(match *resolution { - // If the resolution is already a handle return early - crate::proc::TypeResolution::Handle(ty) => ty, - // If it's a value we need to clone it - crate::proc::TypeResolution::Value(_) => match resolution.clone() { - // This is unreachable - crate::proc::TypeResolution::Handle(ty) => ty, - // Add the value to the type arena and return the handle - crate::proc::TypeResolution::Value(inner) => { - self.module.types.insert(Type { name: None, inner }, meta) - } - }, - }) + Ok(ctx.typifier.register_type(expr, &mut self.module.types)) } /// Invalidates the cached type resolution for `expr` forcing a recomputation diff --git a/src/front/mod.rs b/src/front/mod.rs index 09836c6762..071e805a69 100644 --- a/src/front/mod.rs +++ b/src/front/mod.rs @@ -64,7 +64,35 @@ impl super::ConstantInner { } } -/// Helper processor that derives the types of all expressions. +/// A table of types for an `Arena`. +/// +/// A front end can use a `Typifier` to get types for an arena's expressions +/// while it is still contributing expressions to it. At any point, you can call +/// [`typifier.grow(expr, arena, ctx)`], where `expr` is a `Handle` +/// referring to something in `arena`, and the `Typifier` will resolve the types +/// of all the expressions up to and including `expr`. Then you can write +/// `typifier[handle]` to get the type of any handle at or before `expr`. +/// +/// Note that `Typifier` does *not* build an `Arena` as a part of its +/// usual operation. Ideally, a module's type arena should only contain types +/// actually needed by `Handle`s elsewhere in the module — functions, +/// variables, [`Compose`] expressions, other types, and so on — so we don't +/// want every little thing that occurs as the type of some intermediate +/// expression to show up there. +/// +/// Instead, `Typifier` accumulates a [`TypeResolution`] for each expression, +/// which refers to the `Arena` in the [`ResolveContext`] passed to `grow` +/// as needed. [`TypeResolution`] is a lightweight representation for +/// intermediate types like this; see its documentation for details. +/// +/// If you do need to register a `Typifier`'s conclusion in an `Arena` +/// (say, for a [`LocalVariable`] whose type you've inferred), you can use +/// [`register_type`] to do so. +/// +/// [`typifier.grow(expr, arena)`]: Typifier::grow +/// [`register_type`]: Typifier::register_type +/// [`Compose`]: crate::Expression::Compose +/// [`LocalVariable`]: crate::LocalVariable #[derive(Debug, Default)] pub struct Typifier { resolutions: Vec, @@ -89,6 +117,34 @@ impl Typifier { self.resolutions[expr_handle.index()].inner_with(types) } + /// Add an expression's type to an `Arena`. + /// + /// Add the type of `expr_handle` to `types`, and return a `Handle` + /// referring to it. + /// + /// # Note + /// + /// If you just need a [`TypeInner`] for `expr_handle`'s type, consider + /// using `typifier[expression].inner_with(types)` instead. Calling + /// [`TypeResolution::inner_with`] often lets us avoid adding anything to + /// the arena, which can significantly reduce the number of types that end + /// up in the final module. + /// + /// [`TypeInner`]: crate::TypeInner + pub fn register_type( + &self, + expr_handle: Handle, + types: &mut UniqueArena, + ) -> Handle { + match self[expr_handle].clone() { + TypeResolution::Handle(handle) => handle, + TypeResolution::Value(inner) => { + types.insert(crate::Type { name: None, inner }, crate::Span::UNDEFINED) + } + } + } + + /// Grow this typifier until it contains a type for `expr_handle`. pub fn grow( &mut self, expr_handle: Handle, @@ -106,10 +162,13 @@ impl Typifier { Ok(()) } - /// Invalidates the cached type resolution for `expr_handle` forcing a recomputation + /// Recompute the type resolution for `expr_handle`. /// - /// If the type of the expression hasn't yet been calculated a - /// [`grow`](Self::grow) is performed instead + /// If the type of `expr_handle` hasn't yet been calculated, call + /// [`grow`](Self::grow) to ensure it is covered. + /// + /// In either case, when this returns, `self[expr_handle]` should be an + /// updated type resolution for `expr_handle`. pub fn invalidate( &mut self, expr_handle: Handle, diff --git a/src/front/wgsl/ast.rs b/src/front/wgsl/ast.rs new file mode 100644 index 0000000000..eff74530fa --- /dev/null +++ b/src/front/wgsl/ast.rs @@ -0,0 +1,476 @@ +use super::Number; +use crate::{Arena, FastHashSet, Handle, Span}; +use std::hash::Hash; + +#[derive(Debug, Default)] +pub struct TranslationUnit<'a> { + pub decls: Arena>, + /// The common expressions arena for the entire translation unit. + /// + /// All functions, global initializers, array lengths, etc. store their + /// expressions here. We apportion these out to individual Naga + /// [`Function`]s' expression arenas at lowering time. Keeping them all in a + /// single arena simplifies handling of things like array lengths (which are + /// effectively global and thus don't clearly belong to any function) and + /// initializers (which can appear in both function-local and module-scope + /// contexts). + /// + /// [`Function`]: crate::Function + pub expressions: Arena>, + + /// Non-user-defined types, like `vec4` or `array`. + /// + /// These are referred to by `Handle>` values. + /// User-defined types are referred to by name until lowering. + pub types: Arena>, +} + +#[derive(Debug, Clone, Copy)] +pub struct Ident<'a> { + pub name: &'a str, + pub span: Span, +} + +#[derive(Debug)] +pub enum IdentExpr<'a> { + Unresolved(&'a str), + Local(Handle), +} + +/// A reference to a module-scope definition or predeclared object. +/// +/// Each [`GlobalDecl`] holds a set of these values, to be resolved to +/// specific definitions later. To support de-duplication, `Eq` and +/// `Hash` on a `Dependency` value consider only the name, not the +/// source location at which the reference occurs. +#[derive(Debug)] +pub struct Dependency<'a> { + /// The name referred to. + pub ident: &'a str, + + /// The location at which the reference to that name occurs. + pub usage: Span, +} + +impl Hash for Dependency<'_> { + fn hash(&self, state: &mut H) { + self.ident.hash(state); + } +} + +impl PartialEq for Dependency<'_> { + fn eq(&self, other: &Self) -> bool { + self.ident == other.ident + } +} + +impl Eq for Dependency<'_> {} + +/// A module-scope declaration. +#[derive(Debug)] +pub struct GlobalDecl<'a> { + pub kind: GlobalDeclKind<'a>, + + /// Names of all module-scope or predeclared objects this + /// declaration uses. + pub dependencies: FastHashSet>, +} + +#[derive(Debug)] +pub enum GlobalDeclKind<'a> { + Fn(Function<'a>), + Var(GlobalVariable<'a>), + Const(Const<'a>), + Struct(Struct<'a>), + Type(TypeAlias<'a>), +} + +#[derive(Debug)] +pub struct FunctionArgument<'a> { + pub name: Ident<'a>, + pub ty: Handle>, + pub binding: Option, + pub handle: Handle, +} + +#[derive(Debug)] +pub struct FunctionResult<'a> { + pub ty: Handle>, + pub binding: Option, +} + +#[derive(Debug)] +pub struct EntryPoint { + pub stage: crate::ShaderStage, + pub early_depth_test: Option, + pub workgroup_size: [u32; 3], +} + +#[derive(Debug)] +pub struct Function<'a> { + pub entry_point: Option, + pub name: Ident<'a>, + pub arguments: Vec>, + pub result: Option>, + + /// Local variable and function argument arena. + /// + /// Note that the `Local` here is actually a zero-sized type. The AST keeps + /// all the detailed information about locals - names, types, etc. - in + /// [`LocalDecl`] statements. For arguments, that information is kept in + /// [`arguments`]. This `Arena`'s only role is to assign a unique `Handle` + /// to each of them, and track their definitions' spans for use in + /// diagnostics. + /// + /// In the AST, when an [`Ident`] expression refers to a local variable or + /// argument, its [`IdentExpr`] holds the referent's `Handle` in this + /// arena. + /// + /// During lowering, [`LocalDecl`] statements add entries to a per-function + /// table that maps `Handle` values to their Naga representations, + /// accessed via [`StatementContext::local_table`] and + /// [`ExpressionContext::local_table`]. This table is then consulted when + /// lowering subsequent [`Ident`] expressions. + /// + /// [`LocalDecl`]: StatementKind::LocalDecl + /// [`arguments`]: Function::arguments + /// [`Ident`]: Expression::Ident + /// [`StatementContext::local_table`]: super::StatementContext::local_table + /// [`ExpressionContext::local_table`]: super::ExpressionContext::local_table + pub locals: Arena, + + pub body: Block<'a>, +} + +#[derive(Debug)] +pub struct GlobalVariable<'a> { + pub name: Ident<'a>, + pub space: crate::AddressSpace, + pub binding: Option, + pub ty: Handle>, + pub init: Option>>, +} + +#[derive(Debug)] +pub struct StructMember<'a> { + pub name: Ident<'a>, + pub ty: Handle>, + pub binding: Option, + pub align: Option<(u32, Span)>, + pub size: Option<(u32, Span)>, +} + +#[derive(Debug)] +pub struct Struct<'a> { + pub name: Ident<'a>, + pub members: Vec>, +} + +#[derive(Debug)] +pub struct TypeAlias<'a> { + pub name: Ident<'a>, + pub ty: Handle>, +} + +#[derive(Debug)] +pub struct Const<'a> { + pub name: Ident<'a>, + pub ty: Option>>, + pub init: Handle>, +} + +/// The size of an [`Array`] or [`BindingArray`]. +/// +/// [`Array`]: Type::Array +/// [`BindingArray`]: Type::BindingArray +#[derive(Debug, Copy, Clone)] +pub enum ArraySize<'a> { + /// The length as a constant expression. + Constant(Handle>), + Dynamic, +} + +#[derive(Debug)] +pub enum Type<'a> { + Scalar { + kind: crate::ScalarKind, + width: crate::Bytes, + }, + Vector { + size: crate::VectorSize, + kind: crate::ScalarKind, + width: crate::Bytes, + }, + Matrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + width: crate::Bytes, + }, + Atomic { + kind: crate::ScalarKind, + width: crate::Bytes, + }, + Pointer { + base: Handle>, + space: crate::AddressSpace, + }, + Array { + base: Handle>, + size: ArraySize<'a>, + }, + Image { + dim: crate::ImageDimension, + arrayed: bool, + class: crate::ImageClass, + }, + Sampler { + comparison: bool, + }, + BindingArray { + base: Handle>, + size: ArraySize<'a>, + }, + + /// A user-defined type, like a struct or a type alias. + User(Ident<'a>), +} + +#[derive(Debug, Default)] +pub struct Block<'a> { + pub stmts: Vec>, +} + +#[derive(Debug)] +pub struct Statement<'a> { + pub kind: StatementKind<'a>, + pub span: Span, +} + +#[derive(Debug)] +pub enum StatementKind<'a> { + LocalDecl(LocalDecl<'a>), + Block(Block<'a>), + If { + condition: Handle>, + accept: Block<'a>, + reject: Block<'a>, + }, + Switch { + selector: Handle>, + cases: Vec>, + }, + Loop { + body: Block<'a>, + continuing: Block<'a>, + break_if: Option>>, + }, + Break, + Continue, + Return { + value: Option>>, + }, + Kill, + Call { + function: Ident<'a>, + arguments: Vec>>, + }, + Assign { + target: Handle>, + op: Option, + value: Handle>, + }, + Increment(Handle>), + Decrement(Handle>), + Ignore(Handle>), +} + +#[derive(Debug)] +pub enum SwitchValue { + I32(i32), + U32(u32), + Default, +} + +#[derive(Debug)] +pub struct SwitchCase<'a> { + pub value: SwitchValue, + pub value_span: Span, + pub body: Block<'a>, + pub fall_through: bool, +} + +/// A type at the head of a [`Construct`] expression. +/// +/// WGSL has two types of [`type constructor expressions`]: +/// +/// - Those that fully specify the type being constructed, like +/// `vec3(x,y,z)`, which obviously constructs a `vec3`. +/// +/// - Those that leave the component type of the composite being constructed +/// implicit, to be inferred from the argument types, like `vec3(x,y,z)`, +/// which constructs a `vec3` where `T` is the type of `x`, `y`, and `z`. +/// +/// This enum represents the head type of both cases. The `PartialFoo` variants +/// represent the second case, where the component type is implicit. +/// +/// This does not cover structs or types referred to by type aliases. See the +/// documentation for [`Construct`] and [`Call`] expressions for details. +/// +/// [`Construct`]: Expression::Construct +/// [`type constructor expressions`]: https://gpuweb.github.io/gpuweb/wgsl/#type-constructor-expr +/// [`Call`]: Expression::Call +#[derive(Debug)] +pub enum ConstructorType<'a> { + /// A scalar type or conversion: `f32(1)`. + Scalar { + kind: crate::ScalarKind, + width: crate::Bytes, + }, + + /// A vector construction whose component type is inferred from the + /// argument: `vec3(1.0)`. + PartialVector { size: crate::VectorSize }, + + /// A vector construction whose component type is written out: + /// `vec3(1.0)`. + Vector { + size: crate::VectorSize, + kind: crate::ScalarKind, + width: crate::Bytes, + }, + + /// A matrix construction whose component type is inferred from the + /// argument: `mat2x2(1,2,3,4)`. + PartialMatrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + }, + + /// A matrix construction whose component type is written out: + /// `mat2x2(1,2,3,4)`. + Matrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + width: crate::Bytes, + }, + + /// An array whose component type and size are inferred from the arguments: + /// `array(3,4,5)`. + PartialArray, + + /// An array whose component type and size are written out: + /// `array(3,4,5)`. + Array { + base: Handle>, + size: ArraySize<'a>, + }, + + /// Constructing a value of a known Naga IR type. + /// + /// This variant is produced only during lowering, when we have Naga types + /// available, never during parsing. + Type(Handle), +} + +#[derive(Debug, Copy, Clone)] +pub enum Literal { + Bool(bool), + Number(Number), +} + +#[derive(Debug)] +pub enum Expression<'a> { + Literal(Literal), + Ident(IdentExpr<'a>), + + /// A type constructor expression. + /// + /// This is only used for expressions like `KEYWORD(EXPR...)` and + /// `KEYWORD(EXPR...)`, where `KEYWORD` is a [type-defining keyword] like + /// `vec3`. These keywords cannot be shadowed by user definitions, so we can + /// tell that such an expression is a construction immediately. + /// + /// For ordinary identifiers, we can't tell whether an expression like + /// `IDENTIFIER(EXPR, ...)` is a construction expression or a function call + /// until we know `IDENTIFIER`'s definition, so we represent those as + /// [`Call`] expressions. + /// + /// [type-defining keyword]: https://gpuweb.github.io/gpuweb/wgsl/#type-defining-keywords + /// [`Call`]: Expression::Call + Construct { + ty: ConstructorType<'a>, + ty_span: Span, + components: Vec>>, + }, + Unary { + op: crate::UnaryOperator, + expr: Handle>, + }, + AddrOf(Handle>), + Deref(Handle>), + Binary { + op: crate::BinaryOperator, + left: Handle>, + right: Handle>, + }, + + /// A function call or type constructor expression. + /// + /// We can't tell whether an expression like `IDENTIFIER(EXPR, ...)` is a + /// construction expression or a function call until we know `IDENTIFIER`'s + /// definition, so we represent everything of that form as one of these + /// expressions until lowering. At that point, [`Lowerer::call`] has + /// everything's definition in hand, and can decide whether to emit a Naga + /// [`Constant`], [`As`], [`Splat`], or [`Compose`] expression. + /// + /// [`Lowerer::call`]: super::Lowerer::call + /// [`Constant`]: crate::Expression::Constant + /// [`As`]: crate::Expression::As + /// [`Splat`]: crate::Expression::Splat + /// [`Compose`]: crate::Expression::Compose + Call { + function: Ident<'a>, + arguments: Vec>>, + }, + Index { + base: Handle>, + index: Handle>, + }, + Member { + base: Handle>, + field: Ident<'a>, + }, + Bitcast { + expr: Handle>, + to: Handle>, + ty_span: Span, + }, +} + +#[derive(Debug)] +pub struct LocalVariable<'a> { + pub name: Ident<'a>, + pub ty: Option>>, + pub init: Option>>, + pub handle: Handle, +} + +#[derive(Debug)] +pub struct Let<'a> { + pub name: Ident<'a>, + pub ty: Option>>, + pub init: Handle>, + pub handle: Handle, +} + +#[derive(Debug)] +pub enum LocalDecl<'a> { + Var(LocalVariable<'a>), + Let(Let<'a>), +} + +#[derive(Debug)] +/// A placeholder for a local variable declaration. +/// +/// See [`Function::locals`] for more information. +pub struct Local; diff --git a/src/front/wgsl/construction.rs b/src/front/wgsl/construction.rs index 43e719d0f3..2fae293c16 100644 --- a/src/front/wgsl/construction.rs +++ b/src/front/wgsl/construction.rs @@ -1,679 +1,666 @@ -use crate::{ - proc::TypeResolution, Arena, ArraySize, Bytes, Constant, ConstantInner, Expression, Handle, - ScalarKind, ScalarValue, Span as NagaSpan, Type, TypeInner, UniqueArena, VectorSize, -}; +use crate::{Handle, Span}; -use super::{Error, ExpressionContext, Lexer, Parser, Rule, Span, Token}; +use super::{ast, Error, ExpressionContext, Lowerer, OutputContext}; +use crate::proc::TypeResolution; -/// Represents the type of the constructor -/// -/// Vectors, Matrices and Arrays can have partial type information -/// which later gets inferred from the constructor parameters -enum ConstructorType { - Scalar { - kind: ScalarKind, - width: Bytes, - }, +enum ConcreteConstructorHandle { PartialVector { - size: VectorSize, - }, - Vector { - size: VectorSize, - kind: ScalarKind, - width: Bytes, + size: crate::VectorSize, }, PartialMatrix { - columns: VectorSize, - rows: VectorSize, - }, - Matrix { - columns: VectorSize, - rows: VectorSize, - width: Bytes, + columns: crate::VectorSize, + rows: crate::VectorSize, }, PartialArray, - Array { - base: Handle, - size: ArraySize, - stride: u32, - }, - Struct(Handle), + Type(Handle), } -impl ConstructorType { - const fn to_type_resolution(&self) -> Option { - Some(match *self { - ConstructorType::Scalar { kind, width } => { - TypeResolution::Value(TypeInner::Scalar { kind, width }) +impl ConcreteConstructorHandle { + fn borrow<'a>(&self, module: &'a crate::Module) -> ConcreteConstructor<'a> { + match *self { + Self::PartialVector { size } => ConcreteConstructor::PartialVector { size }, + Self::PartialMatrix { columns, rows } => { + ConcreteConstructor::PartialMatrix { columns, rows } } - ConstructorType::Vector { size, kind, width } => { - TypeResolution::Value(TypeInner::Vector { size, kind, width }) - } - ConstructorType::Matrix { - columns, - rows, - width, - } => TypeResolution::Value(TypeInner::Matrix { - columns, - rows, - width, - }), - ConstructorType::Array { base, size, stride } => { - TypeResolution::Value(TypeInner::Array { base, size, stride }) - } - ConstructorType::Struct(handle) => TypeResolution::Handle(handle), - _ => return None, - }) + Self::PartialArray => ConcreteConstructor::PartialArray, + Self::Type(handle) => ConcreteConstructor::Type(handle, &module.types[handle].inner), + } } } -impl ConstructorType { - fn to_error_string(&self, types: &UniqueArena, constants: &Arena) -> String { +enum ConcreteConstructor<'a> { + PartialVector { + size: crate::VectorSize, + }, + PartialMatrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + }, + PartialArray, + Type(Handle, &'a crate::TypeInner), +} + +impl ConcreteConstructorHandle { + fn to_error_string(&self, ctx: ExpressionContext) -> String { match *self { - ConstructorType::Scalar { kind, width } => kind.to_wgsl(width), - ConstructorType::PartialVector { size } => { + Self::PartialVector { size } => { format!("vec{}", size as u32,) } - ConstructorType::Vector { size, kind, width } => { - format!("vec{}<{}>", size as u32, kind.to_wgsl(width)) - } - ConstructorType::PartialMatrix { columns, rows } => { + Self::PartialMatrix { columns, rows } => { format!("mat{}x{}", columns as u32, rows as u32,) } - ConstructorType::Matrix { - columns, - rows, - width, - } => { - format!( - "mat{}x{}<{}>", - columns as u32, - rows as u32, - ScalarKind::Float.to_wgsl(width) - ) - } - ConstructorType::PartialArray => "array".to_string(), - ConstructorType::Array { base, size, .. } => { - format!( - "array<{}, {}>", - types[base].name.as_deref().unwrap_or("?"), - match size { - ArraySize::Constant(size) => { - constants[size] - .to_array_length() - .map(|len| len.to_string()) - .unwrap_or_else(|| "?".to_string()) - } - _ => unreachable!(), - } - ) - } - ConstructorType::Struct(handle) => types[handle] - .name - .clone() - .unwrap_or_else(|| "?".to_string()), + Self::PartialArray => "array".to_string(), + Self::Type(ty) => ctx.format_type(ty), } } } -fn parse_constructor_type<'a>( - parser: &mut Parser, - lexer: &mut Lexer<'a>, - word: &'a str, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, -) -> Result, Error<'a>> { - if let Some((kind, width)) = super::conv::get_scalar_type(word) { - return Ok(Some(ConstructorType::Scalar { kind, width })); - } +enum ComponentsHandle<'a> { + None, + One { + component: Handle, + span: Span, + ty: &'a TypeResolution, + }, + Many { + components: Vec>, + spans: Vec, + first_component_ty: &'a TypeResolution, + }, +} - let partial = match word { - "vec2" => ConstructorType::PartialVector { - size: VectorSize::Bi, - }, - "vec3" => ConstructorType::PartialVector { - size: VectorSize::Tri, - }, - "vec4" => ConstructorType::PartialVector { - size: VectorSize::Quad, - }, - "mat2x2" => ConstructorType::PartialMatrix { - columns: VectorSize::Bi, - rows: VectorSize::Bi, - }, - "mat2x3" => ConstructorType::PartialMatrix { - columns: VectorSize::Bi, - rows: VectorSize::Tri, - }, - "mat2x4" => ConstructorType::PartialMatrix { - columns: VectorSize::Bi, - rows: VectorSize::Quad, - }, - "mat3x2" => ConstructorType::PartialMatrix { - columns: VectorSize::Tri, - rows: VectorSize::Bi, - }, - "mat3x3" => ConstructorType::PartialMatrix { - columns: VectorSize::Tri, - rows: VectorSize::Tri, - }, - "mat3x4" => ConstructorType::PartialMatrix { - columns: VectorSize::Tri, - rows: VectorSize::Quad, - }, - "mat4x2" => ConstructorType::PartialMatrix { - columns: VectorSize::Quad, - rows: VectorSize::Bi, - }, - "mat4x3" => ConstructorType::PartialMatrix { - columns: VectorSize::Quad, - rows: VectorSize::Tri, - }, - "mat4x4" => ConstructorType::PartialMatrix { - columns: VectorSize::Quad, - rows: VectorSize::Quad, - }, - "array" => ConstructorType::PartialArray, - _ => return Ok(None), - }; - - // parse component type if present - match (lexer.peek().0, partial) { - (Token::Paren('<'), ConstructorType::PartialVector { size }) => { - let (kind, width) = lexer.next_scalar_generic()?; - Ok(Some(ConstructorType::Vector { size, kind, width })) +impl<'a> ComponentsHandle<'a> { + fn borrow(self, module: &'a crate::Module) -> Components<'a> { + match self { + Self::None => Components::None, + Self::One { + component, + span, + ty, + } => Components::One { + component, + span, + ty_inner: ty.inner_with(&module.types), + }, + Self::Many { + components, + spans, + first_component_ty, + } => Components::Many { + components, + spans, + first_component_ty_inner: first_component_ty.inner_with(&module.types), + }, } - (Token::Paren('<'), ConstructorType::PartialMatrix { columns, rows }) => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - match kind { - ScalarKind::Float => Ok(Some(ConstructorType::Matrix { + } +} + +enum Components<'a> { + None, + One { + component: Handle, + span: Span, + ty_inner: &'a crate::TypeInner, + }, + Many { + components: Vec>, + spans: Vec, + first_component_ty_inner: &'a crate::TypeInner, + }, +} + +impl Components<'_> { + fn into_components_vec(self) -> Vec> { + match self { + Self::None => vec![], + Self::One { component, .. } => vec![component], + Self::Many { components, .. } => components, + } + } +} + +impl<'source, 'temp> Lowerer<'source, 'temp> { + /// Generate Naga IR for a type constructor expression. + /// + /// The `constructor` value represents the head of the constructor + /// expression, which is at least a hint of which type is being built; if + /// it's one of the `Partial` variants, we need to consider the argument + /// types as well. + /// + /// This is used for [`Construct`] expressions, but also for [`Call`] + /// expressions, once we've determined that the "callable" (in WGSL spec + /// terms) is actually a type. + /// + /// [`Construct`]: ast::Expression::Construct + /// [`Call`]: ast::Expression::Call + pub(super) fn construct( + &mut self, + span: Span, + constructor: &ast::ConstructorType<'source>, + ty_span: Span, + components: &[Handle>], + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let constructor_h = self.constructor(constructor, ctx.as_output())?; + + let components_h = match *components { + [] => ComponentsHandle::None, + [component] => { + let span = ctx.ast_expressions.get_span(component); + let component = self.expression(component, ctx.reborrow())?; + ctx.grow_types(component)?; + let ty = &ctx.typifier[component]; + + ComponentsHandle::One { + component, + span, + ty, + } + } + [component, ref rest @ ..] => { + let span = ctx.ast_expressions.get_span(component); + let component = self.expression(component, ctx.reborrow())?; + + let components = std::iter::once(Ok(component)) + .chain( + rest.iter() + .map(|&component| self.expression(component, ctx.reborrow())), + ) + .collect::>()?; + let spans = std::iter::once(span) + .chain( + rest.iter() + .map(|&component| ctx.ast_expressions.get_span(component)), + ) + .collect(); + + ctx.grow_types(component)?; + let ty = &ctx.typifier[component]; + + ComponentsHandle::Many { + components, + spans, + first_component_ty: ty, + } + } + }; + + let (components, constructor) = ( + components_h.borrow(ctx.module), + constructor_h.borrow(ctx.module), + ); + let expr = match (components, constructor) { + // Empty constructor + (Components::None, dst_ty) => { + let ty = match dst_ty { + ConcreteConstructor::Type(ty, _) => ty, + _ => return Err(Error::TypeNotInferrable(ty_span)), + }; + + return match ctx.create_zero_value_constant(ty) { + Some(constant) => { + Ok(ctx.interrupt_emitter(crate::Expression::Constant(constant), span)) + } + None => Err(Error::TypeNotConstructible(ty_span)), + }; + } + + // Scalar constructor & conversion (scalar -> scalar) + ( + Components::One { + component, + ty_inner: &crate::TypeInner::Scalar { .. }, + .. + }, + ConcreteConstructor::Type(_, &crate::TypeInner::Scalar { kind, width }), + ) => crate::Expression::As { + expr: component, + kind, + convert: Some(width), + }, + + // Vector conversion (vector -> vector) + ( + Components::One { + component, + ty_inner: &crate::TypeInner::Vector { size: src_size, .. }, + .. + }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Vector { + size: dst_size, + kind: dst_kind, + width: dst_width, + }, + ), + ) if dst_size == src_size => crate::Expression::As { + expr: component, + kind: dst_kind, + convert: Some(dst_width), + }, + + // Vector conversion (vector -> vector) - partial + ( + Components::One { + component, + ty_inner: + &crate::TypeInner::Vector { + size: src_size, + kind: src_kind, + .. + }, + .. + }, + ConcreteConstructor::PartialVector { size: dst_size }, + ) if dst_size == src_size => crate::Expression::As { + expr: component, + kind: src_kind, + convert: None, + }, + + // Matrix conversion (matrix -> matrix) + ( + Components::One { + component, + ty_inner: + &crate::TypeInner::Matrix { + columns: src_columns, + rows: src_rows, + .. + }, + .. + }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Matrix { + columns: dst_columns, + rows: dst_rows, + width: dst_width, + }, + ), + ) if dst_columns == src_columns && dst_rows == src_rows => crate::Expression::As { + expr: component, + kind: crate::ScalarKind::Float, + convert: Some(dst_width), + }, + + // Matrix conversion (matrix -> matrix) - partial + ( + Components::One { + component, + ty_inner: + &crate::TypeInner::Matrix { + columns: src_columns, + rows: src_rows, + .. + }, + .. + }, + ConcreteConstructor::PartialMatrix { + columns: dst_columns, + rows: dst_rows, + }, + ) if dst_columns == src_columns && dst_rows == src_rows => crate::Expression::As { + expr: component, + kind: crate::ScalarKind::Float, + convert: None, + }, + + // Vector constructor (splat) - infer type + ( + Components::One { + component, + ty_inner: &crate::TypeInner::Scalar { .. }, + .. + }, + ConcreteConstructor::PartialVector { size }, + ) => crate::Expression::Splat { + size, + value: component, + }, + + // Vector constructor (splat) + ( + Components::One { + component, + ty_inner: + &crate::TypeInner::Scalar { + kind: src_kind, + width: src_width, + .. + }, + .. + }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Vector { + size, + kind: dst_kind, + width: dst_width, + }, + ), + ) if dst_kind == src_kind || dst_width == src_width => crate::Expression::Splat { + size, + value: component, + }, + + // Vector constructor (by elements) + ( + Components::Many { + components, + first_component_ty_inner: + &crate::TypeInner::Scalar { kind, width } + | &crate::TypeInner::Vector { kind, width, .. }, + .. + }, + ConcreteConstructor::PartialVector { size }, + ) + | ( + Components::Many { + components, + first_component_ty_inner: + &crate::TypeInner::Scalar { .. } | &crate::TypeInner::Vector { .. }, + .. + }, + ConcreteConstructor::Type(_, &crate::TypeInner::Vector { size, width, kind }), + ) => { + let inner = crate::TypeInner::Vector { size, kind, width }; + let ty = ctx.ensure_type_exists(inner); + crate::Expression::Compose { ty, components } + } + + // Matrix constructor (by elements) + ( + Components::Many { + components, + first_component_ty_inner: &crate::TypeInner::Scalar { width, .. }, + .. + }, + ConcreteConstructor::PartialMatrix { columns, rows }, + ) + | ( + Components::Many { + components, + first_component_ty_inner: &crate::TypeInner::Scalar { .. }, + .. + }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Matrix { + columns, + rows, + width, + }, + ), + ) => { + let vec_ty = ctx.ensure_type_exists(crate::TypeInner::Vector { + width, + kind: crate::ScalarKind::Float, + size: rows, + }); + + let components = components + .chunks(rows as usize) + .map(|vec_components| { + ctx.naga_expressions.append( + crate::Expression::Compose { + ty: vec_ty, + components: Vec::from(vec_components), + }, + Default::default(), + ) + }) + .collect(); + + let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { columns, rows, width, - })), - _ => Err(Error::BadMatrixScalarKind(span, kind, width)), + }); + crate::Expression::Compose { ty, components } } - } - (Token::Paren('<'), ConstructorType::PartialArray) => { - lexer.expect_generic_paren('<')?; - let base = parser.parse_type_decl(lexer, None, type_arena, const_arena)?; - let size = if lexer.skip(Token::Separator(',')) { - let const_handle = parser.parse_const_expression(lexer, type_arena, const_arena)?; - ArraySize::Constant(const_handle) - } else { - ArraySize::Dynamic - }; - lexer.expect_generic_paren('>')?; - let stride = { - parser.layouter.update(type_arena, const_arena).unwrap(); - parser.layouter[base].to_stride() - }; + // Matrix constructor (by columns) + ( + Components::Many { + components, + first_component_ty_inner: &crate::TypeInner::Vector { width, .. }, + .. + }, + ConcreteConstructor::PartialMatrix { columns, rows }, + ) + | ( + Components::Many { + components, + first_component_ty_inner: &crate::TypeInner::Vector { .. }, + .. + }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Matrix { + columns, + rows, + width, + }, + ), + ) => { + let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { + columns, + rows, + width, + }); + crate::Expression::Compose { ty, components } + } - Ok(Some(ConstructorType::Array { base, size, stride })) - } - (_, partial) => Ok(Some(partial)), + // Array constructor - infer type + (components, ConcreteConstructor::PartialArray) => { + let components = components.into_components_vec(); + + let base = ctx.register_type(components[0])?; + + let size = crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Uint(components.len() as _), + }, + }; + + let inner = crate::TypeInner::Array { + base, + size: crate::ArraySize::Constant( + ctx.module.constants.fetch_or_append(size, Span::UNDEFINED), + ), + stride: { + self.layouter + .update(&ctx.module.types, &ctx.module.constants) + .unwrap(); + self.layouter[base].to_stride() + }, + }; + let ty = ctx.ensure_type_exists(inner); + + crate::Expression::Compose { ty, components } + } + + // Array constructor + (components, ConcreteConstructor::Type(ty, &crate::TypeInner::Array { .. })) => { + let components = components.into_components_vec(); + crate::Expression::Compose { ty, components } + } + + // Struct constructor + (components, ConcreteConstructor::Type(ty, &crate::TypeInner::Struct { .. })) => { + crate::Expression::Compose { + ty, + components: components.into_components_vec(), + } + } + + // ERRORS + + // Bad conversion (type cast) + (Components::One { span, ty_inner, .. }, _) => { + let from_type = ctx.format_typeinner(ty_inner); + return Err(Error::BadTypeCast { + span, + from_type, + to_type: constructor_h.to_error_string(ctx.reborrow()), + }); + } + + // Too many parameters for scalar constructor + ( + Components::Many { spans, .. }, + ConcreteConstructor::Type(_, &crate::TypeInner::Scalar { .. }), + ) => { + let span = spans[1].until(spans.last().unwrap()); + return Err(Error::UnexpectedComponents(span)); + } + + // Parameters are of the wrong type for vector or matrix constructor + ( + Components::Many { spans, .. }, + ConcreteConstructor::Type( + _, + &crate::TypeInner::Vector { .. } | &crate::TypeInner::Matrix { .. }, + ) + | ConcreteConstructor::PartialVector { .. } + | ConcreteConstructor::PartialMatrix { .. }, + ) => { + return Err(Error::InvalidConstructorComponentType(spans[0], 0)); + } + + // Other types can't be constructed + _ => return Err(Error::TypeNotConstructible(ty_span)), + }; + + let expr = ctx.naga_expressions.append(expr, span); + Ok(expr) } -} -/// Expects [`Rule::PrimaryExpr`] on top of rule stack; if returning Some(_), pops it. -pub(super) fn parse_construction<'a>( - parser: &mut Parser, - lexer: &mut Lexer<'a>, - type_name: &'a str, - type_span: Span, - mut ctx: ExpressionContext<'a, '_, '_>, -) -> Result>, Error<'a>> { - assert_eq!( - parser.rules.last().map(|&(ref rule, _)| rule.clone()), - Some(Rule::PrimaryExpr) - ); - let dst_ty = match parser.lookup_type.get(type_name) { - Some(&handle) => ConstructorType::Struct(handle), - None => match parse_constructor_type(parser, lexer, type_name, ctx.types, ctx.constants)? { - Some(inner) => inner, - None => { - match parser.parse_type_decl_impl( - lexer, - super::TypeAttributes::default(), - type_name, - ctx.types, - ctx.constants, - )? { - Some(_) => { - return Err(Error::TypeNotConstructible(type_span)); + /// Build a Naga IR [`ConstantInner`] given a WGSL construction expression. + /// + /// Given `constructor`, representing the head of a WGSL [`type constructor + /// expression`], and a slice of [`ast::Expression`] handles representing + /// the constructor's arguments, build a Naga [`ConstantInner`] value + /// representing the given value. + /// + /// If `constructor` is for a composite type, this may entail adding new + /// [`Type`]s and [`Constant`]s to [`ctx.module`], if it doesn't already + /// have what we need. + /// + /// If the arguments cannot be evaluated at compile time, return an error. + /// + /// [`ConstantInner`]: crate::ConstantInner + /// [`type constructor expression`]: https://gpuweb.github.io/gpuweb/wgsl/#type-constructor-expr + /// [`Function::expressions`]: ast::Function::expressions + /// [`TranslationUnit::global_expressions`]: ast::TranslationUnit::global_expressions + /// [`Type`]: crate::Type + /// [`Constant`]: crate::Constant + /// [`ctx.module`]: OutputContext::module + pub(super) fn const_construct( + &mut self, + span: Span, + constructor: &ast::ConstructorType<'source>, + components: &[Handle>], + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result> { + // TODO: Support zero values, splatting and inference. + + let constructor = self.constructor(constructor, ctx.reborrow())?; + + let c = match constructor { + ConcreteConstructorHandle::Type(ty) => { + let components = components + .iter() + .map(|&expr| self.constant(expr, ctx.reborrow())) + .collect::>()?; + + crate::ConstantInner::Composite { ty, components } + } + _ => return Err(Error::ConstExprUnsupported(span)), + }; + Ok(c) + } + + /// Build a Naga IR [`Type`] for `constructor` if there is enough + /// information to do so. + /// + /// For `Partial` variants of [`ast::ConstructorType`], we don't know the + /// component type, so in that case we return the appropriate `Partial` + /// variant of [`ConcreteConstructorHandle`]. + /// + /// But for the other `ConstructorType` variants, we have everything we need + /// to know to actually produce a Naga IR type. In this case we add to/find + /// in [`ctx.module`] a suitable Naga `Type` and return a + /// [`ConcreteConstructorHandle::Type`] value holding its handle. + /// + /// Note that constructing an [`Array`] type may require inserting + /// [`Constant`]s as well as `Type`s into `ctx.module`, to represent the + /// array's length. + /// + /// [`Type`]: crate::Type + /// [`ctx.module`]: OutputContext::module + /// [`Array`]: crate::TypeInner::Array + /// [`Constant`]: crate::Constant + fn constructor<'out>( + &mut self, + constructor: &ast::ConstructorType<'source>, + mut ctx: OutputContext<'source, '_, 'out>, + ) -> Result> { + let c = match *constructor { + ast::ConstructorType::Scalar { width, kind } => { + let ty = ctx.ensure_type_exists(crate::TypeInner::Scalar { width, kind }); + ConcreteConstructorHandle::Type(ty) + } + ast::ConstructorType::PartialVector { size } => { + ConcreteConstructorHandle::PartialVector { size } + } + ast::ConstructorType::Vector { size, kind, width } => { + let ty = ctx.ensure_type_exists(crate::TypeInner::Vector { size, kind, width }); + ConcreteConstructorHandle::Type(ty) + } + ast::ConstructorType::PartialMatrix { rows, columns } => { + ConcreteConstructorHandle::PartialMatrix { rows, columns } + } + ast::ConstructorType::Matrix { + rows, + columns, + width, + } => { + let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { + columns, + rows, + width, + }); + ConcreteConstructorHandle::Type(ty) + } + ast::ConstructorType::PartialArray => ConcreteConstructorHandle::PartialArray, + ast::ConstructorType::Array { base, size } => { + let base = self.resolve_ast_type(base, ctx.reborrow())?; + let size = match size { + ast::ArraySize::Constant(expr) => { + crate::ArraySize::Constant(self.constant(expr, ctx.reborrow())?) } - None => return Ok(None), - } + ast::ArraySize::Dynamic => crate::ArraySize::Dynamic, + }; + + self.layouter + .update(&ctx.module.types, &ctx.module.constants) + .unwrap(); + let ty = ctx.ensure_type_exists(crate::TypeInner::Array { + base, + size, + stride: self.layouter[base].to_stride(), + }); + ConcreteConstructorHandle::Type(ty) } - }, - }; + ast::ConstructorType::Type(ty) => ConcreteConstructorHandle::Type(ty), + }; - lexer.open_arguments()?; - - let mut components = Vec::new(); - let mut spans = Vec::new(); - - if lexer.peek().0 == Token::Paren(')') { - let _ = lexer.next(); - } else { - while components.is_empty() || lexer.next_argument()? { - let (component, span) = lexer - .capture_span(|lexer| parser.parse_general_expression(lexer, ctx.reborrow()))?; - components.push(component); - spans.push(span); - } + Ok(c) } - - enum Components<'a> { - None, - One { - component: Handle, - span: Span, - ty: &'a TypeInner, - }, - Many { - components: Vec>, - spans: Vec, - first_component_ty: &'a TypeInner, - }, - } - - impl<'a> Components<'a> { - fn into_components_vec(self) -> Vec> { - match self { - Components::None => vec![], - Components::One { component, .. } => vec![component], - Components::Many { components, .. } => components, - } - } - } - - let components = match *components.as_slice() { - [] => Components::None, - [component] => { - ctx.resolve_type(component)?; - Components::One { - component, - span: spans[0].clone(), - ty: ctx.typifier.get(component, ctx.types), - } - } - [component, ..] => { - ctx.resolve_type(component)?; - Components::Many { - components, - spans, - first_component_ty: ctx.typifier.get(component, ctx.types), - } - } - }; - - let expr = match (components, dst_ty) { - // Empty constructor - (Components::None, dst_ty) => { - let ty = match dst_ty.to_type_resolution() { - Some(TypeResolution::Handle(handle)) => handle, - Some(TypeResolution::Value(inner)) => ctx - .types - .insert(Type { name: None, inner }, Default::default()), - None => return Err(Error::TypeNotInferrable(type_span)), - }; - - return match ctx.create_zero_value_constant(ty) { - Some(constant) => { - let span = parser.pop_rule_span(lexer); - Ok(Some(ctx.interrupt_emitter( - Expression::Constant(constant), - span.into(), - ))) - } - None => Err(Error::TypeNotConstructible(type_span)), - }; - } - - // Scalar constructor & conversion (scalar -> scalar) - ( - Components::One { - component, - ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::Scalar { kind, width }, - ) => Expression::As { - expr: component, - kind, - convert: Some(width), - }, - - // Vector conversion (vector -> vector) - ( - Components::One { - component, - ty: &TypeInner::Vector { size: src_size, .. }, - .. - }, - ConstructorType::Vector { - size: dst_size, - kind: dst_kind, - width: dst_width, - }, - ) if dst_size == src_size => Expression::As { - expr: component, - kind: dst_kind, - convert: Some(dst_width), - }, - - // Vector conversion (vector -> vector) - partial - ( - Components::One { - component, - ty: - &TypeInner::Vector { - size: src_size, - kind: src_kind, - .. - }, - .. - }, - ConstructorType::PartialVector { size: dst_size }, - ) if dst_size == src_size => Expression::As { - expr: component, - kind: src_kind, - convert: None, - }, - - // Matrix conversion (matrix -> matrix) - ( - Components::One { - component, - ty: - &TypeInner::Matrix { - columns: src_columns, - rows: src_rows, - .. - }, - .. - }, - ConstructorType::Matrix { - columns: dst_columns, - rows: dst_rows, - width: dst_width, - }, - ) if dst_columns == src_columns && dst_rows == src_rows => Expression::As { - expr: component, - kind: ScalarKind::Float, - convert: Some(dst_width), - }, - - // Matrix conversion (matrix -> matrix) - partial - ( - Components::One { - component, - ty: - &TypeInner::Matrix { - columns: src_columns, - rows: src_rows, - .. - }, - .. - }, - ConstructorType::PartialMatrix { - columns: dst_columns, - rows: dst_rows, - }, - ) if dst_columns == src_columns && dst_rows == src_rows => Expression::As { - expr: component, - kind: ScalarKind::Float, - convert: None, - }, - - // Vector constructor (splat) - infer type - ( - Components::One { - component, - ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::PartialVector { size }, - ) => Expression::Splat { - size, - value: component, - }, - - // Vector constructor (splat) - ( - Components::One { - component, - ty: - &TypeInner::Scalar { - kind: src_kind, - width: src_width, - .. - }, - .. - }, - ConstructorType::Vector { - size, - kind: dst_kind, - width: dst_width, - }, - ) if dst_kind == src_kind || dst_width == src_width => Expression::Splat { - size, - value: component, - }, - - // Vector constructor (by elements) - ( - Components::Many { - components, - first_component_ty: - &TypeInner::Scalar { kind, width } | &TypeInner::Vector { kind, width, .. }, - .. - }, - ConstructorType::PartialVector { size }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { .. } | &TypeInner::Vector { .. }, - .. - }, - ConstructorType::Vector { size, width, kind }, - ) => { - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Vector { size, kind, width }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Matrix constructor (by elements) - ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { width, .. }, - .. - }, - ConstructorType::PartialMatrix { columns, rows }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::Matrix { - columns, - rows, - width, - }, - ) => { - let vec_ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Vector { - width, - kind: ScalarKind::Float, - size: rows, - }, - }, - Default::default(), - ); - - let components = components - .chunks(rows as usize) - .map(|vec_components| { - ctx.expressions.append( - Expression::Compose { - ty: vec_ty, - components: Vec::from(vec_components), - }, - Default::default(), - ) - }) - .collect(); - - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Matrix { - columns, - rows, - width, - }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Matrix constructor (by columns) - ( - Components::Many { - components, - first_component_ty: &TypeInner::Vector { width, .. }, - .. - }, - ConstructorType::PartialMatrix { columns, rows }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Vector { .. }, - .. - }, - ConstructorType::Matrix { - columns, - rows, - width, - }, - ) => { - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Matrix { - columns, - rows, - width, - }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Array constructor - infer type - (components, ConstructorType::PartialArray) => { - let components = components.into_components_vec(); - - let base = match ctx.typifier[components[0]].clone() { - TypeResolution::Handle(ty) => ty, - TypeResolution::Value(inner) => ctx - .types - .insert(Type { name: None, inner }, Default::default()), - }; - - let size = Constant { - name: None, - specialization: None, - inner: ConstantInner::Scalar { - width: 4, - value: ScalarValue::Uint(components.len() as u64), - }, - }; - - let inner = TypeInner::Array { - base, - size: ArraySize::Constant(ctx.constants.append(size, Default::default())), - stride: { - parser.layouter.update(ctx.types, ctx.constants).unwrap(); - parser.layouter[base].to_stride() - }, - }; - - let ty = ctx - .types - .insert(Type { name: None, inner }, Default::default()); - - Expression::Compose { ty, components } - } - - // Array constructor - (components, ConstructorType::Array { base, size, stride }) => { - let components = components.into_components_vec(); - let inner = TypeInner::Array { base, size, stride }; - let ty = ctx - .types - .insert(Type { name: None, inner }, Default::default()); - Expression::Compose { ty, components } - } - - // Struct constructor - (components, ConstructorType::Struct(ty)) => Expression::Compose { - ty, - components: components.into_components_vec(), - }, - - // ERRORS - - // Bad conversion (type cast) - ( - Components::One { - span, ty: src_ty, .. - }, - dst_ty, - ) => { - return Err(Error::BadTypeCast { - span, - from_type: src_ty.to_wgsl(ctx.types, ctx.constants), - to_type: dst_ty.to_error_string(ctx.types, ctx.constants), - }); - } - - // Too many parameters for scalar constructor - (Components::Many { spans, .. }, ConstructorType::Scalar { .. }) => { - return Err(Error::UnexpectedComponents(Span { - start: spans[1].start, - end: spans.last().unwrap().end, - })); - } - - // Parameters are of the wrong type for vector or matrix constructor - ( - Components::Many { spans, .. }, - ConstructorType::Vector { .. } - | ConstructorType::Matrix { .. } - | ConstructorType::PartialVector { .. } - | ConstructorType::PartialMatrix { .. }, - ) => { - return Err(Error::InvalidConstructorComponentType(spans[0].clone(), 0)); - } - }; - - let span = NagaSpan::from(parser.pop_rule_span(lexer)); - Ok(Some(ctx.expressions.append(expr, span))) } diff --git a/src/front/wgsl/conv.rs b/src/front/wgsl/conv.rs index be3c2933f1..25acdcb217 100644 --- a/src/front/wgsl/conv.rs +++ b/src/front/wgsl/conv.rs @@ -1,4 +1,5 @@ -use super::{Error, Span}; +use super::Error; +use crate::Span; pub fn map_address_space(word: &str, span: Span) -> Result> { match word { diff --git a/src/front/wgsl/index.rs b/src/front/wgsl/index.rs new file mode 100644 index 0000000000..a36273572e --- /dev/null +++ b/src/front/wgsl/index.rs @@ -0,0 +1,192 @@ +use super::{ast, Error}; +use crate::{FastHashMap, Handle, Span}; + +/// A `GlobalDecl` list in which each definition occurs before all its uses. +pub struct Index<'a> { + dependency_order: Vec>>, +} + +impl<'a> Index<'a> { + /// Generate an `Index` for the given translation unit. + /// + /// Perform a topological sort on `tu`'s global declarations, placing + /// referents before the definitions that refer to them. + /// + /// Return an error if the graph of references between declarations contains + /// any cycles. + pub fn generate(tu: &ast::TranslationUnit<'a>) -> Result> { + // Produce a map from global definitions' names to their `Handle`s. + // While doing so, reject conflicting definitions. + let mut globals = FastHashMap::with_capacity_and_hasher(tu.decls.len(), Default::default()); + for (handle, decl) in tu.decls.iter() { + let ident = decl_ident(decl); + let name = ident.name; + if let Some(old) = globals.insert(name, handle) { + return Err(Error::Redefinition { + previous: decl_ident(&tu.decls[old]).span, + current: ident.span, + }); + } + } + + let len = tu.decls.len(); + let solver = DependencySolver { + globals: &globals, + module: tu, + visited: vec![false; len], + temp_visited: vec![false; len], + path: Vec::new(), + out: Vec::with_capacity(len), + }; + let dependency_order = solver.solve()?; + + Ok(Self { dependency_order }) + } + + /// Iterate over `GlobalDecl`s, visiting each definition before all its uses. + /// + /// Produce handles for all of the `GlobalDecl`s of the `TranslationUnit` + /// passed to `Index::generate`, ordered so that a given declaration is + /// produced before any other declaration that uses it. + pub fn visit_ordered(&self) -> impl Iterator>> + '_ { + self.dependency_order.iter().copied() + } +} + +/// An edge from a reference to its referent in the current depth-first +/// traversal. +/// +/// This is like `ast::Dependency`, except that we've determined which +/// `GlobalDecl` it refers to. +struct ResolvedDependency<'a> { + /// The referent of some identifier used in the current declaration. + decl: Handle>, + + /// Where that use occurs within the current declaration. + usage: Span, +} + +/// Local state for ordering a `TranslationUnit`'s module-scope declarations. +/// +/// Values of this type are used temporarily by `Index::generate` +/// to perform a depth-first sort on the declarations. +/// Technically, what we want is a topological sort, but a depth-first sort +/// has one key benefit - it's much more efficient in storing +/// the path of each node for error generation. +struct DependencySolver<'source, 'temp> { + /// A map from module-scope definitions' names to their handles. + globals: &'temp FastHashMap<&'source str, Handle>>, + + /// The translation unit whose declarations we're ordering. + module: &'temp ast::TranslationUnit<'source>, + + /// For each handle, whether we have pushed it onto `out` yet. + visited: Vec, + + /// For each handle, whether it is an predecessor in the current depth-first + /// traversal. This is used to detect cycles in the reference graph. + temp_visited: Vec, + + /// The current path in our depth-first traversal. Used for generating + /// error messages for non-trivial reference cycles. + path: Vec>, + + /// The list of declaration handles, with declarations before uses. + out: Vec>>, +} + +impl<'a> DependencySolver<'a, '_> { + /// Produce the sorted list of declaration handles, and check for cycles. + fn solve(mut self) -> Result>>, Error<'a>> { + for (id, _) in self.module.decls.iter() { + if self.visited[id.index()] { + continue; + } + + self.dfs(id)?; + } + + Ok(self.out) + } + + /// Ensure that all declarations used by `id` have been added to the + /// ordering, and then append `id` itself. + fn dfs(&mut self, id: Handle>) -> Result<(), Error<'a>> { + let decl = &self.module.decls[id]; + let id_usize = id.index(); + + self.temp_visited[id_usize] = true; + for dep in decl.dependencies.iter() { + if let Some(&dep_id) = self.globals.get(dep.ident) { + self.path.push(ResolvedDependency { + decl: dep_id, + usage: dep.usage, + }); + let dep_id_usize = dep_id.index(); + + if self.temp_visited[dep_id_usize] { + // Found a cycle. + return if dep_id == id { + // A declaration refers to itself directly. + Err(Error::RecursiveDeclaration { + ident: decl_ident(decl).span, + usage: dep.usage, + }) + } else { + // A declaration refers to itself indirectly, through + // one or more other definitions. Report the entire path + // of references. + let start_at = self + .path + .iter() + .rev() + .enumerate() + .find_map(|(i, dep)| (dep.decl == dep_id).then_some(i)) + .unwrap_or(0); + + Err(Error::CyclicDeclaration { + ident: decl_ident(&self.module.decls[dep_id]).span, + path: self.path[start_at..] + .iter() + .map(|curr_dep| { + let curr_id = curr_dep.decl; + let curr_decl = &self.module.decls[curr_id]; + + (decl_ident(curr_decl).span, curr_dep.usage) + }) + .collect(), + }) + }; + } else if !self.visited[dep_id_usize] { + self.dfs(dep_id)?; + } + + // Remove this edge from the current path. + self.path.pop(); + } + + // Ignore unresolved identifiers; they may be predeclared objects. + } + + // Remove this node from the current path. + self.temp_visited[id_usize] = false; + + // Now everything this declaration uses has been visited, and is already + // present in `out`. That means we we can append this one to the + // ordering, and mark it as visited. + self.out.push(id); + self.visited[id_usize] = true; + + Ok(()) + } +} + +const fn decl_ident<'a>(decl: &ast::GlobalDecl<'a>) -> ast::Ident<'a> { + match decl.kind { + ast::GlobalDeclKind::Fn(ref f) => f.name, + ast::GlobalDeclKind::Var(ref v) => v.name, + ast::GlobalDeclKind::Const(ref c) => c.name, + ast::GlobalDeclKind::Struct(ref s) => s.name, + ast::GlobalDeclKind::Type(ref t) => t.name, + } +} diff --git a/src/front/wgsl/lexer.rs b/src/front/wgsl/lexer.rs index 35fe450892..d6975bf985 100644 --- a/src/front/wgsl/lexer.rs +++ b/src/front/wgsl/lexer.rs @@ -1,10 +1,26 @@ -use super::{conv, number::consume_number, Error, ExpectedToken, Span, Token, TokenSpan}; +use super::{conv, number::consume_number, Error, ExpectedToken, Token, TokenSpan}; +use crate::Span; fn consume_any(input: &str, what: impl Fn(char) -> bool) -> (&str, &str) { let pos = input.find(|c| !what(c)).unwrap_or(input.len()); input.split_at(pos) } +/// Return the token at the start of `input`. +/// +/// If `generic` is `false`, then the bit shift operators `>>` or `<<` +/// are valid lookahead tokens for the current parser state (see [§3.1 +/// Parsing] in the WGSL specification). In other words: +/// +/// - If `generic` is `true`, then we are expecting an angle bracket +/// around a generic type parameter, like the `<` and `>` in +/// `vec3`, so interpret `<` and `>` as `Token::Paren` tokens, +/// even if they're part of `<<` or `>>` sequences. +/// +/// - Otherwise, interpret `<<` and `>>` as shift operators: +/// `Token::LogicalOperation` tokens. +/// +/// [§3.1 Parsing]: https://gpuweb.github.io/gpuweb/wgsl/#parsing fn consume_token(input: &str, generic: bool) -> (Token<'_>, &str) { let mut chars = input.chars(); let cur = match chars.next() { @@ -176,10 +192,6 @@ impl<'a> Lexer<'a> { } } - pub(super) const fn _leftover_span(&self) -> Span { - self.source.len() - self.input.len()..self.source.len() - } - /// Calls the function with a lexer and returns the result of the function as well as the span for everything the function parsed /// /// # Examples @@ -196,7 +208,7 @@ impl<'a> Lexer<'a> { let start = self.current_byte_offset(); let res = inner(self)?; let end = self.current_byte_offset(); - Ok((res, start..end)) + Ok((res, Span::from(start..end))) } pub(super) fn start_byte_offset(&mut self) -> usize { @@ -211,10 +223,6 @@ impl<'a> Lexer<'a> { } } - pub(super) const fn end_byte_offset(&self) -> usize { - self.last_end_offset - } - fn peek_token_and_rest(&mut self) -> (TokenSpan<'a>, &'a str) { let mut cloned = self.clone(); let token = cloned.next(); @@ -226,49 +234,53 @@ impl<'a> Lexer<'a> { self.source.len() - self.input.len() } - pub(super) const fn span_from(&self, offset: usize) -> Span { - offset..self.end_byte_offset() + pub(super) fn span_from(&self, offset: usize) -> Span { + Span::from(offset..self.last_end_offset) } + /// Return the next non-whitespace token from `self`. + /// + /// Assume we are a parse state where bit shift operators may + /// occur, but not angle brackets. #[must_use] pub(super) fn next(&mut self) -> TokenSpan<'a> { + self.next_impl(false) + } + + /// Return the next non-whitespace token from `self`. + /// + /// Assume we are in a parse state where angle brackets may occur, + /// but not bit shift operators. + #[must_use] + pub(super) fn next_generic(&mut self) -> TokenSpan<'a> { + self.next_impl(true) + } + + /// Return the next non-whitespace token from `self`, with a span. + /// + /// See [`consume_token`] for the meaning of `generic`. + fn next_impl(&mut self, generic: bool) -> TokenSpan<'a> { let mut start_byte_offset = self.current_byte_offset(); loop { - let (token, rest) = consume_token(self.input, false); + let (token, rest) = consume_token(self.input, generic); self.input = rest; match token { Token::Trivia => start_byte_offset = self.current_byte_offset(), _ => { self.last_end_offset = self.current_byte_offset(); - return (token, start_byte_offset..self.last_end_offset); + return (token, self.span_from(start_byte_offset)); } } } } - #[must_use] - pub(super) fn next_generic(&mut self) -> TokenSpan<'a> { - let mut start_byte_offset = self.current_byte_offset(); - loop { - let (token, rest) = consume_token(self.input, true); - self.input = rest; - match token { - Token::Trivia => start_byte_offset = self.current_byte_offset(), - _ => return (token, start_byte_offset..self.current_byte_offset()), - } - } - } - #[must_use] pub(super) fn peek(&mut self) -> TokenSpan<'a> { let (token, _) = self.peek_token_and_rest(); token } - pub(super) fn expect_span( - &mut self, - expected: Token<'a>, - ) -> Result, Error<'a>> { + pub(super) fn expect_span(&mut self, expected: Token<'a>) -> Result> { let next = self.next(); if next.0 == expected { Ok(next.1) @@ -318,8 +330,16 @@ impl<'a> Lexer<'a> { } } - pub(super) fn next_ident(&mut self) -> Result<&'a str, Error<'a>> { - self.next_ident_with_span().map(|(word, _)| word) + pub(super) fn next_ident(&mut self) -> Result, Error<'a>> { + let ident = self + .next_ident_with_span() + .map(|(name, span)| super::ast::Ident { name, span })?; + + if crate::keywords::wgsl::RESERVED.contains(&ident.name) { + return Err(Error::ReservedKeyword(ident.span)); + } + + Ok(ident) } /// Parses a generic scalar type, for example ``. @@ -346,7 +366,7 @@ impl<'a> Lexer<'a> { self.expect_generic_paren('<')?; let pair = match self.next() { (Token::Word(word), span) => conv::get_scalar_type(word) - .map(|(a, b)| (a, b, span.clone())) + .map(|(a, b)| (a, b, span)) .ok_or(Error::UnknownScalarType(span)), (_, span) => Err(Error::UnknownScalarType(span)), }?; diff --git a/src/front/wgsl/mod.rs b/src/front/wgsl/mod.rs index bc68d3e73b..80d542952c 100644 --- a/src/front/wgsl/mod.rs +++ b/src/front/wgsl/mod.rs @@ -4,8 +4,10 @@ Frontend for [WGSL][wgsl] (WebGPU Shading Language). [wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html */ +mod ast; mod construction; mod conv; +mod index; mod lexer; mod number; #[cfg(test)] @@ -17,8 +19,7 @@ use crate::{ ensure_block_returns, Alignment, Layouter, ResolveContext, ResolveError, TypeResolution, }, span::SourceLocation, - span::Span as NagaSpan, - ConstantInner, FastHashMap, ScalarValue, + FastHashMap, FastHashSet, Span, }; use self::{lexer::Lexer, number::Number}; @@ -30,10 +31,9 @@ use codespan_reporting::{ termcolor::{ColorChoice, NoColor, StandardStream}, }, }; -use std::{borrow::Cow, convert::TryFrom, ops}; +use std::{borrow::Cow, convert::TryFrom, ops::Range}; use thiserror::Error; -type Span = ops::Range; type TokenSpan<'a> = (Token<'a>, Span); #[derive(Copy, Clone, Debug, PartialEq)] @@ -68,6 +68,7 @@ pub enum ExpectedToken<'a> { Identifier, Number(NumberType), Integer, + /// A compile-time constant expression. Constant, /// Expected: constant, parenthesized expression, identifier PrimaryExpression, @@ -75,16 +76,18 @@ pub enum ExpectedToken<'a> { Assignment, /// Expected: '}', identifier FieldName, - /// Expected: attribute for a type - TypeAttribute, - /// Expected: ';', '{', word - Statement, /// Expected: 'case', 'default', '}' SwitchItem, /// Expected: ',', ')' WorkgroupSizeSeparator, /// Expected: 'struct', 'let', 'var', 'type', ';', 'fn', eof GlobalItem, + /// Expected a type. + Type, + /// Access of `var`, `let`, `const`. + Variable, + /// Access of a function + Function, } #[derive(Clone, Copy, Debug, Error, PartialEq)] @@ -131,7 +134,7 @@ pub enum Error<'a> { InvalidForInitializer(Span), /// A break if appeared outside of a continuing block InvalidBreakIf(Span), - InvalidGatherComponent(Span, u32), + InvalidGatherComponent(Span), InvalidConstructorComponentType(Span, i32), InvalidIdentifierUnderscore(Span), ReservedIdentifierPrefix(Span), @@ -139,7 +142,6 @@ pub enum Error<'a> { UnknownAttribute(Span), UnknownBuiltin(Span), UnknownAccess(Span), - UnknownShaderStage(Span), UnknownIdent(Span, &'a str), UnknownScalarType(Span), UnknownType(Span), @@ -149,10 +151,9 @@ pub enum Error<'a> { AlignAttributeTooLow(Span, Alignment), NonPowerOfTwoAlignAttribute(Span), InconsistentBinding(Span), - UnknownLocalFunction(Span), TypeNotConstructible(Span), TypeNotInferrable(Span), - InitializationTypeMismatch(Span, String), + InitializationTypeMismatch(Span, String, String), MissingType(Span), MissingAttribute(&'static str, Span), InvalidAtomicPointer(Span), @@ -165,17 +166,55 @@ pub enum Error<'a> { ty: InvalidAssignmentType, }, ReservedKeyword(Span), + /// Redefinition of an identifier (used for both module-scope and local redefinitions). Redefinition { + /// Span of the identifier in the previous definition. previous: Span, + + /// Span of the identifier in the new definition. current: Span, }, + /// A declaration refers to itself directly. + RecursiveDeclaration { + /// The location of the name of the declaration. + ident: Span, + + /// The point at which it is used. + usage: Span, + }, + /// A declaration refers to itself indirectly, through one or more other + /// definitions. + CyclicDeclaration { + /// The location of the name of some declaration in the cycle. + ident: Span, + + /// The edges of the cycle of references. + /// + /// Each `(decl, reference)` pair indicates that the declaration whose + /// name is `decl` has an identifier at `reference` whose definition is + /// the next declaration in the cycle. The last pair's `reference` is + /// the same identifier as `ident`, above. + path: Vec<(Span, Span)>, + }, + ConstExprUnsupported(Span), + InvalidSwitchValue { + uint: bool, + span: Span, + }, + CalledEntryPoint(Span), + WrongArgumentCount { + span: Span, + expected: Range, + found: u32, + }, + FunctionReturnsVoid(Span), Other, } impl<'a> Error<'a> { fn as_parse_error(&self, source: &'a str) -> ParseError { match *self { - Error::Unexpected(ref unexpected_span, expected) => { + Error::Unexpected(unexpected_span, expected) => { let expected_str = match expected { ExpectedToken::Token(token) => { match token { @@ -206,120 +245,107 @@ impl<'a> Error<'a> { }.to_string() }, ExpectedToken::Integer => "unsigned/signed integer literal".to_string(), - ExpectedToken::Constant => "constant".to_string(), + ExpectedToken::Constant => "compile-time constant".to_string(), ExpectedToken::PrimaryExpression => "expression".to_string(), ExpectedToken::Assignment => "assignment or increment/decrement".to_string(), ExpectedToken::FieldName => "field name or a closing curly bracket to signify the end of the struct".to_string(), - ExpectedToken::TypeAttribute => "type attribute".to_string(), - ExpectedToken::Statement => "statement".to_string(), ExpectedToken::SwitchItem => "switch item ('case' or 'default') or a closing curly bracket to signify the end of the switch statement ('}')".to_string(), ExpectedToken::WorkgroupSizeSeparator => "workgroup size separator (',') or a closing parenthesis".to_string(), - ExpectedToken::GlobalItem => "global item ('struct', 'let', 'var', 'type', ';', 'fn') or the end of the file".to_string(), + ExpectedToken::GlobalItem => "global item ('struct', 'const', 'var', 'type', ';', 'fn') or the end of the file".to_string(), + ExpectedToken::Type => "type".to_string(), + ExpectedToken::Variable => "variable access".to_string(), + ExpectedToken::Function => "function name".to_string(), }; ParseError { message: format!( "expected {}, found '{}'", - expected_str, - &source[unexpected_span.clone()], + expected_str, &source[unexpected_span], ), - labels: vec![( - unexpected_span.clone(), - format!("expected {}", expected_str).into(), - )], + labels: vec![(unexpected_span, format!("expected {}", expected_str).into())], notes: vec![], } } - Error::UnexpectedComponents(ref bad_span) => ParseError { + Error::UnexpectedComponents(bad_span) => ParseError { message: "unexpected components".to_string(), - labels: vec![(bad_span.clone(), "unexpected components".into())], + labels: vec![(bad_span, "unexpected components".into())], notes: vec![], }, - Error::BadNumber(ref bad_span, ref err) => ParseError { - message: format!("{}: `{}`", err, &source[bad_span.clone()],), - labels: vec![(bad_span.clone(), err.to_string().into())], + Error::BadNumber(bad_span, ref err) => ParseError { + message: format!("{}: `{}`", err, &source[bad_span],), + labels: vec![(bad_span, err.to_string().into())], notes: vec![], }, - Error::NegativeInt(ref bad_span) => ParseError { + Error::NegativeInt(bad_span) => ParseError { message: format!( "expected non-negative integer literal, found `{}`", - &source[bad_span.clone()], + &source[bad_span], ), - labels: vec![(bad_span.clone(), "expected non-negative integer".into())], + labels: vec![(bad_span, "expected non-negative integer".into())], notes: vec![], }, - Error::BadU32Constant(ref bad_span) => ParseError { + Error::BadU32Constant(bad_span) => ParseError { message: format!( "expected unsigned integer constant expression, found `{}`", - &source[bad_span.clone()], + &source[bad_span], ), - labels: vec![(bad_span.clone(), "expected unsigned integer".into())], + labels: vec![(bad_span, "expected unsigned integer".into())], notes: vec![], }, - Error::BadMatrixScalarKind(ref span, kind, width) => ParseError { + Error::BadMatrixScalarKind(span, kind, width) => ParseError { message: format!( "matrix scalar type must be floating-point, but found `{}`", kind.to_wgsl(width) ), - labels: vec![(span.clone(), "must be floating-point (e.g. `f32`)".into())], + labels: vec![(span, "must be floating-point (e.g. `f32`)".into())], notes: vec![], }, - Error::BadAccessor(ref accessor_span) => ParseError { - message: format!( - "invalid field accessor `{}`", - &source[accessor_span.clone()], - ), - labels: vec![(accessor_span.clone(), "invalid accessor".into())], + Error::BadAccessor(accessor_span) => ParseError { + message: format!("invalid field accessor `{}`", &source[accessor_span],), + labels: vec![(accessor_span, "invalid accessor".into())], notes: vec![], }, - Error::UnknownIdent(ref ident_span, ident) => ParseError { + Error::UnknownIdent(ident_span, ident) => ParseError { message: format!("no definition in scope for identifier: '{}'", ident), - labels: vec![(ident_span.clone(), "unknown identifier".into())], + labels: vec![(ident_span, "unknown identifier".into())], notes: vec![], }, - Error::UnknownScalarType(ref bad_span) => ParseError { - message: format!("unknown scalar type: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown scalar type".into())], + Error::UnknownScalarType(bad_span) => ParseError { + message: format!("unknown scalar type: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown scalar type".into())], notes: vec!["Valid scalar types are f32, f64, i32, u32, bool".into()], }, - Error::BadTextureSampleType { - ref span, - kind, - width, - } => ParseError { + Error::BadTextureSampleType { span, kind, width } => ParseError { message: format!( "texture sample type must be one of f32, i32 or u32, but found {}", kind.to_wgsl(width) ), - labels: vec![(span.clone(), "must be one of f32, i32 or u32".into())], + labels: vec![(span, "must be one of f32, i32 or u32".into())], notes: vec![], }, - Error::BadIncrDecrReferenceType(ref span) => ParseError { + Error::BadIncrDecrReferenceType(span) => ParseError { message: "increment/decrement operation requires reference type to be one of i32 or u32" .to_string(), - labels: vec![( - span.clone(), - "must be a reference type of i32 or u32".into(), - )], + labels: vec![(span, "must be a reference type of i32 or u32".into())], notes: vec![], }, - Error::BadTexture(ref bad_span) => ParseError { + Error::BadTexture(bad_span) => ParseError { message: format!( "expected an image, but found '{}' which is not an image", - &source[bad_span.clone()] + &source[bad_span] ), - labels: vec![(bad_span.clone(), "not an image".into())], + labels: vec![(bad_span, "not an image".into())], notes: vec![], }, Error::BadTypeCast { - ref span, + span, ref from_type, ref to_type, } => { let msg = format!("cannot cast a {} to a {}", from_type, to_type); ParseError { message: msg.clone(), - labels: vec![(span.clone(), msg.into())], + labels: vec![(span, msg.into())], notes: vec![], } } @@ -328,241 +354,294 @@ impl<'a> Error<'a> { labels: vec![], notes: vec![], }, - Error::InvalidForInitializer(ref bad_span) => ParseError { + Error::InvalidForInitializer(bad_span) => ParseError { message: format!( "for(;;) initializer is not an assignment or a function call: '{}'", - &source[bad_span.clone()] + &source[bad_span] ), - labels: vec![( - bad_span.clone(), - "not an assignment or function call".into(), - )], + labels: vec![(bad_span, "not an assignment or function call".into())], notes: vec![], }, - Error::InvalidBreakIf(ref bad_span) => ParseError { + Error::InvalidBreakIf(bad_span) => ParseError { message: "A break if is only allowed in a continuing block".to_string(), - labels: vec![(bad_span.clone(), "not in a continuing block".into())], + labels: vec![(bad_span, "not in a continuing block".into())], notes: vec![], }, - Error::InvalidGatherComponent(ref bad_span, component) => ParseError { + Error::InvalidGatherComponent(bad_span) => ParseError { message: format!( - "textureGather component {} doesn't exist, must be 0, 1, 2, or 3", - component + "textureGather component '{}' doesn't exist, must be 0, 1, 2, or 3", + &source[bad_span] ), - labels: vec![(bad_span.clone(), "invalid component".into())], + labels: vec![(bad_span, "invalid component".into())], notes: vec![], }, - Error::InvalidConstructorComponentType(ref bad_span, component) => ParseError { + Error::InvalidConstructorComponentType(bad_span, component) => ParseError { message: format!( "invalid type for constructor component at index [{}]", component ), - labels: vec![(bad_span.clone(), "invalid component type".into())], + labels: vec![(bad_span, "invalid component type".into())], notes: vec![], }, - Error::InvalidIdentifierUnderscore(ref bad_span) => ParseError { + Error::InvalidIdentifierUnderscore(bad_span) => ParseError { message: "Identifier can't be '_'".to_string(), - labels: vec![(bad_span.clone(), "invalid identifier".into())], + labels: vec![(bad_span, "invalid identifier".into())], notes: vec![ "Use phony assignment instead ('_ =' notice the absence of 'let' or 'var')" .to_string(), ], }, - Error::ReservedIdentifierPrefix(ref bad_span) => ParseError { + Error::ReservedIdentifierPrefix(bad_span) => ParseError { message: format!( "Identifier starts with a reserved prefix: '{}'", - &source[bad_span.clone()] + &source[bad_span] ), - labels: vec![(bad_span.clone(), "invalid identifier".into())], + labels: vec![(bad_span, "invalid identifier".into())], notes: vec![], }, - Error::UnknownAddressSpace(ref bad_span) => ParseError { - message: format!("unknown address space: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown address space".into())], + Error::UnknownAddressSpace(bad_span) => ParseError { + message: format!("unknown address space: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown address space".into())], notes: vec![], }, - Error::UnknownAttribute(ref bad_span) => ParseError { - message: format!("unknown attribute: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown attribute".into())], + Error::UnknownAttribute(bad_span) => ParseError { + message: format!("unknown attribute: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown attribute".into())], notes: vec![], }, - Error::UnknownBuiltin(ref bad_span) => ParseError { - message: format!("unknown builtin: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown builtin".into())], + Error::UnknownBuiltin(bad_span) => ParseError { + message: format!("unknown builtin: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown builtin".into())], notes: vec![], }, - Error::UnknownAccess(ref bad_span) => ParseError { - message: format!("unknown access: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown access".into())], + Error::UnknownAccess(bad_span) => ParseError { + message: format!("unknown access: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown access".into())], notes: vec![], }, - Error::UnknownShaderStage(ref bad_span) => ParseError { - message: format!("unknown shader stage: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown shader stage".into())], + Error::UnknownStorageFormat(bad_span) => ParseError { + message: format!("unknown storage format: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown storage format".into())], notes: vec![], }, - Error::UnknownStorageFormat(ref bad_span) => ParseError { - message: format!("unknown storage format: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown storage format".into())], + Error::UnknownConservativeDepth(bad_span) => ParseError { + message: format!("unknown conservative depth: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown conservative depth".into())], notes: vec![], }, - Error::UnknownConservativeDepth(ref bad_span) => ParseError { - message: format!( - "unknown conservative depth: '{}'", - &source[bad_span.clone()] - ), - labels: vec![(bad_span.clone(), "unknown conservative depth".into())], + Error::UnknownType(bad_span) => ParseError { + message: format!("unknown type: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown type".into())], notes: vec![], }, - Error::UnknownType(ref bad_span) => ParseError { - message: format!("unknown type: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown type".into())], - notes: vec![], - }, - Error::SizeAttributeTooLow(ref bad_span, min_size) => ParseError { + Error::SizeAttributeTooLow(bad_span, min_size) => ParseError { message: format!("struct member size must be at least {}", min_size), - labels: vec![( - bad_span.clone(), - format!("must be at least {}", min_size).into(), - )], + labels: vec![(bad_span, format!("must be at least {}", min_size).into())], notes: vec![], }, - Error::AlignAttributeTooLow(ref bad_span, min_align) => ParseError { + Error::AlignAttributeTooLow(bad_span, min_align) => ParseError { message: format!("struct member alignment must be at least {}", min_align), - labels: vec![( - bad_span.clone(), - format!("must be at least {}", min_align).into(), - )], + labels: vec![(bad_span, format!("must be at least {}", min_align).into())], notes: vec![], }, - Error::NonPowerOfTwoAlignAttribute(ref bad_span) => ParseError { + Error::NonPowerOfTwoAlignAttribute(bad_span) => ParseError { message: "struct member alignment must be a power of 2".to_string(), - labels: vec![(bad_span.clone(), "must be a power of 2".into())], + labels: vec![(bad_span, "must be a power of 2".into())], notes: vec![], }, - Error::InconsistentBinding(ref span) => ParseError { + Error::InconsistentBinding(span) => ParseError { message: "input/output binding is not consistent".to_string(), - labels: vec![( - span.clone(), - "input/output binding is not consistent".into(), - )], + labels: vec![(span, "input/output binding is not consistent".into())], notes: vec![], }, - Error::UnknownLocalFunction(ref span) => ParseError { - message: format!("unknown local function `{}`", &source[span.clone()]), - labels: vec![(span.clone(), "unknown local function".into())], + Error::TypeNotConstructible(span) => ParseError { + message: format!("type `{}` is not constructible", &source[span]), + labels: vec![(span, "type is not constructible".into())], notes: vec![], }, - Error::TypeNotConstructible(ref span) => ParseError { - message: format!("type `{}` is not constructible", &source[span.clone()]), - labels: vec![(span.clone(), "type is not constructible".into())], - notes: vec![], - }, - Error::TypeNotInferrable(ref span) => ParseError { + Error::TypeNotInferrable(span) => ParseError { message: "type can't be inferred".to_string(), - labels: vec![(span.clone(), "type can't be inferred".into())], + labels: vec![(span, "type can't be inferred".into())], notes: vec![], }, - Error::InitializationTypeMismatch(ref name_span, ref expected_ty) => ParseError { - message: format!( - "the type of `{}` is expected to be `{}`", - &source[name_span.clone()], - expected_ty - ), + Error::InitializationTypeMismatch(name_span, ref expected_ty, ref got_ty) => { + ParseError { + message: format!( + "the type of `{}` is expected to be `{}`, but got `{}`", + &source[name_span], expected_ty, got_ty, + ), + labels: vec![( + name_span, + format!("definition of `{}`", &source[name_span]).into(), + )], + notes: vec![], + } + } + Error::MissingType(name_span) => ParseError { + message: format!("variable `{}` needs a type", &source[name_span]), labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), + name_span, + format!("definition of `{}`", &source[name_span]).into(), )], notes: vec![], }, - Error::MissingType(ref name_span) => ParseError { - message: format!("variable `{}` needs a type", &source[name_span.clone()]), - labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), - )], - notes: vec![], - }, - Error::MissingAttribute(name, ref name_span) => ParseError { + Error::MissingAttribute(name, name_span) => ParseError { message: format!( "variable `{}` needs a '{}' attribute", - &source[name_span.clone()], - name + &source[name_span], name ), labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), + name_span, + format!("definition of `{}`", &source[name_span]).into(), )], notes: vec![], }, - Error::InvalidAtomicPointer(ref span) => ParseError { + Error::InvalidAtomicPointer(span) => ParseError { message: "atomic operation is done on a pointer to a non-atomic".to_string(), - labels: vec![(span.clone(), "atomic pointer is invalid".into())], + labels: vec![(span, "atomic pointer is invalid".into())], notes: vec![], }, - Error::InvalidAtomicOperandType(ref span) => ParseError { + Error::InvalidAtomicOperandType(span) => ParseError { message: "atomic operand type is inconsistent with the operation".to_string(), - labels: vec![(span.clone(), "atomic operand type is invalid".into())], + labels: vec![(span, "atomic operand type is invalid".into())], notes: vec![], }, - Error::NotPointer(ref span) => ParseError { + Error::NotPointer(span) => ParseError { message: "the operand of the `*` operator must be a pointer".to_string(), - labels: vec![(span.clone(), "expression is not a pointer".into())], + labels: vec![(span, "expression is not a pointer".into())], notes: vec![], }, - Error::NotReference(what, ref span) => ParseError { + Error::NotReference(what, span) => ParseError { message: format!("{} must be a reference", what), - labels: vec![(span.clone(), "expression is not a reference".into())], + labels: vec![(span, "expression is not a reference".into())], notes: vec![], }, - Error::InvalidAssignment { ref span, ty } => ParseError { + Error::InvalidAssignment { span, ty } => ParseError { message: "invalid left-hand side of assignment".into(), - labels: vec![(span.clone(), "cannot assign to this expression".into())], + labels: vec![(span, "cannot assign to this expression".into())], notes: match ty { InvalidAssignmentType::Swizzle => vec![ "WGSL does not support assignments to swizzles".into(), "consider assigning each component individually".into(), ], InvalidAssignmentType::ImmutableBinding => vec![ - format!("'{}' is an immutable binding", &source[span.clone()]), + format!("'{}' is an immutable binding", &source[span]), "consider declaring it with `var` instead of `let`".into(), ], InvalidAssignmentType::Other => vec![], }, }, - Error::Pointer(what, ref span) => ParseError { + Error::Pointer(what, span) => ParseError { message: format!("{} must not be a pointer", what), - labels: vec![(span.clone(), "expression is a pointer".into())], + labels: vec![(span, "expression is a pointer".into())], notes: vec![], }, - Error::ReservedKeyword(ref name_span) => ParseError { - message: format!( - "name `{}` is a reserved keyword", - &source[name_span.clone()] - ), + Error::ReservedKeyword(name_span) => ParseError { + message: format!("name `{}` is a reserved keyword", &source[name_span]), labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), + name_span, + format!("definition of `{}`", &source[name_span]).into(), )], notes: vec![], }, - Error::Redefinition { - ref previous, - ref current, - } => ParseError { - message: format!("redefinition of `{}`", &source[current.clone()]), + Error::Redefinition { previous, current } => ParseError { + message: format!("redefinition of `{}`", &source[current]), labels: vec![ ( - current.clone(), - format!("redefinition of `{}`", &source[current.clone()]).into(), + current, + format!("redefinition of `{}`", &source[current]).into(), ), ( - previous.clone(), - format!("previous definition of `{}`", &source[previous.clone()]).into(), + previous, + format!("previous definition of `{}`", &source[previous]).into(), ), ], notes: vec![], }, + Error::RecursiveDeclaration { ident, usage } => ParseError { + message: format!("declaration of `{}` is recursive", &source[ident]), + labels: vec![(ident, "".into()), (usage, "uses itself here".into())], + notes: vec![], + }, + Error::CyclicDeclaration { ident, ref path } => ParseError { + message: format!("declaration of `{}` is cyclic", &source[ident]), + labels: path + .iter() + .enumerate() + .flat_map(|(i, &(ident, usage))| { + [ + (ident, "".into()), + ( + usage, + if i == path.len() - 1 { + "ending the cycle".into() + } else { + format!("uses `{}`", &source[ident]).into() + }, + ), + ] + }) + .collect(), + notes: vec![], + }, + Error::ConstExprUnsupported(span) => ParseError { + message: "this constant expression is not supported".to_string(), + labels: vec![(span, "expression is not supported".into())], + notes: vec![ + "this should be fixed in a future version of Naga".into(), + "https://github.com/gfx-rs/naga/issues/1829".into(), + ], + }, + Error::InvalidSwitchValue { uint, span } => ParseError { + message: "invalid switch value".to_string(), + labels: vec![( + span, + if uint { + "expected unsigned integer" + } else { + "expected signed integer" + } + .into(), + )], + notes: vec![if uint { + format!("suffix the integer with a `u`: '{}u'", &source[span]) + } else { + let span = span.to_range().unwrap(); + format!( + "remove the `u` suffix: '{}'", + &source[span.start..span.end - 1] + ) + }], + }, + Error::CalledEntryPoint(span) => ParseError { + message: "entry point cannot be called".to_string(), + labels: vec![(span, "entry point cannot be called".into())], + notes: vec![], + }, + Error::WrongArgumentCount { + span, + ref expected, + found, + } => ParseError { + message: format!( + "wrong number of arguments: expected {}, found {}", + if expected.len() < 2 { + format!("{}", expected.start) + } else { + format!("{}..{}", expected.start, expected.end) + }, + found + ), + labels: vec![(span, "wrong number of arguments".into())], + notes: vec![], + }, + Error::FunctionReturnsVoid(span) => ParseError { + message: "function does not return any value".to_string(), + labels: vec![(span, "".into())], + notes: vec![ + "perhaps you meant to call the function in a separate statement?".into(), + ], + }, Error::Other => ParseError { message: "other error".to_string(), labels: vec![], @@ -658,7 +737,21 @@ impl crate::TypeInner { let base = member_type.name.as_deref().unwrap_or("unknown"); match size { crate::ArraySize::Constant(size) => { - let size = constants[size].name.as_deref().unwrap_or("unknown"); + let constant = &constants[size]; + let size = constant + .name + .clone() + .unwrap_or_else(|| match constant.inner { + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Uint(size), + .. + } => size.to_string(), + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Sint(size), + .. + } => size.to_string(), + _ => "?".to_string(), + }); format!("array<{}, {}>", base, size) } crate::ArraySize::Dynamic => format!("array<{}>", base), @@ -844,43 +937,165 @@ impl crate::ScalarKind { } } -trait StringValueLookup<'a> { - type Value; - fn lookup(&self, key: &'a str, span: Span) -> Result>; +/// State for constructing an AST expression. +struct ParseExpressionContext<'input, 'temp, 'out> { + /// The [`TranslationUnit::expressions`] arena to which we should contribute + /// expressions. + /// + /// [`TranslationUnit::expressions`]: ast::TranslationUnit::expressions + expressions: &'out mut Arena>, + + /// The [`TranslationUnit::types`] arena to which we should contribute new + /// types. + /// + /// [`TranslationUnit::types`]: ast::TranslationUnit::types + types: &'out mut Arena>, + + /// A map from identifiers in scope to the locals/arguments they represent. + /// + /// The handles refer to the [`Function::locals`] area; see that field's + /// documentation for details. + /// + /// [`Function::locals`]: ast::Function::locals + local_table: &'temp mut super::SymbolTable<&'input str, Handle>, + + /// The [`Function::locals`] arena for the function we're building. + /// + /// [`Function::locals`]: ast::Function::locals + locals: &'out mut Arena, + + /// Identifiers used by the current global declaration that have no local definition. + /// + /// This becomes the [`GlobalDecl`]'s [`dependencies`] set. + /// + /// Note that we don't know at parse time what kind of [`GlobalDecl`] the + /// name refers to. We can't look up names until we've seen the entire + /// translation unit. + /// + /// [`GlobalDecl`]: ast::GlobalDecl + /// [`dependencies`]: ast::GlobalDecl::dependencies + unresolved: &'out mut FastHashSet>, } -impl<'a> StringValueLookup<'a> for FastHashMap<&'a str, TypedExpression> { - type Value = TypedExpression; - fn lookup(&self, key: &'a str, span: Span) -> Result> { - self.get(key).cloned().ok_or(Error::UnknownIdent(span, key)) + +impl<'a> ParseExpressionContext<'a, '_, '_> { + fn reborrow(&mut self) -> ParseExpressionContext<'a, '_, '_> { + ParseExpressionContext { + expressions: self.expressions, + types: self.types, + local_table: self.local_table, + locals: self.locals, + unresolved: self.unresolved, + } + } + + fn parse_binary_op( + &mut self, + lexer: &mut Lexer<'a>, + classifier: impl Fn(Token<'a>) -> Option, + mut parser: impl FnMut( + &mut Lexer<'a>, + ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>>, + ) -> Result>, Error<'a>> { + let start = lexer.start_byte_offset(); + let mut accumulator = parser(lexer, self.reborrow())?; + while let Some(op) = classifier(lexer.peek().0) { + let _ = lexer.next(); + let left = accumulator; + let right = parser(lexer, self.reborrow())?; + accumulator = self.expressions.append( + ast::Expression::Binary { op, left, right }, + lexer.span_from(start), + ); + } + Ok(accumulator) } } -struct StatementContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, +/// State for constructing a `crate::Module`. +struct OutputContext<'source, 'temp, 'out> { + /// The `TranslationUnit`'s expressions arena. + ast_expressions: &'temp Arena>, + + /// The `TranslationUnit`'s types arena. + types: &'temp Arena>, + + // Naga IR values. + /// The map from the names of module-scope declarations to the Naga IR + /// `Handle`s we have built for them, owned by `Lowerer::lower`. + globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>, + + /// The module we're constructing. + module: &'out mut crate::Module, +} + +impl<'source> OutputContext<'source, '_, '_> { + fn reborrow(&mut self) -> OutputContext<'source, '_, '_> { + OutputContext { + ast_expressions: self.ast_expressions, + globals: self.globals, + types: self.types, + module: self.module, + } + } + + fn ensure_type_exists(&mut self, inner: crate::TypeInner) -> Handle { + self.module + .types + .insert(crate::Type { inner, name: None }, Span::UNDEFINED) + } +} + +/// State for lowering a statement within a function. +struct StatementContext<'source, 'temp, 'out> { + // WGSL AST values. + /// A reference to [`TranslationUnit::expressions`] for the translation unit + /// we're lowering. + /// + /// [`TranslationUnit::expressions`]: ast::TranslationUnit::expressions + ast_expressions: &'temp Arena>, + + /// A reference to [`TranslationUnit::types`] for the translation unit + /// we're lowering. + /// + /// [`TranslationUnit::types`]: ast::TranslationUnit::types + types: &'temp Arena>, + + // Naga IR values. + /// The map from the names of module-scope declarations to the Naga IR + /// `Handle`s we have built for them, owned by `Lowerer::lower`. + globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>, + + /// A map from `ast::Local` handles to the Naga expressions we've built for them. + /// + /// The Naga expressions are either [`LocalVariable`] or + /// [`FunctionArgument`] expressions. + /// + /// [`LocalVariable`]: crate::Expression::LocalVariable + /// [`FunctionArgument`]: crate::Expression::FunctionArgument + local_table: &'temp mut FastHashMap, TypedExpression>, + typifier: &'temp mut super::Typifier, variables: &'out mut Arena, - expressions: &'out mut Arena, + naga_expressions: &'out mut Arena, named_expressions: &'out mut FastHashMap, String>, - types: &'out mut UniqueArena, - constants: &'out mut Arena, - global_vars: &'out Arena, - functions: &'out Arena, arguments: &'out [crate::FunctionArgument], + module: &'out mut crate::Module, } impl<'a, 'temp> StatementContext<'a, 'temp, '_> { fn reborrow(&mut self) -> StatementContext<'a, '_, '_> { StatementContext { - symbol_table: self.symbol_table, + local_table: self.local_table, + globals: self.globals, + types: self.types, + ast_expressions: self.ast_expressions, typifier: self.typifier, variables: self.variables, - expressions: self.expressions, + naga_expressions: self.naga_expressions, named_expressions: self.named_expressions, - types: self.types, - constants: self.constants, - global_vars: self.global_vars, - functions: self.functions, arguments: self.arguments, + module: self.module, } } @@ -893,36 +1108,46 @@ impl<'a, 'temp> StatementContext<'a, 'temp, '_> { 'temp: 't, { ExpressionContext { - symbol_table: self.symbol_table, - typifier: self.typifier, - expressions: self.expressions, + local_table: self.local_table, + globals: self.globals, types: self.types, - constants: self.constants, - global_vars: self.global_vars, + ast_expressions: self.ast_expressions, + typifier: self.typifier, + naga_expressions: self.naga_expressions, + module: self.module, local_vars: self.variables, - functions: self.functions, arguments: self.arguments, block, emitter, } } + + fn as_output(&mut self) -> OutputContext<'a, '_, '_> { + OutputContext { + ast_expressions: self.ast_expressions, + globals: self.globals, + types: self.types, + module: self.module, + } + } } -struct SamplingContext { - image: Handle, - arrayed: bool, -} +struct ExpressionContext<'source, 'temp, 'out> { + // WGSL AST values. + local_table: &'temp mut FastHashMap, TypedExpression>, + ast_expressions: &'temp Arena>, + types: &'temp Arena>, + + // Naga IR values. + /// The map from the names of module-scope declarations to the Naga IR + /// `Handle`s we have built for them, owned by `Lowerer::lower`. + globals: &'temp mut FastHashMap<&'source str, LoweredGlobalDecl>, -struct ExpressionContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, typifier: &'temp mut super::Typifier, - expressions: &'out mut Arena, - types: &'out mut UniqueArena, - constants: &'out mut Arena, - global_vars: &'out Arena, + naga_expressions: &'out mut Arena, local_vars: &'out Arena, arguments: &'out [crate::FunctionArgument], - functions: &'out Arena, + module: &'out mut crate::Module, block: &'temp mut crate::Block, emitter: &'temp mut super::Emitter, } @@ -930,107 +1155,113 @@ struct ExpressionContext<'input, 'temp, 'out> { impl<'a> ExpressionContext<'a, '_, '_> { fn reborrow(&mut self) -> ExpressionContext<'a, '_, '_> { ExpressionContext { - symbol_table: self.symbol_table, - typifier: self.typifier, - expressions: self.expressions, + local_table: self.local_table, + globals: self.globals, types: self.types, - constants: self.constants, - global_vars: self.global_vars, + ast_expressions: self.ast_expressions, + typifier: self.typifier, + naga_expressions: self.naga_expressions, + module: self.module, local_vars: self.local_vars, - functions: self.functions, arguments: self.arguments, block: self.block, emitter: self.emitter, } } - fn resolve_type( - &mut self, - handle: Handle, - ) -> Result<&crate::TypeInner, Error<'a>> { - let resolve_ctx = ResolveContext { - constants: self.constants, + fn as_output(&mut self) -> OutputContext<'a, '_, '_> { + OutputContext { + ast_expressions: self.ast_expressions, + globals: self.globals, types: self.types, - global_vars: self.global_vars, - local_vars: self.local_vars, - functions: self.functions, - arguments: self.arguments, - }; - match self.typifier.grow(handle, self.expressions, &resolve_ctx) { - Err(e) => Err(Error::InvalidResolve(e)), - Ok(()) => Ok(self.typifier.get(handle, self.types)), + module: self.module, } } - fn prepare_sampling( + /// Determine the type of `handle`, and add it to the module's arena. + /// + /// If you just need a `TypeInner` for `handle`'s type, use + /// [`grow_types`] and [`resolved_inner`] instead. This function + /// should only be used when the type of `handle` needs to appear + /// in the module's final `Arena`, for example, if you're + /// creating a [`LocalVariable`] whose type is inferred from its + /// initializer. + /// + /// [`grow_types`]: Self::grow_types + /// [`resolved_inner`]: Self::resolved_inner + /// [`LocalVariable`]: crate::LocalVariable + fn register_type( + &mut self, + handle: Handle, + ) -> Result, Error<'a>> { + self.grow_types(handle)?; + Ok(self.typifier.register_type(handle, &mut self.module.types)) + } + + /// Resolve the types of all expressions up through `handle`. + /// + /// Ensure that [`self.typifier`] has a [`TypeResolution`] for + /// every expression in [`self.naga_expressions`]. + /// + /// This does not add types to any arena. The [`Typifier`] + /// documentation explains the steps we take to avoid filling + /// arenas with intermediate types. + /// + /// This function takes `&mut self`, so it can't conveniently + /// return a shared reference to the resulting `TypeResolution`: + /// the shared reference would extend the mutable borrow, and you + /// wouldn't be able to use `self` for anything else. Instead, you + /// should call `grow_types` to cover the handles you need, and + /// then use `self.typifier[handle]` or + /// [`self.resolved_inner(handle)`] to get at their resolutions. + /// + /// [`self.typifier`]: ExpressionContext::typifier + /// [`self.resolved_inner(handle)`]: ExpressionContext::resolved_inner + /// [`Typifier`]: super::Typifier + fn grow_types(&mut self, handle: Handle) -> Result<&mut Self, Error<'a>> { + let resolve_ctx = ResolveContext { + constants: &self.module.constants, + types: &self.module.types, + global_vars: &self.module.global_variables, + local_vars: self.local_vars, + functions: &self.module.functions, + arguments: self.arguments, + }; + self.typifier + .grow(handle, self.naga_expressions, &resolve_ctx) + .map_err(Error::InvalidResolve)?; + Ok(self) + } + + fn resolved_inner(&self, handle: Handle) -> &crate::TypeInner { + self.typifier[handle].inner_with(&self.module.types) + } + + fn image_data( &mut self, image: Handle, span: Span, - ) -> Result> { - Ok(SamplingContext { - image, - arrayed: match *self.resolve_type(image)? { - crate::TypeInner::Image { arrayed, .. } => arrayed, - _ => return Err(Error::BadTexture(span)), - }, - }) + ) -> Result<(crate::ImageClass, bool), Error<'a>> { + self.grow_types(image)?; + match *self.resolved_inner(image) { + crate::TypeInner::Image { class, arrayed, .. } => Ok((class, arrayed)), + _ => Err(Error::BadTexture(span)), + } } - fn parse_binary_op( + fn prepare_args<'b>( &mut self, - lexer: &mut Lexer<'a>, - classifier: impl Fn(Token<'a>) -> Option, - mut parser: impl FnMut( - &mut Lexer<'a>, - ExpressionContext<'a, '_, '_>, - ) -> Result>, - ) -> Result> { - let start = lexer.start_byte_offset() as u32; - let mut accumulator = parser(lexer, self.reborrow())?; - while let Some(op) = classifier(lexer.peek().0) { - let _ = lexer.next(); - // Binary expressions always apply the load rule to their operands. - let mut left = self.apply_load_rule(accumulator); - let unloaded_right = parser(lexer, self.reborrow())?; - let right = self.apply_load_rule(unloaded_right); - let end = lexer.end_byte_offset() as u32; - left = self.expressions.append( - crate::Expression::Binary { op, left, right }, - NagaSpan::new(start, end), - ); - // Binary expressions never produce references. - accumulator = TypedExpression::non_reference(left); + args: &'b [Handle>], + min_args: u32, + span: Span, + ) -> ArgumentContext<'b, 'a> { + ArgumentContext { + args: args.iter(), + min_args, + args_used: 0, + total_args: args.len() as u32, + span, } - Ok(accumulator) - } - - fn parse_binary_splat_op( - &mut self, - lexer: &mut Lexer<'a>, - classifier: impl Fn(Token<'a>) -> Option, - mut parser: impl FnMut( - &mut Lexer<'a>, - ExpressionContext<'a, '_, '_>, - ) -> Result>, - ) -> Result> { - let start = lexer.start_byte_offset() as u32; - let mut accumulator = parser(lexer, self.reborrow())?; - while let Some(op) = classifier(lexer.peek().0) { - let _ = lexer.next(); - // Binary expressions always apply the load rule to their operands. - let mut left = self.apply_load_rule(accumulator); - let unloaded_right = parser(lexer, self.reborrow())?; - let mut right = self.apply_load_rule(unloaded_right); - let end = lexer.end_byte_offset() as u32; - - self.binary_op_splat(op, &mut left, &mut right)?; - - accumulator = TypedExpression::non_reference(self.expressions.append( - crate::Expression::Binary { op, left, right }, - NagaSpan::new(start, end), - )); - } - Ok(accumulator) } /// Insert splats, if needed by the non-'*' operations. @@ -1041,24 +1272,27 @@ impl<'a> ExpressionContext<'a, '_, '_> { right: &mut Handle, ) -> Result<(), Error<'a>> { if op != crate::BinaryOperator::Multiply { - let left_size = match *self.resolve_type(*left)? { + self.grow_types(*left)?.grow_types(*right)?; + + let left_size = match *self.resolved_inner(*left) { crate::TypeInner::Vector { size, .. } => Some(size), _ => None, }; - match (left_size, self.resolve_type(*right)?) { + + match (left_size, self.resolved_inner(*right)) { (Some(size), &crate::TypeInner::Scalar { .. }) => { - *right = self.expressions.append( + *right = self.naga_expressions.append( crate::Expression::Splat { size, value: *right, }, - self.expressions.get_span(*right), + self.naga_expressions.get_span(*right), ); } (None, &crate::TypeInner::Vector { size, .. }) => { - *left = self.expressions.append( + *left = self.naga_expressions.append( crate::Expression::Splat { size, value: *left }, - self.expressions.get_span(*left), + self.naga_expressions.get_span(*left), ); } _ => {} @@ -1075,11 +1309,12 @@ impl<'a> ExpressionContext<'a, '_, '_> { fn interrupt_emitter( &mut self, expression: crate::Expression, - span: NagaSpan, + span: Span, ) -> Handle { - self.block.extend(self.emitter.finish(self.expressions)); - let result = self.expressions.append(expression, span); - self.emitter.start(self.expressions); + self.block + .extend(self.emitter.finish(self.naga_expressions)); + let result = self.naga_expressions.append(expression, span); + self.emitter.start(self.naga_expressions); result } @@ -1092,8 +1327,8 @@ impl<'a> ExpressionContext<'a, '_, '_> { let load = crate::Expression::Load { pointer: expr.handle, }; - let span = self.expressions.get_span(expr.handle); - self.expressions.append(load, span) + let span = self.naga_expressions.get_span(expr.handle); + self.naga_expressions.append(load, span) } else { expr.handle } @@ -1106,7 +1341,7 @@ impl<'a> ExpressionContext<'a, '_, '_> { &mut self, ty: Handle, ) -> Option> { - let inner = match self.types[ty].inner { + let inner = match self.module.types[ty].inner { crate::TypeInner::Scalar { kind, width } => { let value = match kind { crate::ScalarKind::Sint => crate::ScalarValue::Sint(0), @@ -1117,13 +1352,7 @@ impl<'a> ExpressionContext<'a, '_, '_> { crate::ConstantInner::Scalar { width, value } } crate::TypeInner::Vector { size, kind, width } => { - let scalar_ty = self.types.insert( - crate::Type { - name: None, - inner: crate::TypeInner::Scalar { width, kind }, - }, - Default::default(), - ); + let scalar_ty = self.ensure_type_exists(crate::TypeInner::Scalar { width, kind }); let component = self.create_zero_value_constant(scalar_ty); crate::ConstantInner::Composite { ty, @@ -1135,17 +1364,11 @@ impl<'a> ExpressionContext<'a, '_, '_> { rows, width, } => { - let vec_ty = self.types.insert( - crate::Type { - name: None, - inner: crate::TypeInner::Vector { - width, - kind: crate::ScalarKind::Float, - size: rows, - }, - }, - Default::default(), - ); + let vec_ty = self.ensure_type_exists(crate::TypeInner::Vector { + width, + kind: crate::ScalarKind::Float, + size: rows, + }); let component = self.create_zero_value_constant(vec_ty); crate::ConstantInner::Composite { ty, @@ -1162,7 +1385,7 @@ impl<'a> ExpressionContext<'a, '_, '_> { let component = self.create_zero_value_constant(base); crate::ConstantInner::Composite { ty, - components: (0..self.constants[size].to_array_length().unwrap()) + components: (0..self.module.constants[size].to_array_length().unwrap()) .map(|_| component) .collect::>()?, } @@ -1180,16 +1403,75 @@ impl<'a> ExpressionContext<'a, '_, '_> { _ => return None, }; - let constant = self.constants.fetch_or_append( + let constant = self.module.constants.fetch_or_append( crate::Constant { name: None, specialization: None, inner, }, - crate::Span::default(), + Span::UNDEFINED, ); Some(constant) } + + fn format_typeinner(&self, inner: &crate::TypeInner) -> String { + inner.to_wgsl(&self.module.types, &self.module.constants) + } + + fn format_type(&self, handle: Handle) -> String { + let ty = &self.module.types[handle]; + match ty.name { + Some(ref name) => name.clone(), + None => self.format_typeinner(&ty.inner), + } + } + + fn format_type_resolution(&self, resolution: &TypeResolution) -> String { + match *resolution { + TypeResolution::Handle(handle) => self.format_type(handle), + TypeResolution::Value(ref inner) => self.format_typeinner(inner), + } + } + + fn ensure_type_exists(&mut self, inner: crate::TypeInner) -> Handle { + self.as_output().ensure_type_exists(inner) + } +} + +struct ArgumentContext<'ctx, 'source> { + args: std::slice::Iter<'ctx, Handle>>, + min_args: u32, + args_used: u32, + total_args: u32, + span: Span, +} + +impl<'source> ArgumentContext<'_, 'source> { + pub fn finish(self) -> Result<(), Error<'source>> { + if self.args.len() == 0 { + Ok(()) + } else { + Err(Error::WrongArgumentCount { + found: self.total_args, + expected: self.min_args..self.args_used + 1, + span: self.span, + }) + } + } + + pub fn next(&mut self) -> Result>, Error<'source>> { + match self.args.next().copied() { + Some(arg) => { + self.args_used += 1; + Ok(arg) + } + None => Err(Error::WrongArgumentCount { + found: self.total_args, + expected: self.min_args..self.args_used + 1, + span: self.span, + }), + } + } } /// A Naga [`Expression`] handle, with WGSL type information. @@ -1237,10 +1519,7 @@ impl Composition { } fn extract_impl(name: &str, name_span: Span) -> Result { - let ch = name - .chars() - .next() - .ok_or_else(|| Error::BadAccessor(name_span.clone()))?; + let ch = name.chars().next().ok_or(Error::BadAccessor(name_span))?; match Self::letter_component(ch) { Some(sc) => Ok(sc as u32), None => Err(Error::BadAccessor(name_span)), @@ -1251,8 +1530,7 @@ impl Composition { if name.len() > 1 { let mut components = [crate::SwizzleComponent::X; 4]; for (comp, ch) in components.iter_mut().zip(name.chars()) { - *comp = Self::letter_component(ch) - .ok_or_else(|| Error::BadAccessor(name_span.clone()))?; + *comp = Self::letter_component(ch).ok_or(Error::BadAccessor(name_span))?; } let size = match name.len() { @@ -1268,13 +1546,6 @@ impl Composition { } } -#[derive(Default)] -struct TypeAttributes { - // Although WGSL nas no type attributes at the moment, it had them in the past - // (`[[stride]]`) and may as well acquire some again in the future. - // Therefore, we are leaving the plumbing in for now. -} - /// Which grammar rule we are in the midst of parsing. /// /// This is used for error checking. `Parser` maintains a stack of @@ -1288,15 +1559,12 @@ enum Rule { FunctionDecl, Block, Statement, - ConstantExpr, PrimaryExpr, SingularExpr, UnaryExpr, GeneralExpr, } -type LocalFunctionCall = (Handle, Vec>); - #[derive(Default)] struct BindingParser { location: Option, @@ -1316,7 +1584,7 @@ impl BindingParser { match name { "location" => { lexer.expect(Token::Paren('('))?; - self.location = Some(Parser::parse_non_negative_i32_literal(lexer)?); + self.location = Some(Parser::non_negative_i32_literal(lexer)?); lexer.expect(Token::Paren(')'))?; } "builtin" => { @@ -1374,18 +1642,6 @@ impl BindingParser { } } -struct ParsedVariable<'a> { - name: &'a str, - name_span: Span, - space: Option, - ty: Handle, - init: Option>, -} - -struct CalledFunction { - result: Option>, -} - #[derive(Clone, Debug)] pub struct ParseError { message: String, @@ -1397,7 +1653,7 @@ impl ParseError { pub fn labels(&self) -> impl Iterator + ExactSizeIterator + '_ { self.labels .iter() - .map(|&(ref span, ref msg)| (span.clone(), msg.as_ref())) + .map(|&(span, ref msg)| (span, msg.as_ref())) } pub fn message(&self) -> &str { @@ -1411,7 +1667,8 @@ impl ParseError { self.labels .iter() .map(|label| { - Label::primary((), label.0.clone()).with_message(label.1.to_string()) + Label::primary((), label.0.to_range().unwrap()) + .with_message(label.1.to_string()) }) .collect(), ) @@ -1454,9 +1711,7 @@ impl ParseError { /// Returns a [`SourceLocation`] for the first label in the error message. pub fn location(&self, source: &str) -> Option { - self.labels - .get(0) - .map(|label| NagaSpan::new(label.0.start as u32, label.0.end as u32).location(source)) + self.labels.get(0).map(|label| label.0.location(source)) } } @@ -1474,26 +1729,15 @@ impl std::error::Error for ParseError { pub struct Parser { rules: Vec<(Rule, usize)>, - module_scope_identifiers: FastHashMap, - lookup_type: FastHashMap>, - layouter: Layouter, } impl Parser { - pub fn new() -> Self { - Parser { - rules: Vec::new(), - module_scope_identifiers: FastHashMap::default(), - lookup_type: FastHashMap::default(), - layouter: Default::default(), - } + pub const fn new() -> Self { + Parser { rules: Vec::new() } } fn reset(&mut self) { self.rules.clear(); - self.module_scope_identifiers.clear(); - self.lookup_type.clear(); - self.layouter.clear(); } fn push_rule_span(&mut self, rule: Rule, lexer: &mut Lexer<'_>) { @@ -1510,26 +1754,20 @@ impl Parser { lexer.span_from(initial) } - fn parse_switch_value<'a>( - lexer: &mut Lexer<'a>, - uint: bool, - ) -> Result> { - match lexer.next() { - (Token::Word("default"), _) => Ok(crate::SwitchValue::Default), - (Token::Number(Ok(Number::U32(num))), _) if uint => { - Ok(crate::SwitchValue::Integer(num as i32)) - } - (Token::Number(Ok(Number::I32(num))), _) if !uint => { - Ok(crate::SwitchValue::Integer(num)) - } - (Token::Number(Err(e)), span) => Err(Error::BadNumber(span, e)), - (_, span) => Err(Error::Unexpected(span, ExpectedToken::Integer)), + fn switch_value<'a>(lexer: &mut Lexer<'a>) -> Result<(ast::SwitchValue, Span), Error<'a>> { + let token_span = lexer.next(); + match token_span.0 { + Token::Word("default") => Ok((ast::SwitchValue::Default, token_span.1)), + Token::Number(Ok(Number::U32(num))) => Ok((ast::SwitchValue::U32(num), token_span.1)), + Token::Number(Ok(Number::I32(num))) => Ok((ast::SwitchValue::I32(num), token_span.1)), + Token::Number(Err(e)) => Err(Error::BadNumber(token_span.1, e)), + _ => Err(Error::Unexpected(token_span.1, ExpectedToken::Integer)), } } /// Parse a non-negative signed integer literal. /// This is for attributes like `size`, `location` and others. - fn parse_non_negative_i32_literal<'a>(lexer: &mut Lexer<'a>) -> Result> { + fn non_negative_i32_literal<'a>(lexer: &mut Lexer<'a>) -> Result> { match lexer.next() { (Token::Number(Ok(Number::I32(num))), span) => { u32::try_from(num).map_err(|_| Error::NegativeInt(span)) @@ -1545,7 +1783,7 @@ impl Parser { /// Parse a non-negative integer literal that may be either signed or unsigned. /// This is for the `workgroup_size` attribute and array lengths. /// Note: these values should be no larger than [`i32::MAX`], but this is not checked here. - fn parse_generic_non_negative_int_literal<'a>(lexer: &mut Lexer<'a>) -> Result> { + fn generic_non_negative_int_literal<'a>(lexer: &mut Lexer<'a>) -> Result> { match lexer.next() { (Token::Number(Ok(Number::I32(num))), span) => { u32::try_from(num).map_err(|_| Error::NegativeInt(span)) @@ -1559,1182 +1797,365 @@ impl Parser { } } - fn parse_atomic_pointer<'a>( + /// Decide if we're looking at a construction expression, and return its + /// type if so. + /// + /// If the identifier `word` is a [type-defining keyword], then return a + /// [`ConstructorType`] value describing the type to build. Return an error + /// if the type is not constructible (like `sampler`). + /// + /// If `word` isn't a type name, then return `None`. + /// + /// [type-defining keyword]: https://gpuweb.github.io/gpuweb/wgsl/#type-defining-keywords + /// [`ConstructorType`]: ast::ConstructorType + fn constructor_type<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - let (pointer, pointer_span) = - lexer.capture_span(|lexer| self.parse_general_expression(lexer, ctx.reborrow()))?; - // Check if the pointer expression is to an atomic. - // The IR uses regular `Expression::Load` and `Statement::Store` for atomic load/stores, - // and it will not catch the use of a non-atomic variable here. - match *ctx.resolve_type(pointer)? { - crate::TypeInner::Pointer { base, .. } => match ctx.types[base].inner { - crate::TypeInner::Atomic { .. } => Ok(pointer), - ref other => { - log::error!("Pointer type to {:?} passed to atomic op", other); - Err(Error::InvalidAtomicPointer(pointer_span)) - } + word: &'a str, + span: Span, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + if let Some((kind, width)) = conv::get_scalar_type(word) { + return Ok(Some(ast::ConstructorType::Scalar { kind, width })); + } + + let partial = match word { + "vec2" => ast::ConstructorType::PartialVector { + size: crate::VectorSize::Bi, }, - ref other => { - log::error!("Type {:?} passed to atomic op", other); - Err(Error::InvalidAtomicPointer(pointer_span)) + "vec3" => ast::ConstructorType::PartialVector { + size: crate::VectorSize::Tri, + }, + "vec4" => ast::ConstructorType::PartialVector { + size: crate::VectorSize::Quad, + }, + "mat2x2" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Bi, + rows: crate::VectorSize::Bi, + }, + "mat2x3" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Bi, + rows: crate::VectorSize::Tri, + }, + "mat2x4" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Bi, + rows: crate::VectorSize::Quad, + }, + "mat3x2" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Tri, + rows: crate::VectorSize::Bi, + }, + "mat3x3" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Tri, + rows: crate::VectorSize::Tri, + }, + "mat3x4" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Tri, + rows: crate::VectorSize::Quad, + }, + "mat4x2" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Quad, + rows: crate::VectorSize::Bi, + }, + "mat4x3" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Quad, + rows: crate::VectorSize::Tri, + }, + "mat4x4" => ast::ConstructorType::PartialMatrix { + columns: crate::VectorSize::Quad, + rows: crate::VectorSize::Quad, + }, + "array" => ast::ConstructorType::PartialArray, + "atomic" + | "binding_array" + | "sampler" + | "sampler_comparison" + | "texture_1d" + | "texture_1d_array" + | "texture_2d" + | "texture_2d_array" + | "texture_3d" + | "texture_cube" + | "texture_cube_array" + | "texture_multisampled_2d" + | "texture_multisampled_2d_array" + | "texture_depth_2d" + | "texture_depth_2d_array" + | "texture_depth_cube" + | "texture_depth_cube_array" + | "texture_depth_multisampled_2d" + | "texture_storage_1d" + | "texture_storage_1d_array" + | "texture_storage_2d" + | "texture_storage_2d_array" + | "texture_storage_3d" => return Err(Error::TypeNotConstructible(span)), + _ => return Ok(None), + }; + + // parse component type if present + match (lexer.peek().0, partial) { + (Token::Paren('<'), ast::ConstructorType::PartialVector { size }) => { + let (kind, width) = lexer.next_scalar_generic()?; + Ok(Some(ast::ConstructorType::Vector { size, kind, width })) } + (Token::Paren('<'), ast::ConstructorType::PartialMatrix { columns, rows }) => { + let (kind, width, span) = lexer.next_scalar_generic_with_span()?; + match kind { + crate::ScalarKind::Float => Ok(Some(ast::ConstructorType::Matrix { + columns, + rows, + width, + })), + _ => Err(Error::BadMatrixScalarKind(span, kind, width)), + } + } + (Token::Paren('<'), ast::ConstructorType::PartialArray) => { + lexer.expect_generic_paren('<')?; + let base = self.type_decl(lexer, ctx.reborrow())?; + let size = if lexer.skip(Token::Separator(',')) { + let expr = self.unary_expression(lexer, ctx.reborrow())?; + ast::ArraySize::Constant(expr) + } else { + ast::ArraySize::Dynamic + }; + lexer.expect_generic_paren('>')?; + + Ok(Some(ast::ConstructorType::Array { base, size })) + } + (_, partial) => Ok(Some(partial)), } } - /// Expects name to be peeked from lexer, does not consume if returns None. - fn parse_local_function_call<'a>( + /// Expects `name` to be consumed (not in lexer). + fn arguments<'a>( &mut self, lexer: &mut Lexer<'a>, - name: &'a str, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - let fun_handle = match ctx.functions.iter().find(|&(_, fun)| match fun.name { - Some(ref string) => string == name, - None => false, - }) { - Some((fun_handle, _)) => fun_handle, - None => return Ok(None), - }; - - let count = ctx.functions[fun_handle].arguments.len(); - let mut arguments = Vec::with_capacity(count); - let _ = lexer.next(); + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>>, Error<'a>> { lexer.open_arguments()?; - while arguments.len() != count { + let mut arguments = Vec::new(); + loop { if !arguments.is_empty() { - lexer.expect(Token::Separator(','))?; + if !lexer.next_argument()? { + break; + } + } else if lexer.skip(Token::Paren(')')) { + break; } - let arg = self.parse_general_expression(lexer, ctx.reborrow())?; + let arg = self.general_expression(lexer, ctx.reborrow())?; arguments.push(arg); } - lexer.close_arguments()?; - Ok(Some((fun_handle, arguments))) - } - fn parse_atomic_helper<'a>( - &mut self, - lexer: &mut Lexer<'a>, - fun: crate::AtomicFunction, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - lexer.open_arguments()?; - let pointer = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let ctx_span = ctx.reborrow(); - let (value, value_span) = - lexer.capture_span(|lexer| self.parse_general_expression(lexer, ctx_span))?; - lexer.close_arguments()?; - - let expression = match *ctx.resolve_type(value)? { - crate::TypeInner::Scalar { kind, width } => crate::Expression::AtomicResult { - ty: ctx.types.insert( - crate::Type { - name: None, - inner: crate::TypeInner::Scalar { kind, width }, - }, - NagaSpan::UNDEFINED, - ), - comparison: false, - }, - _ => return Err(Error::InvalidAtomicOperandType(value_span)), - }; - - let span = NagaSpan::from(value_span); - let result = ctx.interrupt_emitter(expression, span); - ctx.block.push( - crate::Statement::Atomic { - pointer, - fun, - value, - result, - }, - span, - ); - Ok(result) + Ok(arguments) } /// Expects [`Rule::PrimaryExpr`] or [`Rule::SingularExpr`] on top; does not pop it. - /// Expects `word` to be peeked (still in lexer), doesn't consume if returning None. - fn parse_function_call_inner<'a>( + /// Expects `name` to be consumed (not in lexer). + fn function_call<'a>( &mut self, lexer: &mut Lexer<'a>, name: &'a str, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { + name_span: Span, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { assert!(self.rules.last().is_some()); - let expr = if let Some(fun) = conv::map_relational_fun(name) { - let _ = lexer.next(); - lexer.open_arguments()?; - let argument = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::Relational { fun, argument } - } else if let Some(axis) = conv::map_derivative_axis(name) { - let _ = lexer.next(); - lexer.open_arguments()?; - let expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::Derivative { axis, expr } - } else if let Some(fun) = conv::map_standard_fun(name) { - let _ = lexer.next(); - lexer.open_arguments()?; - let arg_count = fun.argument_count(); - let arg = self.parse_general_expression(lexer, ctx.reborrow())?; - let arg1 = if arg_count > 1 { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let arg2 = if arg_count > 2 { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let arg3 = if arg_count > 3 { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::Math { - fun, - arg, - arg1, - arg2, - arg3, - } - } else { - match name { - "bitcast" => { - let _ = lexer.next(); - lexer.expect_generic_paren('<')?; - let (ty, type_span) = lexer.capture_span(|lexer| { - self.parse_type_decl(lexer, None, ctx.types, ctx.constants) - })?; - lexer.expect_generic_paren('>')?; - lexer.open_arguments()?; - let expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - - let kind = match ctx.types[ty].inner { - crate::TypeInner::Scalar { kind, .. } => kind, - crate::TypeInner::Vector { kind, .. } => kind, - _ => { - return Err(Error::BadTypeCast { - from_type: format!("{:?}", ctx.resolve_type(expr)?), - span: type_span, - to_type: format!("{:?}", ctx.types[ty].inner), - }) - } - }; - - crate::Expression::As { - expr, - kind, - convert: None, - } - } - "select" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let reject = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let accept = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let condition = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::Select { - condition, - accept, - reject, - } - } - "arrayLength" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let array = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ArrayLength(array) - } - // atomics - "atomicLoad" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let pointer = self.parse_atomic_pointer(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::Load { pointer } - } - "atomicAdd" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::Add, - ctx.reborrow(), - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicSub" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::Subtract, - ctx.reborrow(), - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicAnd" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::And, - ctx.reborrow(), - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicOr" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::InclusiveOr, - ctx.reborrow(), - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicXor" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::ExclusiveOr, - ctx.reborrow(), - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicMin" => { - let _ = lexer.next(); - let handle = - self.parse_atomic_helper(lexer, crate::AtomicFunction::Min, ctx)?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicMax" => { - let _ = lexer.next(); - let handle = - self.parse_atomic_helper(lexer, crate::AtomicFunction::Max, ctx)?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicExchange" => { - let _ = lexer.next(); - let handle = self.parse_atomic_helper( - lexer, - crate::AtomicFunction::Exchange { compare: None }, - ctx, - )?; - return Ok(Some(CalledFunction { - result: Some(handle), - })); - } - "atomicCompareExchangeWeak" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let pointer = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let cmp = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let (value, value_span) = lexer.capture_span(|lexer| { - self.parse_general_expression(lexer, ctx.reborrow()) - })?; - lexer.close_arguments()?; - - let expression = match *ctx.resolve_type(value)? { - crate::TypeInner::Scalar { kind, width } => { - let bool_ty = ctx.types.insert( - crate::Type { - name: None, - inner: crate::TypeInner::Scalar { - kind: crate::ScalarKind::Bool, - width: crate::BOOL_WIDTH, - }, - }, - NagaSpan::UNDEFINED, - ); - let scalar_ty = ctx.types.insert( - crate::Type { - name: None, - inner: crate::TypeInner::Scalar { kind, width }, - }, - NagaSpan::UNDEFINED, - ); - let struct_ty = ctx.types.insert( - crate::Type { - name: Some("__atomic_compare_exchange_result".to_string()), - inner: crate::TypeInner::Struct { - members: vec![ - crate::StructMember { - name: Some("old_value".to_string()), - ty: scalar_ty, - binding: None, - offset: 0, - }, - crate::StructMember { - name: Some("exchanged".to_string()), - ty: bool_ty, - binding: None, - offset: 4, - }, - ], - span: 8, - }, - }, - NagaSpan::UNDEFINED, - ); - crate::Expression::AtomicResult { - ty: struct_ty, - comparison: true, - } - } - _ => return Err(Error::InvalidAtomicOperandType(value_span)), - }; - - let span = NagaSpan::from(self.peek_rule_span(lexer)); - let result = ctx.interrupt_emitter(expression, span); - ctx.block.push( - crate::Statement::Atomic { - pointer, - fun: crate::AtomicFunction::Exchange { compare: Some(cmp) }, - value, - result, - }, - span, - ); - return Ok(Some(CalledFunction { - result: Some(result), - })); - } - // texture sampling - "textureSample" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Auto, - depth_ref: None, - } - } - "textureSampleLevel" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let level = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Exact(level), - depth_ref: None, - } - } - "textureSampleBias" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let bias = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Bias(bias), - depth_ref: None, - } - } - "textureSampleGrad" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let x = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let y = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Gradient { x, y }, - depth_ref: None, - } - } - "textureSampleCompare" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Auto, - depth_ref: Some(reference), - } - } - "textureSampleCompareLevel" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: Some(reference), - } - } - "textureGather" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let component = if let (Token::Number(..), span) = lexer.peek() { - let index = Self::parse_non_negative_i32_literal(lexer)?; - lexer.expect(Token::Separator(','))?; - *crate::SwizzleComponent::XYZW - .get(index as usize) - .ok_or(Error::InvalidGatherComponent(span, index))? - } else { - crate::SwizzleComponent::X - }; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: Some(component), - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: None, - } - } - "textureGatherCompare" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: Some(crate::SwizzleComponent::X), - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: Some(reference), - } - } - "textureLoad" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let (class, arrayed) = match *ctx.resolve_type(image)? { - crate::TypeInner::Image { class, arrayed, .. } => (class, arrayed), - _ => return Err(Error::BadTexture(image_span)), - }; - let array_index = if arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let level = if class.is_mipmapped() { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let sample = if class.is_multisampled() { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageLoad { - image, - coordinate, - array_index, - sample, - level, - } - } - "textureDimensions" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - let level = if lexer.skip(Token::Separator(',')) { - let expr = self.parse_general_expression(lexer, ctx.reborrow())?; - Some(expr) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::Size { level }, - } - } - "textureNumLevels" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumLevels, - } - } - "textureNumLayers" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumLayers, - } - } - "textureNumSamples" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumSamples, - } - } - // other - _ => { - let result = - match self.parse_local_function_call(lexer, name, ctx.reborrow())? { - Some((function, arguments)) => { - let span = NagaSpan::from(self.peek_rule_span(lexer)); - ctx.block.extend(ctx.emitter.finish(ctx.expressions)); - let result = ctx.functions[function].result.as_ref().map(|_| { - ctx.expressions - .append(crate::Expression::CallResult(function), span) - }); - ctx.emitter.start(ctx.expressions); - ctx.block.push( - crate::Statement::Call { - function, - arguments, - result, - }, - span, - ); - result - } - None => return Ok(None), - }; - return Ok(Some(CalledFunction { result })); - } - } - }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - let handle = ctx.expressions.append(expr, span); - Ok(Some(CalledFunction { - result: Some(handle), - })) - } - - fn parse_const_expression_impl<'a>( - &mut self, - first_token_span: TokenSpan<'a>, - lexer: &mut Lexer<'a>, - register_name: Option<&'a str>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - self.push_rule_span(Rule::ConstantExpr, lexer); - let inner = match first_token_span { - (Token::Word("true"), _) => crate::ConstantInner::boolean(true), - (Token::Word("false"), _) => crate::ConstantInner::boolean(false), - (Token::Number(num), _) => match num { - Ok(Number::I32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Sint(num as i64), - width: 4, - }, - Ok(Number::U32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Uint(num as u64), - width: 4, - }, - Ok(Number::F32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Float(num as f64), - width: 4, - }, - Ok(Number::AbstractInt(_) | Number::AbstractFloat(_)) => unreachable!(), - Err(e) => return Err(Error::BadNumber(first_token_span.1, e)), - }, - (Token::Word(name), name_span) => { - // look for an existing constant first - for (handle, var) in const_arena.iter() { - match var.name { - Some(ref string) if string == name => { - self.pop_rule_span(lexer); - return Ok(handle); - } - _ => {} - } - } - let composite_ty = self.parse_type_decl_name( - lexer, - name, - name_span, - None, - TypeAttributes::default(), - type_arena, - const_arena, - )?; + let expr = match name { + // bitcast looks like a function call, but it's an operator and must be handled differently. + "bitcast" => { + lexer.expect_generic_paren('<')?; + let start = lexer.start_byte_offset(); + let to = self.type_decl(lexer, ctx.reborrow())?; + let span = lexer.span_from(start); + lexer.expect_generic_paren('>')?; lexer.open_arguments()?; - //Note: this expects at least one argument - let mut components = Vec::new(); - while components.is_empty() || lexer.next_argument()? { - let component = self.parse_const_expression(lexer, type_arena, const_arena)?; - components.push(component); - } - crate::ConstantInner::Composite { - ty: composite_ty, - components, + let expr = self.general_expression(lexer, ctx.reborrow())?; + lexer.close_arguments()?; + + ast::Expression::Bitcast { + expr, + to, + ty_span: span, } } - other => return Err(Error::Unexpected(other.1, ExpectedToken::Constant)), - }; - - // Only set span if it's a named constant. Otherwise, the enclosing Expression should have - // the span. - let span = self.pop_rule_span(lexer); - let handle = if let Some(name) = register_name { - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(span)); + // everything else must be handled later, since they can be hidden by user-defined functions. + _ => { + let arguments = self.arguments(lexer, ctx.reborrow())?; + ctx.unresolved.insert(ast::Dependency { + ident: name, + usage: name_span, + }); + ast::Expression::Call { + function: ast::Ident { + name, + span: name_span, + }, + arguments, + } } - const_arena.append( - crate::Constant { - name: Some(name.to_string()), - specialization: None, - inner, - }, - NagaSpan::from(span), - ) - } else { - const_arena.fetch_or_append( - crate::Constant { - name: None, - specialization: None, - inner, - }, - Default::default(), - ) }; - Ok(handle) + let span = self.peek_rule_span(lexer); + let expr = ctx.expressions.append(expr, span); + Ok(expr) } - fn parse_const_expression<'a>( + fn ident_expr<'a>( &mut self, - lexer: &mut Lexer<'a>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - self.parse_const_expression_impl(lexer.next(), lexer, None, type_arena, const_arena) + name: &'a str, + name_span: Span, + ctx: ParseExpressionContext<'a, '_, '_>, + ) -> ast::IdentExpr<'a> { + match ctx.local_table.lookup(name) { + Some(&local) => ast::IdentExpr::Local(local), + None => { + ctx.unresolved.insert(ast::Dependency { + ident: name, + usage: name_span, + }); + ast::IdentExpr::Unresolved(name) + } + } } - fn parse_primary_expression<'a>( + fn primary_expression<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result> { - // Will be popped inside match, possibly inside parse_function_call_inner or parse_construction + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { self.push_rule_span(Rule::PrimaryExpr, lexer); + let expr = match lexer.peek() { (Token::Paren('('), _) => { let _ = lexer.next(); - let (expr, _span) = - self.parse_general_expression_for_reference(lexer, ctx.reborrow())?; + let expr = self.general_expression(lexer, ctx.reborrow())?; lexer.expect(Token::Paren(')'))?; self.pop_rule_span(lexer); - expr + return Ok(expr); } - (Token::Word("true" | "false") | Token::Number(..), _) => { - let const_handle = self.parse_const_expression(lexer, ctx.types, ctx.constants)?; - let span = NagaSpan::from(self.pop_rule_span(lexer)); - TypedExpression::non_reference( - ctx.interrupt_emitter(crate::Expression::Constant(const_handle), span), - ) + (Token::Word("true"), _) => { + let _ = lexer.next(); + ast::Expression::Literal(ast::Literal::Bool(true)) + } + (Token::Word("false"), _) => { + let _ = lexer.next(); + ast::Expression::Literal(ast::Literal::Bool(false)) + } + (Token::Number(res), span) => { + let _ = lexer.next(); + let num = res.map_err(|err| Error::BadNumber(span, err))?; + ast::Expression::Literal(ast::Literal::Number(num)) } (Token::Word(word), span) => { - if let Some(definition) = ctx.symbol_table.lookup(word) { - let _ = lexer.next(); - self.pop_rule_span(lexer); + let start = lexer.start_byte_offset(); + let _ = lexer.next(); - *definition - } else if let Some(CalledFunction { result: Some(expr) }) = - self.parse_function_call_inner(lexer, word, ctx.reborrow())? - { - //TODO: resolve the duplicate call in `parse_singular_expression` - self.pop_rule_span(lexer); - TypedExpression::non_reference(expr) - } else { - let _ = lexer.next(); - if let Some(expr) = construction::parse_construction( - self, - lexer, - word, - span.clone(), - ctx.reborrow(), - )? { - TypedExpression::non_reference(expr) - } else { - return Err(Error::UnknownIdent(span, word)); + if let Some(ty) = self.constructor_type(lexer, word, span, ctx.reborrow())? { + let ty_span = lexer.span_from(start); + let components = self.arguments(lexer, ctx.reborrow())?; + ast::Expression::Construct { + ty, + ty_span, + components, } + } else if let Token::Paren('(') = lexer.peek().0 { + self.pop_rule_span(lexer); + return self.function_call(lexer, word, span, ctx); + } else if word == "bitcast" { + self.pop_rule_span(lexer); + return self.function_call(lexer, word, span, ctx); + } else { + let ident = self.ident_expr(word, span, ctx.reborrow()); + ast::Expression::Ident(ident) } } other => return Err(Error::Unexpected(other.1, ExpectedToken::PrimaryExpression)), }; + + let span = self.pop_rule_span(lexer); + let expr = ctx.expressions.append(expr, span); Ok(expr) } - fn parse_postfix<'a>( + fn postfix<'a>( &mut self, span_start: usize, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - expr: TypedExpression, - ) -> Result> { - // Parse postfix expressions, adjusting `handle` and `is_reference` along the way. - // - // Most postfix expressions don't affect `is_reference`: for example, `s.x` is a - // reference whenever `s` is a reference. But swizzles (WGSL spec: "multiple - // component selection") apply the load rule, converting references to values, so - // those affect `is_reference` as well as `handle`. - let TypedExpression { - mut handle, - mut is_reference, - } = expr; - let mut prefix_span = lexer.span_from(span_start); + mut ctx: ParseExpressionContext<'a, '_, '_>, + expr: Handle>, + ) -> Result>, Error<'a>> { + let mut expr = expr; loop { - // Step lightly around `resolve_type`'s mutable borrow. - ctx.resolve_type(handle)?; - - // Find the type of the composite whose elements, components or members we're - // accessing, skipping through references: except for swizzles, the `Access` - // or `AccessIndex` expressions we'd generate are the same either way. - // - // Pointers, however, are not permitted. For error checks below, note whether - // the base expression is a WGSL pointer. - let temp_inner; - let (composite, wgsl_pointer) = match *ctx.typifier.get(handle, ctx.types) { - crate::TypeInner::Pointer { base, .. } => (&ctx.types[base].inner, !is_reference), - crate::TypeInner::ValuePointer { - size: None, - kind, - width, - .. - } => { - temp_inner = crate::TypeInner::Scalar { kind, width }; - (&temp_inner, !is_reference) - } - crate::TypeInner::ValuePointer { - size: Some(size), - kind, - width, - .. - } => { - temp_inner = crate::TypeInner::Vector { size, kind, width }; - (&temp_inner, !is_reference) - } - ref other => (other, false), - }; - let expression = match lexer.peek().0 { Token::Separator('.') => { let _ = lexer.next(); - let (name, name_span) = lexer.next_ident_with_span()?; + let field = lexer.next_ident()?; - // WGSL doesn't allow accessing members on pointers, or swizzling - // them. But Naga IR doesn't distinguish pointers and references, so - // we must check here. - if wgsl_pointer { - return Err(Error::Pointer( - "the value accessed by a `.member` expression", - prefix_span, - )); - } - - let access = match *composite { - crate::TypeInner::Struct { ref members, .. } => { - let index = members - .iter() - .position(|m| m.name.as_deref() == Some(name)) - .ok_or(Error::BadAccessor(name_span))? - as u32; - crate::Expression::AccessIndex { - base: handle, - index, - } - } - crate::TypeInner::Vector { .. } | crate::TypeInner::Matrix { .. } => { - match Composition::make(name, name_span)? { - Composition::Multi(size, pattern) => { - // Once you apply the load rule, the expression is no - // longer a reference. - let current_expr = TypedExpression { - handle, - is_reference, - }; - let vector = ctx.apply_load_rule(current_expr); - is_reference = false; - - crate::Expression::Swizzle { - size, - vector, - pattern, - } - } - Composition::Single(index) => crate::Expression::AccessIndex { - base: handle, - index, - }, - } - } - _ => return Err(Error::BadAccessor(name_span)), - }; - - access + ast::Expression::Member { base: expr, field } } Token::Paren('[') => { - let (_, open_brace_span) = lexer.next(); - let index = self.parse_general_expression(lexer, ctx.reborrow())?; - let close_brace_span = lexer.expect_span(Token::Paren(']'))?; + let _ = lexer.next(); + let index = self.general_expression(lexer, ctx.reborrow())?; + lexer.expect(Token::Paren(']'))?; - // WGSL doesn't allow pointers to be subscripted. But Naga IR doesn't - // distinguish pointers and references, so we must check here. - if wgsl_pointer { - return Err(Error::Pointer( - "the value indexed by a `[]` subscripting expression", - prefix_span, - )); - } - - if let crate::Expression::Constant(constant) = ctx.expressions[index] { - let expr_span = open_brace_span.end..close_brace_span.start; - - let index = match ctx.constants[constant].inner { - ConstantInner::Scalar { - value: ScalarValue::Uint(int), - .. - } => u32::try_from(int).map_err(|_| Error::BadU32Constant(expr_span)), - ConstantInner::Scalar { - value: ScalarValue::Sint(int), - .. - } => u32::try_from(int).map_err(|_| Error::BadU32Constant(expr_span)), - _ => Err(Error::BadU32Constant(expr_span)), - }?; - - crate::Expression::AccessIndex { - base: handle, - index, - } - } else { - crate::Expression::Access { - base: handle, - index, - } - } + ast::Expression::Index { base: expr, index } } _ => break, }; - prefix_span = lexer.span_from(span_start); - handle = ctx - .expressions - .append(expression, NagaSpan::from(prefix_span.clone())); + let span = lexer.span_from(span_start); + expr = ctx.expressions.append(expression, span); } - Ok(TypedExpression { - handle, - is_reference, - }) + Ok(expr) } /// Parse a `unary_expression`. - fn parse_unary_expression<'a>( + fn unary_expression<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { self.push_rule_span(Rule::UnaryExpr, lexer); //TODO: refactor this to avoid backing up let expr = match lexer.peek().0 { Token::Operation('-') => { let _ = lexer.next(); - let unloaded_expr = self.parse_unary_expression(lexer, ctx.reborrow())?; - let expr = ctx.apply_load_rule(unloaded_expr); - let expr = crate::Expression::Unary { + let expr = self.unary_expression(lexer, ctx.reborrow())?; + let expr = ast::Expression::Unary { op: crate::UnaryOperator::Negate, expr, }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - TypedExpression::non_reference(ctx.expressions.append(expr, span)) + let span = self.peek_rule_span(lexer); + ctx.expressions.append(expr, span) } Token::Operation('!' | '~') => { let _ = lexer.next(); - let unloaded_expr = self.parse_unary_expression(lexer, ctx.reborrow())?; - let expr = ctx.apply_load_rule(unloaded_expr); - let expr = crate::Expression::Unary { + let expr = self.unary_expression(lexer, ctx.reborrow())?; + let expr = ast::Expression::Unary { op: crate::UnaryOperator::Not, expr, }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - TypedExpression::non_reference(ctx.expressions.append(expr, span)) + let span = self.peek_rule_span(lexer); + ctx.expressions.append(expr, span) } Token::Operation('*') => { let _ = lexer.next(); - // The `*` operator does not accept a reference, so we must apply the Load - // Rule here. But the operator itself simply changes the type from - // `ptr` to `ref`, so we generate no code for the - // operator itself. We simply return a `TypedExpression` with - // `is_reference` set to true. - let unloaded_pointer = self.parse_unary_expression(lexer, ctx.reborrow())?; - let pointer = ctx.apply_load_rule(unloaded_pointer); - - // An expression like `&*ptr` may generate no Naga IR at all, but WGSL requires - // an error if `ptr` is not a pointer. So we have to type-check this ourselves. - if ctx.resolve_type(pointer)?.pointer_space().is_none() { - let span = ctx - .expressions - .get_span(pointer) - .to_range() - .unwrap_or_else(|| self.peek_rule_span(lexer)); - return Err(Error::NotPointer(span)); - } - - TypedExpression { - handle: pointer, - is_reference: true, - } + let expr = self.unary_expression(lexer, ctx.reborrow())?; + let expr = ast::Expression::Deref(expr); + let span = self.peek_rule_span(lexer); + ctx.expressions.append(expr, span) } Token::Operation('&') => { let _ = lexer.next(); - // The `&` operator simply converts a reference to a pointer. And since a - // reference is required, the Load Rule is not applied. - let operand = self.parse_unary_expression(lexer, ctx.reborrow())?; - if !operand.is_reference { - let span = ctx - .expressions - .get_span(operand.handle) - .to_range() - .unwrap_or_else(|| self.peek_rule_span(lexer)); - return Err(Error::NotReference("the operand of the `&` operator", span)); - } - - // No code is generated. We just declare the pointer a reference now. - TypedExpression { - is_reference: false, - ..operand - } + let expr = self.unary_expression(lexer, ctx.reborrow())?; + let expr = ast::Expression::AddrOf(expr); + let span = self.peek_rule_span(lexer); + ctx.expressions.append(expr, span) } - _ => self.parse_singular_expression(lexer, ctx.reborrow())?, + _ => self.singular_expression(lexer, ctx.reborrow())?, }; self.pop_rule_span(lexer); @@ -2742,25 +2163,25 @@ impl Parser { } /// Parse a `singular_expression`. - fn parse_singular_expression<'a>( + fn singular_expression<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { let start = lexer.start_byte_offset(); self.push_rule_span(Rule::SingularExpr, lexer); - let primary_expr = self.parse_primary_expression(lexer, ctx.reborrow())?; - let singular_expr = self.parse_postfix(start, lexer, ctx.reborrow(), primary_expr)?; + let primary_expr = self.primary_expression(lexer, ctx.reborrow())?; + let singular_expr = self.postfix(start, lexer, ctx.reborrow(), primary_expr)?; self.pop_rule_span(lexer); Ok(singular_expr) } - fn parse_equality_expression<'a>( + fn equality_expression<'a>( &mut self, lexer: &mut Lexer<'a>, - mut context: ExpressionContext<'a, '_, '_>, - ) -> Result> { + mut context: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { // equality_expression context.parse_binary_op( lexer, @@ -2795,7 +2216,7 @@ impl Parser { }, // additive_expression |lexer, mut context| { - context.parse_binary_splat_op( + context.parse_binary_op( lexer, |token| match token { Token::Operation('+') => Some(crate::BinaryOperator::Add), @@ -2806,7 +2227,7 @@ impl Parser { }, // multiplicative_expression |lexer, mut context| { - context.parse_binary_splat_op( + context.parse_binary_op( lexer, |token| match token { Token::Operation('*') => { @@ -2820,9 +2241,7 @@ impl Parser { } _ => None, }, - |lexer, context| { - self.parse_unary_expression(lexer, context) - }, + |lexer, context| self.unary_expression(lexer, context), ) }, ) @@ -2834,29 +2253,20 @@ impl Parser { ) } - fn parse_general_expression_with_span<'a>( + fn general_expression<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result<(Handle, Span), Error<'a>> { - let (expr, span) = self.parse_general_expression_for_reference(lexer, ctx.reborrow())?; - Ok((ctx.apply_load_rule(expr), span)) + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + self.general_expression_with_span(lexer, ctx.reborrow()) + .map(|(expr, _)| expr) } - fn parse_general_expression<'a>( + fn general_expression_with_span<'a>( &mut self, lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - let (expr, _span) = self.parse_general_expression_for_reference(lexer, ctx.reborrow())?; - Ok(ctx.apply_load_rule(expr)) - } - - fn parse_general_expression_for_reference<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: ExpressionContext<'a, '_, '_>, - ) -> Result<(TypedExpression, Span), Error<'a>> { + mut context: ParseExpressionContext<'a, '_, '_>, + ) -> Result<(Handle>, Span), Error<'a>> { self.push_rule_span(Rule::GeneralExpr, lexer); // logical_or_expression let handle = context.parse_binary_op( @@ -2902,7 +2312,7 @@ impl Parser { _ => None, }, |lexer, context| { - self.parse_equality_expression(lexer, context) + self.equality_expression(lexer, context) }, ) }, @@ -2916,30 +2326,17 @@ impl Parser { Ok((handle, self.pop_rule_span(lexer))) } - fn parse_variable_ident_decl<'a>( + fn variable_decl<'a>( &mut self, lexer: &mut Lexer<'a>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result<(&'a str, Span, Handle), Error<'a>> { - let (name, name_span) = lexer.next_ident_with_span()?; - lexer.expect(Token::Separator(':'))?; - let ty = self.parse_type_decl(lexer, None, type_arena, const_arena)?; - Ok((name, name_span, ty)) - } - - fn parse_variable_decl<'a>( - &mut self, - lexer: &mut Lexer<'a>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result, Error<'a>> { self.push_rule_span(Rule::VariableDecl, lexer); - let mut space = None; + let mut space = crate::AddressSpace::Handle; if lexer.skip(Token::Paren('<')) { let (class_str, span) = lexer.next_ident_with_span()?; - space = Some(match class_str { + space = match class_str { "storage" => { let access = if lexer.skip(Token::Separator(',')) { lexer.next_storage_access()? @@ -2950,38 +2347,36 @@ impl Parser { crate::AddressSpace::Storage { access } } _ => conv::map_address_space(class_str, span)?, - }); + }; lexer.expect(Token::Paren('>'))?; } let name = lexer.next_ident()?; lexer.expect(Token::Separator(':'))?; - let ty = self.parse_type_decl(lexer, None, type_arena, const_arena)?; + let ty = self.type_decl(lexer, ctx.reborrow())?; let init = if lexer.skip(Token::Operation('=')) { - let handle = self.parse_const_expression(lexer, type_arena, const_arena)?; + let handle = self.general_expression(lexer, ctx.reborrow())?; Some(handle) } else { None }; lexer.expect(Token::Separator(';'))?; - let name_span = self.pop_rule_span(lexer); - Ok(ParsedVariable { + self.pop_rule_span(lexer); + + Ok(ast::GlobalVariable { name, - name_span, space, + binding: None, ty, init, }) } - fn parse_struct_body<'a>( + fn struct_body<'a>( &mut self, lexer: &mut Lexer<'a>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result<(Vec, u32), Error<'a>> { - let mut offset = 0; - let mut struct_alignment = Alignment::ONE; + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { let mut members = Vec::new(); lexer.expect(Token::Paren('{'))?; @@ -2993,102 +2388,56 @@ impl Parser { ExpectedToken::Token(Token::Separator(',')), )); } - let (mut size_attr, mut align_attr) = (None, None); + let (mut size, mut align) = (None, None); self.push_rule_span(Rule::Attribute, lexer); let mut bind_parser = BindingParser::default(); while lexer.skip(Token::Attribute) { match lexer.next_ident_with_span()? { ("size", _) => { lexer.expect(Token::Paren('('))?; - let (value, span) = - lexer.capture_span(Self::parse_non_negative_i32_literal)?; + let (value, span) = lexer.capture_span(Self::non_negative_i32_literal)?; lexer.expect(Token::Paren(')'))?; - size_attr = Some((value, span)); + size = Some((value, span)); } ("align", _) => { lexer.expect(Token::Paren('('))?; - let (value, span) = - lexer.capture_span(Self::parse_non_negative_i32_literal)?; + let (value, span) = lexer.capture_span(Self::non_negative_i32_literal)?; lexer.expect(Token::Paren(')'))?; - align_attr = Some((value, span)); + align = Some((value, span)); } (word, word_span) => bind_parser.parse(lexer, word, word_span)?, } } let bind_span = self.pop_rule_span(lexer); - let mut binding = bind_parser.finish(bind_span)?; + let binding = bind_parser.finish(bind_span)?; - let (name, span) = match lexer.next() { - (Token::Word(word), span) => (word, span), - other => return Err(Error::Unexpected(other.1, ExpectedToken::FieldName)), - }; - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(span)); - } + let name = lexer.next_ident()?; lexer.expect(Token::Separator(':'))?; - let ty = self.parse_type_decl(lexer, None, type_arena, const_arena)?; + let ty = self.type_decl(lexer, ctx.reborrow())?; ready = lexer.skip(Token::Separator(',')); - self.layouter.update(type_arena, const_arena).unwrap(); - - let member_min_size = self.layouter[ty].size; - let member_min_alignment = self.layouter[ty].alignment; - - let member_size = if let Some((size, span)) = size_attr { - if size < member_min_size { - return Err(Error::SizeAttributeTooLow(span, member_min_size)); - } else { - size - } - } else { - member_min_size - }; - - let member_alignment = if let Some((align, span)) = align_attr { - if let Some(alignment) = Alignment::new(align) { - if alignment < member_min_alignment { - return Err(Error::AlignAttributeTooLow(span, member_min_alignment)); - } else { - alignment - } - } else { - return Err(Error::NonPowerOfTwoAlignAttribute(span)); - } - } else { - member_min_alignment - }; - - offset = member_alignment.round_up(offset); - struct_alignment = struct_alignment.max(member_alignment); - - if let Some(ref mut binding) = binding { - binding.apply_default_interpolation(&type_arena[ty].inner); - } - - members.push(crate::StructMember { - name: Some(name.to_owned()), + members.push(ast::StructMember { + name, ty, binding, - offset, + size, + align, }); - - offset += member_size; } - let struct_size = struct_alignment.round_up(offset); - Ok((members, struct_size)) + Ok(members) } - fn parse_matrix_scalar_type<'a>( + fn matrix_scalar_type<'a>( &mut self, lexer: &mut Lexer<'a>, columns: crate::VectorSize, rows: crate::VectorSize, - ) -> Result> { + ) -> Result, Error<'a>> { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; match kind { - crate::ScalarKind::Float => Ok(crate::TypeInner::Matrix { + crate::ScalarKind::Float => Ok(ast::Type::Matrix { columns, rows, width, @@ -3097,22 +2446,20 @@ impl Parser { } } - fn parse_type_decl_impl<'a>( + fn type_decl_impl<'a>( &mut self, lexer: &mut Lexer<'a>, - _attribute: TypeAttributes, word: &'a str, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { if let Some((kind, width)) = conv::get_scalar_type(word) { - return Ok(Some(crate::TypeInner::Scalar { kind, width })); + return Ok(Some(ast::Type::Scalar { kind, width })); } Ok(Some(match word { "vec2" => { let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { + ast::Type::Vector { size: crate::VectorSize::Bi, kind, width, @@ -3120,7 +2467,7 @@ impl Parser { } "vec3" => { let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { + ast::Type::Vector { size: crate::VectorSize::Tri, kind, width, @@ -3128,61 +2475,49 @@ impl Parser { } "vec4" => { let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { + ast::Type::Vector { size: crate::VectorSize::Quad, kind, width, } } "mat2x2" => { - self.parse_matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Bi)? + self.matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Bi)? } "mat2x3" => { - self.parse_matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Tri)? + self.matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Tri)? + } + "mat2x4" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Quad)? } - "mat2x4" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Bi, - crate::VectorSize::Quad, - )?, "mat3x2" => { - self.parse_matrix_scalar_type(lexer, crate::VectorSize::Tri, crate::VectorSize::Bi)? + self.matrix_scalar_type(lexer, crate::VectorSize::Tri, crate::VectorSize::Bi)? + } + "mat3x3" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Tri, crate::VectorSize::Tri)? + } + "mat3x4" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Tri, crate::VectorSize::Quad)? + } + "mat4x2" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Quad, crate::VectorSize::Bi)? + } + "mat4x3" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Quad, crate::VectorSize::Tri)? + } + "mat4x4" => { + self.matrix_scalar_type(lexer, crate::VectorSize::Quad, crate::VectorSize::Quad)? } - "mat3x3" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Tri, - crate::VectorSize::Tri, - )?, - "mat3x4" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Tri, - crate::VectorSize::Quad, - )?, - "mat4x2" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Quad, - crate::VectorSize::Bi, - )?, - "mat4x3" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Quad, - crate::VectorSize::Tri, - )?, - "mat4x4" => self.parse_matrix_scalar_type( - lexer, - crate::VectorSize::Quad, - crate::VectorSize::Quad, - )?, "atomic" => { let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Atomic { kind, width } + ast::Type::Atomic { kind, width } } "ptr" => { lexer.expect_generic_paren('<')?; let (ident, span) = lexer.next_ident_with_span()?; let mut space = conv::map_address_space(ident, span)?; lexer.expect(Token::Separator(','))?; - let base = self.parse_type_decl(lexer, None, type_arena, const_arena)?; + let base = self.type_decl(lexer, ctx)?; if let crate::AddressSpace::Storage { ref mut access } = space { *access = if lexer.skip(Token::Separator(',')) { lexer.next_storage_access()? @@ -3191,46 +2526,40 @@ impl Parser { }; } lexer.expect_generic_paren('>')?; - crate::TypeInner::Pointer { base, space } + ast::Type::Pointer { base, space } } "array" => { lexer.expect_generic_paren('<')?; - let base = self.parse_type_decl(lexer, None, type_arena, const_arena)?; + let base = self.type_decl(lexer, ctx.reborrow())?; let size = if lexer.skip(Token::Separator(',')) { - let const_handle = - self.parse_const_expression(lexer, type_arena, const_arena)?; - crate::ArraySize::Constant(const_handle) + let size = self.unary_expression(lexer, ctx.reborrow())?; + ast::ArraySize::Constant(size) } else { - crate::ArraySize::Dynamic + ast::ArraySize::Dynamic }; lexer.expect_generic_paren('>')?; - let stride = { - self.layouter.update(type_arena, const_arena).unwrap(); - self.layouter[base].to_stride() - }; - crate::TypeInner::Array { base, size, stride } + ast::Type::Array { base, size } } "binding_array" => { lexer.expect_generic_paren('<')?; - let base = self.parse_type_decl(lexer, None, type_arena, const_arena)?; + let base = self.type_decl(lexer, ctx.reborrow())?; let size = if lexer.skip(Token::Separator(',')) { - let const_handle = - self.parse_const_expression(lexer, type_arena, const_arena)?; - crate::ArraySize::Constant(const_handle) + let size = self.unary_expression(lexer, ctx.reborrow())?; + ast::ArraySize::Constant(size) } else { - crate::ArraySize::Dynamic + ast::ArraySize::Dynamic }; lexer.expect_generic_paren('>')?; - crate::TypeInner::BindingArray { base, size } + ast::Type::BindingArray { base, size } } - "sampler" => crate::TypeInner::Sampler { comparison: false }, - "sampler_comparison" => crate::TypeInner::Sampler { comparison: true }, + "sampler" => ast::Type::Sampler { comparison: false }, + "sampler_comparison" => ast::Type::Sampler { comparison: true }, "texture_1d" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D1, arrayed: false, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3239,7 +2568,7 @@ impl Parser { "texture_1d_array" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D1, arrayed: true, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3248,7 +2577,7 @@ impl Parser { "texture_2d" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: false, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3257,7 +2586,7 @@ impl Parser { "texture_2d_array" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: true, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3266,7 +2595,7 @@ impl Parser { "texture_3d" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D3, arrayed: false, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3275,7 +2604,7 @@ impl Parser { "texture_cube" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::Cube, arrayed: false, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3284,7 +2613,7 @@ impl Parser { "texture_cube_array" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::Cube, arrayed: true, class: crate::ImageClass::Sampled { kind, multi: false }, @@ -3293,7 +2622,7 @@ impl Parser { "texture_multisampled_2d" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: false, class: crate::ImageClass::Sampled { kind, multi: true }, @@ -3302,40 +2631,40 @@ impl Parser { "texture_multisampled_2d_array" => { let (kind, width, span) = lexer.next_scalar_generic_with_span()?; Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: true, class: crate::ImageClass::Sampled { kind, multi: true }, } } - "texture_depth_2d" => crate::TypeInner::Image { + "texture_depth_2d" => ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: false, class: crate::ImageClass::Depth { multi: false }, }, - "texture_depth_2d_array" => crate::TypeInner::Image { + "texture_depth_2d_array" => ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: true, class: crate::ImageClass::Depth { multi: false }, }, - "texture_depth_cube" => crate::TypeInner::Image { + "texture_depth_cube" => ast::Type::Image { dim: crate::ImageDimension::Cube, arrayed: false, class: crate::ImageClass::Depth { multi: false }, }, - "texture_depth_cube_array" => crate::TypeInner::Image { + "texture_depth_cube_array" => ast::Type::Image { dim: crate::ImageDimension::Cube, arrayed: true, class: crate::ImageClass::Depth { multi: false }, }, - "texture_depth_multisampled_2d" => crate::TypeInner::Image { + "texture_depth_multisampled_2d" => ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: false, class: crate::ImageClass::Depth { multi: true }, }, "texture_storage_1d" => { let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D1, arrayed: false, class: crate::ImageClass::Storage { format, access }, @@ -3343,7 +2672,7 @@ impl Parser { } "texture_storage_1d_array" => { let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D1, arrayed: true, class: crate::ImageClass::Storage { format, access }, @@ -3351,7 +2680,7 @@ impl Parser { } "texture_storage_2d" => { let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: false, class: crate::ImageClass::Storage { format, access }, @@ -3359,7 +2688,7 @@ impl Parser { } "texture_storage_2d_array" => { let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D2, arrayed: true, class: crate::ImageClass::Storage { format, access }, @@ -3367,7 +2696,7 @@ impl Parser { } "texture_storage_3d" => { let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { + ast::Type::Image { dim: crate::ImageDimension::D3, arrayed: false, class: crate::ImageClass::Storage { format, access }, @@ -3390,114 +2719,50 @@ impl Parser { } } - /// Parse type declaration of a given name and attribute. - #[allow(clippy::too_many_arguments)] - fn parse_type_decl_name<'a>( + /// Parse type declaration of a given name. + fn type_decl<'a>( &mut self, lexer: &mut Lexer<'a>, - name: &'a str, - name_span: Span, - debug_name: Option<&'a str>, - attribute: TypeAttributes, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - Ok(match self.lookup_type.get(name) { - Some(&handle) => handle, - None => { - match self.parse_type_decl_impl(lexer, attribute, name, type_arena, const_arena)? { - Some(inner) => { - let span = name_span.start..lexer.end_byte_offset(); - type_arena.insert( - crate::Type { - name: debug_name.map(|s| s.to_string()), - inner, - }, - NagaSpan::from(span), - ) - } - None => return Err(Error::UnknownType(name_span)), - } - } - }) - } - - fn parse_type_decl<'a>( - &mut self, - lexer: &mut Lexer<'a>, - debug_name: Option<&'a str>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { self.push_rule_span(Rule::TypeDecl, lexer); - let attribute = TypeAttributes::default(); - if lexer.skip(Token::Attribute) { - let other = lexer.next(); - return Err(Error::Unexpected(other.1, ExpectedToken::TypeAttribute)); - } + let (name, span) = lexer.next_ident_with_span()?; + + let ty = match self.type_decl_impl(lexer, name, ctx.reborrow())? { + Some(ty) => ty, + None => { + ctx.unresolved.insert(ast::Dependency { + ident: name, + usage: span, + }); + ast::Type::User(ast::Ident { name, span }) + } + }; - let (name, name_span) = lexer.next_ident_with_span()?; - let handle = self.parse_type_decl_name( - lexer, - name, - name_span, - debug_name, - attribute, - type_arena, - const_arena, - )?; self.pop_rule_span(lexer); - // Only set span if it's the first occurrence of the type. - // Type spans therefore should only be used for errors in type declarations; - // use variable spans/expression spans/etc. otherwise + + let handle = ctx.types.append(ty, Span::UNDEFINED); Ok(handle) } - /// Parse an assignment statement (will also parse increment and decrement statements) - fn parse_assignment_statement<'a, 'out>( + fn assignment_op_and_rhs<'a, 'out>( &mut self, lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, 'out>, - block: &mut crate::Block, - emitter: &mut super::Emitter, + mut ctx: ParseExpressionContext<'a, '_, 'out>, + block: &'out mut ast::Block<'a>, + target: Handle>, + span_start: usize, ) -> Result<(), Error<'a>> { use crate::BinaryOperator as Bo; - let span_start = lexer.start_byte_offset(); - emitter.start(context.expressions); - let (reference, lhs_span) = self - .parse_general_expression_for_reference(lexer, context.as_expression(block, emitter))?; let op = lexer.next(); - // The left hand side of an assignment must be a reference. - if !matches!( - op.0, - Token::Operation('=') - | Token::AssignmentOperation(_) - | Token::IncrementOperation - | Token::DecrementOperation - ) { - return Err(Error::Unexpected(lhs_span, ExpectedToken::Assignment)); - } else if !reference.is_reference { - let ty = if context.named_expressions.contains_key(&reference.handle) { - InvalidAssignmentType::ImmutableBinding - } else { - match *context.expressions.get_mut(reference.handle) { - crate::Expression::Swizzle { .. } => InvalidAssignmentType::Swizzle, - _ => InvalidAssignmentType::Other, - } - }; - - return Err(Error::InvalidAssignment { span: lhs_span, ty }); - } - - let mut context = context.as_expression(block, emitter); - - let value = match op { + let (op, value) = match op { (Token::Operation('='), _) => { - self.parse_general_expression(lexer, context.reborrow())? + let value = self.general_expression(lexer, ctx.reborrow())?; + (None, value) } - (Token::AssignmentOperation(c), span) => { + (Token::AssignmentOperation(c), _) => { let op = match c { '<' => Bo::ShiftLeft, '>' => Bo::ShiftRight, @@ -3509,127 +2774,122 @@ impl Parser { '&' => Bo::And, '|' => Bo::InclusiveOr, '^' => Bo::ExclusiveOr, - //Note: `consume_token` shouldn't produce any other assignment ops + // Note: `consume_token` shouldn't produce any other assignment ops _ => unreachable!(), }; - let mut left = context.expressions.append( - crate::Expression::Load { - pointer: reference.handle, - }, - lhs_span.into(), - ); - let mut right = self.parse_general_expression(lexer, context.reborrow())?; - context.binary_op_splat(op, &mut left, &mut right)?; - - context - .expressions - .append(crate::Expression::Binary { op, left, right }, span.into()) + let value = self.general_expression(lexer, ctx.reborrow())?; + (Some(op), value) } token @ (Token::IncrementOperation | Token::DecrementOperation, _) => { let op = match token.0 { - Token::IncrementOperation => Bo::Add, - Token::DecrementOperation => Bo::Subtract, + Token::IncrementOperation => ast::StatementKind::Increment, + Token::DecrementOperation => ast::StatementKind::Decrement, _ => unreachable!(), }; - let op_span = token.1; - // prepare the typifier, but work around mutable borrowing... - let _ = context.resolve_type(reference.handle)?; - - let ty = context.typifier.get(reference.handle, context.types); - let (kind, width) = match *ty { - crate::TypeInner::ValuePointer { - size: None, - kind, - width, - .. - } => (kind, width), - crate::TypeInner::Pointer { base, .. } => match context.types[base].inner { - crate::TypeInner::Scalar { kind, width } => (kind, width), - _ => return Err(Error::BadIncrDecrReferenceType(lhs_span)), - }, - _ => return Err(Error::BadIncrDecrReferenceType(lhs_span)), - }; - let constant_inner = crate::ConstantInner::Scalar { - width, - value: match kind { - crate::ScalarKind::Sint => crate::ScalarValue::Sint(1), - crate::ScalarKind::Uint => crate::ScalarValue::Uint(1), - _ => return Err(Error::BadIncrDecrReferenceType(lhs_span)), - }, - }; - let constant = context.constants.append( - crate::Constant { - name: None, - specialization: None, - inner: constant_inner, - }, - crate::Span::default(), - ); - - let left = context.expressions.append( - crate::Expression::Load { - pointer: reference.handle, - }, - lhs_span.into(), - ); - let right = context.interrupt_emitter( - crate::Expression::Constant(constant), - crate::Span::default(), - ); - context.expressions.append( - crate::Expression::Binary { op, left, right }, - op_span.into(), - ) + let span = lexer.span_from(span_start); + block.stmts.push(ast::Statement { + kind: op(target), + span, + }); + return Ok(()); } - other => return Err(Error::Unexpected(other.1, ExpectedToken::SwitchItem)), + _ => return Err(Error::Unexpected(op.1, ExpectedToken::Assignment)), }; - let span_end = lexer.end_byte_offset(); - context - .block - .extend(context.emitter.finish(context.expressions)); - context.block.push( - crate::Statement::Store { - pointer: reference.handle, - value, - }, - NagaSpan::from(span_start..span_end), - ); + let span = lexer.span_from(span_start); + block.stmts.push(ast::Statement { + kind: ast::StatementKind::Assign { target, op, value }, + span, + }); Ok(()) } + /// Parse an assignment statement (will also parse increment and decrement statements) + fn assignment_statement<'a, 'out>( + &mut self, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, 'out>, + block: &'out mut ast::Block<'a>, + ) -> Result<(), Error<'a>> { + let span_start = lexer.start_byte_offset(); + let target = self.general_expression(lexer, ctx.reborrow())?; + self.assignment_op_and_rhs(lexer, ctx, block, target, span_start) + } + /// Parse a function call statement. - fn parse_function_statement<'a, 'out>( + /// Expects `ident` to be consumed (not in the lexer). + fn function_statement<'a, 'out>( &mut self, lexer: &mut Lexer<'a>, ident: &'a str, - mut context: ExpressionContext<'a, '_, 'out>, + ident_span: Span, + span_start: usize, + mut context: ParseExpressionContext<'a, '_, 'out>, + block: &'out mut ast::Block<'a>, ) -> Result<(), Error<'a>> { self.push_rule_span(Rule::SingularExpr, lexer); - context.emitter.start(context.expressions); - if self - .parse_function_call_inner(lexer, ident, context.reborrow())? - .is_none() - { - let span = lexer.next().1; - return Err(Error::UnknownLocalFunction(span)); - } - context - .block - .extend(context.emitter.finish(context.expressions)); + + context.unresolved.insert(ast::Dependency { + ident, + usage: ident_span, + }); + let arguments = self.arguments(lexer, context.reborrow())?; + let span = lexer.span_from(span_start); + + block.stmts.push(ast::Statement { + kind: ast::StatementKind::Call { + function: ast::Ident { + name: ident, + span: ident_span, + }, + arguments, + }, + span, + }); + self.pop_rule_span(lexer); Ok(()) } - fn parse_statement<'a, 'out>( + fn function_call_or_assignment_statement<'a, 'out>( &mut self, lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, 'out>, - block: &'out mut crate::Block, - is_uniform_control_flow: bool, + mut context: ParseExpressionContext<'a, '_, 'out>, + block: &'out mut ast::Block<'a>, + ) -> Result<(), Error<'a>> { + let span_start = lexer.start_byte_offset(); + match lexer.peek() { + (Token::Word(name), span) => { + // A little hack for 2 token lookahead. + let cloned = lexer.clone(); + let _ = lexer.next(); + match lexer.peek() { + (Token::Paren('('), _) => self.function_statement( + lexer, + name, + span, + span_start, + context.reborrow(), + block, + ), + _ => { + *lexer = cloned; + self.assignment_statement(lexer, context.reborrow(), block) + } + } + } + _ => self.assignment_statement(lexer, context.reborrow(), block), + } + } + + fn statement<'a, 'out>( + &mut self, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, 'out>, + block: &'out mut ast::Block<'a>, ) -> Result<(), Error<'a>> { self.push_rule_span(Rule::Statement, lexer); match lexer.peek() { @@ -3639,296 +2899,151 @@ impl Parser { return Ok(()); } (Token::Paren('{'), _) => { - let body = self.parse_block(lexer, context, is_uniform_control_flow)?; - let span = self.pop_rule_span(lexer); - block.push(crate::Statement::Block(body), NagaSpan::from(span)); + let (inner, span) = self.block(lexer, ctx.reborrow())?; + block.stmts.push(ast::Statement { + kind: ast::StatementKind::Block(inner), + span, + }); + self.pop_rule_span(lexer); return Ok(()); } (Token::Word(word), _) => { - let mut emitter = super::Emitter::default(); - let statement = match word { + let kind = match word { "_" => { let _ = lexer.next(); - emitter.start(context.expressions); lexer.expect(Token::Operation('='))?; - self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; + let expr = self.general_expression(lexer, ctx.reborrow())?; lexer.expect(Token::Separator(';'))?; - block.extend(emitter.finish(context.expressions)); - None + + ast::StatementKind::Ignore(expr) } "let" => { let _ = lexer.next(); - emitter.start(context.expressions); - let (name, name_span) = lexer.next_ident_with_span()?; - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(name_span)); - } + let name = lexer.next_ident()?; + let given_ty = if lexer.skip(Token::Separator(':')) { - let ty = self.parse_type_decl( - lexer, - None, - context.types, - context.constants, - )?; + let ty = self.type_decl(lexer, ctx.reborrow())?; Some(ty) } else { None }; lexer.expect(Token::Operation('='))?; - let expr_id = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; + let expr_id = self.general_expression(lexer, ctx.reborrow())?; lexer.expect(Token::Separator(';'))?; - if let Some(ty) = given_ty { - // prepare the typifier, but work around mutable borrowing... - let _ = context - .as_expression(block, &mut emitter) - .resolve_type(expr_id)?; - let expr_inner = context.typifier.get(expr_id, context.types); - let given_inner = &context.types[ty].inner; - if !given_inner.equivalent(expr_inner, context.types) { - log::error!( - "Given type {:?} doesn't match expected {:?}", - given_inner, - expr_inner - ); - return Err(Error::InitializationTypeMismatch( - name_span, - expr_inner.to_wgsl(context.types, context.constants), - )); - } + + let handle = ctx.locals.append(ast::Local, name.span); + if let Some(old) = ctx.local_table.add(name.name, handle) { + return Err(Error::Redefinition { + previous: ctx.locals.get_span(old), + current: name.span, + }); } - block.extend(emitter.finish(context.expressions)); - context.symbol_table.add( + + ast::StatementKind::LocalDecl(ast::LocalDecl::Let(ast::Let { name, - TypedExpression { - handle: expr_id, - is_reference: false, - }, - ); - context - .named_expressions - .insert(expr_id, String::from(name)); - None + ty: given_ty, + init: expr_id, + handle, + })) } "var" => { let _ = lexer.next(); - enum Init { - Empty, - Constant(Handle), - Variable(Handle), - } - let (name, name_span) = lexer.next_ident_with_span()?; - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(name_span)); - } - let given_ty = if lexer.skip(Token::Separator(':')) { - let ty = self.parse_type_decl( - lexer, - None, - context.types, - context.constants, - )?; + let name = lexer.next_ident()?; + let ty = if lexer.skip(Token::Separator(':')) { + let ty = self.type_decl(lexer, ctx.reborrow())?; Some(ty) } else { None }; - let (init, ty) = if lexer.skip(Token::Operation('=')) { - emitter.start(context.expressions); - let value = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - block.extend(emitter.finish(context.expressions)); - - // prepare the typifier, but work around mutable borrowing... - let _ = context - .as_expression(block, &mut emitter) - .resolve_type(value)?; - - //TODO: share more of this code with `let` arm - let ty = match given_ty { - Some(ty) => { - let expr_inner = context.typifier.get(value, context.types); - let given_inner = &context.types[ty].inner; - if !given_inner.equivalent(expr_inner, context.types) { - log::error!( - "Given type {:?} doesn't match expected {:?}", - given_inner, - expr_inner - ); - return Err(Error::InitializationTypeMismatch( - name_span, - expr_inner.to_wgsl(context.types, context.constants), - )); - } - ty - } - None => { - // register the type, if needed - match context.typifier[value].clone() { - TypeResolution::Handle(ty) => ty, - TypeResolution::Value(inner) => context.types.insert( - crate::Type { name: None, inner }, - Default::default(), - ), - } - } - }; - - let init = match context.expressions[value] { - crate::Expression::Constant(handle) if is_uniform_control_flow => { - Init::Constant(handle) - } - _ => Init::Variable(value), - }; - (init, ty) + let init = if lexer.skip(Token::Operation('=')) { + let init = self.general_expression(lexer, ctx.reborrow())?; + Some(init) } else { - match given_ty { - Some(ty) => (Init::Empty, ty), - None => { - log::error!( - "Variable '{}' without an initializer needs a type", - name - ); - return Err(Error::MissingType(name_span)); - } - } + None }; lexer.expect(Token::Separator(';'))?; - let var_id = context.variables.append( - crate::LocalVariable { - name: Some(name.to_owned()), - ty, - init: match init { - Init::Constant(value) => Some(value), - _ => None, - }, - }, - NagaSpan::from(name_span), - ); - // Doesn't make sense to assign a span to cached lookup - let expr_id = context - .expressions - .append(crate::Expression::LocalVariable(var_id), Default::default()); - context.symbol_table.add( - name, - TypedExpression { - handle: expr_id, - is_reference: true, - }, - ); - - if let Init::Variable(value) = init { - Some(crate::Statement::Store { - pointer: expr_id, - value, - }) - } else { - None + let handle = ctx.locals.append(ast::Local, name.span); + if let Some(old) = ctx.local_table.add(name.name, handle) { + return Err(Error::Redefinition { + previous: ctx.locals.get_span(old), + current: name.span, + }); } + + ast::StatementKind::LocalDecl(ast::LocalDecl::Var(ast::LocalVariable { + name, + ty, + init, + handle, + })) } "return" => { let _ = lexer.next(); let value = if lexer.peek().0 != Token::Separator(';') { - emitter.start(context.expressions); - let handle = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - block.extend(emitter.finish(context.expressions)); + let handle = self.general_expression(lexer, ctx.reborrow())?; Some(handle) } else { None }; lexer.expect(Token::Separator(';'))?; - Some(crate::Statement::Return { value }) + ast::StatementKind::Return { value } } "if" => { let _ = lexer.next(); - emitter.start(context.expressions); - let condition = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - block.extend(emitter.finish(context.expressions)); + let condition = self.general_expression(lexer, ctx.reborrow())?; - let accept = self.parse_block(lexer, context.reborrow(), false)?; + let accept = self.block(lexer, ctx.reborrow())?.0; let mut elsif_stack = Vec::new(); let mut elseif_span_start = lexer.start_byte_offset(); let mut reject = loop { if !lexer.skip(Token::Word("else")) { - break crate::Block::new(); + break ast::Block::default(); } if !lexer.skip(Token::Word("if")) { // ... else { ... } - break self.parse_block(lexer, context.reborrow(), false)?; + break self.block(lexer, ctx.reborrow())?.0; } // ... else if (...) { ... } - let mut sub_emitter = super::Emitter::default(); - - sub_emitter.start(context.expressions); - let other_condition = self.parse_general_expression( - lexer, - context.as_expression(block, &mut sub_emitter), - )?; - let other_emit = sub_emitter.finish(context.expressions); - let other_block = self.parse_block(lexer, context.reborrow(), false)?; - elsif_stack.push(( - elseif_span_start, - other_condition, - other_emit, - other_block, - )); + let other_condition = self.general_expression(lexer, ctx.reborrow())?; + let other_block = self.block(lexer, ctx.reborrow())?; + elsif_stack.push((elseif_span_start, other_condition, other_block)); elseif_span_start = lexer.start_byte_offset(); }; - let span_end = lexer.end_byte_offset(); // reverse-fold the else-if blocks //Note: we may consider uplifting this to the IR - for (other_span_start, other_cond, other_emit, other_block) in + for (other_span_start, other_cond, other_block) in elsif_stack.into_iter().rev() { - let sub_stmt = crate::Statement::If { + let sub_stmt = ast::StatementKind::If { condition: other_cond, - accept: other_block, + accept: other_block.0, reject, }; - reject = crate::Block::new(); - reject.extend(other_emit); - reject.push(sub_stmt, NagaSpan::from(other_span_start..span_end)) + reject = ast::Block::default(); + let span = lexer.span_from(other_span_start); + reject.stmts.push(ast::Statement { + kind: sub_stmt, + span, + }) } - Some(crate::Statement::If { + ast::StatementKind::If { condition, accept, reject, - }) + } } "switch" => { let _ = lexer.next(); - emitter.start(context.expressions); - let selector = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - let uint = Some(crate::ScalarKind::Uint) - == context - .as_expression(block, &mut emitter) - .resolve_type(selector)? - .scalar_kind(); - block.extend(emitter.finish(context.expressions)); + let selector = self.general_expression(lexer, ctx.reborrow())?; lexer.expect(Token::Paren('{'))?; let mut cases = Vec::new(); @@ -3937,38 +3052,39 @@ impl Parser { match lexer.next() { (Token::Word("case"), _) => { // parse a list of values - let value = loop { - let value = Self::parse_switch_value(lexer, uint)?; + let (value, value_span) = loop { + let (value, value_span) = Self::switch_value(lexer)?; if lexer.skip(Token::Separator(',')) { if lexer.skip(Token::Separator(':')) { - break value; + break (value, value_span); } } else { lexer.skip(Token::Separator(':')); - break value; + break (value, value_span); } - cases.push(crate::SwitchCase { + cases.push(ast::SwitchCase { value, - body: crate::Block::new(), + value_span, + body: ast::Block::default(), fall_through: true, }); }; - let body = - self.parse_block(lexer, context.reborrow(), false)?; - cases.push(crate::SwitchCase { + let body = self.block(lexer, ctx.reborrow())?.0; + + cases.push(ast::SwitchCase { value, + value_span, body, fall_through: false, }); } - (Token::Word("default"), _) => { + (Token::Word("default"), value_span) => { lexer.skip(Token::Separator(':')); - - let body = - self.parse_block(lexer, context.reborrow(), false)?; - cases.push(crate::SwitchCase { - value: crate::SwitchValue::Default, + let body = self.block(lexer, ctx.reborrow())?.0; + cases.push(ast::SwitchCase { + value: ast::SwitchValue::Default, + value_span, body, fall_through: false, }); @@ -3980,254 +3096,166 @@ impl Parser { } } - Some(crate::Statement::Switch { selector, cases }) + ast::StatementKind::Switch { selector, cases } } - "loop" => Some(self.parse_loop(lexer, context.reborrow(), &mut emitter)?), + "loop" => self.r#loop(lexer, ctx.reborrow())?, "while" => { let _ = lexer.next(); - let mut body = crate::Block::new(); + let mut body = ast::Block::default(); let (condition, span) = lexer.capture_span(|lexer| { - emitter.start(context.expressions); - let condition = self.parse_general_expression( - lexer, - context.as_expression(&mut body, &mut emitter), - )?; - body.extend(emitter.finish(context.expressions)); + let condition = self.general_expression(lexer, ctx.reborrow())?; Ok(condition) })?; - let mut reject = crate::Block::new(); - reject.push(crate::Statement::Break, NagaSpan::default()); - body.push( - crate::Statement::If { + let mut reject = ast::Block::default(); + reject.stmts.push(ast::Statement { + kind: ast::StatementKind::Break, + span, + }); + + body.stmts.push(ast::Statement { + kind: ast::StatementKind::If { condition, - accept: crate::Block::new(), + accept: ast::Block::default(), reject, }, - NagaSpan::from(span), - ); + span, + }); - body.extend_block(self.parse_block(lexer, context.reborrow(), false)?); + let (block, span) = self.block(lexer, ctx.reborrow())?; + body.stmts.push(ast::Statement { + kind: ast::StatementKind::Block(block), + span, + }); - Some(crate::Statement::Loop { + ast::StatementKind::Loop { body, - continuing: crate::Block::new(), + continuing: ast::Block::default(), break_if: None, - }) + } } "for" => { let _ = lexer.next(); lexer.expect(Token::Paren('('))?; - // Push a lexical scope for the for loop - context.symbol_table.push_scope(); + + ctx.local_table.push_scope(); if !lexer.skip(Token::Separator(';')) { - let num_statements = block.len(); + let num_statements = block.stmts.len(); let (_, span) = lexer.capture_span(|lexer| { - self.parse_statement( - lexer, - context.reborrow(), - block, - is_uniform_control_flow, - ) + self.statement(lexer, ctx.reborrow(), block) })?; - if block.len() != num_statements { - match *block.last().unwrap() { - crate::Statement::Store { .. } - | crate::Statement::Call { .. } => {} + if block.stmts.len() != num_statements { + match block.stmts.last().unwrap().kind { + ast::StatementKind::Call { .. } + | ast::StatementKind::Assign { .. } + | ast::StatementKind::LocalDecl(_) => {} _ => return Err(Error::InvalidForInitializer(span)), } } }; - let mut body = crate::Block::new(); + let mut body = ast::Block::default(); if !lexer.skip(Token::Separator(';')) { let (condition, span) = lexer.capture_span(|lexer| { - emitter.start(context.expressions); - let condition = self.parse_general_expression( - lexer, - context.as_expression(&mut body, &mut emitter), - )?; + let condition = self.general_expression(lexer, ctx.reborrow())?; lexer.expect(Token::Separator(';'))?; - body.extend(emitter.finish(context.expressions)); Ok(condition) })?; - let mut reject = crate::Block::new(); - reject.push(crate::Statement::Break, NagaSpan::default()); - body.push( - crate::Statement::If { + let mut reject = ast::Block::default(); + reject.stmts.push(ast::Statement { + kind: ast::StatementKind::Break, + span, + }); + body.stmts.push(ast::Statement { + kind: ast::StatementKind::If { condition, - accept: crate::Block::new(), + accept: ast::Block::default(), reject, }, - NagaSpan::from(span), - ); + span, + }); }; - let mut continuing = crate::Block::new(); + let mut continuing = ast::Block::default(); if !lexer.skip(Token::Paren(')')) { - match lexer.peek().0 { - Token::Word(ident) - if context.symbol_table.lookup(ident).is_none() => - { - self.parse_function_statement( - lexer, - ident, - context.as_expression(&mut continuing, &mut emitter), - )? - } - _ => self.parse_assignment_statement( - lexer, - context.reborrow(), - &mut continuing, - &mut emitter, - )?, - } + self.function_call_or_assignment_statement( + lexer, + ctx.reborrow(), + &mut continuing, + )?; lexer.expect(Token::Paren(')'))?; } - body.extend_block(self.parse_block(lexer, context.reborrow(), false)?); + let (block, span) = self.block(lexer, ctx.reborrow())?; + body.stmts.push(ast::Statement { + kind: ast::StatementKind::Block(block), + span, + }); - // Pop the for loop lexical scope - context.symbol_table.pop_scope(); + ctx.local_table.pop_scope(); - Some(crate::Statement::Loop { + ast::StatementKind::Loop { body, continuing, break_if: None, - }) + } } "break" => { - let (_, mut span) = lexer.next(); + let (_, span) = lexer.next(); // Check if the next token is an `if`, this indicates // that the user tried to type out a `break if` which // is illegal in this position. let (peeked_token, peeked_span) = lexer.peek(); if let Token::Word("if") = peeked_token { - span.end = peeked_span.end; + let span = span.until(&peeked_span); return Err(Error::InvalidBreakIf(span)); } - Some(crate::Statement::Break) + ast::StatementKind::Break } "continue" => { let _ = lexer.next(); - Some(crate::Statement::Continue) + ast::StatementKind::Continue } "discard" => { let _ = lexer.next(); - Some(crate::Statement::Kill) - } - "storageBarrier" => { - let _ = lexer.next(); - lexer.expect(Token::Paren('('))?; - lexer.expect(Token::Paren(')'))?; - Some(crate::Statement::Barrier(crate::Barrier::STORAGE)) - } - "workgroupBarrier" => { - let _ = lexer.next(); - lexer.expect(Token::Paren('('))?; - lexer.expect(Token::Paren(')'))?; - Some(crate::Statement::Barrier(crate::Barrier::WORK_GROUP)) - } - "atomicStore" => { - let _ = lexer.next(); - emitter.start(context.expressions); - lexer.open_arguments()?; - let mut expression_ctx = context.as_expression(block, &mut emitter); - let pointer = - self.parse_atomic_pointer(lexer, expression_ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let value = self.parse_general_expression(lexer, expression_ctx)?; - lexer.close_arguments()?; - block.extend(emitter.finish(context.expressions)); - Some(crate::Statement::Store { pointer, value }) - } - "textureStore" => { - let _ = lexer.next(); - emitter.start(context.expressions); - lexer.open_arguments()?; - let mut expr_context = context.as_expression(block, &mut emitter); - let (image, image_span) = self - .parse_general_expression_with_span(lexer, expr_context.reborrow())?; - lexer.expect(Token::Separator(','))?; - let arrayed = match *expr_context.resolve_type(image)? { - crate::TypeInner::Image { arrayed, .. } => arrayed, - _ => return Err(Error::BadTexture(image_span)), - }; - let coordinate = self.parse_general_expression(lexer, expr_context)?; - let array_index = if arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let value = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - lexer.close_arguments()?; - block.extend(emitter.finish(context.expressions)); - Some(crate::Statement::ImageStore { - image, - coordinate, - array_index, - value, - }) + ast::StatementKind::Kill } // assignment or a function call - ident => { - match context.symbol_table.lookup(ident) { - Some(_) => self.parse_assignment_statement( - lexer, - context, - block, - &mut emitter, - )?, - None => self.parse_function_statement( - lexer, - ident, - context.as_expression(block, &mut emitter), - )?, - } + _ => { + self.function_call_or_assignment_statement(lexer, ctx.reborrow(), block)?; lexer.expect(Token::Separator(';'))?; - None + self.pop_rule_span(lexer); + return Ok(()); } }; - let span = NagaSpan::from(self.pop_rule_span(lexer)); - if let Some(statement) = statement { - block.push(statement, span); - } + + let span = self.pop_rule_span(lexer); + block.stmts.push(ast::Statement { kind, span }); } _ => { - let mut emitter = super::Emitter::default(); - self.parse_assignment_statement(lexer, context, block, &mut emitter)?; + self.assignment_statement(lexer, ctx.reborrow(), block)?; self.pop_rule_span(lexer); } } Ok(()) } - fn parse_loop<'a>( + fn r#loop<'a>( &mut self, lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, '_>, - emitter: &mut super::Emitter, - ) -> Result> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result, Error<'a>> { let _ = lexer.next(); - let mut body = crate::Block::new(); - let mut continuing = crate::Block::new(); + let mut body = ast::Block::default(); + let mut continuing = ast::Block::default(); let mut break_if = None; - // Push a lexical scope for the loop body - context.symbol_table.push_scope(); - lexer.expect(Token::Paren('{'))?; + ctx.local_table.push_scope(); + loop { if lexer.skip(Token::Word("continuing")) { // Branch for the `continuing` block, this must be @@ -4245,19 +3273,12 @@ impl Parser { // the break if lexer.expect(Token::Word("if"))?; - // Start the emitter to begin parsing an expression - emitter.start(context.expressions); - let condition = self.parse_general_expression( - lexer, - context.as_expression(&mut body, emitter), - )?; - // Add all emits to the continuing body - continuing.extend(emitter.finish(context.expressions)); + let condition = self.general_expression(lexer, ctx.reborrow())?; // Set the condition of the break if to the newly parsed // expression break_if = Some(condition); - // Expext a semicolon to close the statement + // Expect a semicolon to close the statement lexer.expect(Token::Separator(';'))?; // Expect a closing brace to close the continuing block, // since the break if must be the last statement @@ -4270,7 +3291,7 @@ impl Parser { break; } else { // Otherwise try to parse a statement - self.parse_statement(lexer, context.reborrow(), &mut continuing, false)?; + self.statement(lexer, ctx.reborrow(), &mut continuing)?; } } // Since the continuing block must be the last part of the loop body, @@ -4284,13 +3305,12 @@ impl Parser { break; } // Otherwise try to parse a statement - self.parse_statement(lexer, context.reborrow(), &mut body, false)?; + self.statement(lexer, ctx.reborrow(), &mut body)?; } - // Pop the loop body lexical scope - context.symbol_table.pop_scope(); + ctx.local_table.pop_scope(); - Ok(crate::Statement::Loop { + Ok(ast::StatementKind::Loop { body, continuing, break_if, @@ -4298,34 +3318,28 @@ impl Parser { } /// compound_statement - fn parse_block<'a>( + fn block<'a>( &mut self, lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, '_>, - is_uniform_control_flow: bool, - ) -> Result> { + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result<(ast::Block<'a>, Span), Error<'a>> { self.push_rule_span(Rule::Block, lexer); - // Push a lexical scope for the block - context.symbol_table.push_scope(); - lexer.expect(Token::Paren('{'))?; - let mut block = crate::Block::new(); + ctx.local_table.push_scope(); + + let _ = lexer.next(); + let mut statements = ast::Block::default(); while !lexer.skip(Token::Paren('}')) { - self.parse_statement( - lexer, - context.reborrow(), - &mut block, - is_uniform_control_flow, - )?; + self.statement(lexer, ctx.reborrow(), &mut statements)?; } - // Pop the block lexical scope - context.symbol_table.pop_scope(); - self.pop_rule_span(lexer); - Ok(block) + ctx.local_table.pop_scope(); + + let span = self.pop_rule_span(lexer); + Ok((statements, span)) } - fn parse_varying_binding<'a>( + fn varying_binding<'a>( &mut self, lexer: &mut Lexer<'a>, ) -> Result, Error<'a>> { @@ -4341,48 +3355,26 @@ impl Parser { bind_parser.finish(span) } - fn parse_function_decl<'a>( + fn function_decl<'a>( &mut self, lexer: &mut Lexer<'a>, - module: &mut crate::Module, - lookup_global_expression: &FastHashMap<&'a str, crate::Expression>, - ) -> Result<(crate::Function, &'a str), Error<'a>> { + out: &mut ast::TranslationUnit<'a>, + dependencies: &mut FastHashSet>, + ) -> Result, Error<'a>> { self.push_rule_span(Rule::FunctionDecl, lexer); // read function name - let mut symbol_table = super::SymbolTable::default(); - let (fun_name, span) = lexer.next_ident_with_span()?; - if crate::keywords::wgsl::RESERVED.contains(&fun_name) { - return Err(Error::ReservedKeyword(span)); - } - if let Some(entry) = self - .module_scope_identifiers - .insert(String::from(fun_name), span.clone()) - { - return Err(Error::Redefinition { - previous: entry, - current: span, - }); - } - // populate initial expressions - let mut expressions = Arena::new(); - for (&name, expression) in lookup_global_expression.iter() { - let (span, is_reference) = match *expression { - crate::Expression::GlobalVariable(handle) => ( - module.global_variables.get_span(handle), - module.global_variables[handle].space != crate::AddressSpace::Handle, - ), - crate::Expression::Constant(handle) => (module.constants.get_span(handle), false), - _ => unreachable!(), - }; - let expression = expressions.append(expression.clone(), span); - symbol_table.add( - name, - TypedExpression { - handle: expression, - is_reference, - }, - ); - } + let fun_name = lexer.next_ident()?; + + let mut locals = Arena::new(); + + let mut ctx = ParseExpressionContext { + expressions: &mut out.expressions, + local_table: &mut super::SymbolTable::default(), + locals: &mut locals, + types: &mut out.types, + unresolved: dependencies, + }; + // read parameter list let mut arguments = Vec::new(); lexer.expect(Token::Paren('('))?; @@ -4394,92 +3386,55 @@ impl Parser { ExpectedToken::Token(Token::Separator(',')), )); } - let mut binding = self.parse_varying_binding(lexer)?; - let (param_name, param_name_span, param_type) = - self.parse_variable_ident_decl(lexer, &mut module.types, &mut module.constants)?; - if crate::keywords::wgsl::RESERVED.contains(¶m_name) { - return Err(Error::ReservedKeyword(param_name_span)); - } - let param_index = arguments.len() as u32; - let expression = expressions.append( - crate::Expression::FunctionArgument(param_index), - NagaSpan::from(param_name_span), - ); - symbol_table.add( - param_name, - TypedExpression { - handle: expression, - is_reference: false, - }, - ); - if let Some(ref mut binding) = binding { - binding.apply_default_interpolation(&module.types[param_type].inner); - } - arguments.push(crate::FunctionArgument { - name: Some(param_name.to_string()), + let binding = self.varying_binding(lexer)?; + + let param_name = lexer.next_ident()?; + + lexer.expect(Token::Separator(':'))?; + let param_type = self.type_decl(lexer, ctx.reborrow())?; + + let handle = ctx.locals.append(ast::Local, param_name.span); + ctx.local_table.add(param_name.name, handle); + arguments.push(ast::FunctionArgument { + name: param_name, ty: param_type, binding, + handle, }); ready = lexer.skip(Token::Separator(',')); } // read return type let result = if lexer.skip(Token::Arrow) && !lexer.skip(Token::Word("void")) { - let mut binding = self.parse_varying_binding(lexer)?; - let ty = self.parse_type_decl(lexer, None, &mut module.types, &mut module.constants)?; - if let Some(ref mut binding) = binding { - binding.apply_default_interpolation(&module.types[ty].inner); - } - Some(crate::FunctionResult { ty, binding }) + let binding = self.varying_binding(lexer)?; + let ty = self.type_decl(lexer, ctx.reborrow())?; + Some(ast::FunctionResult { ty, binding }) } else { None }; - let mut fun = crate::Function { - name: Some(fun_name.to_string()), + // read body + let body = self.block(lexer, ctx)?.0; + + let fun = ast::Function { + entry_point: None, + name: fun_name, arguments, result, - local_variables: Arena::new(), - expressions, - named_expressions: crate::NamedExpressions::default(), - body: crate::Block::new(), + body, + locals, }; - // read body - let mut typifier = super::Typifier::new(); - let mut named_expressions = crate::FastHashMap::default(); - fun.body = self.parse_block( - lexer, - StatementContext { - symbol_table: &mut symbol_table, - typifier: &mut typifier, - variables: &mut fun.local_variables, - expressions: &mut fun.expressions, - named_expressions: &mut named_expressions, - types: &mut module.types, - constants: &mut module.constants, - global_vars: &module.global_variables, - functions: &module.functions, - arguments: &fun.arguments, - }, - true, - )?; - // fixup the IR - ensure_block_returns(&mut fun.body); // done self.pop_rule_span(lexer); - // Set named expressions after block parsing ends - fun.named_expressions = named_expressions; - - Ok((fun, fun_name)) + Ok(fun) } - fn parse_global_decl<'a>( + fn global_decl<'a>( &mut self, lexer: &mut Lexer<'a>, - module: &mut crate::Module, - lookup_global_expression: &mut FastHashMap<&'a str, crate::Expression>, - ) -> Result> { + out: &mut ast::TranslationUnit<'a>, + ) -> Result<(), Error<'a>> { // read attributes let mut binding = None; let mut stage = None; @@ -4492,12 +3447,12 @@ impl Parser { match lexer.next_ident_with_span()? { ("binding", _) => { lexer.expect(Token::Paren('('))?; - bind_index = Some(Self::parse_non_negative_i32_literal(lexer)?); + bind_index = Some(Self::non_negative_i32_literal(lexer)?); lexer.expect(Token::Paren(')'))?; } ("group", _) => { lexer.expect(Token::Paren('('))?; - bind_group = Some(Self::parse_non_negative_i32_literal(lexer)?); + bind_group = Some(Self::non_negative_i32_literal(lexer)?); lexer.expect(Token::Paren(')'))?; } ("vertex", _) => { @@ -4513,7 +3468,7 @@ impl Parser { lexer.expect(Token::Paren('('))?; workgroup_size = [1u32; 3]; for (i, size) in workgroup_size.iter_mut().enumerate() { - *size = Self::parse_generic_non_negative_int_literal(lexer)?; + *size = Self::generic_non_negative_int_literal(lexer)?; match lexer.next() { (Token::Paren(')'), _) => break, (Token::Separator(','), _) if i != 2 => (), @@ -4554,162 +3509,84 @@ impl Parser { (None, None) => {} } - // read items + let mut dependencies = FastHashSet::default(); + let mut ctx = ParseExpressionContext { + expressions: &mut out.expressions, + local_table: &mut super::SymbolTable::default(), + locals: &mut Arena::new(), + types: &mut out.types, + unresolved: &mut dependencies, + }; + + // read item let start = lexer.start_byte_offset(); - match lexer.next() { - (Token::Separator(';'), _) => {} + let kind = match lexer.next() { + (Token::Separator(';'), _) => None, (Token::Word("struct"), _) => { - let (name, span) = lexer.next_ident_with_span()?; - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(span)); - } - let (members, span) = - self.parse_struct_body(lexer, &mut module.types, &mut module.constants)?; - let type_span = NagaSpan::from(lexer.span_from(start)); - let ty = module.types.insert( - crate::Type { - name: Some(name.to_string()), - inner: crate::TypeInner::Struct { members, span }, - }, - type_span, - ); - self.lookup_type.insert(name.to_owned(), ty); + let name = lexer.next_ident()?; + + let members = self.struct_body(lexer, ctx)?; + Some(ast::GlobalDeclKind::Struct(ast::Struct { name, members })) } (Token::Word("type"), _) => { let name = lexer.next_ident()?; + lexer.expect(Token::Operation('='))?; - let ty = self.parse_type_decl( - lexer, - Some(name), - &mut module.types, - &mut module.constants, - )?; - self.lookup_type.insert(name.to_owned(), ty); + let ty = self.type_decl(lexer, ctx)?; lexer.expect(Token::Separator(';'))?; + Some(ast::GlobalDeclKind::Type(ast::TypeAlias { name, ty })) } - (Token::Word("let"), _) => { - let (name, name_span) = lexer.next_ident_with_span()?; - if crate::keywords::wgsl::RESERVED.contains(&name) { - return Err(Error::ReservedKeyword(name_span)); - } - if let Some(entry) = self - .module_scope_identifiers - .insert(String::from(name), name_span.clone()) - { - return Err(Error::Redefinition { - previous: entry, - current: name_span, - }); - } - let given_ty = if lexer.skip(Token::Separator(':')) { - let ty = self.parse_type_decl( - lexer, - None, - &mut module.types, - &mut module.constants, - )?; + (Token::Word("const"), _) => { + let name = lexer.next_ident()?; + + let ty = if lexer.skip(Token::Separator(':')) { + let ty = self.type_decl(lexer, ctx.reborrow())?; Some(ty) } else { None }; lexer.expect(Token::Operation('='))?; - let first_token_span = lexer.next(); - let const_handle = self.parse_const_expression_impl( - first_token_span, - lexer, - Some(name), - &mut module.types, - &mut module.constants, - )?; - - if let Some(explicit_ty) = given_ty { - let con = &module.constants[const_handle]; - let type_match = match con.inner { - crate::ConstantInner::Scalar { width, value } => { - module.types[explicit_ty].inner - == crate::TypeInner::Scalar { - kind: value.scalar_kind(), - width, - } - } - crate::ConstantInner::Composite { ty, components: _ } => ty == explicit_ty, - }; - if !type_match { - let expected_inner_str = match con.inner { - crate::ConstantInner::Scalar { width, value } => { - crate::TypeInner::Scalar { - kind: value.scalar_kind(), - width, - } - .to_wgsl(&module.types, &module.constants) - } - crate::ConstantInner::Composite { .. } => module.types[explicit_ty] - .inner - .to_wgsl(&module.types, &module.constants), - }; - return Err(Error::InitializationTypeMismatch( - name_span, - expected_inner_str, - )); - } - } - + let init = self.general_expression(lexer, ctx)?; lexer.expect(Token::Separator(';'))?; - lookup_global_expression.insert(name, crate::Expression::Constant(const_handle)); + + Some(ast::GlobalDeclKind::Const(ast::Const { name, ty, init })) } (Token::Word("var"), _) => { - let pvar = - self.parse_variable_decl(lexer, &mut module.types, &mut module.constants)?; - if crate::keywords::wgsl::RESERVED.contains(&pvar.name) { - return Err(Error::ReservedKeyword(pvar.name_span)); - } - if let Some(entry) = self - .module_scope_identifiers - .insert(String::from(pvar.name), pvar.name_span.clone()) - { - return Err(Error::Redefinition { - previous: entry, - current: pvar.name_span, - }); - } - let var_handle = module.global_variables.append( - crate::GlobalVariable { - name: Some(pvar.name.to_owned()), - space: pvar.space.unwrap_or(crate::AddressSpace::Handle), - binding: binding.take(), - ty: pvar.ty, - init: pvar.init, - }, - NagaSpan::from(pvar.name_span), - ); - lookup_global_expression - .insert(pvar.name, crate::Expression::GlobalVariable(var_handle)); + let mut var = self.variable_decl(lexer, ctx)?; + var.binding = binding.take(); + Some(ast::GlobalDeclKind::Var(var)) } (Token::Word("fn"), _) => { - let (function, name) = - self.parse_function_decl(lexer, module, lookup_global_expression)?; - match stage { - Some(stage) => module.entry_points.push(crate::EntryPoint { - name: name.to_string(), + let function = self.function_decl(lexer, out, &mut dependencies)?; + Some(ast::GlobalDeclKind::Fn(ast::Function { + entry_point: stage.map(|stage| ast::EntryPoint { stage, early_depth_test, workgroup_size, - function, }), - None => { - module - .functions - .append(function, NagaSpan::from(lexer.span_from(start))); - } - } + ..function + })) } - (Token::End, _) => return Ok(false), + (Token::End, _) => return Ok(()), other => return Err(Error::Unexpected(other.1, ExpectedToken::GlobalItem)), + }; + + if let Some(kind) = kind { + out.decls.append( + ast::GlobalDecl { kind, dependencies }, + lexer.span_from(start), + ); } + if !self.rules.is_empty() { + log::error!("Reached the end of global decl, but rule stack is not empty"); + log::error!("Rules: {:?}", self.rules); + return Err(Error::Other); + }; + match binding { - None => Ok(true), + None => Ok(()), // we had the attribute but no var? Some(_) => Err(Error::Other), } @@ -4718,22 +3595,1850 @@ impl Parser { pub fn parse(&mut self, source: &str) -> Result { self.reset(); - let mut module = crate::Module::default(); let mut lexer = Lexer::new(source); - let mut lookup_global_expression = FastHashMap::default(); + let mut tu = ast::TranslationUnit::default(); loop { - match self.parse_global_decl(&mut lexer, &mut module, &mut lookup_global_expression) { + match self.global_decl(&mut lexer, &mut tu) { Err(error) => return Err(error.as_parse_error(lexer.source)), - Ok(true) => {} - Ok(false) => { - if !self.rules.is_empty() { - log::error!("Reached the end of file, but rule stack is not empty"); - return Err(Error::Other.as_parse_error(lexer.source)); - }; - return Ok(module); + Ok(()) => { + if lexer.peek().0 == Token::End { + break; + } } } } + + let index = index::Index::generate(&tu).map_err(|x| x.as_parse_error(source))?; + let module = Lowerer::new(&index) + .lower(&tu) + .map_err(|x| x.as_parse_error(source))?; + + Ok(module) + } +} + +/// An `ast::GlobalDecl` for which we have built the Naga IR equivalent. +enum LoweredGlobalDecl { + Function(Handle), + Var(Handle), + Const(Handle), + Type(Handle), + EntryPoint, +} + +enum ConstantOrInner { + Constant(Handle), + Inner(crate::ConstantInner), +} + +enum Texture { + Gather, + GatherCompare, + + Sample, + SampleBias, + SampleCompare, + SampleCompareLevel, + SampleGrad, + SampleLevel, + // SampleBaseClampToEdge, +} + +impl Texture { + pub fn map(word: &str) -> Option { + Some(match word { + "textureGather" => Self::Gather, + "textureGatherCompare" => Self::GatherCompare, + + "textureSample" => Self::Sample, + "textureSampleBias" => Self::SampleBias, + "textureSampleCompare" => Self::SampleCompare, + "textureSampleCompareLevel" => Self::SampleCompareLevel, + "textureSampleGrad" => Self::SampleGrad, + "textureSampleLevel" => Self::SampleLevel, + // "textureSampleBaseClampToEdge" => Some(Self::SampleBaseClampToEdge), + _ => return None, + }) + } + + pub const fn min_argument_count(&self) -> u32 { + match *self { + Self::Gather => 3, + Self::GatherCompare => 4, + + Self::Sample => 3, + Self::SampleBias => 5, + Self::SampleCompare => 5, + Self::SampleCompareLevel => 5, + Self::SampleGrad => 6, + Self::SampleLevel => 5, + // Self::SampleBaseClampToEdge => 3, + } + } +} + +struct Lowerer<'source, 'temp> { + index: &'temp index::Index<'source>, + layouter: Layouter, +} + +impl<'source, 'temp> Lowerer<'source, 'temp> { + pub fn new(index: &'temp index::Index<'source>) -> Self { + Self { + index, + layouter: Layouter::default(), + } + } + + pub fn lower( + &mut self, + tu: &'temp ast::TranslationUnit<'source>, + ) -> Result> { + let mut module = crate::Module::default(); + + let mut ctx = OutputContext { + ast_expressions: &tu.expressions, + globals: &mut FastHashMap::default(), + types: &tu.types, + module: &mut module, + }; + + for decl in self.index.visit_ordered() { + let span = tu.decls.get_span(decl); + let decl = &tu.decls[decl]; + + match decl.kind { + ast::GlobalDeclKind::Fn(ref f) => { + let decl = self.function(f, span, ctx.reborrow())?; + ctx.globals.insert(f.name.name, decl); + } + ast::GlobalDeclKind::Var(ref v) => { + let ty = self.resolve_ast_type(v.ty, ctx.reborrow())?; + + let init = v + .init + .map(|init| self.constant(init, ctx.reborrow())) + .transpose()?; + + let handle = ctx.module.global_variables.append( + crate::GlobalVariable { + name: Some(v.name.name.to_string()), + space: v.space, + binding: v.binding.clone(), + ty, + init, + }, + span, + ); + + ctx.globals + .insert(v.name.name, LoweredGlobalDecl::Var(handle)); + } + ast::GlobalDeclKind::Const(ref c) => { + let inner = self.constant_inner(c.init, ctx.reborrow())?; + let inner = match inner { + ConstantOrInner::Constant(c) => ctx.module.constants[c].inner.clone(), + ConstantOrInner::Inner(inner) => inner, + }; + + let inferred_type = match inner { + crate::ConstantInner::Scalar { width, value } => { + ctx.ensure_type_exists(crate::TypeInner::Scalar { + width, + kind: value.scalar_kind(), + }) + } + crate::ConstantInner::Composite { ty, .. } => ty, + }; + + let handle = ctx.module.constants.append( + crate::Constant { + name: Some(c.name.name.to_string()), + specialization: None, + inner, + }, + span, + ); + + let explicit_ty = + c.ty.map(|ty| self.resolve_ast_type(ty, ctx.reborrow())) + .transpose()?; + + if let Some(explicit) = explicit_ty { + if explicit != inferred_type { + let ty = &ctx.module.types[explicit]; + let explicit = ty.name.clone().unwrap_or_else(|| { + ty.inner.to_wgsl(&ctx.module.types, &ctx.module.constants) + }); + + let ty = &ctx.module.types[inferred_type]; + let inferred = ty.name.clone().unwrap_or_else(|| { + ty.inner.to_wgsl(&ctx.module.types, &ctx.module.constants) + }); + + return Err(Error::InitializationTypeMismatch( + c.name.span, + explicit, + inferred, + )); + } + } + + ctx.globals + .insert(c.name.name, LoweredGlobalDecl::Const(handle)); + } + ast::GlobalDeclKind::Struct(ref s) => { + let handle = self.r#struct(s, span, ctx.reborrow())?; + ctx.globals + .insert(s.name.name, LoweredGlobalDecl::Type(handle)); + } + ast::GlobalDeclKind::Type(ref alias) => { + let ty = self.resolve_ast_type(alias.ty, ctx.reborrow())?; + ctx.globals + .insert(alias.name.name, LoweredGlobalDecl::Type(ty)); + } + } + } + + Ok(module) + } + + fn function( + &mut self, + f: &ast::Function<'source>, + span: Span, + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result> { + let mut local_table = FastHashMap::default(); + let mut local_variables = Arena::new(); + let mut expressions = Arena::new(); + let mut named_expressions = crate::NamedExpressions::default(); + + let arguments = f + .arguments + .iter() + .enumerate() + .map(|(i, arg)| { + let ty = self.resolve_ast_type(arg.ty, ctx.reborrow())?; + let expr = expressions + .append(crate::Expression::FunctionArgument(i as u32), arg.name.span); + local_table.insert(arg.handle, TypedExpression::non_reference(expr)); + named_expressions.insert(expr, arg.name.name.to_string()); + + Ok(crate::FunctionArgument { + name: Some(arg.name.name.to_string()), + ty, + binding: self.interpolate_default(&arg.binding, ty, ctx.reborrow()), + }) + }) + .collect::, _>>()?; + + let result = f + .result + .as_ref() + .map(|res| { + self.resolve_ast_type(res.ty, ctx.reborrow()) + .map(|ty| crate::FunctionResult { + ty, + binding: self.interpolate_default(&res.binding, ty, ctx.reborrow()), + }) + }) + .transpose()?; + + let mut typifier = super::Typifier::default(); + let mut body = self.block( + &f.body, + StatementContext { + local_table: &mut local_table, + globals: ctx.globals, + ast_expressions: ctx.ast_expressions, + typifier: &mut typifier, + variables: &mut local_variables, + naga_expressions: &mut expressions, + named_expressions: &mut named_expressions, + types: ctx.types, + module: ctx.module, + arguments: &arguments, + }, + )?; + ensure_block_returns(&mut body); + + let function = crate::Function { + name: Some(f.name.name.to_string()), + arguments, + result, + local_variables, + expressions, + named_expressions, + body, + }; + + if let Some(ref entry) = f.entry_point { + ctx.module.entry_points.push(crate::EntryPoint { + name: f.name.name.to_string(), + stage: entry.stage, + early_depth_test: entry.early_depth_test, + workgroup_size: entry.workgroup_size, + function, + }); + Ok(LoweredGlobalDecl::EntryPoint) + } else { + let handle = ctx.module.functions.append(function, span); + Ok(LoweredGlobalDecl::Function(handle)) + } + } + + fn block( + &mut self, + b: &ast::Block<'source>, + mut ctx: StatementContext<'source, '_, '_>, + ) -> Result> { + let mut block = crate::Block::default(); + + for stmt in b.stmts.iter() { + self.statement(stmt, &mut block, ctx.reborrow())?; + } + + Ok(block) + } + + fn statement( + &mut self, + stmt: &ast::Statement<'source>, + block: &mut crate::Block, + mut ctx: StatementContext<'source, '_, '_>, + ) -> Result<(), Error<'source>> { + let out = match stmt.kind { + ast::StatementKind::Block(ref block) => { + let block = self.block(block, ctx.reborrow())?; + crate::Statement::Block(block) + } + ast::StatementKind::LocalDecl(ref decl) => match *decl { + ast::LocalDecl::Let(ref l) => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let value = self.expression(l.init, ctx.as_expression(block, &mut emitter))?; + + let explicit_ty = + l.ty.map(|ty| self.resolve_ast_type(ty, ctx.as_output())) + .transpose()?; + + if let Some(ty) = explicit_ty { + let mut ctx = ctx.as_expression(block, &mut emitter); + let init_ty = ctx.register_type(value)?; + if !ctx.module.types[ty] + .inner + .equivalent(&ctx.module.types[init_ty].inner, &ctx.module.types) + { + return Err(Error::InitializationTypeMismatch( + l.name.span, + ctx.format_type(ty), + ctx.format_type(init_ty), + )); + } + } + + block.extend(emitter.finish(ctx.naga_expressions)); + ctx.local_table + .insert(l.handle, TypedExpression::non_reference(value)); + ctx.named_expressions.insert(value, l.name.name.to_string()); + + return Ok(()); + } + ast::LocalDecl::Var(ref v) => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let initializer = match v.init { + Some(init) => { + let initializer = + self.expression(init, ctx.as_expression(block, &mut emitter))?; + ctx.as_expression(block, &mut emitter) + .grow_types(initializer)?; + Some(initializer) + } + None => None, + }; + + let explicit_ty = + v.ty.map(|ty| self.resolve_ast_type(ty, ctx.as_output())) + .transpose()?; + + let ty = match (explicit_ty, initializer) { + (Some(explicit), Some(initializer)) => { + let ctx = ctx.as_expression(block, &mut emitter); + let initializer_ty = ctx.resolved_inner(initializer); + if !ctx.module.types[explicit] + .inner + .equivalent(initializer_ty, &ctx.module.types) + { + return Err(Error::InitializationTypeMismatch( + v.name.span, + ctx.format_type(explicit), + ctx.format_typeinner(initializer_ty), + )); + } + explicit + } + (Some(explicit), None) => explicit, + (None, Some(initializer)) => ctx + .as_expression(block, &mut emitter) + .register_type(initializer)?, + (None, None) => { + return Err(Error::MissingType(v.name.span)); + } + }; + + let var = ctx.variables.append( + crate::LocalVariable { + name: Some(v.name.name.to_string()), + ty, + init: None, + }, + stmt.span, + ); + + let handle = ctx + .as_expression(block, &mut emitter) + .interrupt_emitter(crate::Expression::LocalVariable(var), Span::UNDEFINED); + block.extend(emitter.finish(ctx.naga_expressions)); + ctx.local_table.insert( + v.handle, + TypedExpression { + handle, + is_reference: true, + }, + ); + + match initializer { + Some(initializer) => crate::Statement::Store { + pointer: handle, + value: initializer, + }, + None => return Ok(()), + } + } + }, + ast::StatementKind::If { + condition, + ref accept, + ref reject, + } => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let condition = + self.expression(condition, ctx.as_expression(block, &mut emitter))?; + block.extend(emitter.finish(ctx.naga_expressions)); + + let accept = self.block(accept, ctx.reborrow())?; + let reject = self.block(reject, ctx.reborrow())?; + + crate::Statement::If { + condition, + accept, + reject, + } + } + ast::StatementKind::Switch { + selector, + ref cases, + } => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let mut ectx = ctx.as_expression(block, &mut emitter); + let selector = self.expression(selector, ectx.reborrow())?; + + ectx.grow_types(selector)?; + let uint = + ectx.resolved_inner(selector).scalar_kind() == Some(crate::ScalarKind::Uint); + block.extend(emitter.finish(ctx.naga_expressions)); + + let cases = cases + .iter() + .map(|case| { + Ok(crate::SwitchCase { + value: match case.value { + ast::SwitchValue::I32(num) if !uint => { + crate::SwitchValue::Integer(num) + } + ast::SwitchValue::U32(num) if uint => { + crate::SwitchValue::Integer(num as i32) + } + ast::SwitchValue::Default => crate::SwitchValue::Default, + _ => { + return Err(Error::InvalidSwitchValue { + uint, + span: case.value_span, + }); + } + }, + body: self.block(&case.body, ctx.reborrow())?, + fall_through: case.fall_through, + }) + }) + .collect::>()?; + + crate::Statement::Switch { selector, cases } + } + ast::StatementKind::Loop { + ref body, + ref continuing, + break_if, + } => { + let body = self.block(body, ctx.reborrow())?; + let mut continuing = self.block(continuing, ctx.reborrow())?; + + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + let break_if = break_if + .map(|expr| self.expression(expr, ctx.as_expression(block, &mut emitter))) + .transpose()?; + continuing.extend(emitter.finish(ctx.naga_expressions)); + + crate::Statement::Loop { + body, + continuing, + break_if, + } + } + ast::StatementKind::Break => crate::Statement::Break, + ast::StatementKind::Continue => crate::Statement::Continue, + ast::StatementKind::Return { value } => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let value = value + .map(|expr| self.expression(expr, ctx.as_expression(block, &mut emitter))) + .transpose()?; + block.extend(emitter.finish(ctx.naga_expressions)); + + crate::Statement::Return { value } + } + ast::StatementKind::Kill => crate::Statement::Kill, + ast::StatementKind::Call { + ref function, + ref arguments, + } => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let _ = self.call( + stmt.span, + function, + arguments, + ctx.as_expression(block, &mut emitter), + )?; + block.extend(emitter.finish(ctx.naga_expressions)); + return Ok(()); + } + ast::StatementKind::Assign { target, op, value } => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let expr = + self.expression_for_reference(target, ctx.as_expression(block, &mut emitter))?; + let mut value = self.expression(value, ctx.as_expression(block, &mut emitter))?; + + if !expr.is_reference { + let ty = if ctx.named_expressions.contains_key(&expr.handle) { + InvalidAssignmentType::ImmutableBinding + } else { + match ctx.naga_expressions[expr.handle] { + crate::Expression::Swizzle { .. } => InvalidAssignmentType::Swizzle, + _ => InvalidAssignmentType::Other, + } + }; + + return Err(Error::InvalidAssignment { + span: ctx.ast_expressions.get_span(target), + ty, + }); + } + + let value = match op { + Some(op) => { + let mut ctx = ctx.as_expression(block, &mut emitter); + let mut left = ctx.apply_load_rule(expr); + ctx.binary_op_splat(op, &mut left, &mut value)?; + ctx.naga_expressions.append( + crate::Expression::Binary { + op, + left, + right: value, + }, + stmt.span, + ) + } + None => value, + }; + block.extend(emitter.finish(ctx.naga_expressions)); + + crate::Statement::Store { + pointer: expr.handle, + value, + } + } + ast::StatementKind::Increment(value) | ast::StatementKind::Decrement(value) => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let op = match stmt.kind { + ast::StatementKind::Increment(_) => crate::BinaryOperator::Add, + ast::StatementKind::Decrement(_) => crate::BinaryOperator::Subtract, + _ => unreachable!(), + }; + + let value_span = ctx.ast_expressions.get_span(value); + let reference = + self.expression_for_reference(value, ctx.as_expression(block, &mut emitter))?; + let mut ectx = ctx.as_expression(block, &mut emitter); + + ectx.grow_types(reference.handle)?; + let (kind, width) = match *ectx.resolved_inner(reference.handle) { + crate::TypeInner::ValuePointer { + size: None, + kind, + width, + .. + } => (kind, width), + crate::TypeInner::Pointer { base, .. } => match ectx.module.types[base].inner { + crate::TypeInner::Scalar { kind, width } => (kind, width), + _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + }, + _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + }; + let constant_inner = crate::ConstantInner::Scalar { + width, + value: match kind { + crate::ScalarKind::Sint => crate::ScalarValue::Sint(1), + crate::ScalarKind::Uint => crate::ScalarValue::Uint(1), + _ => return Err(Error::BadIncrDecrReferenceType(value_span)), + }, + }; + let constant = ectx.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner: constant_inner, + }, + Span::UNDEFINED, + ); + + let left = ectx.naga_expressions.append( + crate::Expression::Load { + pointer: reference.handle, + }, + value_span, + ); + let right = + ectx.interrupt_emitter(crate::Expression::Constant(constant), Span::UNDEFINED); + let value = ectx + .naga_expressions + .append(crate::Expression::Binary { op, left, right }, stmt.span); + + block.extend(emitter.finish(ctx.naga_expressions)); + crate::Statement::Store { + pointer: reference.handle, + value, + } + } + ast::StatementKind::Ignore(expr) => { + let mut emitter = super::Emitter::default(); + emitter.start(ctx.naga_expressions); + + let _ = self.expression(expr, ctx.as_expression(block, &mut emitter))?; + block.extend(emitter.finish(ctx.naga_expressions)); + return Ok(()); + } + }; + + block.push(out, stmt.span); + + Ok(()) + } + + fn expression( + &mut self, + expr: Handle>, + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let expr = self.expression_for_reference(expr, ctx.reborrow())?; + Ok(ctx.apply_load_rule(expr)) + } + + fn expression_for_reference( + &mut self, + expr: Handle>, + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result> { + let span = ctx.ast_expressions.get_span(expr); + let expr = &ctx.ast_expressions[expr]; + + let (expr, is_reference) = match *expr { + ast::Expression::Literal(literal) => { + let inner = match literal { + ast::Literal::Number(Number::F32(f)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Float(f as _), + }, + ast::Literal::Number(Number::I32(i)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Sint(i as _), + }, + ast::Literal::Number(Number::U32(u)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Uint(u as _), + }, + ast::Literal::Number(_) => { + unreachable!("got abstract numeric type when not expected"); + } + ast::Literal::Bool(b) => crate::ConstantInner::Scalar { + width: 1, + value: crate::ScalarValue::Bool(b), + }, + }; + let handle = ctx.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner, + }, + Span::UNDEFINED, + ); + let handle = ctx.interrupt_emitter(crate::Expression::Constant(handle), span); + return Ok(TypedExpression::non_reference(handle)); + } + ast::Expression::Ident(ast::IdentExpr::Local(local)) => { + return Ok(ctx.local_table[&local]) + } + ast::Expression::Ident(ast::IdentExpr::Unresolved(name)) => { + return if let Some(global) = ctx.globals.get(name) { + let (expr, is_reference) = match *global { + LoweredGlobalDecl::Var(handle) => ( + crate::Expression::GlobalVariable(handle), + ctx.module.global_variables[handle].space + != crate::AddressSpace::Handle, + ), + LoweredGlobalDecl::Const(handle) => { + (crate::Expression::Constant(handle), false) + } + _ => { + return Err(Error::Unexpected(span, ExpectedToken::Variable)); + } + }; + + let handle = ctx.interrupt_emitter(expr, span); + Ok(TypedExpression { + handle, + is_reference, + }) + } else { + Err(Error::UnknownIdent(span, name)) + } + } + ast::Expression::Construct { + ref ty, + ty_span, + ref components, + } => { + let handle = self.construct(span, ty, ty_span, components, ctx.reborrow())?; + return Ok(TypedExpression::non_reference(handle)); + } + ast::Expression::Unary { op, expr } => { + let expr = self.expression(expr, ctx.reborrow())?; + (crate::Expression::Unary { op, expr }, false) + } + ast::Expression::AddrOf(expr) => { + // The `&` operator simply converts a reference to a pointer. And since a + // reference is required, the Load Rule is not applied. + let expr = self.expression_for_reference(expr, ctx.reborrow())?; + if !expr.is_reference { + return Err(Error::NotReference("the operand of the `&` operator", span)); + } + + // No code is generated. We just declare the pointer a reference now. + return Ok(TypedExpression { + is_reference: false, + ..expr + }); + } + ast::Expression::Deref(expr) => { + // The pointer we dereference must be loaded. + let pointer = self.expression(expr, ctx.reborrow())?; + + ctx.grow_types(pointer)?; + if ctx.resolved_inner(pointer).pointer_space().is_none() { + return Err(Error::NotPointer(span)); + } + + return Ok(TypedExpression { + handle: pointer, + is_reference: true, + }); + } + ast::Expression::Binary { op, left, right } => { + // Load both operands. + let mut left = self.expression(left, ctx.reborrow())?; + let mut right = self.expression(right, ctx.reborrow())?; + ctx.binary_op_splat(op, &mut left, &mut right)?; + (crate::Expression::Binary { op, left, right }, false) + } + ast::Expression::Call { + ref function, + ref arguments, + } => { + let handle = self + .call(span, function, arguments, ctx.reborrow())? + .ok_or(Error::FunctionReturnsVoid(function.span))?; + return Ok(TypedExpression::non_reference(handle)); + } + ast::Expression::Index { base, index } => { + let expr = self.expression_for_reference(base, ctx.reborrow())?; + let index = self.expression(index, ctx.reborrow())?; + + ctx.grow_types(expr.handle)?; + let wgsl_pointer = + ctx.resolved_inner(expr.handle).pointer_space().is_some() && !expr.is_reference; + + if wgsl_pointer { + return Err(Error::Pointer( + "the value indexed by a `[]` subscripting expression", + ctx.ast_expressions.get_span(base), + )); + } + + if let crate::Expression::Constant(constant) = ctx.naga_expressions[index] { + let span = ctx.naga_expressions.get_span(index); + let index = match ctx.module.constants[constant].inner { + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Uint(int), + .. + } => u32::try_from(int).map_err(|_| Error::BadU32Constant(span)), + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Sint(int), + .. + } => u32::try_from(int).map_err(|_| Error::BadU32Constant(span)), + _ => Err(Error::BadU32Constant(span)), + }?; + + ( + crate::Expression::AccessIndex { + base: expr.handle, + index, + }, + expr.is_reference, + ) + } else { + ( + crate::Expression::Access { + base: expr.handle, + index, + }, + expr.is_reference, + ) + } + } + ast::Expression::Member { base, ref field } => { + let TypedExpression { + handle, + is_reference, + } = self.expression_for_reference(base, ctx.reborrow())?; + + ctx.grow_types(handle)?; + let temp_inner; + let (composite, wgsl_pointer) = match *ctx.resolved_inner(handle) { + crate::TypeInner::Pointer { base, .. } => { + (&ctx.module.types[base].inner, !is_reference) + } + crate::TypeInner::ValuePointer { + size: None, + kind, + width, + .. + } => { + temp_inner = crate::TypeInner::Scalar { kind, width }; + (&temp_inner, !is_reference) + } + crate::TypeInner::ValuePointer { + size: Some(size), + kind, + width, + .. + } => { + temp_inner = crate::TypeInner::Vector { size, kind, width }; + (&temp_inner, !is_reference) + } + ref other => (other, false), + }; + + if wgsl_pointer { + return Err(Error::Pointer( + "the value accessed by a `.member` expression", + ctx.ast_expressions.get_span(base), + )); + } + + let access = match *composite { + crate::TypeInner::Struct { ref members, .. } => { + let index = members + .iter() + .position(|m| m.name.as_deref() == Some(field.name)) + .ok_or(Error::BadAccessor(field.span))? + as u32; + + ( + crate::Expression::AccessIndex { + base: handle, + index, + }, + is_reference, + ) + } + crate::TypeInner::Vector { .. } | crate::TypeInner::Matrix { .. } => { + match Composition::make(field.name, field.span)? { + Composition::Multi(size, pattern) => { + let vector = ctx.apply_load_rule(TypedExpression { + handle, + is_reference, + }); + + ( + crate::Expression::Swizzle { + size, + vector, + pattern, + }, + false, + ) + } + Composition::Single(index) => ( + crate::Expression::AccessIndex { + base: handle, + index, + }, + is_reference, + ), + } + } + _ => return Err(Error::BadAccessor(field.span)), + }; + + access + } + ast::Expression::Bitcast { expr, to, ty_span } => { + let expr = self.expression(expr, ctx.reborrow())?; + let to_resolved = self.resolve_ast_type(to, ctx.as_output())?; + + let kind = match ctx.module.types[to_resolved].inner { + crate::TypeInner::Scalar { kind, .. } => kind, + crate::TypeInner::Vector { kind, .. } => kind, + _ => { + let ty = &ctx.typifier[expr]; + return Err(Error::BadTypeCast { + from_type: ctx.format_type_resolution(ty), + span: ty_span, + to_type: ctx.format_type(to_resolved), + }); + } + }; + + ( + crate::Expression::As { + expr, + kind, + convert: None, + }, + false, + ) + } + }; + + let handle = ctx.naga_expressions.append(expr, span); + Ok(TypedExpression { + handle, + is_reference, + }) + } + + /// Generate Naga IR for call expressions and statements, and type + /// constructor expressions. + /// + /// The "function" being called is simply an `Ident` that we know refers to + /// some module-scope definition. + /// + /// - If it is the name of a type, then the expression is a type constructor + /// expression: either constructing a value from components, a conversion + /// expression, or a zero value expression. + /// + /// - If it is the name of a function, then we're generating a [`Call`] + /// statement. We may be in the midst of generating code for an + /// expression, in which case we must generate an `Emit` statement to + /// force evaluation of the IR expressions we've generated so far, add the + /// `Call` statement to the current block, and then resume generating + /// expressions. + /// + /// [`Call`]: crate::Statement::Call + fn call( + &mut self, + span: Span, + function: &ast::Ident<'source>, + arguments: &[Handle>], + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result>, Error<'source>> { + match ctx.globals.get(function.name) { + Some(&LoweredGlobalDecl::Type(ty)) => { + let handle = self.construct( + span, + &ast::ConstructorType::Type(ty), + function.span, + arguments, + ctx.reborrow(), + )?; + Ok(Some(handle)) + } + Some(&LoweredGlobalDecl::Const(_) | &LoweredGlobalDecl::Var(_)) => { + Err(Error::Unexpected(function.span, ExpectedToken::Function)) + } + Some(&LoweredGlobalDecl::EntryPoint) => Err(Error::CalledEntryPoint(function.span)), + Some(&LoweredGlobalDecl::Function(function)) => { + let arguments = arguments + .iter() + .map(|&arg| self.expression(arg, ctx.reborrow())) + .collect::, _>>()?; + + ctx.block.extend(ctx.emitter.finish(ctx.naga_expressions)); + let result = ctx.module.functions[function].result.is_some().then(|| { + ctx.naga_expressions + .append(crate::Expression::CallResult(function), span) + }); + ctx.emitter.start(ctx.naga_expressions); + ctx.block.push( + crate::Statement::Call { + function, + arguments, + result, + }, + span, + ); + + Ok(result) + } + None => { + let span = function.span; + let expr = if let Some(fun) = conv::map_relational_fun(function.name) { + let mut args = ctx.prepare_args(arguments, 1, span); + let argument = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::Relational { fun, argument } + } else if let Some(axis) = conv::map_derivative_axis(function.name) { + let mut args = ctx.prepare_args(arguments, 1, span); + let expr = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::Derivative { axis, expr } + } else if let Some(fun) = conv::map_standard_fun(function.name) { + let expected = fun.argument_count() as _; + let mut args = ctx.prepare_args(arguments, expected, span); + + let arg = self.expression(args.next()?, ctx.reborrow())?; + let arg1 = args + .next() + .map(|x| self.expression(x, ctx.reborrow())) + .ok() + .transpose()?; + let arg2 = args + .next() + .map(|x| self.expression(x, ctx.reborrow())) + .ok() + .transpose()?; + let arg3 = args + .next() + .map(|x| self.expression(x, ctx.reborrow())) + .ok() + .transpose()?; + + args.finish()?; + + crate::Expression::Math { + fun, + arg, + arg1, + arg2, + arg3, + } + } else if let Some(fun) = Texture::map(function.name) { + self.texture_sample_helper(fun, arguments, span, ctx.reborrow())? + } else { + match function.name { + "select" => { + let mut args = ctx.prepare_args(arguments, 3, span); + + let reject = self.expression(args.next()?, ctx.reborrow())?; + let accept = self.expression(args.next()?, ctx.reborrow())?; + let condition = self.expression(args.next()?, ctx.reborrow())?; + + args.finish()?; + + crate::Expression::Select { + reject, + accept, + condition, + } + } + "arrayLength" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let expr = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::ArrayLength(expr) + } + "atomicLoad" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::Load { pointer } + } + "atomicStore" => { + let mut args = ctx.prepare_args(arguments, 2, span); + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; + let value = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + ctx.block.extend(ctx.emitter.finish(ctx.naga_expressions)); + ctx.emitter.start(ctx.naga_expressions); + ctx.block + .push(crate::Statement::Store { pointer, value }, span); + return Ok(None); + } + "atomicAdd" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::Add, + arguments, + ctx.reborrow(), + )?)) + } + "atomicSub" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::Subtract, + arguments, + ctx.reborrow(), + )?)) + } + "atomicAnd" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::And, + arguments, + ctx.reborrow(), + )?)) + } + "atomicOr" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::InclusiveOr, + arguments, + ctx.reborrow(), + )?)) + } + "atomicXor" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::ExclusiveOr, + arguments, + ctx.reborrow(), + )?)) + } + "atomicMin" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::Min, + arguments, + ctx.reborrow(), + )?)) + } + "atomicMax" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::Max, + arguments, + ctx.reborrow(), + )?)) + } + "atomicExchange" => { + return Ok(Some(self.atomic_helper( + span, + crate::AtomicFunction::Exchange { compare: None }, + arguments, + ctx.reborrow(), + )?)) + } + "atomicCompareExchangeWeak" => { + let mut args = ctx.prepare_args(arguments, 3, span); + + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; + + let compare = self.expression(args.next()?, ctx.reborrow())?; + + let value = args.next()?; + let value_span = ctx.ast_expressions.get_span(value); + let value = self.expression(value, ctx.reborrow())?; + ctx.grow_types(value)?; + + args.finish()?; + + let expression = match *ctx.resolved_inner(value) { + crate::TypeInner::Scalar { kind, width } => { + let bool_ty = ctx.module.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Scalar { + kind: crate::ScalarKind::Bool, + width: crate::BOOL_WIDTH, + }, + }, + Span::UNDEFINED, + ); + let scalar_ty = ctx.module.types.insert( + crate::Type { + name: None, + inner: crate::TypeInner::Scalar { kind, width }, + }, + Span::UNDEFINED, + ); + let struct_ty = ctx.module.types.insert( + crate::Type { + name: Some( + "__atomic_compare_exchange_result".to_string(), + ), + inner: crate::TypeInner::Struct { + members: vec![ + crate::StructMember { + name: Some("old_value".to_string()), + ty: scalar_ty, + binding: None, + offset: 0, + }, + crate::StructMember { + name: Some("exchanged".to_string()), + ty: bool_ty, + binding: None, + offset: 4, + }, + ], + span: 8, + }, + }, + Span::UNDEFINED, + ); + crate::Expression::AtomicResult { + ty: struct_ty, + comparison: true, + } + } + _ => return Err(Error::InvalidAtomicOperandType(value_span)), + }; + + let result = ctx.interrupt_emitter(expression, span); + ctx.block.push( + crate::Statement::Atomic { + pointer, + fun: crate::AtomicFunction::Exchange { + compare: Some(compare), + }, + value, + result, + }, + span, + ); + return Ok(Some(result)); + } + "storageBarrier" => { + ctx.prepare_args(arguments, 0, span).finish()?; + + ctx.block + .push(crate::Statement::Barrier(crate::Barrier::STORAGE), span); + return Ok(None); + } + "workgroupBarrier" => { + ctx.prepare_args(arguments, 0, span).finish()?; + + ctx.block + .push(crate::Statement::Barrier(crate::Barrier::WORK_GROUP), span); + return Ok(None); + } + "textureStore" => { + let mut args = ctx.prepare_args(arguments, 3, span); + + let image = args.next()?; + let image_span = ctx.ast_expressions.get_span(image); + let image = self.expression(image, ctx.reborrow())?; + + let coordinate = self.expression(args.next()?, ctx.reborrow())?; + + let (_, arrayed) = ctx.image_data(image, image_span)?; + let array_index = arrayed + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; + + let value = self.expression(args.next()?, ctx.reborrow())?; + + args.finish()?; + + ctx.block.extend(ctx.emitter.finish(ctx.naga_expressions)); + ctx.emitter.start(ctx.naga_expressions); + let stmt = crate::Statement::ImageStore { + image, + coordinate, + array_index, + value, + }; + ctx.block.push(stmt, span); + return Ok(None); + } + "textureLoad" => { + let mut args = ctx.prepare_args(arguments, 3, span); + + let image = args.next()?; + let image_span = ctx.ast_expressions.get_span(image); + let image = self.expression(image, ctx.reborrow())?; + + let coordinate = self.expression(args.next()?, ctx.reborrow())?; + + let (class, arrayed) = ctx.image_data(image, image_span)?; + let array_index = arrayed + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; + + let level = class + .is_mipmapped() + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; + + let sample = class + .is_multisampled() + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; + + args.finish()?; + + crate::Expression::ImageLoad { + image, + coordinate, + array_index, + level, + sample, + } + } + "textureDimensions" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let image = self.expression(args.next()?, ctx.reborrow())?; + let level = args + .next() + .map(|arg| self.expression(arg, ctx.reborrow())) + .ok() + .transpose()?; + args.finish()?; + + crate::Expression::ImageQuery { + image, + query: crate::ImageQuery::Size { level }, + } + } + "textureNumLevels" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let image = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::ImageQuery { + image, + query: crate::ImageQuery::NumLevels, + } + } + "textureNumLayers" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let image = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::ImageQuery { + image, + query: crate::ImageQuery::NumLayers, + } + } + "textureNumSamples" => { + let mut args = ctx.prepare_args(arguments, 1, span); + let image = self.expression(args.next()?, ctx.reborrow())?; + args.finish()?; + + crate::Expression::ImageQuery { + image, + query: crate::ImageQuery::NumSamples, + } + } + _ => return Err(Error::UnknownIdent(function.span, function.name)), + } + }; + + let expr = ctx.naga_expressions.append(expr, span); + Ok(Some(expr)) + } + } + } + + fn atomic_pointer( + &mut self, + expr: Handle>, + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let span = ctx.ast_expressions.get_span(expr); + let pointer = self.expression(expr, ctx.reborrow())?; + + ctx.grow_types(pointer)?; + match *ctx.resolved_inner(pointer) { + crate::TypeInner::Pointer { base, .. } => match ctx.module.types[base].inner { + crate::TypeInner::Atomic { .. } => Ok(pointer), + ref other => { + log::error!("Pointer type to {:?} passed to atomic op", other); + Err(Error::InvalidAtomicPointer(span)) + } + }, + ref other => { + log::error!("Type {:?} passed to atomic op", other); + Err(Error::InvalidAtomicPointer(span)) + } + } + } + + fn atomic_helper( + &mut self, + span: Span, + fun: crate::AtomicFunction, + args: &[Handle>], + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let mut args = ctx.prepare_args(args, 2, span); + + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; + + let value = args.next()?; + let value = self.expression(value, ctx.reborrow())?; + let ty = ctx.register_type(value)?; + + args.finish()?; + + let result = ctx.interrupt_emitter( + crate::Expression::AtomicResult { + ty, + comparison: false, + }, + span, + ); + ctx.block.push( + crate::Statement::Atomic { + pointer, + fun, + value, + result, + }, + span, + ); + Ok(result) + } + + fn texture_sample_helper( + &mut self, + fun: Texture, + args: &[Handle>], + span: Span, + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result> { + let mut args = ctx.prepare_args(args, fun.min_argument_count(), span); + + let (image, gather) = match fun { + Texture::Gather => { + let image_or_component = args.next()?; + match self.gather_component(image_or_component, ctx.reborrow())? { + Some(component) => { + let image = args.next()?; + (image, Some(component)) + } + None => (image_or_component, Some(crate::SwizzleComponent::X)), + } + } + Texture::GatherCompare => { + let image = args.next()?; + (image, Some(crate::SwizzleComponent::X)) + } + + _ => { + let image = args.next()?; + (image, None) + } + }; + + let image_span = ctx.ast_expressions.get_span(image); + let image = self.expression(image, ctx.reborrow())?; + + let sampler = self.expression(args.next()?, ctx.reborrow())?; + + let coordinate = self.expression(args.next()?, ctx.reborrow())?; + + let (_, arrayed) = ctx.image_data(image, image_span)?; + let array_index = arrayed + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; + + let (level, depth_ref) = match fun { + Texture::Gather => (crate::SampleLevel::Zero, None), + Texture::GatherCompare => { + let reference = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Zero, Some(reference)) + } + + Texture::Sample => (crate::SampleLevel::Auto, None), + Texture::SampleBias => { + let bias = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Bias(bias), None) + } + Texture::SampleCompare => { + let reference = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Auto, Some(reference)) + } + Texture::SampleCompareLevel => { + let reference = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Zero, Some(reference)) + } + Texture::SampleGrad => { + let x = self.expression(args.next()?, ctx.reborrow())?; + let y = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Gradient { x, y }, None) + } + Texture::SampleLevel => { + let level = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Exact(level), None) + } + }; + + let offset = args + .next() + .map(|arg| self.constant(arg, ctx.as_output())) + .ok() + .transpose()?; + + args.finish()?; + + Ok(crate::Expression::ImageSample { + image, + sampler, + gather, + coordinate, + array_index, + offset, + level, + depth_ref, + }) + } + + fn gather_component( + &mut self, + expr: Handle>, + mut ctx: ExpressionContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let span = ctx.ast_expressions.get_span(expr); + + let constant = match self.constant_inner(expr, ctx.as_output()).ok() { + Some(ConstantOrInner::Constant(c)) => ctx.module.constants[c].inner.clone(), + Some(ConstantOrInner::Inner(inner)) => inner, + None => return Ok(None), + }; + + let int = match constant { + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Sint(i), + .. + } if i >= 0 => i as u64, + crate::ConstantInner::Scalar { + value: crate::ScalarValue::Uint(i), + .. + } => i, + _ => { + return Err(Error::InvalidGatherComponent(span)); + } + }; + + crate::SwizzleComponent::XYZW + .get(int as usize) + .copied() + .map(Some) + .ok_or(Error::InvalidGatherComponent(span)) + } + + fn r#struct( + &mut self, + s: &ast::Struct<'source>, + span: Span, + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let mut offset = 0; + let mut struct_alignment = Alignment::ONE; + let mut members = Vec::with_capacity(s.members.len()); + + for member in s.members.iter() { + let ty = self.resolve_ast_type(member.ty, ctx.reborrow())?; + + self.layouter + .update(&ctx.module.types, &ctx.module.constants) + .unwrap(); + + let member_min_size = self.layouter[ty].size; + let member_min_alignment = self.layouter[ty].alignment; + + let member_size = if let Some((size, span)) = member.size { + if size < member_min_size { + return Err(Error::SizeAttributeTooLow(span, member_min_size)); + } else { + size + } + } else { + member_min_size + }; + + let member_alignment = if let Some((align, span)) = member.align { + if let Some(alignment) = Alignment::new(align) { + if alignment < member_min_alignment { + return Err(Error::AlignAttributeTooLow(span, member_min_alignment)); + } else { + alignment + } + } else { + return Err(Error::NonPowerOfTwoAlignAttribute(span)); + } + } else { + member_min_alignment + }; + + let binding = self.interpolate_default(&member.binding, ty, ctx.reborrow()); + + offset = member_alignment.round_up(offset); + struct_alignment = struct_alignment.max(member_alignment); + + members.push(crate::StructMember { + name: Some(member.name.name.to_owned()), + ty, + binding, + offset, + }); + + offset += member_size; + } + + let size = struct_alignment.round_up(offset); + let inner = crate::TypeInner::Struct { + members, + span: size, + }; + + let handle = ctx.module.types.insert( + crate::Type { + name: Some(s.name.name.to_string()), + inner, + }, + span, + ); + Ok(handle) + } + + /// Return a Naga `Handle` representing the front-end type `handle`. + fn resolve_ast_type( + &mut self, + handle: Handle>, + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let inner = match ctx.types[handle] { + ast::Type::Scalar { kind, width } => crate::TypeInner::Scalar { kind, width }, + ast::Type::Vector { size, kind, width } => { + crate::TypeInner::Vector { size, kind, width } + } + ast::Type::Matrix { + rows, + columns, + width, + } => crate::TypeInner::Matrix { + columns, + rows, + width, + }, + ast::Type::Atomic { kind, width } => crate::TypeInner::Atomic { kind, width }, + ast::Type::Pointer { base, space } => { + let base = self.resolve_ast_type(base, ctx.reborrow())?; + crate::TypeInner::Pointer { base, space } + } + ast::Type::Array { base, size } => { + let base = self.resolve_ast_type(base, ctx.reborrow())?; + self.layouter + .update(&ctx.module.types, &ctx.module.constants) + .unwrap(); + + crate::TypeInner::Array { + base, + size: match size { + ast::ArraySize::Constant(constant) => { + let constant = self.constant(constant, ctx.reborrow())?; + crate::ArraySize::Constant(constant) + } + ast::ArraySize::Dynamic => crate::ArraySize::Dynamic, + }, + stride: self.layouter[base].to_stride(), + } + } + ast::Type::Image { + dim, + arrayed, + class, + } => crate::TypeInner::Image { + dim, + arrayed, + class, + }, + ast::Type::Sampler { comparison } => crate::TypeInner::Sampler { comparison }, + ast::Type::BindingArray { base, size } => { + let base = self.resolve_ast_type(base, ctx.reborrow())?; + + crate::TypeInner::BindingArray { + base, + size: match size { + ast::ArraySize::Constant(constant) => { + let constant = self.constant(constant, ctx.reborrow())?; + crate::ArraySize::Constant(constant) + } + ast::ArraySize::Dynamic => crate::ArraySize::Dynamic, + }, + } + } + ast::Type::User(ref ident) => { + return match ctx.globals.get(ident.name) { + Some(&LoweredGlobalDecl::Type(handle)) => Ok(handle), + Some(_) => Err(Error::Unexpected(ident.span, ExpectedToken::Type)), + None => Err(Error::UnknownType(ident.span)), + } + } + }; + + Ok(ctx.ensure_type_exists(inner)) + } + + /// Find or construct a Naga [`Constant`] whose value is `expr`. + /// + /// The `ctx` indicates the Naga [`Module`] to which we should add + /// new `Constant`s or [`Type`]s as needed. + /// + /// [`Module`]: crate::Module + /// [`Constant`]: crate::Constant + /// [`Type`]: crate::Type + fn constant( + &mut self, + expr: Handle>, + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result, Error<'source>> { + let inner = match self.constant_inner(expr, ctx.reborrow())? { + ConstantOrInner::Constant(c) => return Ok(c), + ConstantOrInner::Inner(inner) => inner, + }; + + let c = ctx.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner, + }, + Span::UNDEFINED, + ); + Ok(c) + } + + fn constant_inner( + &mut self, + expr: Handle>, + mut ctx: OutputContext<'source, '_, '_>, + ) -> Result> { + let span = ctx.ast_expressions.get_span(expr); + let inner = match ctx.ast_expressions[expr] { + ast::Expression::Literal(literal) => match literal { + ast::Literal::Number(Number::F32(f)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Float(f as _), + }, + ast::Literal::Number(Number::I32(i)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Sint(i as _), + }, + ast::Literal::Number(Number::U32(u)) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Uint(u as _), + }, + ast::Literal::Number(_) => { + unreachable!("got abstract numeric type when not expected"); + } + ast::Literal::Bool(b) => crate::ConstantInner::Scalar { + width: 1, + value: crate::ScalarValue::Bool(b), + }, + }, + ast::Expression::Ident(ast::IdentExpr::Local(_)) => { + return Err(Error::Unexpected(span, ExpectedToken::Constant)) + } + ast::Expression::Ident(ast::IdentExpr::Unresolved(name)) => { + return if let Some(global) = ctx.globals.get(name) { + match *global { + LoweredGlobalDecl::Const(handle) => Ok(ConstantOrInner::Constant(handle)), + _ => Err(Error::Unexpected(span, ExpectedToken::Constant)), + } + } else { + Err(Error::UnknownIdent(span, name)) + } + } + ast::Expression::Construct { + ref ty, + ref components, + .. + } => self.const_construct(span, ty, components, ctx.reborrow())?, + ast::Expression::Call { + ref function, + ref arguments, + } => match ctx.globals.get(function.name) { + Some(&LoweredGlobalDecl::Type(ty)) => self.const_construct( + span, + &ast::ConstructorType::Type(ty), + arguments, + ctx.reborrow(), + )?, + Some(_) => return Err(Error::ConstExprUnsupported(span)), + None => return Err(Error::UnknownIdent(function.span, function.name)), + }, + _ => return Err(Error::ConstExprUnsupported(span)), + }; + + Ok(ConstantOrInner::Inner(inner)) + } + + fn interpolate_default( + &mut self, + binding: &Option, + ty: Handle, + ctx: OutputContext<'source, '_, '_>, + ) -> Option { + let mut binding = binding.clone(); + if let Some(ref mut binding) = binding { + binding.apply_default_interpolation(&ctx.module.types[ty].inner); + } + + binding } } diff --git a/src/front/wgsl/tests.rs b/src/front/wgsl/tests.rs index 6aaa505d4d..73e843229c 100644 --- a/src/front/wgsl/tests.rs +++ b/src/front/wgsl/tests.rs @@ -16,8 +16,8 @@ fn parse_comment() { #[test] fn parse_types() { - parse_str("let a : i32 = 2;").unwrap(); - assert!(parse_str("let a : x32 = 2;").is_err()); + parse_str("const a : i32 = 2;").unwrap(); + assert!(parse_str("const a : x32 = 2;").is_err()); parse_str("var t: texture_2d;").unwrap(); parse_str("var t: texture_cube_array;").unwrap(); parse_str("var t: texture_multisampled_2d;").unwrap(); @@ -48,7 +48,7 @@ fn parse_type_inference() { fn parse_type_cast() { parse_str( " - let a : i32 = 2; + const a : i32 = 2; fn main() { var x: f32 = f32(a); x = f32(i32(a + 1) / 2); diff --git a/src/span.rs b/src/span.rs index a4670e2dad..90bf3d174e 100644 --- a/src/span.rs +++ b/src/span.rs @@ -18,6 +18,14 @@ impl Span { Span { start, end } } + /// Returns a new `Span` starting at `self` and ending at `other` + pub const fn until(&self, other: &Self) -> Self { + Span { + start: self.start, + end: other.end, + } + } + /// Modifies `self` to contain the smallest `Span` possible that /// contains both `self` and `other` pub fn subsume(&mut self, other: Self) { @@ -85,6 +93,15 @@ impl From> for Span { } } +impl std::ops::Index for str { + type Output = str; + + #[inline] + fn index(&self, span: Span) -> &str { + &self[span.start as usize..span.end as usize] + } +} + /// A human-readable representation for a span, tailored for text source. /// /// Corresponds to the positional members of [`GPUCompilationMessage`][gcm] from diff --git a/tests/in/access.wgsl b/tests/in/access.wgsl index c2e4d25b6e..798de528df 100644 --- a/tests/in/access.wgsl +++ b/tests/in/access.wgsl @@ -129,9 +129,9 @@ fn foo_vert(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4 { let foo_value = read_from_private(&foo); // test array indexing - var c = array(a, i32(b), 3, 4, 5); - c[vi + 1u] = 42; - let value = c[vi]; + var c2 = array(a, i32(b), 3, 4, 5); + c2[vi + 1u] = 42; + let value = c2[vi]; _ = test_arr_as_arg(array, 5>()); diff --git a/tests/in/atomicCompareExchange.wgsl b/tests/in/atomicCompareExchange.wgsl index 35b91aaf7f..4b6144b12d 100644 --- a/tests/in/atomicCompareExchange.wgsl +++ b/tests/in/atomicCompareExchange.wgsl @@ -1,4 +1,4 @@ -let SIZE: u32 = 128u; +const SIZE: u32 = 128u; @group(0) @binding(0) var arr_i32: array, SIZE>; diff --git a/tests/in/bitcast.wgsl b/tests/in/bitcast.wgsl index 11613f9b4f..c698f1bdff 100644 --- a/tests/in/bitcast.wgsl +++ b/tests/in/bitcast.wgsl @@ -3,11 +3,11 @@ fn main() { var i2 = vec2(0); var i3 = vec3(0); var i4 = vec4(0); - + var u2 = vec2(0u); var u3 = vec3(0u); var u4 = vec4(0u); - + var f2 = vec2(0.0); var f3 = vec3(0.0); var f4 = vec4(0.0); @@ -15,11 +15,11 @@ fn main() { u2 = bitcast>(i2); u3 = bitcast>(i3); u4 = bitcast>(i4); - + i2 = bitcast>(u2); i3 = bitcast>(u3); i4 = bitcast>(u4); - + f2 = bitcast>(i2); f3 = bitcast>(i3); f4 = bitcast>(i4); diff --git a/tests/in/boids.wgsl b/tests/in/boids.wgsl index 31bbc85bba..caa67df77d 100644 --- a/tests/in/boids.wgsl +++ b/tests/in/boids.wgsl @@ -1,4 +1,4 @@ -let NUM_PARTICLES: u32 = 1500u; +const NUM_PARTICLES: u32 = 1500u; struct Particle { pos : vec2, diff --git a/tests/in/globals.wgsl b/tests/in/globals.wgsl index 59820ab367..8f687fd356 100644 --- a/tests/in/globals.wgsl +++ b/tests/in/globals.wgsl @@ -1,17 +1,17 @@ // Global variable & constant declarations -let Foo: bool = true; +const Foo: bool = true; var wg : array; var at: atomic; -struct Foo { +struct FooStruct { v3: vec3, // test packed vec3 v1: f32, } @group(0) @binding(1) -var alignment: Foo; +var alignment: FooStruct; @group(0) @binding(2) var dummy: array>; diff --git a/tests/in/module-scope.wgsl b/tests/in/module-scope.wgsl new file mode 100644 index 0000000000..54638cb40b --- /dev/null +++ b/tests/in/module-scope.wgsl @@ -0,0 +1,26 @@ +fn call() { + statement(); + let x: S = returns(); + let vf = f32(Value); + let s = textureSample(Texture, Sampler, Vec2(vf)); +} + +fn statement() {} + +fn returns() -> S { + return S(Value); +} + +struct S { + x: i32, +} + +const Value: i32 = 1; + +@group(0) @binding(0) +var Texture: texture_2d; + +@group(0) @binding(1) +var Sampler: sampler; + +type Vec2 = vec2; diff --git a/tests/in/operators.wgsl b/tests/in/operators.wgsl index be185399ed..e5b9a15d5d 100644 --- a/tests/in/operators.wgsl +++ b/tests/in/operators.wgsl @@ -1,8 +1,8 @@ //TODO: support splatting constructors for globals? -let v_f32_one = vec4(1.0, 1.0, 1.0, 1.0); -let v_f32_zero = vec4(0.0, 0.0, 0.0, 0.0); -let v_f32_half = vec4(0.5, 0.5, 0.5, 0.5); -let v_i32_one = vec4(1, 1, 1, 1); +const v_f32_one = vec4(1.0, 1.0, 1.0, 1.0); +const v_f32_zero = vec4(0.0, 0.0, 0.0, 0.0); +const v_f32_half = vec4(0.5, 0.5, 0.5, 0.5); +const v_i32_one = vec4(1, 1, 1, 1); fn builtins() -> vec4 { // select() diff --git a/tests/in/quad.wgsl b/tests/in/quad.wgsl index f2c85f095b..b51e1a91d9 100644 --- a/tests/in/quad.wgsl +++ b/tests/in/quad.wgsl @@ -1,5 +1,5 @@ // vertex -let c_scale: f32 = 1.2; +const c_scale: f32 = 1.2; struct VertexOutput { @location(0) uv : vec2, @@ -31,7 +31,7 @@ fn frag_main(@location(0) uv : vec2) -> @location(0) vec4 { } -// We need to make sure that backends are successfully handling multiple entry points for the same shader stage. +// We need to make sure that backends are successfully handling multiple entry points for the same shader stage. @fragment fn fs_extra() -> @location(0) vec4 { return vec4(0.0, 0.5, 0.0, 0.5); diff --git a/tests/in/shadow.wgsl b/tests/in/shadow.wgsl index 5750188639..b02cf68775 100644 --- a/tests/in/shadow.wgsl +++ b/tests/in/shadow.wgsl @@ -77,8 +77,8 @@ fn fetch_shadow(light_id: u32, homogeneous_coords: vec4) -> f32 { return textureSampleCompareLevel(t_shadow, sampler_shadow, light_local, i32(light_id), homogeneous_coords.z * proj_correction); } -let c_ambient: vec3 = vec3(0.05, 0.05, 0.05); -let c_max_lights: u32 = 10u; +const c_ambient: vec3 = vec3(0.05, 0.05, 0.05); +const c_max_lights: u32 = 10u; @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { diff --git a/tests/in/type-alias.wgsl b/tests/in/type-alias.wgsl new file mode 100644 index 0000000000..429f153b5b --- /dev/null +++ b/tests/in/type-alias.wgsl @@ -0,0 +1,13 @@ +type FVec3 = vec3; +type IVec3 = vec3; +type Mat2 = mat2x2; + +fn main() { + let a = FVec3(0.0, 0.0, 0.0); + let c = FVec3(0.0); + let b = FVec3(vec2(0.0), 0.0); + let d = FVec3(vec2(0.0), 0.0); + let e = IVec3(d); + + let f = Mat2(1.0, 2.0, 3.0, 4.0); +} diff --git a/tests/out/analysis/collatz.info.ron b/tests/out/analysis/collatz.info.ron index 3e1805c6f9..f334394441 100644 --- a/tests/out/analysis/collatz.info.ron +++ b/tests/out/analysis/collatz.info.ron @@ -8,7 +8,7 @@ bits: 7, ), uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -28,31 +28,13 @@ bits: 0, ), ), - ref_count: 0, - assignable_global: Some(1), - ty: Value(Pointer( - base: 3, - space: Storage( - access: ( - bits: 3, - ), - ), - )), - ), - ( - uniformity: ( - non_uniform_result: Some(2), - requirements: ( - bits: 0, - ), - ), ref_count: 1, assignable_global: None, ty: Handle(1), ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -71,7 +53,7 @@ bits: 0, ), ), - ref_count: 0, + ref_count: 1, assignable_global: None, ty: Value(Scalar( kind: Uint, @@ -80,12 +62,12 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), ), - ref_count: 3, + ref_count: 4, assignable_global: None, ty: Value(Pointer( base: 1, @@ -94,7 +76,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -119,7 +101,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -133,7 +115,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -158,7 +140,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -183,7 +165,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -197,7 +179,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -222,7 +204,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -247,7 +229,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -258,7 +240,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -283,7 +265,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -294,7 +276,7 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -319,7 +301,7 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -330,7 +312,7 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -352,7 +334,7 @@ bits: 7, ), uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -373,6 +355,17 @@ ), ), ref_count: 2, + assignable_global: None, + ty: Handle(4), + ), + ( + uniformity: ( + non_uniform_result: Some(2), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, assignable_global: Some(1), ty: Value(Pointer( base: 3, @@ -390,17 +383,6 @@ bits: 0, ), ), - ref_count: 2, - assignable_global: None, - ty: Handle(4), - ), - ( - uniformity: ( - non_uniform_result: Some(1), - requirements: ( - bits: 0, - ), - ), ref_count: 1, assignable_global: Some(1), ty: Value(Pointer( @@ -414,7 +396,7 @@ ), ( uniformity: ( - non_uniform_result: Some(2), + non_uniform_result: Some(1), requirements: ( bits: 0, ), @@ -428,7 +410,7 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -446,7 +428,25 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(6), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: Some(1), + ty: Value(Pointer( + base: 3, + space: Storage( + access: ( + bits: 3, + ), + ), + )), + ), + ( + uniformity: ( + non_uniform_result: Some(6), requirements: ( bits: 0, ), @@ -464,7 +464,7 @@ ), ( uniformity: ( - non_uniform_result: Some(2), + non_uniform_result: Some(1), requirements: ( bits: 0, ), @@ -478,7 +478,7 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(6), requirements: ( bits: 0, ), @@ -496,7 +496,7 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(6), requirements: ( bits: 0, ), @@ -507,7 +507,7 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(4), requirements: ( bits: 0, ), diff --git a/tests/out/dot/quad.dot b/tests/out/dot/quad.dot index c4e242b3ae..4f2cde18c9 100644 --- a/tests/out/dot/quad.dot +++ b/tests/out/dot/quad.dot @@ -7,18 +7,18 @@ digraph Module { subgraph cluster_ep0 { label="Vertex/'vert_main'" node [ style=filled ] - ep0_e0 [ fillcolor="#ffffb3" label="[1] Constant" ] - ep0_e1 [ color="#8dd3c7" label="[2] Argument[0]" ] - ep0_e2 [ color="#8dd3c7" label="[3] Argument[1]" ] + ep0_e0 [ color="#8dd3c7" label="[1] Argument[0]" ] + ep0_e1 [ color="#8dd3c7" label="[2] Argument[1]" ] + ep0_e2 [ fillcolor="#ffffb3" label="[3] Constant" ] ep0_e3 [ color="#fdb462" label="[4] Multiply" ] - ep0_e1 -> ep0_e3 [ label="right" ] - ep0_e0 -> ep0_e3 [ label="left" ] + ep0_e0 -> ep0_e3 [ label="right" ] + ep0_e2 -> ep0_e3 [ label="left" ] ep0_e4 [ fillcolor="#ffffb3" label="[5] Constant" ] ep0_e5 [ fillcolor="#ffffb3" label="[6] Constant" ] ep0_e6 [ color="#bebada" label="[7] Compose" ] { ep0_e3 ep0_e4 ep0_e5 } -> ep0_e6 ep0_e7 [ color="#bebada" label="[8] Compose" ] - { ep0_e2 ep0_e6 } -> ep0_e7 + { ep0_e1 ep0_e6 } -> ep0_e7 ep0_s0 [ shape=square label="Root" ] ep0_s1 [ shape=square label="Emit" ] ep0_s2 [ shape=square label="Emit" ] @@ -34,27 +34,26 @@ digraph Module { subgraph cluster_ep1 { label="Fragment/'frag_main'" node [ style=filled ] - ep1_e0 [ fillcolor="#ffffb3" label="[1] Constant" ] + ep1_e0 [ color="#8dd3c7" label="[1] Argument[0]" ] ep1_e1 [ color="#ffffb3" label="[2] Global" ] - g1 -> ep1_e1 [fillcolor=gray] + g0 -> ep1_e1 [fillcolor=gray] ep1_e2 [ color="#ffffb3" label="[3] Global" ] - g0 -> ep1_e2 [fillcolor=gray] - ep1_e3 [ color="#8dd3c7" label="[4] Argument[0]" ] - ep1_e4 [ color="#80b1d3" label="[5] ImageSample" ] - ep1_e1 -> ep1_e4 [ label="sampler" ] - ep1_e2 -> ep1_e4 [ label="image" ] - ep1_e3 -> ep1_e4 [ label="coordinate" ] - ep1_e5 [ color="#8dd3c7" label="[6] AccessIndex[3]" ] - ep1_e4 -> ep1_e5 [ label="base" ] - ep1_e6 [ fillcolor="#ffffb3" label="[7] Constant" ] - ep1_e7 [ color="#fdb462" label="[8] Equal" ] - ep1_e6 -> ep1_e7 [ label="right" ] - ep1_e5 -> ep1_e7 [ label="left" ] - ep1_e8 [ color="#8dd3c7" label="[9] AccessIndex[3]" ] - ep1_e4 -> ep1_e8 [ label="base" ] - ep1_e9 [ color="#fdb462" label="[10] Multiply" ] - ep1_e4 -> ep1_e9 [ label="right" ] - ep1_e8 -> ep1_e9 [ label="left" ] + g1 -> ep1_e2 [fillcolor=gray] + ep1_e3 [ color="#80b1d3" label="[4] ImageSample" ] + ep1_e2 -> ep1_e3 [ label="sampler" ] + ep1_e1 -> ep1_e3 [ label="image" ] + ep1_e0 -> ep1_e3 [ label="coordinate" ] + ep1_e4 [ color="#8dd3c7" label="[5] AccessIndex[3]" ] + ep1_e3 -> ep1_e4 [ label="base" ] + ep1_e5 [ fillcolor="#ffffb3" label="[6] Constant" ] + ep1_e6 [ color="#fdb462" label="[7] Equal" ] + ep1_e5 -> ep1_e6 [ label="right" ] + ep1_e4 -> ep1_e6 [ label="left" ] + ep1_e7 [ color="#8dd3c7" label="[8] AccessIndex[3]" ] + ep1_e3 -> ep1_e7 [ label="base" ] + ep1_e8 [ color="#fdb462" label="[9] Multiply" ] + ep1_e3 -> ep1_e8 [ label="right" ] + ep1_e7 -> ep1_e8 [ label="left" ] ep1_s0 [ shape=square label="Root" ] ep1_s1 [ shape=square label="Emit" ] ep1_s2 [ shape=square label="Emit" ] @@ -77,34 +76,29 @@ digraph Module { ep1_s7 -> ep1_s8 [ arrowhead=tee label="" ] ep1_s8 -> ep1_s9 [ arrowhead=tee label="" ] ep1_s9 -> ep1_s10 [ arrowhead=tee label="" ] - ep1_e7 -> ep1_s4 [ label="condition" ] - ep1_e9 -> ep1_s10 [ label="value" ] - ep1_s1 -> ep1_e4 [ style=dotted ] - ep1_s2 -> ep1_e5 [ style=dotted ] - ep1_s3 -> ep1_e7 [ style=dotted ] + ep1_e6 -> ep1_s4 [ label="condition" ] + ep1_e8 -> ep1_s10 [ label="value" ] + ep1_s1 -> ep1_e3 [ style=dotted ] + ep1_s2 -> ep1_e4 [ style=dotted ] + ep1_s3 -> ep1_e6 [ style=dotted ] + ep1_s9 -> ep1_e7 [ style=dotted ] ep1_s9 -> ep1_e8 [ style=dotted ] - ep1_s9 -> ep1_e9 [ style=dotted ] } subgraph cluster_ep2 { label="Fragment/'fs_extra'" node [ style=filled ] ep2_e0 [ fillcolor="#ffffb3" label="[1] Constant" ] - ep2_e1 [ color="#ffffb3" label="[2] Global" ] - g1 -> ep2_e1 [fillcolor=gray] - ep2_e2 [ color="#ffffb3" label="[3] Global" ] - g0 -> ep2_e2 [fillcolor=gray] + ep2_e1 [ fillcolor="#ffffb3" label="[2] Constant" ] + ep2_e2 [ fillcolor="#ffffb3" label="[3] Constant" ] ep2_e3 [ fillcolor="#ffffb3" label="[4] Constant" ] - ep2_e4 [ fillcolor="#ffffb3" label="[5] Constant" ] - ep2_e5 [ fillcolor="#ffffb3" label="[6] Constant" ] - ep2_e6 [ fillcolor="#ffffb3" label="[7] Constant" ] - ep2_e7 [ fillcolor="#bebada" label="[8] Compose" ] - { ep2_e3 ep2_e4 ep2_e5 ep2_e6 } -> ep2_e7 + ep2_e4 [ fillcolor="#bebada" label="[5] Compose" ] + { ep2_e0 ep2_e1 ep2_e2 ep2_e3 } -> ep2_e4 ep2_s0 [ shape=square label="Root" ] ep2_s1 [ shape=square label="Emit" ] ep2_s2 [ shape=square label="Return" ] ep2_s0 -> ep2_s1 [ arrowhead=tee label="" ] ep2_s1 -> ep2_s2 [ arrowhead=tee label="" ] - ep2_e7 -> ep2_s2 [ label="value" ] - ep2_s1 -> ep2_e7 [ style=dotted ] + ep2_e4 -> ep2_s2 [ label="value" ] + ep2_s1 -> ep2_e4 [ style=dotted ] } } diff --git a/tests/out/glsl/access.assign_through_ptr.Compute.glsl b/tests/out/glsl/access.assign_through_ptr.Compute.glsl index c7ee8362c2..aafc30b909 100644 --- a/tests/out/glsl/access.assign_through_ptr.Compute.glsl +++ b/tests/out/glsl/access.assign_through_ptr.Compute.glsl @@ -23,8 +23,8 @@ shared uint val; float read_from_private(inout float foo_1) { - float _e6 = foo_1; - return _e6; + float _e1 = foo_1; + return _e1; } float test_arr_as_arg(float a[5][10]) { diff --git a/tests/out/glsl/access.atomics.Compute.glsl b/tests/out/glsl/access.atomics.Compute.glsl index 56c844f6a1..f5448b8420 100644 --- a/tests/out/glsl/access.atomics.Compute.glsl +++ b/tests/out/glsl/access.atomics.Compute.glsl @@ -29,8 +29,8 @@ layout(std430) buffer Bar_block_0Compute { float read_from_private(inout float foo_1) { - float _e6 = foo_1; - return _e6; + float _e1 = foo_1; + return _e1; } float test_arr_as_arg(float a[5][10]) { @@ -45,22 +45,22 @@ void assign_through_ptr_fn(inout uint p) { void main() { int tmp = 0; int value = _group_0_binding_0_cs.atom; - int _e10 = atomicAdd(_group_0_binding_0_cs.atom, 5); - tmp = _e10; - int _e13 = atomicAdd(_group_0_binding_0_cs.atom, -5); - tmp = _e13; - int _e16 = atomicAnd(_group_0_binding_0_cs.atom, 5); - tmp = _e16; + int _e7 = atomicAdd(_group_0_binding_0_cs.atom, 5); + tmp = _e7; + int _e11 = atomicAdd(_group_0_binding_0_cs.atom, -5); + tmp = _e11; + int _e15 = atomicAnd(_group_0_binding_0_cs.atom, 5); + tmp = _e15; int _e19 = atomicOr(_group_0_binding_0_cs.atom, 5); tmp = _e19; - int _e22 = atomicXor(_group_0_binding_0_cs.atom, 5); - tmp = _e22; - int _e25 = atomicMin(_group_0_binding_0_cs.atom, 5); - tmp = _e25; - int _e28 = atomicMax(_group_0_binding_0_cs.atom, 5); - tmp = _e28; - int _e31 = atomicExchange(_group_0_binding_0_cs.atom, 5); + int _e23 = atomicXor(_group_0_binding_0_cs.atom, 5); + tmp = _e23; + int _e27 = atomicMin(_group_0_binding_0_cs.atom, 5); + tmp = _e27; + int _e31 = atomicMax(_group_0_binding_0_cs.atom, 5); tmp = _e31; + int _e35 = atomicExchange(_group_0_binding_0_cs.atom, 5); + tmp = _e35; _group_0_binding_0_cs.atom = value; return; } diff --git a/tests/out/glsl/access.foo_frag.Fragment.glsl b/tests/out/glsl/access.foo_frag.Fragment.glsl index a3d6d21dd1..2e52a4698a 100644 --- a/tests/out/glsl/access.foo_frag.Fragment.glsl +++ b/tests/out/glsl/access.foo_frag.Fragment.glsl @@ -30,8 +30,8 @@ layout(std430) buffer type_11_block_1Fragment { ivec2 _group_0_binding_2_fs; }; layout(location = 0) out vec4 _fs2p_location0; float read_from_private(inout float foo_1) { - float _e6 = foo_1; - return _e6; + float _e1 = foo_1; + return _e1; } float test_arr_as_arg(float a[5][10]) { diff --git a/tests/out/glsl/access.foo_vert.Vertex.glsl b/tests/out/glsl/access.foo_vert.Vertex.glsl index 9fbfc272f7..866d6f64b3 100644 --- a/tests/out/glsl/access.foo_vert.Vertex.glsl +++ b/tests/out/glsl/access.foo_vert.Vertex.glsl @@ -33,80 +33,82 @@ uniform MatCx2InArray_block_3Vertex { MatCx2InArray _group_0_binding_3_vs; }; void test_matrix_within_struct_accesses() { - int idx = 1; + int idx = 0; Baz t = Baz(mat3x2(0.0)); - int _e6 = idx; - idx = (_e6 - 1); + idx = 1; + int _e2 = idx; + idx = (_e2 - 1); mat3x2 unnamed = _group_0_binding_1_vs.m; vec2 unnamed_1 = _group_0_binding_1_vs.m[0]; - int _e16 = idx; - vec2 unnamed_2 = _group_0_binding_1_vs.m[_e16]; + int _e15 = idx; + vec2 unnamed_2 = _group_0_binding_1_vs.m[_e15]; float unnamed_3 = _group_0_binding_1_vs.m[0][1]; - int _e28 = idx; - float unnamed_4 = _group_0_binding_1_vs.m[0][_e28]; - int _e32 = idx; - float unnamed_5 = _group_0_binding_1_vs.m[_e32][1]; - int _e38 = idx; - int _e40 = idx; - float unnamed_6 = _group_0_binding_1_vs.m[_e38][_e40]; + int _e29 = idx; + float unnamed_4 = _group_0_binding_1_vs.m[0][_e29]; + int _e34 = idx; + float unnamed_5 = _group_0_binding_1_vs.m[_e34][1]; + int _e41 = idx; + int _e43 = idx; + float unnamed_6 = _group_0_binding_1_vs.m[_e41][_e43]; t = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); - int _e52 = idx; - idx = (_e52 + 1); + int _e55 = idx; + idx = (_e55 + 1); t.m = mat3x2(vec2(6.0), vec2(5.0), vec2(4.0)); t.m[0] = vec2(9.0); - int _e69 = idx; - t.m[_e69] = vec2(90.0); + int _e72 = idx; + t.m[_e72] = vec2(90.0); t.m[0][1] = 10.0; - int _e82 = idx; - t.m[0][_e82] = 20.0; - int _e86 = idx; - t.m[_e86][1] = 30.0; - int _e92 = idx; - int _e94 = idx; - t.m[_e92][_e94] = 40.0; + int _e85 = idx; + t.m[0][_e85] = 20.0; + int _e89 = idx; + t.m[_e89][1] = 30.0; + int _e95 = idx; + int _e97 = idx; + t.m[_e95][_e97] = 40.0; return; } void test_matrix_within_array_within_struct_accesses() { - int idx_1 = 1; + int idx_1 = 0; MatCx2InArray t_1 = MatCx2InArray(mat4x2[2](mat4x2(0.0), mat4x2(0.0))); - int _e7 = idx_1; - idx_1 = (_e7 - 1); + idx_1 = 1; + int _e2 = idx_1; + idx_1 = (_e2 - 1); mat4x2 unnamed_7[2] = _group_0_binding_3_vs.am; mat4x2 unnamed_8 = _group_0_binding_3_vs.am[0]; vec2 unnamed_9 = _group_0_binding_3_vs.am[0][0]; - int _e25 = idx_1; - vec2 unnamed_10 = _group_0_binding_3_vs.am[0][_e25]; + int _e24 = idx_1; + vec2 unnamed_10 = _group_0_binding_3_vs.am[0][_e24]; float unnamed_11 = _group_0_binding_3_vs.am[0][0][1]; - int _e41 = idx_1; - float unnamed_12 = _group_0_binding_3_vs.am[0][0][_e41]; - int _e47 = idx_1; - float unnamed_13 = _group_0_binding_3_vs.am[0][_e47][1]; - int _e55 = idx_1; - int _e57 = idx_1; - float unnamed_14 = _group_0_binding_3_vs.am[0][_e55][_e57]; + int _e42 = idx_1; + float unnamed_12 = _group_0_binding_3_vs.am[0][0][_e42]; + int _e49 = idx_1; + float unnamed_13 = _group_0_binding_3_vs.am[0][_e49][1]; + int _e58 = idx_1; + int _e60 = idx_1; + float unnamed_14 = _group_0_binding_3_vs.am[0][_e58][_e60]; t_1 = MatCx2InArray(mat4x2[2](mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)), mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)))); - int _e63 = idx_1; - idx_1 = (_e63 + 1); + int _e66 = idx_1; + idx_1 = (_e66 + 1); t_1.am = mat4x2[2](mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)), mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0))); t_1.am[0] = mat4x2(vec2(8.0), vec2(7.0), vec2(6.0), vec2(5.0)); t_1.am[0][0] = vec2(9.0); - int _e90 = idx_1; - t_1.am[0][_e90] = vec2(90.0); + int _e93 = idx_1; + t_1.am[0][_e93] = vec2(90.0); t_1.am[0][0][1] = 10.0; - int _e107 = idx_1; - t_1.am[0][0][_e107] = 20.0; - int _e113 = idx_1; - t_1.am[0][_e113][1] = 30.0; - int _e121 = idx_1; - int _e123 = idx_1; - t_1.am[0][_e121][_e123] = 40.0; + int _e110 = idx_1; + t_1.am[0][0][_e110] = 20.0; + int _e116 = idx_1; + t_1.am[0][_e116][1] = 30.0; + int _e124 = idx_1; + int _e126 = idx_1; + t_1.am[0][_e124][_e126] = 40.0; return; } float read_from_private(inout float foo_1) { - float _e6 = foo_1; - return _e6; + float _e1 = foo_1; + return _e1; } float test_arr_as_arg(float a[5][10]) { @@ -121,7 +123,8 @@ void assign_through_ptr_fn(inout uint p) { void main() { uint vi = uint(gl_VertexID); float foo = 0.0; - int c[5] = int[5](0, 0, 0, 0, 0); + int c2_[5] = int[5](0, 0, 0, 0, 0); + foo = 0.0; float baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(); @@ -130,12 +133,12 @@ void main() { uvec2 arr[2] = _group_0_binding_0_vs.arr; float b = _group_0_binding_0_vs._matrix[3][0]; int a_1 = _group_0_binding_0_vs.data[(uint(_group_0_binding_0_vs.data.length()) - 2u)].value; - ivec2 c_1 = _group_0_binding_2_vs; - float _e32 = read_from_private(foo); - c = int[5](a_1, int(b), 3, 4, 5); - c[(vi + 1u)] = 42; - int value = c[vi]; - float _e46 = test_arr_as_arg(float[5][10](float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); + ivec2 c = _group_0_binding_2_vs; + float _e34 = read_from_private(foo); + c2_ = int[5](a_1, int(b), 3, 4, 5); + c2_[(vi + 1u)] = 42; + int value = c2_[vi]; + float _e48 = test_arr_as_arg(float[5][10](float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), float[10](0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); gl_Position = vec4((_matrix * vec4(ivec4(value))), 2.0); gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w); return; diff --git a/tests/out/glsl/bits.main.Compute.glsl b/tests/out/glsl/bits.main.Compute.glsl index 0cdc8906a7..504fb7c94f 100644 --- a/tests/out/glsl/bits.main.Compute.glsl +++ b/tests/out/glsl/bits.main.Compute.glsl @@ -17,9 +17,11 @@ void main() { uvec4 u4_ = uvec4(0u); vec2 f2_ = vec2(0.0); vec4 f4_ = vec4(0.0); + i = 0; i2_ = ivec2(0); i3_ = ivec3(0); i4_ = ivec4(0); + u = 0u; u2_ = uvec2(0u); u3_ = uvec3(0u); u4_ = uvec4(0u); diff --git a/tests/out/glsl/boids.main.Compute.glsl b/tests/out/glsl/boids.main.Compute.glsl index 8253d50d94..c8df993f54 100644 --- a/tests/out/glsl/boids.main.Compute.glsl +++ b/tests/out/glsl/boids.main.Compute.glsl @@ -45,112 +45,115 @@ void main() { if ((index >= 1500u)) { return; } - vec2 _e10 = _group_0_binding_1_cs.particles[index].pos; - vPos = _e10; - vec2 _e15 = _group_0_binding_1_cs.particles[index].vel; - vVel = _e15; + vec2 _e8 = _group_0_binding_1_cs.particles[index].pos; + vPos = _e8; + vec2 _e14 = _group_0_binding_1_cs.particles[index].vel; + vVel = _e14; cMass = vec2(0.0, 0.0); cVel = vec2(0.0, 0.0); colVel = vec2(0.0, 0.0); + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e86 = i; - i = (_e86 + 1u); + uint _e91 = i; + i = (_e91 + 1u); } loop_init = false; - uint _e37 = i; - if ((_e37 >= 1500u)) { + uint _e36 = i; + if ((_e36 >= 1500u)) { break; } uint _e39 = i; if ((_e39 == index)) { continue; } - uint _e42 = i; - vec2 _e45 = _group_0_binding_1_cs.particles[_e42].pos; - pos = _e45; - uint _e47 = i; - vec2 _e50 = _group_0_binding_1_cs.particles[_e47].vel; - vel = _e50; - vec2 _e51 = pos; - vec2 _e52 = vPos; - float _e55 = _group_0_binding_0_cs.rule1Distance; - if ((distance(_e51, _e52) < _e55)) { - vec2 _e57 = cMass; - vec2 _e58 = pos; - cMass = (_e57 + _e58); - int _e60 = cMassCount; - cMassCount = (_e60 + 1); + uint _e43 = i; + vec2 _e46 = _group_0_binding_1_cs.particles[_e43].pos; + pos = _e46; + uint _e49 = i; + vec2 _e52 = _group_0_binding_1_cs.particles[_e49].vel; + vel = _e52; + vec2 _e53 = pos; + vec2 _e54 = vPos; + float _e58 = _group_0_binding_0_cs.rule1Distance; + if ((distance(_e53, _e54) < _e58)) { + vec2 _e60 = cMass; + vec2 _e61 = pos; + cMass = (_e60 + _e61); + int _e63 = cMassCount; + cMassCount = (_e63 + 1); } - vec2 _e63 = pos; - vec2 _e64 = vPos; - float _e67 = _group_0_binding_0_cs.rule2Distance; - if ((distance(_e63, _e64) < _e67)) { - vec2 _e69 = colVel; - vec2 _e70 = pos; - vec2 _e71 = vPos; - colVel = (_e69 - (_e70 - _e71)); + vec2 _e66 = pos; + vec2 _e67 = vPos; + float _e71 = _group_0_binding_0_cs.rule2Distance; + if ((distance(_e66, _e67) < _e71)) { + vec2 _e73 = colVel; + vec2 _e74 = pos; + vec2 _e75 = vPos; + colVel = (_e73 - (_e74 - _e75)); } - vec2 _e74 = pos; - vec2 _e75 = vPos; - float _e78 = _group_0_binding_0_cs.rule3Distance; - if ((distance(_e74, _e75) < _e78)) { - vec2 _e80 = cVel; - vec2 _e81 = vel; - cVel = (_e80 + _e81); - int _e83 = cVelCount; - cVelCount = (_e83 + 1); + vec2 _e78 = pos; + vec2 _e79 = vPos; + float _e83 = _group_0_binding_0_cs.rule3Distance; + if ((distance(_e78, _e79) < _e83)) { + vec2 _e85 = cVel; + vec2 _e86 = vel; + cVel = (_e85 + _e86); + int _e88 = cVelCount; + cVelCount = (_e88 + 1); } } - int _e89 = cMassCount; - if ((_e89 > 0)) { - vec2 _e92 = cMass; - int _e93 = cMassCount; - vec2 _e97 = vPos; - cMass = ((_e92 / vec2(float(_e93))) - _e97); + int _e94 = cMassCount; + if ((_e94 > 0)) { + vec2 _e97 = cMass; + int _e98 = cMassCount; + vec2 _e102 = vPos; + cMass = ((_e97 / vec2(float(_e98))) - _e102); } - int _e99 = cVelCount; - if ((_e99 > 0)) { - vec2 _e102 = cVel; - int _e103 = cVelCount; - cVel = (_e102 / vec2(float(_e103))); + int _e104 = cVelCount; + if ((_e104 > 0)) { + vec2 _e107 = cVel; + int _e108 = cVelCount; + cVel = (_e107 / vec2(float(_e108))); } - vec2 _e107 = vVel; - vec2 _e108 = cMass; - float _e110 = _group_0_binding_0_cs.rule1Scale; - vec2 _e113 = colVel; - float _e115 = _group_0_binding_0_cs.rule2Scale; - vec2 _e118 = cVel; - float _e120 = _group_0_binding_0_cs.rule3Scale; - vVel = (((_e107 + (_e108 * _e110)) + (_e113 * _e115)) + (_e118 * _e120)); - vec2 _e123 = vVel; - vec2 _e125 = vVel; - vVel = (normalize(_e123) * clamp(length(_e125), 0.0, 0.10000000149011612)); - vec2 _e131 = vPos; - vec2 _e132 = vVel; - float _e134 = _group_0_binding_0_cs.deltaT; - vPos = (_e131 + (_e132 * _e134)); - float _e138 = vPos.x; - if ((_e138 < -1.0)) { + vec2 _e112 = vVel; + vec2 _e113 = cMass; + float _e116 = _group_0_binding_0_cs.rule1Scale; + vec2 _e119 = colVel; + float _e122 = _group_0_binding_0_cs.rule2Scale; + vec2 _e125 = cVel; + float _e128 = _group_0_binding_0_cs.rule3Scale; + vVel = (((_e112 + (_e113 * _e116)) + (_e119 * _e122)) + (_e125 * _e128)); + vec2 _e131 = vVel; + vec2 _e133 = vVel; + vVel = (normalize(_e131) * clamp(length(_e133), 0.0, 0.10000000149011612)); + vec2 _e139 = vPos; + vec2 _e140 = vVel; + float _e143 = _group_0_binding_0_cs.deltaT; + vPos = (_e139 + (_e140 * _e143)); + float _e147 = vPos.x; + if ((_e147 < -1.0)) { vPos.x = 1.0; } - float _e144 = vPos.x; - if ((_e144 > 1.0)) { + float _e153 = vPos.x; + if ((_e153 > 1.0)) { vPos.x = -1.0; } - float _e150 = vPos.y; - if ((_e150 < -1.0)) { + float _e159 = vPos.y; + if ((_e159 < -1.0)) { vPos.y = 1.0; } - float _e156 = vPos.y; - if ((_e156 > 1.0)) { + float _e165 = vPos.y; + if ((_e165 > 1.0)) { vPos.y = -1.0; } - vec2 _e164 = vPos; - _group_0_binding_2_cs.particles[index].pos = _e164; - vec2 _e168 = vVel; - _group_0_binding_2_cs.particles[index].vel = _e168; + vec2 _e174 = vPos; + _group_0_binding_2_cs.particles[index].pos = _e174; + vec2 _e179 = vVel; + _group_0_binding_2_cs.particles[index].vel = _e179; return; } diff --git a/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl b/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl index a1d8b5b055..8196d197dd 100644 --- a/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl +++ b/tests/out/glsl/bounds-check-image-restrict.fragment_shader.Fragment.glsl @@ -27,27 +27,27 @@ vec4 test_textureLoad_1d(int coords, int level) { } vec4 test_textureLoad_2d(ivec2 coords_1, int level_1) { - int _e4_clamped_lod = clamp(level_1, 0, textureQueryLevels(_group_0_binding_1_fs) - 1); - vec4 _e4 = texelFetch(_group_0_binding_1_fs, clamp(coords_1, ivec2(0), textureSize(_group_0_binding_1_fs, _e4_clamped_lod) - ivec2(1)), _e4_clamped_lod); - return _e4; + int _e3_clamped_lod = clamp(level_1, 0, textureQueryLevels(_group_0_binding_1_fs) - 1); + vec4 _e3 = texelFetch(_group_0_binding_1_fs, clamp(coords_1, ivec2(0), textureSize(_group_0_binding_1_fs, _e3_clamped_lod) - ivec2(1)), _e3_clamped_lod); + return _e3; } vec4 test_textureLoad_2d_array(ivec2 coords_2, int index, int level_2) { - int _e6_clamped_lod = clamp(level_2, 0, textureQueryLevels(_group_0_binding_2_fs) - 1); - vec4 _e6 = texelFetch(_group_0_binding_2_fs, clamp(ivec3(coords_2, index), ivec3(0), textureSize(_group_0_binding_2_fs, _e6_clamped_lod) - ivec3(1)), _e6_clamped_lod); - return _e6; + int _e4_clamped_lod = clamp(level_2, 0, textureQueryLevels(_group_0_binding_2_fs) - 1); + vec4 _e4 = texelFetch(_group_0_binding_2_fs, clamp(ivec3(coords_2, index), ivec3(0), textureSize(_group_0_binding_2_fs, _e4_clamped_lod) - ivec3(1)), _e4_clamped_lod); + return _e4; } vec4 test_textureLoad_3d(ivec3 coords_3, int level_3) { - int _e6_clamped_lod = clamp(level_3, 0, textureQueryLevels(_group_0_binding_3_fs) - 1); - vec4 _e6 = texelFetch(_group_0_binding_3_fs, clamp(coords_3, ivec3(0), textureSize(_group_0_binding_3_fs, _e6_clamped_lod) - ivec3(1)), _e6_clamped_lod); - return _e6; + int _e3_clamped_lod = clamp(level_3, 0, textureQueryLevels(_group_0_binding_3_fs) - 1); + vec4 _e3 = texelFetch(_group_0_binding_3_fs, clamp(coords_3, ivec3(0), textureSize(_group_0_binding_3_fs, _e3_clamped_lod) - ivec3(1)), _e3_clamped_lod); + return _e3; } vec4 test_textureLoad_multisampled_2d(ivec2 coords_4, int _sample) { - vec4 _e7 = texelFetch(_group_0_binding_4_fs, clamp(coords_4, ivec2(0), textureSize(_group_0_binding_4_fs) - ivec2(1)), clamp(_sample, 0, textureSamples(_group_0_binding_4_fs) - 1) + vec4 _e3 = texelFetch(_group_0_binding_4_fs, clamp(coords_4, ivec2(0), textureSize(_group_0_binding_4_fs) - ivec2(1)), clamp(_sample, 0, textureSamples(_group_0_binding_4_fs) - 1) ); - return _e7; + return _e3; } void test_textureStore_1d(int coords_8, vec4 value) { @@ -71,11 +71,11 @@ void test_textureStore_3d(ivec3 coords_11, vec4 value_3) { } void main() { - vec4 _e14 = test_textureLoad_1d(0, 0); - vec4 _e17 = test_textureLoad_2d(ivec2(0, 0), 0); - vec4 _e21 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); - vec4 _e24 = test_textureLoad_3d(ivec3(0, 0, 0), 0); - vec4 _e27 = test_textureLoad_multisampled_2d(ivec2(0, 0), 0); + vec4 _e2 = test_textureLoad_1d(0, 0); + vec4 _e5 = test_textureLoad_2d(ivec2(0, 0), 0); + vec4 _e9 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); + vec4 _e12 = test_textureLoad_3d(ivec3(0, 0, 0), 0); + vec4 _e15 = test_textureLoad_multisampled_2d(ivec2(0, 0), 0); test_textureStore_1d(0, vec4(0.0, 0.0, 0.0, 0.0)); test_textureStore_2d(ivec2(0, 0), vec4(0.0, 0.0, 0.0, 0.0)); test_textureStore_2d_array(ivec2(0, 0), 0, vec4(0.0, 0.0, 0.0, 0.0)); diff --git a/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl b/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl index 9c2bef19ab..50d1590d29 100644 --- a/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl +++ b/tests/out/glsl/bounds-check-image-rzsw.fragment_shader.Fragment.glsl @@ -26,23 +26,23 @@ vec4 test_textureLoad_1d(int coords, int level) { } vec4 test_textureLoad_2d(ivec2 coords_1, int level_1) { - vec4 _e4 = (level_1 < textureQueryLevels(_group_0_binding_1_fs) && all(lessThan(coords_1, textureSize(_group_0_binding_1_fs, level_1))) ? texelFetch(_group_0_binding_1_fs, coords_1, level_1) : vec4(0.0)); - return _e4; + vec4 _e3 = (level_1 < textureQueryLevels(_group_0_binding_1_fs) && all(lessThan(coords_1, textureSize(_group_0_binding_1_fs, level_1))) ? texelFetch(_group_0_binding_1_fs, coords_1, level_1) : vec4(0.0)); + return _e3; } vec4 test_textureLoad_2d_array(ivec2 coords_2, int index, int level_2) { - vec4 _e6 = (level_2 < textureQueryLevels(_group_0_binding_2_fs) && all(lessThan(ivec3(coords_2, index), textureSize(_group_0_binding_2_fs, level_2))) ? texelFetch(_group_0_binding_2_fs, ivec3(coords_2, index), level_2) : vec4(0.0)); - return _e6; + vec4 _e4 = (level_2 < textureQueryLevels(_group_0_binding_2_fs) && all(lessThan(ivec3(coords_2, index), textureSize(_group_0_binding_2_fs, level_2))) ? texelFetch(_group_0_binding_2_fs, ivec3(coords_2, index), level_2) : vec4(0.0)); + return _e4; } vec4 test_textureLoad_3d(ivec3 coords_3, int level_3) { - vec4 _e6 = (level_3 < textureQueryLevels(_group_0_binding_3_fs) && all(lessThan(coords_3, textureSize(_group_0_binding_3_fs, level_3))) ? texelFetch(_group_0_binding_3_fs, coords_3, level_3) : vec4(0.0)); - return _e6; + vec4 _e3 = (level_3 < textureQueryLevels(_group_0_binding_3_fs) && all(lessThan(coords_3, textureSize(_group_0_binding_3_fs, level_3))) ? texelFetch(_group_0_binding_3_fs, coords_3, level_3) : vec4(0.0)); + return _e3; } vec4 test_textureLoad_multisampled_2d(ivec2 coords_4, int _sample) { - vec4 _e7 = (_sample < textureSamples(_group_0_binding_4_fs) && all(lessThan(coords_4, textureSize(_group_0_binding_4_fs))) ? texelFetch(_group_0_binding_4_fs, coords_4, _sample) : vec4(0.0)); - return _e7; + vec4 _e3 = (_sample < textureSamples(_group_0_binding_4_fs) && all(lessThan(coords_4, textureSize(_group_0_binding_4_fs))) ? texelFetch(_group_0_binding_4_fs, coords_4, _sample) : vec4(0.0)); + return _e3; } void test_textureStore_1d(int coords_8, vec4 value) { @@ -66,11 +66,11 @@ void test_textureStore_3d(ivec3 coords_11, vec4 value_3) { } void main() { - vec4 _e14 = test_textureLoad_1d(0, 0); - vec4 _e17 = test_textureLoad_2d(ivec2(0, 0), 0); - vec4 _e21 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); - vec4 _e24 = test_textureLoad_3d(ivec3(0, 0, 0), 0); - vec4 _e27 = test_textureLoad_multisampled_2d(ivec2(0, 0), 0); + vec4 _e2 = test_textureLoad_1d(0, 0); + vec4 _e5 = test_textureLoad_2d(ivec2(0, 0), 0); + vec4 _e9 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); + vec4 _e12 = test_textureLoad_3d(ivec3(0, 0, 0), 0); + vec4 _e15 = test_textureLoad_multisampled_2d(ivec2(0, 0), 0); test_textureStore_1d(0, vec4(0.0, 0.0, 0.0, 0.0)); test_textureStore_2d(ivec2(0, 0), vec4(0.0, 0.0, 0.0, 0.0)); test_textureStore_2d_array(ivec2(0, 0), 0, vec4(0.0, 0.0, 0.0, 0.0)); diff --git a/tests/out/glsl/globals.main.Compute.glsl b/tests/out/glsl/globals.main.Compute.glsl index 0d5cb797bf..e77585f0b9 100644 --- a/tests/out/glsl/globals.main.Compute.glsl +++ b/tests/out/glsl/globals.main.Compute.glsl @@ -5,7 +5,7 @@ precision highp int; layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; -struct Foo { +struct FooStruct { vec3 v3_; float v1_; }; @@ -13,7 +13,7 @@ shared float wg[10]; shared uint at_1; -layout(std430) buffer Foo_block_0Compute { Foo _group_0_binding_1_cs; }; +layout(std430) buffer FooStruct_block_0Compute { FooStruct _group_0_binding_1_cs; }; layout(std430) readonly buffer type_6_block_1Compute { vec2 _group_0_binding_2_cs[]; }; @@ -33,13 +33,14 @@ void test_msl_packed_vec3_as_arg(vec3 arg) { } void test_msl_packed_vec3_() { - int idx = 1; + int idx = 0; _group_0_binding_1_cs.v3_ = vec3(1.0); + idx = 1; _group_0_binding_1_cs.v3_.x = 1.0; _group_0_binding_1_cs.v3_.x = 2.0; - int _e23 = idx; - _group_0_binding_1_cs.v3_[_e23] = 3.0; - Foo data = _group_0_binding_1_cs; + int _e17 = idx; + _group_0_binding_1_cs.v3_[_e17] = 3.0; + FooStruct data = _group_0_binding_1_cs; vec3 unnamed = data.v3_; vec2 unnamed_1 = data.v3_.zx; test_msl_packed_vec3_as_arg(data.v3_); @@ -50,26 +51,28 @@ void test_msl_packed_vec3_() { } void main() { - float Foo_1 = 1.0; - bool at = true; + float Foo = 0.0; + bool at = false; test_msl_packed_vec3_(); - mat4x2 _e16 = _group_0_binding_7_cs[0][0]; - vec4 _e23 = _group_0_binding_6_cs[0][0][0]; - wg[7] = (_e16 * _e23).x; - mat3x2 _e28 = _group_0_binding_5_cs; - vec3 _e29 = _group_0_binding_4_cs; - wg[6] = (_e28 * _e29).x; - float _e37 = _group_0_binding_2_cs[1].y; - wg[5] = _e37; + mat4x2 _e8 = _group_0_binding_7_cs[0][0]; + vec4 _e16 = _group_0_binding_6_cs[0][0][0]; + wg[7] = (_e8 * _e16).x; + mat3x2 _e23 = _group_0_binding_5_cs; + vec3 _e25 = _group_0_binding_4_cs; + wg[6] = (_e23 * _e25).x; + float _e35 = _group_0_binding_2_cs[1].y; + wg[5] = _e35; float _e43 = _group_0_binding_3_cs[0].w; wg[4] = _e43; - float _e47 = _group_0_binding_1_cs.v1_; - wg[3] = _e47; - float _e52 = _group_0_binding_1_cs.v3_.x; - wg[2] = _e52; + float _e49 = _group_0_binding_1_cs.v1_; + wg[3] = _e49; + float _e56 = _group_0_binding_1_cs.v3_.x; + wg[2] = _e56; _group_0_binding_1_cs.v1_ = 4.0; wg[1] = float(uint(_group_0_binding_2_cs.length())); at_1 = 2u; + Foo = 1.0; + at = true; return; } diff --git a/tests/out/glsl/operators.main.Compute.glsl b/tests/out/glsl/operators.main.Compute.glsl index 30d7c53a30..3857923393 100644 --- a/tests/out/glsl/operators.main.Compute.glsl +++ b/tests/out/glsl/operators.main.Compute.glsl @@ -31,14 +31,14 @@ vec4 splat() { vec2 splat_assignment() { vec2 a = vec2(0.0); a = vec2(2.0); - vec2 _e7 = a; - a = (_e7 + vec2(1.0)); - vec2 _e11 = a; - a = (_e11 - vec2(3.0)); + vec2 _e4 = a; + a = (_e4 + vec2(1.0)); + vec2 _e8 = a; + a = (_e8 - vec2(3.0)); + vec2 _e12 = a; + a = (_e12 / vec2(4.0)); vec2 _e15 = a; - a = (_e15 / vec2(4.0)); - vec2 _e19 = a; - return _e19; + return _e15; } vec3 bool_cast(vec3 x) { @@ -62,8 +62,8 @@ float constructors() { mat2x3 unnamed_8 = mat2x3(mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); uvec2 unnamed_9 = uvec2(0u, 0u); mat2x3 unnamed_10 = mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)); - float _e75 = foo.a.x; - return _e75; + float _e71 = foo.a.x; + return _e71; } void logical() { @@ -216,38 +216,40 @@ void comparison() { } void assignment() { - int a_1 = 1; - ivec3 vec0_ = ivec3(0, 0, 0); + int a_1 = 0; + ivec3 vec0_ = ivec3(0); + a_1 = 1; + int _e3 = a_1; + a_1 = (_e3 + 1); int _e6 = a_1; - a_1 = (_e6 + 1); + a_1 = (_e6 - 1); + int _e8 = a_1; int _e9 = a_1; - a_1 = (_e9 - 1); + a_1 = (_e9 * _e8); + int _e11 = a_1; int _e12 = a_1; - int _e13 = a_1; - a_1 = (_e12 * _e13); + a_1 = (_e12 / _e11); int _e15 = a_1; - int _e16 = a_1; - a_1 = (_e15 / _e16); + a_1 = (_e15 % 1); int _e18 = a_1; - a_1 = (_e18 % 1); + a_1 = (_e18 & 0); int _e21 = a_1; - a_1 = (_e21 & 0); + a_1 = (_e21 | 0); int _e24 = a_1; - a_1 = (_e24 | 0); + a_1 = (_e24 ^ 0); int _e27 = a_1; - a_1 = (_e27 ^ 0); + a_1 = (_e27 << 2u); int _e30 = a_1; - a_1 = (_e30 << 2u); - int _e33 = a_1; - a_1 = (_e33 >> 1u); - int _e36 = a_1; - a_1 = (_e36 + 1); - int _e39 = a_1; - a_1 = (_e39 - 1); - int _e46 = vec0_.y; - vec0_.y = (_e46 + 1); - int _e51 = vec0_.y; - vec0_.y = (_e51 - 1); + a_1 = (_e30 >> 1u); + int _e32 = a_1; + a_1 = (_e32 + 1); + int _e35 = a_1; + a_1 = (_e35 - 1); + vec0_ = ivec3(0, 0, 0); + int _e42 = vec0_.y; + vec0_.y = (_e42 + 1); + int _e47 = vec0_.y; + vec0_.y = (_e47 - 1); return; } @@ -262,10 +264,10 @@ void negation_avoids_prefix_decrement() { } void main() { - vec4 _e4 = builtins(); - vec4 _e5 = splat(); - vec3 _e7 = bool_cast(vec4(1.0, 1.0, 1.0, 1.0).xyz); - float _e8 = constructors(); + vec4 _e0 = builtins(); + vec4 _e1 = splat(); + vec3 _e4 = bool_cast(vec4(1.0, 1.0, 1.0, 1.0).xyz); + float _e5 = constructors(); logical(); arithmetic(); bit(); diff --git a/tests/out/glsl/padding.vertex.Vertex.glsl b/tests/out/glsl/padding.vertex.Vertex.glsl index 21a231a37b..1810cffc69 100644 --- a/tests/out/glsl/padding.vertex.Vertex.glsl +++ b/tests/out/glsl/padding.vertex.Vertex.glsl @@ -26,10 +26,10 @@ uniform Test3__block_2Vertex { Test3_ _group_0_binding_2_vs; }; void main() { - float _e6 = _group_0_binding_0_vs.b; - float _e9 = _group_0_binding_1_vs.b; + float _e4 = _group_0_binding_0_vs.b; + float _e8 = _group_0_binding_1_vs.b; float _e12 = _group_0_binding_2_vs.b; - gl_Position = (((vec4(1.0) * _e6) * _e9) * _e12); + gl_Position = (((vec4(1.0) * _e4) * _e8) * _e12); gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w); return; } diff --git a/tests/out/glsl/shadow.fs_main.Fragment.glsl b/tests/out/glsl/shadow.fs_main.Fragment.glsl index 6c0fed4333..b34e39e5c4 100644 --- a/tests/out/glsl/shadow.fs_main.Fragment.glsl +++ b/tests/out/glsl/shadow.fs_main.Fragment.glsl @@ -40,40 +40,44 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { vec2 flip_correction = vec2(0.5, -0.5); float proj_correction = (1.0 / homogeneous_coords.w); vec2 light_local = (((homogeneous_coords.xy * flip_correction) * proj_correction) + vec2(0.5, 0.5)); - float _e28 = textureGrad(_group_0_binding_2_fs, vec4(light_local, int(light_id), (homogeneous_coords.z * proj_correction)), vec2(0.0), vec2(0.0)); - return _e28; + float _e24 = textureGrad(_group_0_binding_2_fs, vec4(light_local, int(light_id), (homogeneous_coords.z * proj_correction)), vec2(0.0), vec2(0.0)); + return _e24; } void main() { VertexOutput in_ = VertexOutput(gl_FragCoord, _vs2fs_location0, _vs2fs_location1); - vec3 color = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + vec3 color = vec3(0.0); uint i = 0u; vec3 normal_1 = normalize(in_.world_normal); + color = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e20 = i; - i = (_e20 + 1u); + uint _e39 = i; + i = (_e39 + 1u); } loop_init = false; - uint _e14 = i; - uint _e17 = _group_0_binding_0_fs.num_lights.x; - if ((_e14 < min(_e17, 10u))) { + uint _e7 = i; + uint _e11 = _group_0_binding_0_fs.num_lights.x; + if ((_e7 < min(_e11, 10u))) { } else { break; } - uint _e23 = i; - Light light = _group_0_binding_1_fs[_e23]; - uint _e26 = i; - float _e30 = fetch_shadow(_e26, (light.proj * in_.world_position)); - vec3 light_dir = normalize((light.pos.xyz - in_.world_position.xyz)); - float diffuse = max(0.0, dot(normal_1, light_dir)); - vec3 _e40 = color; - color = (_e40 + ((_e30 * diffuse) * light.color.xyz)); + { + uint _e16 = i; + Light light = _group_0_binding_1_fs[_e16]; + uint _e19 = i; + float _e23 = fetch_shadow(_e19, (light.proj * in_.world_position)); + vec3 light_dir = normalize((light.pos.xyz - in_.world_position.xyz)); + float diffuse = max(0.0, dot(normal_1, light_dir)); + vec3 _e37 = color; + color = (_e37 + ((_e23 * diffuse) * light.color.xyz)); + } } - vec3 _e46 = color; - vec4 _e50 = _group_1_binding_0_fs.color; - _fs2p_location0 = (vec4(_e46, 1.0) * _e50); + vec3 _e42 = color; + vec4 _e47 = _group_1_binding_0_fs.color; + _fs2p_location0 = (vec4(_e42, 1.0) * _e47); return; } diff --git a/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl b/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl index 7cd75cff93..ae3dd1c861 100644 --- a/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl +++ b/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl @@ -40,40 +40,44 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { vec2 flip_correction = vec2(0.5, -0.5); float proj_correction = (1.0 / homogeneous_coords.w); vec2 light_local = (((homogeneous_coords.xy * flip_correction) * proj_correction) + vec2(0.5, 0.5)); - float _e28 = textureGrad(_group_0_binding_2_fs, vec4(light_local, int(light_id), (homogeneous_coords.z * proj_correction)), vec2(0.0), vec2(0.0)); - return _e28; + float _e24 = textureGrad(_group_0_binding_2_fs, vec4(light_local, int(light_id), (homogeneous_coords.z * proj_correction)), vec2(0.0), vec2(0.0)); + return _e24; } void main() { VertexOutput in_1 = VertexOutput(gl_FragCoord, _vs2fs_location0, _vs2fs_location1); - vec3 color_1 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + vec3 color_1 = vec3(0.0); uint i_1 = 0u; vec3 normal_1 = normalize(in_1.world_normal); + color_1 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i_1 = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e20 = i_1; - i_1 = (_e20 + 1u); + uint _e39 = i_1; + i_1 = (_e39 + 1u); } loop_init = false; - uint _e14 = i_1; - uint _e17 = _group_0_binding_0_fs.num_lights.x; - if ((_e14 < min(_e17, 10u))) { + uint _e7 = i_1; + uint _e11 = _group_0_binding_0_fs.num_lights.x; + if ((_e7 < min(_e11, 10u))) { } else { break; } - uint _e23 = i_1; - Light light = _group_0_binding_1_fs[_e23]; - uint _e26 = i_1; - float _e30 = fetch_shadow(_e26, (light.proj * in_1.world_position)); - vec3 light_dir = normalize((light.pos.xyz - in_1.world_position.xyz)); - float diffuse = max(0.0, dot(normal_1, light_dir)); - vec3 _e40 = color_1; - color_1 = (_e40 + ((_e30 * diffuse) * light.color.xyz)); + { + uint _e16 = i_1; + Light light = _group_0_binding_1_fs[_e16]; + uint _e19 = i_1; + float _e23 = fetch_shadow(_e19, (light.proj * in_1.world_position)); + vec3 light_dir = normalize((light.pos.xyz - in_1.world_position.xyz)); + float diffuse = max(0.0, dot(normal_1, light_dir)); + vec3 _e37 = color_1; + color_1 = (_e37 + ((_e23 * diffuse) * light.color.xyz)); + } } - vec3 _e46 = color_1; - vec4 _e50 = _group_1_binding_0_fs.color; - _fs2p_location0 = (vec4(_e46, 1.0) * _e50); + vec3 _e42 = color_1; + vec4 _e47 = _group_1_binding_0_fs.color; + _fs2p_location0 = (vec4(_e42, 1.0) * _e47); return; } diff --git a/tests/out/glsl/shadow.vs_main.Vertex.glsl b/tests/out/glsl/shadow.vs_main.Vertex.glsl index dce8b2f7d6..eced93ae71 100644 --- a/tests/out/glsl/shadow.vs_main.Vertex.glsl +++ b/tests/out/glsl/shadow.vs_main.Vertex.glsl @@ -39,12 +39,12 @@ void main() { vec4 world_pos = (_e7 * vec4(position)); out_.world_normal = (mat3x3(w[0].xyz, w[1].xyz, w[2].xyz) * vec3(normal.xyz)); out_.world_position = world_pos; - mat4x4 _e25 = _group_0_binding_0_vs.view_proj; - out_.proj_position = (_e25 * world_pos); - VertexOutput _e27 = out_; - gl_Position = _e27.proj_position; - _vs2fs_location0 = _e27.world_normal; - _vs2fs_location1 = _e27.world_position; + mat4x4 _e26 = _group_0_binding_0_vs.view_proj; + out_.proj_position = (_e26 * world_pos); + VertexOutput _e28 = out_; + gl_Position = _e28.proj_position; + _vs2fs_location0 = _e28.world_normal; + _vs2fs_location1 = _e28.world_position; gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w); return; } diff --git a/tests/out/glsl/skybox.fs_main.Fragment.glsl b/tests/out/glsl/skybox.fs_main.Fragment.glsl index 2b151db2af..1334614815 100644 --- a/tests/out/glsl/skybox.fs_main.Fragment.glsl +++ b/tests/out/glsl/skybox.fs_main.Fragment.glsl @@ -18,8 +18,8 @@ layout(location = 0) out vec4 _fs2p_location0; void main() { VertexOutput in_ = VertexOutput(gl_FragCoord, _vs2fs_location0); - vec4 _e5 = texture(_group_0_binding_1_fs, vec3(in_.uv)); - _fs2p_location0 = _e5; + vec4 _e4 = texture(_group_0_binding_1_fs, vec3(in_.uv)); + _fs2p_location0 = _e4; return; } diff --git a/tests/out/glsl/skybox.vs_main.Vertex.glsl b/tests/out/glsl/skybox.vs_main.Vertex.glsl index 115245a716..e40addaa2f 100644 --- a/tests/out/glsl/skybox.vs_main.Vertex.glsl +++ b/tests/out/glsl/skybox.vs_main.Vertex.glsl @@ -21,15 +21,15 @@ void main() { int tmp2_ = 0; tmp1_ = (int(vertex_index) / 2); tmp2_ = (int(vertex_index) & 1); - int _e10 = tmp1_; - int _e16 = tmp2_; - vec4 pos = vec4(((float(_e10) * 4.0) - 1.0), ((float(_e16) * 4.0) - 1.0), 0.0, 1.0); + int _e9 = tmp1_; + int _e15 = tmp2_; + vec4 pos = vec4(((float(_e9) * 4.0) - 1.0), ((float(_e15) * 4.0) - 1.0), 0.0, 1.0); vec4 _e27 = _group_0_binding_0_vs.view[0]; - vec4 _e31 = _group_0_binding_0_vs.view[1]; - vec4 _e35 = _group_0_binding_0_vs.view[2]; - mat3x3 inv_model_view = transpose(mat3x3(_e27.xyz, _e31.xyz, _e35.xyz)); - mat4x4 _e40 = _group_0_binding_0_vs.proj_inv; - vec4 unprojected = (_e40 * pos); + vec4 _e32 = _group_0_binding_0_vs.view[1]; + vec4 _e37 = _group_0_binding_0_vs.view[2]; + mat3x3 inv_model_view = transpose(mat3x3(_e27.xyz, _e32.xyz, _e37.xyz)); + mat4x4 _e43 = _group_0_binding_0_vs.proj_inv; + vec4 unprojected = (_e43 * pos); VertexOutput _tmp_return = VertexOutput(pos, (inv_model_view * unprojected.xyz)); gl_Position = _tmp_return.position; _vs2fs_location0 = _tmp_return.uv; diff --git a/tests/out/glsl/texture-arg.main.Fragment.glsl b/tests/out/glsl/texture-arg.main.Fragment.glsl index 1ff2a9022c..234043d95c 100644 --- a/tests/out/glsl/texture-arg.main.Fragment.glsl +++ b/tests/out/glsl/texture-arg.main.Fragment.glsl @@ -8,8 +8,8 @@ uniform highp sampler2D _group_0_binding_0_fs; layout(location = 0) out vec4 _fs2p_location0; vec4 test(highp sampler2D Passed_Texture) { - vec4 _e7 = texture(Passed_Texture, vec2(vec2(0.0, 0.0))); - return _e7; + vec4 _e5 = texture(Passed_Texture, vec2(vec2(0.0, 0.0))); + return _e5; } void main() { diff --git a/tests/out/hlsl/access.hlsl b/tests/out/hlsl/access.hlsl index 4402cfdf83..35a96e1187 100644 --- a/tests/out/hlsl/access.hlsl +++ b/tests/out/hlsl/access.hlsl @@ -138,38 +138,39 @@ Baz ConstructBaz(float3x2 arg0) { void test_matrix_within_struct_accesses() { - int idx = 1; + int idx = (int)0; Baz t = (Baz)0; - int _expr6 = idx; - idx = (_expr6 - 1); + idx = 1; + int _expr2 = idx; + idx = (_expr2 - 1); float3x2 unnamed = GetMatmOnBaz(baz); float2 unnamed_1 = GetMatmOnBaz(baz)[0]; - int _expr16 = idx; - float2 unnamed_2 = GetMatmOnBaz(baz)[_expr16]; + int _expr15 = idx; + float2 unnamed_2 = GetMatmOnBaz(baz)[_expr15]; float unnamed_3 = GetMatmOnBaz(baz)[0].y; - int _expr28 = idx; - float unnamed_4 = GetMatmOnBaz(baz)[0][_expr28]; - int _expr32 = idx; - float unnamed_5 = GetMatmOnBaz(baz)[_expr32].y; - int _expr38 = idx; - int _expr40 = idx; - float unnamed_6 = GetMatmOnBaz(baz)[_expr38][_expr40]; + int _expr29 = idx; + float unnamed_4 = GetMatmOnBaz(baz)[0][_expr29]; + int _expr34 = idx; + float unnamed_5 = GetMatmOnBaz(baz)[_expr34].y; + int _expr41 = idx; + int _expr43 = idx; + float unnamed_6 = GetMatmOnBaz(baz)[_expr41][_expr43]; t = ConstructBaz(float3x2((1.0).xx, (2.0).xx, (3.0).xx)); - int _expr52 = idx; - idx = (_expr52 + 1); + int _expr55 = idx; + idx = (_expr55 + 1); SetMatmOnBaz(t, float3x2((6.0).xx, (5.0).xx, (4.0).xx)); t.m_0 = (9.0).xx; - int _expr69 = idx; - SetMatVecmOnBaz(t, (90.0).xx, _expr69); + int _expr72 = idx; + SetMatVecmOnBaz(t, (90.0).xx, _expr72); t.m_0[1] = 10.0; - int _expr82 = idx; - t.m_0[_expr82] = 20.0; - int _expr86 = idx; - SetMatScalarmOnBaz(t, 30.0, _expr86, 1); - int _expr92 = idx; - int _expr94 = idx; - SetMatScalarmOnBaz(t, 40.0, _expr92, _expr94); + int _expr85 = idx; + t.m_0[_expr85] = 20.0; + int _expr89 = idx; + SetMatScalarmOnBaz(t, 30.0, _expr89, 1); + int _expr95 = idx; + int _expr97 = idx; + SetMatScalarmOnBaz(t, 40.0, _expr95, _expr97); return; } @@ -181,47 +182,48 @@ MatCx2InArray ConstructMatCx2InArray(float4x2 arg0[2]) { void test_matrix_within_array_within_struct_accesses() { - int idx_1 = 1; + int idx_1 = (int)0; MatCx2InArray t_1 = (MatCx2InArray)0; - int _expr7 = idx_1; - idx_1 = (_expr7 - 1); + idx_1 = 1; + int _expr2 = idx_1; + idx_1 = (_expr2 - 1); float4x2 unnamed_7[2] = ((float4x2[2])nested_mat_cx2_.am); float4x2 unnamed_8 = ((float4x2)nested_mat_cx2_.am[0]); float2 unnamed_9 = nested_mat_cx2_.am[0]._0; - int _expr25 = idx_1; - float2 unnamed_10 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr25); + int _expr24 = idx_1; + float2 unnamed_10 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr24); float unnamed_11 = nested_mat_cx2_.am[0]._0.y; - int _expr41 = idx_1; - float unnamed_12 = nested_mat_cx2_.am[0]._0[_expr41]; - int _expr47 = idx_1; - float unnamed_13 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr47).y; - int _expr55 = idx_1; - int _expr57 = idx_1; - float unnamed_14 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr55)[_expr57]; + int _expr42 = idx_1; + float unnamed_12 = nested_mat_cx2_.am[0]._0[_expr42]; + int _expr49 = idx_1; + float unnamed_13 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr49).y; + int _expr58 = idx_1; + int _expr60 = idx_1; + float unnamed_14 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr58)[_expr60]; t_1 = ConstructMatCx2InArray(Constructarray2_float4x2_(float4x2(float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0)), float4x2(float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0)))); - int _expr63 = idx_1; - idx_1 = (_expr63 + 1); + int _expr66 = idx_1; + idx_1 = (_expr66 + 1); t_1.am = (__mat4x2[2])Constructarray2_float4x2_(float4x2(float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0)), float4x2(float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0), float2(0.0, 0.0))); t_1.am[0] = (__mat4x2)float4x2((8.0).xx, (7.0).xx, (6.0).xx, (5.0).xx); t_1.am[0]._0 = (9.0).xx; - int _expr90 = idx_1; - __set_col_of_mat4x2(t_1.am[0], _expr90, (90.0).xx); + int _expr93 = idx_1; + __set_col_of_mat4x2(t_1.am[0], _expr93, (90.0).xx); t_1.am[0]._0.y = 10.0; - int _expr107 = idx_1; - t_1.am[0]._0[_expr107] = 20.0; - int _expr113 = idx_1; - __set_el_of_mat4x2(t_1.am[0], _expr113, 1, 30.0); - int _expr121 = idx_1; - int _expr123 = idx_1; - __set_el_of_mat4x2(t_1.am[0], _expr121, _expr123, 40.0); + int _expr110 = idx_1; + t_1.am[0]._0[_expr110] = 20.0; + int _expr116 = idx_1; + __set_el_of_mat4x2(t_1.am[0], _expr116, 1, 30.0); + int _expr124 = idx_1; + int _expr126 = idx_1; + __set_el_of_mat4x2(t_1.am[0], _expr124, _expr126, 40.0); return; } float read_from_private(inout float foo_1) { - float _expr6 = foo_1; - return _expr6; + float _expr1 = foo_1; + return _expr1; } float test_arr_as_arg(float a[5][10]) @@ -250,9 +252,10 @@ ret_Constructarray5_int_ Constructarray5_int_(int arg0, int arg1, int arg2, int float4 foo_vert(uint vi : SV_VertexID) : SV_Position { - float foo = 0.0; - int c[5] = {(int)0,(int)0,(int)0,(int)0,(int)0}; + float foo = (float)0; + int c2_[5] = {(int)0,(int)0,(int)0,(int)0,(int)0}; + foo = 0.0; float baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(); @@ -261,12 +264,12 @@ float4 foo_vert(uint vi : SV_VertexID) : SV_Position uint2 arr[2] = {asuint(bar.Load2(104+0)), asuint(bar.Load2(104+8))}; float b = asfloat(bar.Load(0+48+0)); int a_1 = asint(bar.Load(0+(((NagaBufferLengthRW(bar) - 120) / 8) - 2u)*8+120)); - int2 c_1 = asint(qux.Load2(0)); - const float _e32 = read_from_private(foo); - c = Constructarray5_int_(a_1, int(b), 3, 4, 5); - c[(vi + 1u)] = 42; - int value = c[vi]; - const float _e46 = test_arr_as_arg(Constructarray5_array10_float__(Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); + int2 c = asint(qux.Load2(0)); + const float _e34 = read_from_private(foo); + c2_ = Constructarray5_int_(a_1, int(b), 3, 4, 5); + c2_[(vi + 1u)] = 42; + int value = c2_[vi]; + const float _e48 = test_arr_as_arg(Constructarray5_array10_float__(Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), Constructarray10_float_(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); return float4(mul(float4((value).xxxx), _matrix), 2.0); } @@ -302,22 +305,22 @@ void atomics() int tmp = (int)0; int value_1 = asint(bar.Load(96)); - int _e10; bar.InterlockedAdd(96, 5, _e10); - tmp = _e10; - int _e13; bar.InterlockedAdd(96, -5, _e13); - tmp = _e13; - int _e16; bar.InterlockedAnd(96, 5, _e16); - tmp = _e16; + int _e7; bar.InterlockedAdd(96, 5, _e7); + tmp = _e7; + int _e11; bar.InterlockedAdd(96, -5, _e11); + tmp = _e11; + int _e15; bar.InterlockedAnd(96, 5, _e15); + tmp = _e15; int _e19; bar.InterlockedOr(96, 5, _e19); tmp = _e19; - int _e22; bar.InterlockedXor(96, 5, _e22); - tmp = _e22; - int _e25; bar.InterlockedMin(96, 5, _e25); - tmp = _e25; - int _e28; bar.InterlockedMax(96, 5, _e28); - tmp = _e28; - int _e31; bar.InterlockedExchange(96, 5, _e31); + int _e23; bar.InterlockedXor(96, 5, _e23); + tmp = _e23; + int _e27; bar.InterlockedMin(96, 5, _e27); + tmp = _e27; + int _e31; bar.InterlockedMax(96, 5, _e31); tmp = _e31; + int _e35; bar.InterlockedExchange(96, 5, _e35); + tmp = _e35; bar.Store(96, asuint(value_1)); return; } diff --git a/tests/out/hlsl/binding-arrays.hlsl b/tests/out/hlsl/binding-arrays.hlsl index f01d67329d..b596ae28f6 100644 --- a/tests/out/hlsl/binding-arrays.hlsl +++ b/tests/out/hlsl/binding-arrays.hlsl @@ -52,132 +52,134 @@ int NagaMSNumSamples2D(Texture2DMS tex) float4 main(FragmentInput_main fragmentinput_main) : SV_Target0 { FragmentIn fragment_in = { fragmentinput_main.index }; - int i1_ = 0; + int i1_ = (int)0; int2 i2_ = (int2)0; - float v1_ = 0.0; + float v1_ = (float)0; float4 v4_ = (float4)0; uint uniform_index = uni.index; uint non_uniform_index = fragment_in.index; + i1_ = 0; i2_ = (0).xx; + v1_ = 0.0; v4_ = (0.0).xxxx; float2 uv = (0.0).xx; int2 pix = (0).xx; - int2 _expr27 = i2_; - i2_ = (_expr27 + NagaDimensions2D(texture_array_unbounded[0])); - int2 _expr32 = i2_; - i2_ = (_expr32 + NagaDimensions2D(texture_array_unbounded[uniform_index])); - int2 _expr36 = i2_; - i2_ = (_expr36 + NagaDimensions2D(texture_array_unbounded[NonUniformResourceIndex(non_uniform_index)])); - float4 _expr40 = v4_; - float4 _expr45 = texture_array_bounded[0].Gather(samp[0], uv); - v4_ = (_expr40 + _expr45); - float4 _expr47 = v4_; - float4 _expr50 = texture_array_bounded[uniform_index].Gather(samp[uniform_index], uv); - v4_ = (_expr47 + _expr50); - float4 _expr52 = v4_; + int2 _expr23 = i2_; + i2_ = (_expr23 + NagaDimensions2D(texture_array_unbounded[0])); + int2 _expr28 = i2_; + i2_ = (_expr28 + NagaDimensions2D(texture_array_unbounded[uniform_index])); + int2 _expr33 = i2_; + i2_ = (_expr33 + NagaDimensions2D(texture_array_unbounded[NonUniformResourceIndex(non_uniform_index)])); + float4 _expr41 = texture_array_bounded[0].Gather(samp[0], uv); + float4 _expr42 = v4_; + v4_ = (_expr42 + _expr41); + float4 _expr48 = texture_array_bounded[uniform_index].Gather(samp[uniform_index], uv); + float4 _expr49 = v4_; + v4_ = (_expr49 + _expr48); float4 _expr55 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].Gather(samp[NonUniformResourceIndex(non_uniform_index)], uv); - v4_ = (_expr52 + _expr55); - float4 _expr57 = v4_; - float4 _expr63 = texture_array_depth[0].GatherCmp(samp_comp[0], uv, 0.0); - v4_ = (_expr57 + _expr63); - float4 _expr65 = v4_; - float4 _expr69 = texture_array_depth[uniform_index].GatherCmp(samp_comp[uniform_index], uv, 0.0); - v4_ = (_expr65 + _expr69); - float4 _expr71 = v4_; - float4 _expr75 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].GatherCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); - v4_ = (_expr71 + _expr75); - float4 _expr77 = v4_; - float4 _expr81 = texture_array_unbounded[0].Load(int3(pix, 0)); - v4_ = (_expr77 + _expr81); - float4 _expr83 = v4_; - float4 _expr86 = texture_array_unbounded[uniform_index].Load(int3(pix, 0)); - v4_ = (_expr83 + _expr86); - float4 _expr88 = v4_; - float4 _expr91 = texture_array_unbounded[NonUniformResourceIndex(non_uniform_index)].Load(int3(pix, 0)); - v4_ = (_expr88 + _expr91); - int _expr93 = i1_; - i1_ = (_expr93 + NagaNumLayers2DArray(texture_array_2darray[0])); - int _expr98 = i1_; - i1_ = (_expr98 + NagaNumLayers2DArray(texture_array_2darray[uniform_index])); - int _expr102 = i1_; - i1_ = (_expr102 + NagaNumLayers2DArray(texture_array_2darray[NonUniformResourceIndex(non_uniform_index)])); - int _expr106 = i1_; - i1_ = (_expr106 + NagaNumLevels2D(texture_array_bounded[0])); - int _expr111 = i1_; - i1_ = (_expr111 + NagaNumLevels2D(texture_array_bounded[uniform_index])); - int _expr115 = i1_; - i1_ = (_expr115 + NagaNumLevels2D(texture_array_bounded[NonUniformResourceIndex(non_uniform_index)])); - int _expr119 = i1_; - i1_ = (_expr119 + NagaMSNumSamples2D(texture_array_multisampled[0])); - int _expr124 = i1_; - i1_ = (_expr124 + NagaMSNumSamples2D(texture_array_multisampled[uniform_index])); + float4 _expr56 = v4_; + v4_ = (_expr56 + _expr55); + float4 _expr65 = texture_array_depth[0].GatherCmp(samp_comp[0], uv, 0.0); + float4 _expr66 = v4_; + v4_ = (_expr66 + _expr65); + float4 _expr73 = texture_array_depth[uniform_index].GatherCmp(samp_comp[uniform_index], uv, 0.0); + float4 _expr74 = v4_; + v4_ = (_expr74 + _expr73); + float4 _expr81 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].GatherCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr82 = v4_; + v4_ = (_expr82 + _expr81); + float4 _expr88 = texture_array_unbounded[0].Load(int3(pix, 0)); + float4 _expr89 = v4_; + v4_ = (_expr89 + _expr88); + float4 _expr94 = texture_array_unbounded[uniform_index].Load(int3(pix, 0)); + float4 _expr95 = v4_; + v4_ = (_expr95 + _expr94); + float4 _expr100 = texture_array_unbounded[NonUniformResourceIndex(non_uniform_index)].Load(int3(pix, 0)); + float4 _expr101 = v4_; + v4_ = (_expr101 + _expr100); + int _expr107 = i1_; + i1_ = (_expr107 + NagaNumLayers2DArray(texture_array_2darray[0])); + int _expr112 = i1_; + i1_ = (_expr112 + NagaNumLayers2DArray(texture_array_2darray[uniform_index])); + int _expr117 = i1_; + i1_ = (_expr117 + NagaNumLayers2DArray(texture_array_2darray[NonUniformResourceIndex(non_uniform_index)])); + int _expr123 = i1_; + i1_ = (_expr123 + NagaNumLevels2D(texture_array_bounded[0])); int _expr128 = i1_; - i1_ = (_expr128 + NagaMSNumSamples2D(texture_array_multisampled[NonUniformResourceIndex(non_uniform_index)])); - float4 _expr132 = v4_; - float4 _expr137 = texture_array_bounded[0].Sample(samp[0], uv); - v4_ = (_expr132 + _expr137); - float4 _expr139 = v4_; - float4 _expr142 = texture_array_bounded[uniform_index].Sample(samp[uniform_index], uv); - v4_ = (_expr139 + _expr142); - float4 _expr144 = v4_; - float4 _expr147 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].Sample(samp[NonUniformResourceIndex(non_uniform_index)], uv); - v4_ = (_expr144 + _expr147); - float4 _expr149 = v4_; - float4 _expr155 = texture_array_bounded[0].SampleBias(samp[0], uv, 0.0); - v4_ = (_expr149 + _expr155); - float4 _expr157 = v4_; - float4 _expr161 = texture_array_bounded[uniform_index].SampleBias(samp[uniform_index], uv, 0.0); - v4_ = (_expr157 + _expr161); - float4 _expr163 = v4_; - float4 _expr167 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleBias(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); - v4_ = (_expr163 + _expr167); - float _expr169 = v1_; - float _expr175 = texture_array_depth[0].SampleCmp(samp_comp[0], uv, 0.0); - v1_ = (_expr169 + _expr175); - float _expr177 = v1_; - float _expr181 = texture_array_depth[uniform_index].SampleCmp(samp_comp[uniform_index], uv, 0.0); - v1_ = (_expr177 + _expr181); - float _expr183 = v1_; - float _expr187 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); - v1_ = (_expr183 + _expr187); - float _expr189 = v1_; - float _expr195 = texture_array_depth[0].SampleCmpLevelZero(samp_comp[0], uv, 0.0); - v1_ = (_expr189 + _expr195); - float _expr197 = v1_; - float _expr201 = texture_array_depth[uniform_index].SampleCmpLevelZero(samp_comp[uniform_index], uv, 0.0); - v1_ = (_expr197 + _expr201); - float _expr203 = v1_; - float _expr207 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmpLevelZero(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); - v1_ = (_expr203 + _expr207); - float4 _expr209 = v4_; - float4 _expr214 = texture_array_bounded[0].SampleGrad(samp[0], uv, uv, uv); - v4_ = (_expr209 + _expr214); - float4 _expr216 = v4_; - float4 _expr219 = texture_array_bounded[uniform_index].SampleGrad(samp[uniform_index], uv, uv, uv); - v4_ = (_expr216 + _expr219); - float4 _expr221 = v4_; - float4 _expr224 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleGrad(samp[NonUniformResourceIndex(non_uniform_index)], uv, uv, uv); - v4_ = (_expr221 + _expr224); - float4 _expr226 = v4_; - float4 _expr232 = texture_array_bounded[0].SampleLevel(samp[0], uv, 0.0); - v4_ = (_expr226 + _expr232); - float4 _expr234 = v4_; - float4 _expr238 = texture_array_bounded[uniform_index].SampleLevel(samp[uniform_index], uv, 0.0); - v4_ = (_expr234 + _expr238); - float4 _expr240 = v4_; - float4 _expr244 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleLevel(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); - v4_ = (_expr240 + _expr244); - float4 _expr248 = v4_; - texture_array_storage[0][pix] = _expr248; - float4 _expr250 = v4_; - texture_array_storage[uniform_index][pix] = _expr250; - float4 _expr252 = v4_; - texture_array_storage[NonUniformResourceIndex(non_uniform_index)][pix] = _expr252; - int2 _expr253 = i2_; - int _expr254 = i1_; - float2 v2_ = float2((_expr253 + (_expr254).xx)); - float4 _expr258 = v4_; - float _expr265 = v1_; - return ((_expr258 + float4(v2_.x, v2_.y, v2_.x, v2_.y)) + (_expr265).xxxx); + i1_ = (_expr128 + NagaNumLevels2D(texture_array_bounded[uniform_index])); + int _expr133 = i1_; + i1_ = (_expr133 + NagaNumLevels2D(texture_array_bounded[NonUniformResourceIndex(non_uniform_index)])); + int _expr139 = i1_; + i1_ = (_expr139 + NagaMSNumSamples2D(texture_array_multisampled[0])); + int _expr144 = i1_; + i1_ = (_expr144 + NagaMSNumSamples2D(texture_array_multisampled[uniform_index])); + int _expr149 = i1_; + i1_ = (_expr149 + NagaMSNumSamples2D(texture_array_multisampled[NonUniformResourceIndex(non_uniform_index)])); + float4 _expr157 = texture_array_bounded[0].Sample(samp[0], uv); + float4 _expr158 = v4_; + v4_ = (_expr158 + _expr157); + float4 _expr164 = texture_array_bounded[uniform_index].Sample(samp[uniform_index], uv); + float4 _expr165 = v4_; + v4_ = (_expr165 + _expr164); + float4 _expr171 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].Sample(samp[NonUniformResourceIndex(non_uniform_index)], uv); + float4 _expr172 = v4_; + v4_ = (_expr172 + _expr171); + float4 _expr181 = texture_array_bounded[0].SampleBias(samp[0], uv, 0.0); + float4 _expr182 = v4_; + v4_ = (_expr182 + _expr181); + float4 _expr189 = texture_array_bounded[uniform_index].SampleBias(samp[uniform_index], uv, 0.0); + float4 _expr190 = v4_; + v4_ = (_expr190 + _expr189); + float4 _expr197 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleBias(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr198 = v4_; + v4_ = (_expr198 + _expr197); + float _expr207 = texture_array_depth[0].SampleCmp(samp_comp[0], uv, 0.0); + float _expr208 = v1_; + v1_ = (_expr208 + _expr207); + float _expr215 = texture_array_depth[uniform_index].SampleCmp(samp_comp[uniform_index], uv, 0.0); + float _expr216 = v1_; + v1_ = (_expr216 + _expr215); + float _expr223 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float _expr224 = v1_; + v1_ = (_expr224 + _expr223); + float _expr233 = texture_array_depth[0].SampleCmpLevelZero(samp_comp[0], uv, 0.0); + float _expr234 = v1_; + v1_ = (_expr234 + _expr233); + float _expr241 = texture_array_depth[uniform_index].SampleCmpLevelZero(samp_comp[uniform_index], uv, 0.0); + float _expr242 = v1_; + v1_ = (_expr242 + _expr241); + float _expr249 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmpLevelZero(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float _expr250 = v1_; + v1_ = (_expr250 + _expr249); + float4 _expr258 = texture_array_bounded[0].SampleGrad(samp[0], uv, uv, uv); + float4 _expr259 = v4_; + v4_ = (_expr259 + _expr258); + float4 _expr265 = texture_array_bounded[uniform_index].SampleGrad(samp[uniform_index], uv, uv, uv); + float4 _expr266 = v4_; + v4_ = (_expr266 + _expr265); + float4 _expr272 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleGrad(samp[NonUniformResourceIndex(non_uniform_index)], uv, uv, uv); + float4 _expr273 = v4_; + v4_ = (_expr273 + _expr272); + float4 _expr282 = texture_array_bounded[0].SampleLevel(samp[0], uv, 0.0); + float4 _expr283 = v4_; + v4_ = (_expr283 + _expr282); + float4 _expr290 = texture_array_bounded[uniform_index].SampleLevel(samp[uniform_index], uv, 0.0); + float4 _expr291 = v4_; + v4_ = (_expr291 + _expr290); + float4 _expr298 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleLevel(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr299 = v4_; + v4_ = (_expr299 + _expr298); + float4 _expr304 = v4_; + texture_array_storage[0][pix] = _expr304; + float4 _expr307 = v4_; + texture_array_storage[uniform_index][pix] = _expr307; + float4 _expr310 = v4_; + texture_array_storage[NonUniformResourceIndex(non_uniform_index)][pix] = _expr310; + int2 _expr311 = i2_; + int _expr312 = i1_; + float2 v2_ = float2((_expr311 + (_expr312).xx)); + float4 _expr316 = v4_; + float _expr323 = v1_; + return ((_expr316 + float4(v2_.x, v2_.y, v2_.x, v2_.y)) + (_expr323).xxxx); } diff --git a/tests/out/hlsl/boids.hlsl b/tests/out/hlsl/boids.hlsl index fb4640a766..d9f1340480 100644 --- a/tests/out/hlsl/boids.hlsl +++ b/tests/out/hlsl/boids.hlsl @@ -27,121 +27,124 @@ void main(uint3 global_invocation_id : SV_DispatchThreadID) float2 cMass = (float2)0; float2 cVel = (float2)0; float2 colVel = (float2)0; - int cMassCount = 0; - int cVelCount = 0; + int cMassCount = (int)0; + int cVelCount = (int)0; float2 pos = (float2)0; float2 vel = (float2)0; - uint i = 0u; + uint i = (uint)0; uint index = global_invocation_id.x; if ((index >= NUM_PARTICLES)) { return; } - float2 _expr10 = asfloat(particlesSrc.Load2(0+index*16+0)); - vPos = _expr10; - float2 _expr15 = asfloat(particlesSrc.Load2(8+index*16+0)); - vVel = _expr15; + float2 _expr8 = asfloat(particlesSrc.Load2(0+index*16+0)); + vPos = _expr8; + float2 _expr14 = asfloat(particlesSrc.Load2(8+index*16+0)); + vVel = _expr14; cMass = float2(0.0, 0.0); cVel = float2(0.0, 0.0); colVel = float2(0.0, 0.0); + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _expr86 = i; - i = (_expr86 + 1u); + uint _expr91 = i; + i = (_expr91 + 1u); } loop_init = false; - uint _expr37 = i; - if ((_expr37 >= NUM_PARTICLES)) { + uint _expr36 = i; + if ((_expr36 >= NUM_PARTICLES)) { break; } uint _expr39 = i; if ((_expr39 == index)) { continue; } - uint _expr42 = i; - float2 _expr45 = asfloat(particlesSrc.Load2(0+_expr42*16+0)); - pos = _expr45; - uint _expr47 = i; - float2 _expr50 = asfloat(particlesSrc.Load2(8+_expr47*16+0)); - vel = _expr50; - float2 _expr51 = pos; - float2 _expr52 = vPos; - float _expr55 = params.rule1Distance; - if ((distance(_expr51, _expr52) < _expr55)) { - float2 _expr57 = cMass; - float2 _expr58 = pos; - cMass = (_expr57 + _expr58); - int _expr60 = cMassCount; - cMassCount = (_expr60 + 1); + uint _expr43 = i; + float2 _expr46 = asfloat(particlesSrc.Load2(0+_expr43*16+0)); + pos = _expr46; + uint _expr49 = i; + float2 _expr52 = asfloat(particlesSrc.Load2(8+_expr49*16+0)); + vel = _expr52; + float2 _expr53 = pos; + float2 _expr54 = vPos; + float _expr58 = params.rule1Distance; + if ((distance(_expr53, _expr54) < _expr58)) { + float2 _expr60 = cMass; + float2 _expr61 = pos; + cMass = (_expr60 + _expr61); + int _expr63 = cMassCount; + cMassCount = (_expr63 + 1); } - float2 _expr63 = pos; - float2 _expr64 = vPos; - float _expr67 = params.rule2Distance; - if ((distance(_expr63, _expr64) < _expr67)) { - float2 _expr69 = colVel; - float2 _expr70 = pos; - float2 _expr71 = vPos; - colVel = (_expr69 - (_expr70 - _expr71)); + float2 _expr66 = pos; + float2 _expr67 = vPos; + float _expr71 = params.rule2Distance; + if ((distance(_expr66, _expr67) < _expr71)) { + float2 _expr73 = colVel; + float2 _expr74 = pos; + float2 _expr75 = vPos; + colVel = (_expr73 - (_expr74 - _expr75)); } - float2 _expr74 = pos; - float2 _expr75 = vPos; - float _expr78 = params.rule3Distance; - if ((distance(_expr74, _expr75) < _expr78)) { - float2 _expr80 = cVel; - float2 _expr81 = vel; - cVel = (_expr80 + _expr81); - int _expr83 = cVelCount; - cVelCount = (_expr83 + 1); + float2 _expr78 = pos; + float2 _expr79 = vPos; + float _expr83 = params.rule3Distance; + if ((distance(_expr78, _expr79) < _expr83)) { + float2 _expr85 = cVel; + float2 _expr86 = vel; + cVel = (_expr85 + _expr86); + int _expr88 = cVelCount; + cVelCount = (_expr88 + 1); } } - int _expr89 = cMassCount; - if ((_expr89 > 0)) { - float2 _expr92 = cMass; - int _expr93 = cMassCount; - float2 _expr97 = vPos; - cMass = ((_expr92 / (float(_expr93)).xx) - _expr97); + int _expr94 = cMassCount; + if ((_expr94 > 0)) { + float2 _expr97 = cMass; + int _expr98 = cMassCount; + float2 _expr102 = vPos; + cMass = ((_expr97 / (float(_expr98)).xx) - _expr102); } - int _expr99 = cVelCount; - if ((_expr99 > 0)) { - float2 _expr102 = cVel; - int _expr103 = cVelCount; - cVel = (_expr102 / (float(_expr103)).xx); + int _expr104 = cVelCount; + if ((_expr104 > 0)) { + float2 _expr107 = cVel; + int _expr108 = cVelCount; + cVel = (_expr107 / (float(_expr108)).xx); } - float2 _expr107 = vVel; - float2 _expr108 = cMass; - float _expr110 = params.rule1Scale; - float2 _expr113 = colVel; - float _expr115 = params.rule2Scale; - float2 _expr118 = cVel; - float _expr120 = params.rule3Scale; - vVel = (((_expr107 + (_expr108 * _expr110)) + (_expr113 * _expr115)) + (_expr118 * _expr120)); - float2 _expr123 = vVel; - float2 _expr125 = vVel; - vVel = (normalize(_expr123) * clamp(length(_expr125), 0.0, 0.10000000149011612)); - float2 _expr131 = vPos; - float2 _expr132 = vVel; - float _expr134 = params.deltaT; - vPos = (_expr131 + (_expr132 * _expr134)); - float _expr138 = vPos.x; - if ((_expr138 < -1.0)) { + float2 _expr112 = vVel; + float2 _expr113 = cMass; + float _expr116 = params.rule1Scale; + float2 _expr119 = colVel; + float _expr122 = params.rule2Scale; + float2 _expr125 = cVel; + float _expr128 = params.rule3Scale; + vVel = (((_expr112 + (_expr113 * _expr116)) + (_expr119 * _expr122)) + (_expr125 * _expr128)); + float2 _expr131 = vVel; + float2 _expr133 = vVel; + vVel = (normalize(_expr131) * clamp(length(_expr133), 0.0, 0.10000000149011612)); + float2 _expr139 = vPos; + float2 _expr140 = vVel; + float _expr143 = params.deltaT; + vPos = (_expr139 + (_expr140 * _expr143)); + float _expr147 = vPos.x; + if ((_expr147 < -1.0)) { vPos.x = 1.0; } - float _expr144 = vPos.x; - if ((_expr144 > 1.0)) { + float _expr153 = vPos.x; + if ((_expr153 > 1.0)) { vPos.x = -1.0; } - float _expr150 = vPos.y; - if ((_expr150 < -1.0)) { + float _expr159 = vPos.y; + if ((_expr159 < -1.0)) { vPos.y = 1.0; } - float _expr156 = vPos.y; - if ((_expr156 > 1.0)) { + float _expr165 = vPos.y; + if ((_expr165 > 1.0)) { vPos.y = -1.0; } - float2 _expr164 = vPos; - particlesDst.Store2(0+index*16+0, asuint(_expr164)); - float2 _expr168 = vVel; - particlesDst.Store2(8+index*16+0, asuint(_expr168)); + float2 _expr174 = vPos; + particlesDst.Store2(0+index*16+0, asuint(_expr174)); + float2 _expr179 = vVel; + particlesDst.Store2(8+index*16+0, asuint(_expr179)); return; } diff --git a/tests/out/hlsl/collatz.hlsl b/tests/out/hlsl/collatz.hlsl index d74efad893..aa04129651 100644 --- a/tests/out/hlsl/collatz.hlsl +++ b/tests/out/hlsl/collatz.hlsl @@ -4,35 +4,38 @@ RWByteAddressBuffer v_indices : register(u0); uint collatz_iterations(uint n_base) { uint n = (uint)0; - uint i = 0u; + uint i = (uint)0; n = n_base; + i = 0u; while(true) { - uint _expr5 = n; - if ((_expr5 > 1u)) { + uint _expr4 = n; + if ((_expr4 > 1u)) { } else { break; } - uint _expr8 = n; - if (((_expr8 % 2u) == 0u)) { - uint _expr13 = n; - n = (_expr13 / 2u); - } else { - uint _expr17 = n; - n = ((3u * _expr17) + 1u); + { + uint _expr7 = n; + if (((_expr7 % 2u) == 0u)) { + uint _expr12 = n; + n = (_expr12 / 2u); + } else { + uint _expr16 = n; + n = ((3u * _expr16) + 1u); + } + uint _expr20 = i; + i = (_expr20 + 1u); } - uint _expr21 = i; - i = (_expr21 + 1u); } - uint _expr24 = i; - return _expr24; + uint _expr23 = i; + return _expr23; } [numthreads(1, 1, 1)] void main(uint3 global_id : SV_DispatchThreadID) { - uint _expr8 = asuint(v_indices.Load(global_id.x*4+0)); - const uint _e9 = collatz_iterations(_expr8); - v_indices.Store(global_id.x*4+0, asuint(_e9)); + uint _expr9 = asuint(v_indices.Load(global_id.x*4+0)); + const uint _e10 = collatz_iterations(_expr9); + v_indices.Store(global_id.x*4+0, asuint(_e10)); return; } diff --git a/tests/out/hlsl/globals.hlsl b/tests/out/hlsl/globals.hlsl index def5c8dbb2..d941f8e096 100644 --- a/tests/out/hlsl/globals.hlsl +++ b/tests/out/hlsl/globals.hlsl @@ -1,4 +1,4 @@ -static const bool Foo_2 = true; +static const bool Foo_1 = true; typedef struct { float2 _0; float2 _1; float2 _2; } __mat3x2; float2 __get_col_of_mat3x2(__mat3x2 mat, uint idx) { @@ -51,7 +51,7 @@ void __set_el_of_mat4x2(__mat4x2 mat, uint idx, uint vec_idx, float value) { } } -struct Foo { +struct FooStruct { float3 v3_; float v1_; }; @@ -71,8 +71,8 @@ void test_msl_packed_vec3_as_arg(float3 arg) return; } -Foo ConstructFoo(float3 arg0, float arg1) { - Foo ret = (Foo)0; +FooStruct ConstructFooStruct(float3 arg0, float arg1) { + FooStruct ret = (FooStruct)0; ret.v3_ = arg0; ret.v1_ = arg1; return ret; @@ -80,14 +80,15 @@ Foo ConstructFoo(float3 arg0, float arg1) { void test_msl_packed_vec3_() { - int idx = 1; + int idx = (int)0; alignment.Store3(0, asuint((1.0).xxx)); + idx = 1; alignment.Store(0+0, asuint(1.0)); alignment.Store(0+0, asuint(2.0)); - int _expr23 = idx; - alignment.Store(_expr23*4+0, asuint(3.0)); - Foo data = ConstructFoo(asfloat(alignment.Load3(0)), asfloat(alignment.Load(12))); + int _expr17 = idx; + alignment.Store(_expr17*4+0, asuint(3.0)); + FooStruct data = ConstructFooStruct(asfloat(alignment.Load3(0)), asfloat(alignment.Load(12))); float3 unnamed = data.v3_; float2 unnamed_1 = data.v3_.zx; test_msl_packed_vec3_as_arg(data.v3_); @@ -107,26 +108,28 @@ uint NagaBufferLength(ByteAddressBuffer buffer) [numthreads(1, 1, 1)] void main() { - float Foo_1 = 1.0; - bool at = true; + float Foo = (float)0; + bool at = (bool)0; test_msl_packed_vec3_(); - float4x2 _expr16 = ((float4x2)global_nested_arrays_of_matrices_4x2_[0][0]); - float4 _expr23 = global_nested_arrays_of_matrices_2x4_[0][0][0]; - wg[7] = mul(_expr23, _expr16).x; - float3x2 _expr28 = ((float3x2)global_mat); - float3 _expr29 = global_vec; - wg[6] = mul(_expr29, _expr28).x; - float _expr37 = asfloat(dummy.Load(4+8)); - wg[5] = _expr37; + float4x2 _expr8 = ((float4x2)global_nested_arrays_of_matrices_4x2_[0][0]); + float4 _expr16 = global_nested_arrays_of_matrices_2x4_[0][0][0]; + wg[7] = mul(_expr16, _expr8).x; + float3x2 _expr23 = ((float3x2)global_mat); + float3 _expr25 = global_vec; + wg[6] = mul(_expr25, _expr23).x; + float _expr35 = asfloat(dummy.Load(4+8)); + wg[5] = _expr35; float _expr43 = float_vecs[0].w; wg[4] = _expr43; - float _expr47 = asfloat(alignment.Load(12)); - wg[3] = _expr47; - float _expr52 = asfloat(alignment.Load(0+0)); - wg[2] = _expr52; + float _expr49 = asfloat(alignment.Load(12)); + wg[3] = _expr49; + float _expr56 = asfloat(alignment.Load(0+0)); + wg[2] = _expr56; alignment.Store(12, asuint(4.0)); wg[1] = float(((NagaBufferLength(dummy) - 0) / 8)); at_1 = 2u; + Foo = 1.0; + at = true; return; } diff --git a/tests/out/hlsl/interface.hlsl b/tests/out/hlsl/interface.hlsl index c88d1ee774..99d5ecccbc 100644 --- a/tests/out/hlsl/interface.hlsl +++ b/tests/out/hlsl/interface.hlsl @@ -83,8 +83,9 @@ void compute(uint3 global_id : SV_DispatchThreadID, uint3 local_id : SV_GroupThr precise float4 vertex_two_structs(Input1_ in1_, Input2_ in2_) : SV_Position { - uint index = 2u; + uint index = (uint)0; - uint _expr9 = index; - return float4(float((_NagaConstants.base_vertex + in1_.index)), float((_NagaConstants.base_instance + in2_.index)), float(_expr9), 0.0); + index = 2u; + uint _expr8 = index; + return float4(float((_NagaConstants.base_vertex + in1_.index)), float((_NagaConstants.base_instance + in2_.index)), float(_expr8), 0.0); } diff --git a/tests/out/hlsl/operators.hlsl b/tests/out/hlsl/operators.hlsl index 743ca2813b..3136972d49 100644 --- a/tests/out/hlsl/operators.hlsl +++ b/tests/out/hlsl/operators.hlsl @@ -49,14 +49,14 @@ float2 splat_assignment() float2 a = (float2)0; a = (2.0).xx; - float2 _expr7 = a; - a = (_expr7 + (1.0).xx); - float2 _expr11 = a; - a = (_expr11 - (3.0).xx); + float2 _expr4 = a; + a = (_expr4 + (1.0).xx); + float2 _expr8 = a; + a = (_expr8 - (3.0).xx); + float2 _expr12 = a; + a = (_expr12 / (4.0).xx); float2 _expr15 = a; - a = (_expr15 / (4.0).xx); - float2 _expr19 = a; - return _expr19; + return _expr15; } float3 bool_cast(float3 x) @@ -89,8 +89,8 @@ float constructors() float2x3 unnamed_8 = float2x3(float2x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); uint2 unnamed_9 = asuint(uint2(0u, 0u)); float2x3 unnamed_10 = asfloat(float2x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float _expr75 = foo.a.x; - return _expr75; + float _expr71 = foo.a.x; + return _expr71; } void logical() @@ -248,39 +248,41 @@ void comparison() void assignment() { - int a_1 = 1; - int3 vec0_ = int3(0, 0, 0); + int a_1 = (int)0; + int3 vec0_ = (int3)0; + a_1 = 1; + int _expr3 = a_1; + a_1 = (_expr3 + 1); int _expr6 = a_1; - a_1 = (_expr6 + 1); + a_1 = (_expr6 - 1); + int _expr8 = a_1; int _expr9 = a_1; - a_1 = (_expr9 - 1); + a_1 = (_expr9 * _expr8); + int _expr11 = a_1; int _expr12 = a_1; - int _expr13 = a_1; - a_1 = (_expr12 * _expr13); + a_1 = (_expr12 / _expr11); int _expr15 = a_1; - int _expr16 = a_1; - a_1 = (_expr15 / _expr16); + a_1 = (_expr15 % 1); int _expr18 = a_1; - a_1 = (_expr18 % 1); + a_1 = (_expr18 & 0); int _expr21 = a_1; - a_1 = (_expr21 & 0); + a_1 = (_expr21 | 0); int _expr24 = a_1; - a_1 = (_expr24 | 0); + a_1 = (_expr24 ^ 0); int _expr27 = a_1; - a_1 = (_expr27 ^ 0); + a_1 = (_expr27 << 2u); int _expr30 = a_1; - a_1 = (_expr30 << 2u); - int _expr33 = a_1; - a_1 = (_expr33 >> 1u); - int _expr36 = a_1; - a_1 = (_expr36 + 1); - int _expr39 = a_1; - a_1 = (_expr39 - 1); - int _expr46 = vec0_.y; - vec0_.y = (_expr46 + 1); - int _expr51 = vec0_.y; - vec0_.y = (_expr51 - 1); + a_1 = (_expr30 >> 1u); + int _expr32 = a_1; + a_1 = (_expr32 + 1); + int _expr35 = a_1; + a_1 = (_expr35 - 1); + vec0_ = int3(0, 0, 0); + int _expr42 = vec0_.y; + vec0_.y = (_expr42 + 1); + int _expr47 = vec0_.y; + vec0_.y = (_expr47 - 1); return; } @@ -298,10 +300,10 @@ void negation_avoids_prefix_decrement() [numthreads(1, 1, 1)] void main() { - const float4 _e4 = builtins(); - const float4 _e5 = splat(); - const float3 _e7 = bool_cast(float4(1.0, 1.0, 1.0, 1.0).xyz); - const float _e8 = constructors(); + const float4 _e0 = builtins(); + const float4 _e1 = splat(); + const float3 _e4 = bool_cast(float4(1.0, 1.0, 1.0, 1.0).xyz); + const float _e5 = constructors(); logical(); arithmetic(); bit(); diff --git a/tests/out/hlsl/padding.hlsl b/tests/out/hlsl/padding.hlsl index f833b936cd..32e762cce8 100644 --- a/tests/out/hlsl/padding.hlsl +++ b/tests/out/hlsl/padding.hlsl @@ -36,8 +36,8 @@ cbuffer input3_ : register(b2) { Test3_ input3_; } float4 vertex() : SV_Position { - float _expr6 = input1_.b; - float _expr9 = input2_.b; + float _expr4 = input1_.b; + float _expr8 = input2_.b; float _expr12 = input3_.b; - return ((((1.0).xxxx * _expr6) * _expr9) * _expr12); + return ((((1.0).xxxx * _expr4) * _expr8) * _expr12); } diff --git a/tests/out/hlsl/shadow.hlsl b/tests/out/hlsl/shadow.hlsl index a3942386b5..5ea06f90c3 100644 --- a/tests/out/hlsl/shadow.hlsl +++ b/tests/out/hlsl/shadow.hlsl @@ -56,8 +56,8 @@ float fetch_shadow(uint light_id, float4 homogeneous_coords) float2 flip_correction = float2(0.5, -0.5); float proj_correction = (1.0 / homogeneous_coords.w); float2 light_local = (((homogeneous_coords.xy * flip_correction) * proj_correction) + float2(0.5, 0.5)); - float _expr28 = t_shadow.SampleCmpLevelZero(sampler_shadow, float3(light_local, int(light_id)), (homogeneous_coords.z * proj_correction)); - return _expr28; + float _expr24 = t_shadow.SampleCmpLevelZero(sampler_shadow, float3(light_local, int(light_id)), (homogeneous_coords.z * proj_correction)); + return _expr24; } VertexOutput_vs_main vs_main(int4 position : LOC0, int4 normal : LOC1) @@ -69,10 +69,10 @@ VertexOutput_vs_main vs_main(int4 position : LOC0, int4 normal : LOC1) float4 world_pos = mul(float4(position), _expr7); out_.world_normal = mul(float3(normal.xyz), float3x3(w[0].xyz, w[1].xyz, w[2].xyz)); out_.world_position = world_pos; - float4x4 _expr25 = u_globals.view_proj; - out_.proj_position = mul(world_pos, _expr25); - VertexOutput _expr27 = out_; - const VertexOutput vertexoutput = _expr27; + float4x4 _expr26 = u_globals.view_proj; + out_.proj_position = mul(world_pos, _expr26); + VertexOutput _expr28 = out_; + const VertexOutput vertexoutput = _expr28; const VertexOutput_vs_main vertexoutput_1 = { vertexoutput.world_normal, vertexoutput.world_position, vertexoutput.proj_position }; return vertexoutput_1; } @@ -88,67 +88,75 @@ Light ConstructLight(float4x4 arg0, float4 arg1, float4 arg2) { float4 fs_main(FragmentInput_fs_main fragmentinput_fs_main) : SV_Target0 { VertexOutput in_ = { fragmentinput_fs_main.proj_position_1, fragmentinput_fs_main.world_normal_1, fragmentinput_fs_main.world_position_1 }; - float3 color = float3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); - uint i = 0u; + float3 color = (float3)0; + uint i = (uint)0; float3 normal_1 = normalize(in_.world_normal); + color = float3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _expr20 = i; - i = (_expr20 + 1u); + uint _expr39 = i; + i = (_expr39 + 1u); } loop_init = false; - uint _expr14 = i; - uint _expr17 = u_globals.num_lights.x; - if ((_expr14 < min(_expr17, c_max_lights))) { + uint _expr7 = i; + uint _expr11 = u_globals.num_lights.x; + if ((_expr7 < min(_expr11, c_max_lights))) { } else { break; } - uint _expr23 = i; - Light light = ConstructLight(float4x4(asfloat(s_lights.Load4(_expr23*96+0+0)), asfloat(s_lights.Load4(_expr23*96+0+16)), asfloat(s_lights.Load4(_expr23*96+0+32)), asfloat(s_lights.Load4(_expr23*96+0+48))), asfloat(s_lights.Load4(_expr23*96+64)), asfloat(s_lights.Load4(_expr23*96+80))); - uint _expr26 = i; - const float _e30 = fetch_shadow(_expr26, mul(in_.world_position, light.proj)); - float3 light_dir = normalize((light.pos.xyz - in_.world_position.xyz)); - float diffuse = max(0.0, dot(normal_1, light_dir)); - float3 _expr40 = color; - color = (_expr40 + ((_e30 * diffuse) * light.color.xyz)); + { + uint _expr16 = i; + Light light = ConstructLight(float4x4(asfloat(s_lights.Load4(_expr16*96+0+0)), asfloat(s_lights.Load4(_expr16*96+0+16)), asfloat(s_lights.Load4(_expr16*96+0+32)), asfloat(s_lights.Load4(_expr16*96+0+48))), asfloat(s_lights.Load4(_expr16*96+64)), asfloat(s_lights.Load4(_expr16*96+80))); + uint _expr19 = i; + const float _e23 = fetch_shadow(_expr19, mul(in_.world_position, light.proj)); + float3 light_dir = normalize((light.pos.xyz - in_.world_position.xyz)); + float diffuse = max(0.0, dot(normal_1, light_dir)); + float3 _expr37 = color; + color = (_expr37 + ((_e23 * diffuse) * light.color.xyz)); + } } - float3 _expr46 = color; - float4 _expr50 = u_entity.color; - return (float4(_expr46, 1.0) * _expr50); + float3 _expr42 = color; + float4 _expr47 = u_entity.color; + return (float4(_expr42, 1.0) * _expr47); } float4 fs_main_without_storage(FragmentInput_fs_main_without_storage fragmentinput_fs_main_without_storage) : SV_Target0 { VertexOutput in_1 = { fragmentinput_fs_main_without_storage.proj_position_2, fragmentinput_fs_main_without_storage.world_normal_2, fragmentinput_fs_main_without_storage.world_position_2 }; - float3 color_1 = float3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); - uint i_1 = 0u; + float3 color_1 = (float3)0; + uint i_1 = (uint)0; float3 normal_2 = normalize(in_1.world_normal); + color_1 = float3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i_1 = 0u; bool loop_init_1 = true; while(true) { if (!loop_init_1) { - uint _expr20 = i_1; - i_1 = (_expr20 + 1u); + uint _expr39 = i_1; + i_1 = (_expr39 + 1u); } loop_init_1 = false; - uint _expr14 = i_1; - uint _expr17 = u_globals.num_lights.x; - if ((_expr14 < min(_expr17, c_max_lights))) { + uint _expr7 = i_1; + uint _expr11 = u_globals.num_lights.x; + if ((_expr7 < min(_expr11, c_max_lights))) { } else { break; } - uint _expr23 = i_1; - Light light_1 = u_lights[_expr23]; - uint _expr26 = i_1; - const float _e30 = fetch_shadow(_expr26, mul(in_1.world_position, light_1.proj)); - float3 light_dir_1 = normalize((light_1.pos.xyz - in_1.world_position.xyz)); - float diffuse_1 = max(0.0, dot(normal_2, light_dir_1)); - float3 _expr40 = color_1; - color_1 = (_expr40 + ((_e30 * diffuse_1) * light_1.color.xyz)); + { + uint _expr16 = i_1; + Light light_1 = u_lights[_expr16]; + uint _expr19 = i_1; + const float _e23 = fetch_shadow(_expr19, mul(in_1.world_position, light_1.proj)); + float3 light_dir_1 = normalize((light_1.pos.xyz - in_1.world_position.xyz)); + float diffuse_1 = max(0.0, dot(normal_2, light_dir_1)); + float3 _expr37 = color_1; + color_1 = (_expr37 + ((_e23 * diffuse_1) * light_1.color.xyz)); + } } - float3 _expr46 = color_1; - float4 _expr50 = u_entity.color; - return (float4(_expr46, 1.0) * _expr50); + float3 _expr42 = color_1; + float4 _expr47 = u_entity.color; + return (float4(_expr42, 1.0) * _expr47); } diff --git a/tests/out/hlsl/skybox.hlsl b/tests/out/hlsl/skybox.hlsl index 7d5714a22d..7a6a36b87f 100644 --- a/tests/out/hlsl/skybox.hlsl +++ b/tests/out/hlsl/skybox.hlsl @@ -43,15 +43,15 @@ VertexOutput_vs_main vs_main(uint vertex_index : SV_VertexID) tmp1_ = (int((_NagaConstants.base_vertex + vertex_index)) / 2); tmp2_ = (int((_NagaConstants.base_vertex + vertex_index)) & 1); - int _expr10 = tmp1_; - int _expr16 = tmp2_; - float4 pos = float4(((float(_expr10) * 4.0) - 1.0), ((float(_expr16) * 4.0) - 1.0), 0.0, 1.0); + int _expr9 = tmp1_; + int _expr15 = tmp2_; + float4 pos = float4(((float(_expr9) * 4.0) - 1.0), ((float(_expr15) * 4.0) - 1.0), 0.0, 1.0); float4 _expr27 = r_data.view[0]; - float4 _expr31 = r_data.view[1]; - float4 _expr35 = r_data.view[2]; - float3x3 inv_model_view = transpose(float3x3(_expr27.xyz, _expr31.xyz, _expr35.xyz)); - float4x4 _expr40 = r_data.proj_inv; - float4 unprojected = mul(pos, _expr40); + float4 _expr32 = r_data.view[1]; + float4 _expr37 = r_data.view[2]; + float3x3 inv_model_view = transpose(float3x3(_expr27.xyz, _expr32.xyz, _expr37.xyz)); + float4x4 _expr43 = r_data.proj_inv; + float4 unprojected = mul(pos, _expr43); const VertexOutput vertexoutput = ConstructVertexOutput(pos, mul(unprojected.xyz, inv_model_view)); const VertexOutput_vs_main vertexoutput_1 = { vertexoutput.uv, vertexoutput.position }; return vertexoutput_1; @@ -60,6 +60,6 @@ VertexOutput_vs_main vs_main(uint vertex_index : SV_VertexID) float4 fs_main(FragmentInput_fs_main fragmentinput_fs_main) : SV_Target0 { VertexOutput in_ = { fragmentinput_fs_main.position_1, fragmentinput_fs_main.uv_1 }; - float4 _expr5 = r_texture.Sample(r_sampler, in_.uv); - return _expr5; + float4 _expr4 = r_texture.Sample(r_sampler, in_.uv); + return _expr4; } diff --git a/tests/out/hlsl/texture-arg.hlsl b/tests/out/hlsl/texture-arg.hlsl index 32f950dfff..dd0ca1096c 100644 --- a/tests/out/hlsl/texture-arg.hlsl +++ b/tests/out/hlsl/texture-arg.hlsl @@ -4,8 +4,8 @@ SamplerState Sampler : register(s1); float4 test(Texture2D Passed_Texture, SamplerState Passed_Sampler) { - float4 _expr7 = Passed_Texture.Sample(Passed_Sampler, float2(0.0, 0.0)); - return _expr7; + float4 _expr5 = Passed_Texture.Sample(Passed_Sampler, float2(0.0, 0.0)); + return _expr5; } float4 main() : SV_Target0 diff --git a/tests/out/ir/collatz.ron b/tests/out/ir/collatz.ron index 2f3d06d137..00cab8e885 100644 --- a/tests/out/ir/collatz.ron +++ b/tests/out/ir/collatz.ron @@ -111,164 +111,171 @@ ( name: Some("i"), ty: 1, - init: Some(1), + init: None, ), ], expressions: [ - GlobalVariable(1), FunctionArgument(0), LocalVariable(1), Constant(1), LocalVariable(2), Load( - pointer: 3, + pointer: 2, ), Constant(2), Binary( op: Greater, - left: 6, - right: 7, + left: 5, + right: 6, ), Load( - pointer: 3, + pointer: 2, ), Constant(3), Binary( op: Modulo, - left: 9, - right: 10, + left: 8, + right: 9, ), Constant(1), Binary( op: Equal, - left: 11, - right: 12, + left: 10, + right: 11, ), Load( - pointer: 3, + pointer: 2, ), Constant(3), Binary( op: Divide, - left: 14, - right: 15, + left: 13, + right: 14, ), Constant(4), Load( - pointer: 3, + pointer: 2, ), Binary( op: Multiply, - left: 17, - right: 18, + left: 16, + right: 17, ), Constant(2), Binary( op: Add, - left: 19, - right: 20, + left: 18, + right: 19, ), Load( - pointer: 5, + pointer: 4, ), Constant(2), Binary( op: Add, - left: 22, - right: 23, + left: 21, + right: 22, ), Load( - pointer: 5, + pointer: 4, ), ], - named_expressions: {}, + named_expressions: { + 1: "n_base", + }, body: [ Store( - pointer: 3, - value: 2, + pointer: 2, + value: 1, + ), + Store( + pointer: 4, + value: 3, ), Loop( body: [ Emit(( - start: 5, - end: 6, + start: 4, + end: 5, )), Emit(( - start: 7, - end: 8, + start: 6, + end: 7, )), If( - condition: 8, + condition: 7, accept: [], reject: [ Break, ], ), - Emit(( - start: 8, - end: 9, - )), - Emit(( - start: 10, - end: 11, - )), - Emit(( - start: 12, - end: 13, - )), - If( - condition: 13, - accept: [ - Emit(( - start: 13, - end: 14, - )), - Emit(( - start: 15, - end: 16, - )), - Store( - pointer: 3, - value: 16, - ), - ], - reject: [ - Emit(( - start: 17, - end: 19, - )), - Emit(( - start: 20, - end: 21, - )), - Store( - pointer: 3, - value: 21, - ), - ], - ), - Emit(( - start: 21, - end: 22, - )), - Emit(( - start: 23, - end: 24, - )), - Store( - pointer: 5, - value: 24, - ), + Block([ + Emit(( + start: 7, + end: 8, + )), + Emit(( + start: 9, + end: 10, + )), + Emit(( + start: 11, + end: 12, + )), + If( + condition: 12, + accept: [ + Emit(( + start: 12, + end: 13, + )), + Emit(( + start: 14, + end: 15, + )), + Store( + pointer: 2, + value: 15, + ), + ], + reject: [ + Emit(( + start: 16, + end: 18, + )), + Emit(( + start: 19, + end: 20, + )), + Store( + pointer: 2, + value: 20, + ), + ], + ), + Emit(( + start: 20, + end: 21, + )), + Emit(( + start: 22, + end: 23, + )), + Store( + pointer: 4, + value: 23, + ), + ]), ], continuing: [], break_if: None, ), Emit(( - start: 24, - end: 25, + start: 23, + end: 24, )), Return( - value: Some(25), + value: Some(24), ), ], ), @@ -291,53 +298,60 @@ result: None, local_variables: [], expressions: [ - GlobalVariable(1), FunctionArgument(0), + GlobalVariable(1), AccessIndex( - base: 1, + base: 2, index: 0, ), AccessIndex( - base: 2, + base: 1, index: 0, ), Access( base: 3, index: 4, ), + GlobalVariable(1), + AccessIndex( + base: 6, + index: 0, + ), AccessIndex( base: 1, index: 0, ), - AccessIndex( - base: 2, - index: 0, - ), Access( - base: 6, - index: 7, + base: 7, + index: 8, ), Load( - pointer: 8, + pointer: 9, ), CallResult(1), ], - named_expressions: {}, + named_expressions: { + 1: "global_id", + }, body: [ Emit(( start: 2, - end: 9, + end: 5, + )), + Emit(( + start: 6, + end: 10, )), Call( function: 1, arguments: [ - 9, + 10, ], - result: Some(10), + result: Some(11), ), Store( pointer: 5, - value: 10, + value: 11, ), Return( value: None, diff --git a/tests/out/msl/access.msl b/tests/out/msl/access.msl index 19e4ab21d7..245f8a2beb 100644 --- a/tests/out/msl/access.msl +++ b/tests/out/msl/access.msl @@ -35,11 +35,11 @@ struct Bar { struct Baz { metal::float3x2 m; }; -struct type_13 { +struct type_14 { metal::float4x2 inner[2]; }; struct MatCx2InArray { - type_13 am; + type_14 am; }; struct type_17 { float inner[10]; @@ -52,9 +52,9 @@ struct type_21 { }; constant metal::uint3 const_type_1_ = {0u, 0u, 0u}; constant GlobalConst const_GlobalConst = {0u, {}, const_type_1_, 0}; -constant metal::float2 const_type_14_ = {0.0, 0.0}; -constant metal::float4x2 const_type_12_ = {const_type_14_, const_type_14_, const_type_14_, const_type_14_}; -constant type_13 const_type_13_ = {const_type_12_, const_type_12_}; +constant metal::float2 const_type_12_ = {0.0, 0.0}; +constant metal::float4x2 const_type_13_ = {const_type_12_, const_type_12_, const_type_12_, const_type_12_}; +constant type_14 const_type_14_ = {const_type_13_, const_type_13_}; constant type_17 const_type_17_ = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; constant type_18 const_type_18_ = {const_type_17_, const_type_17_, const_type_17_, const_type_17_, const_type_17_}; constant metal::int2 const_type_11_ = {0, 0}; @@ -62,84 +62,86 @@ constant metal::int2 const_type_11_ = {0, 0}; void test_matrix_within_struct_accesses( constant Baz& baz ) { - int idx = 1; + int idx = {}; Baz t = {}; - int _e6 = idx; - idx = _e6 - 1; + idx = 1; + int _e2 = idx; + idx = _e2 - 1; metal::float3x2 unnamed = baz.m; metal::float2 unnamed_1 = baz.m[0]; - int _e16 = idx; - metal::float2 unnamed_2 = baz.m[_e16]; + int _e15 = idx; + metal::float2 unnamed_2 = baz.m[_e15]; float unnamed_3 = baz.m[0].y; - int _e28 = idx; - float unnamed_4 = baz.m[0][_e28]; - int _e32 = idx; - float unnamed_5 = baz.m[_e32].y; - int _e38 = idx; - int _e40 = idx; - float unnamed_6 = baz.m[_e38][_e40]; + int _e29 = idx; + float unnamed_4 = baz.m[0][_e29]; + int _e34 = idx; + float unnamed_5 = baz.m[_e34].y; + int _e41 = idx; + int _e43 = idx; + float unnamed_6 = baz.m[_e41][_e43]; t = Baz {metal::float3x2(metal::float2(1.0), metal::float2(2.0), metal::float2(3.0))}; - int _e52 = idx; - idx = _e52 + 1; + int _e55 = idx; + idx = _e55 + 1; t.m = metal::float3x2(metal::float2(6.0), metal::float2(5.0), metal::float2(4.0)); t.m[0] = metal::float2(9.0); - int _e69 = idx; - t.m[_e69] = metal::float2(90.0); + int _e72 = idx; + t.m[_e72] = metal::float2(90.0); t.m[0].y = 10.0; - int _e82 = idx; - t.m[0][_e82] = 20.0; - int _e86 = idx; - t.m[_e86].y = 30.0; - int _e92 = idx; - int _e94 = idx; - t.m[_e92][_e94] = 40.0; + int _e85 = idx; + t.m[0][_e85] = 20.0; + int _e89 = idx; + t.m[_e89].y = 30.0; + int _e95 = idx; + int _e97 = idx; + t.m[_e95][_e97] = 40.0; return; } void test_matrix_within_array_within_struct_accesses( constant MatCx2InArray& nested_mat_cx2_ ) { - int idx_1 = 1; + int idx_1 = {}; MatCx2InArray t_1 = {}; - int _e7 = idx_1; - idx_1 = _e7 - 1; - type_13 unnamed_7 = nested_mat_cx2_.am; + idx_1 = 1; + int _e2 = idx_1; + idx_1 = _e2 - 1; + type_14 unnamed_7 = nested_mat_cx2_.am; metal::float4x2 unnamed_8 = nested_mat_cx2_.am.inner[0]; metal::float2 unnamed_9 = nested_mat_cx2_.am.inner[0][0]; - int _e25 = idx_1; - metal::float2 unnamed_10 = nested_mat_cx2_.am.inner[0][_e25]; + int _e24 = idx_1; + metal::float2 unnamed_10 = nested_mat_cx2_.am.inner[0][_e24]; float unnamed_11 = nested_mat_cx2_.am.inner[0][0].y; - int _e41 = idx_1; - float unnamed_12 = nested_mat_cx2_.am.inner[0][0][_e41]; - int _e47 = idx_1; - float unnamed_13 = nested_mat_cx2_.am.inner[0][_e47].y; - int _e55 = idx_1; - int _e57 = idx_1; - float unnamed_14 = nested_mat_cx2_.am.inner[0][_e55][_e57]; - t_1 = MatCx2InArray {const_type_13_}; - int _e63 = idx_1; - idx_1 = _e63 + 1; - for(int _i=0; _i<2; ++_i) t_1.am.inner[_i] = const_type_13_.inner[_i]; + int _e42 = idx_1; + float unnamed_12 = nested_mat_cx2_.am.inner[0][0][_e42]; + int _e49 = idx_1; + float unnamed_13 = nested_mat_cx2_.am.inner[0][_e49].y; + int _e58 = idx_1; + int _e60 = idx_1; + float unnamed_14 = nested_mat_cx2_.am.inner[0][_e58][_e60]; + t_1 = MatCx2InArray {const_type_14_}; + int _e66 = idx_1; + idx_1 = _e66 + 1; + for(int _i=0; _i<2; ++_i) t_1.am.inner[_i] = const_type_14_.inner[_i]; t_1.am.inner[0] = metal::float4x2(metal::float2(8.0), metal::float2(7.0), metal::float2(6.0), metal::float2(5.0)); t_1.am.inner[0][0] = metal::float2(9.0); - int _e90 = idx_1; - t_1.am.inner[0][_e90] = metal::float2(90.0); + int _e93 = idx_1; + t_1.am.inner[0][_e93] = metal::float2(90.0); t_1.am.inner[0][0].y = 10.0; - int _e107 = idx_1; - t_1.am.inner[0][0][_e107] = 20.0; - int _e113 = idx_1; - t_1.am.inner[0][_e113].y = 30.0; - int _e121 = idx_1; - int _e123 = idx_1; - t_1.am.inner[0][_e121][_e123] = 40.0; + int _e110 = idx_1; + t_1.am.inner[0][0][_e110] = 20.0; + int _e116 = idx_1; + t_1.am.inner[0][_e116].y = 30.0; + int _e124 = idx_1; + int _e126 = idx_1; + t_1.am.inner[0][_e124][_e126] = 40.0; return; } float read_from_private( thread float& foo_1 ) { - float _e6 = foo_1; - return _e6; + float _e1 = foo_1; + return _e1; } float test_arr_as_arg( @@ -168,8 +170,9 @@ vertex foo_vertOutput foo_vert( , constant MatCx2InArray& nested_mat_cx2_ [[buffer(3)]] , constant _mslBufferSizes& _buffer_sizes [[buffer(24)]] ) { - float foo = 0.0; - type_21 c = {}; + float foo = {}; + type_21 c2_ = {}; + foo = 0.0; float baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(baz); @@ -178,12 +181,12 @@ vertex foo_vertOutput foo_vert( type_8 arr = bar.arr; float b = bar._matrix[3].x; int a_1 = bar.data[(1 + (_buffer_sizes.size1 - 120 - 8) / 8) - 2u].value; - metal::int2 c_1 = qux; - float _e32 = read_from_private(foo); - for(int _i=0; _i<5; ++_i) c.inner[_i] = type_21 {a_1, static_cast(b), 3, 4, 5}.inner[_i]; - c.inner[vi + 1u] = 42; - int value = c.inner[vi]; - float _e46 = test_arr_as_arg(const_type_18_); + metal::int2 c = qux; + float _e34 = read_from_private(foo); + for(int _i=0; _i<5; ++_i) c2_.inner[_i] = type_21 {a_1, static_cast(b), 3, 4, 5}.inner[_i]; + c2_.inner[vi + 1u] = 42; + int value = c2_.inner[vi]; + float _e48 = test_arr_as_arg(const_type_18_); return foo_vertOutput { metal::float4(_matrix * static_cast(metal::int4(value)), 2.0) }; } @@ -211,22 +214,22 @@ kernel void atomics( ) { int tmp = {}; int value_1 = metal::atomic_load_explicit(&bar.atom, metal::memory_order_relaxed); - int _e10 = metal::atomic_fetch_add_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e10; - int _e13 = metal::atomic_fetch_sub_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e13; - int _e16 = metal::atomic_fetch_and_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e16; + int _e7 = metal::atomic_fetch_add_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e7; + int _e11 = metal::atomic_fetch_sub_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e11; + int _e15 = metal::atomic_fetch_and_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e15; int _e19 = metal::atomic_fetch_or_explicit(&bar.atom, 5, metal::memory_order_relaxed); tmp = _e19; - int _e22 = metal::atomic_fetch_xor_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e22; - int _e25 = metal::atomic_fetch_min_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e25; - int _e28 = metal::atomic_fetch_max_explicit(&bar.atom, 5, metal::memory_order_relaxed); - tmp = _e28; - int _e31 = metal::atomic_exchange_explicit(&bar.atom, 5, metal::memory_order_relaxed); + int _e23 = metal::atomic_fetch_xor_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e23; + int _e27 = metal::atomic_fetch_min_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e27; + int _e31 = metal::atomic_fetch_max_explicit(&bar.atom, 5, metal::memory_order_relaxed); tmp = _e31; + int _e35 = metal::atomic_exchange_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e35; metal::atomic_store_explicit(&bar.atom, value_1, metal::memory_order_relaxed); return; } diff --git a/tests/out/msl/binding-arrays.msl b/tests/out/msl/binding-arrays.msl index ba3c3c8b06..d54fc99821 100644 --- a/tests/out/msl/binding-arrays.msl +++ b/tests/out/msl/binding-arrays.msl @@ -36,137 +36,139 @@ fragment main_Output main_( , constant UniformIndex& uni [[user(fake0)]] ) { const FragmentIn fragment_in = { varyings.index }; - int i1_ = 0; + int i1_ = {}; metal::int2 i2_ = {}; - float v1_ = 0.0; + float v1_ = {}; metal::float4 v4_ = {}; uint uniform_index = uni.index; uint non_uniform_index = fragment_in.index; + i1_ = 0; i2_ = metal::int2(0); + v1_ = 0.0; v4_ = metal::float4(0.0); metal::float2 uv = metal::float2(0.0); metal::int2 pix = metal::int2(0); - metal::int2 _e27 = i2_; - i2_ = _e27 + metal::int2(texture_array_unbounded[0].get_width(), texture_array_unbounded[0].get_height()); - metal::int2 _e32 = i2_; - i2_ = _e32 + metal::int2(texture_array_unbounded[uniform_index].get_width(), texture_array_unbounded[uniform_index].get_height()); - metal::int2 _e36 = i2_; - i2_ = _e36 + metal::int2(texture_array_unbounded[non_uniform_index].get_width(), texture_array_unbounded[non_uniform_index].get_height()); - metal::float4 _e40 = v4_; - metal::float4 _e45 = texture_array_bounded[0].gather(samp[0], uv); - v4_ = _e40 + _e45; - metal::float4 _e47 = v4_; - metal::float4 _e50 = texture_array_bounded[uniform_index].gather(samp[uniform_index], uv); - v4_ = _e47 + _e50; - metal::float4 _e52 = v4_; + metal::int2 _e23 = i2_; + i2_ = _e23 + metal::int2(texture_array_unbounded[0].get_width(), texture_array_unbounded[0].get_height()); + metal::int2 _e28 = i2_; + i2_ = _e28 + metal::int2(texture_array_unbounded[uniform_index].get_width(), texture_array_unbounded[uniform_index].get_height()); + metal::int2 _e33 = i2_; + i2_ = _e33 + metal::int2(texture_array_unbounded[non_uniform_index].get_width(), texture_array_unbounded[non_uniform_index].get_height()); + metal::float4 _e41 = texture_array_bounded[0].gather(samp[0], uv); + metal::float4 _e42 = v4_; + v4_ = _e42 + _e41; + metal::float4 _e48 = texture_array_bounded[uniform_index].gather(samp[uniform_index], uv); + metal::float4 _e49 = v4_; + v4_ = _e49 + _e48; metal::float4 _e55 = texture_array_bounded[non_uniform_index].gather(samp[non_uniform_index], uv); - v4_ = _e52 + _e55; - metal::float4 _e57 = v4_; - metal::float4 _e63 = texture_array_depth[0].gather_compare(samp_comp[0], uv, 0.0); - v4_ = _e57 + _e63; - metal::float4 _e65 = v4_; - metal::float4 _e69 = texture_array_depth[uniform_index].gather_compare(samp_comp[uniform_index], uv, 0.0); - v4_ = _e65 + _e69; - metal::float4 _e71 = v4_; - metal::float4 _e75 = texture_array_depth[non_uniform_index].gather_compare(samp_comp[non_uniform_index], uv, 0.0); - v4_ = _e71 + _e75; - metal::float4 _e77 = v4_; - metal::float4 _e81 = (uint(0) < texture_array_unbounded[0].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[0].get_width(0), texture_array_unbounded[0].get_height(0))) ? texture_array_unbounded[0].read(metal::uint2(pix), 0): DefaultConstructible()); - v4_ = _e77 + _e81; - metal::float4 _e83 = v4_; - metal::float4 _e86 = (uint(0) < texture_array_unbounded[uniform_index].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[uniform_index].get_width(0), texture_array_unbounded[uniform_index].get_height(0))) ? texture_array_unbounded[uniform_index].read(metal::uint2(pix), 0): DefaultConstructible()); - v4_ = _e83 + _e86; - metal::float4 _e88 = v4_; - metal::float4 _e91 = (uint(0) < texture_array_unbounded[non_uniform_index].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[non_uniform_index].get_width(0), texture_array_unbounded[non_uniform_index].get_height(0))) ? texture_array_unbounded[non_uniform_index].read(metal::uint2(pix), 0): DefaultConstructible()); - v4_ = _e88 + _e91; - int _e93 = i1_; - i1_ = _e93 + int(texture_array_2darray[0].get_array_size()); - int _e98 = i1_; - i1_ = _e98 + int(texture_array_2darray[uniform_index].get_array_size()); - int _e102 = i1_; - i1_ = _e102 + int(texture_array_2darray[non_uniform_index].get_array_size()); - int _e106 = i1_; - i1_ = _e106 + int(texture_array_bounded[0].get_num_mip_levels()); - int _e111 = i1_; - i1_ = _e111 + int(texture_array_bounded[uniform_index].get_num_mip_levels()); - int _e115 = i1_; - i1_ = _e115 + int(texture_array_bounded[non_uniform_index].get_num_mip_levels()); - int _e119 = i1_; - i1_ = _e119 + int(texture_array_multisampled[0].get_num_samples()); - int _e124 = i1_; - i1_ = _e124 + int(texture_array_multisampled[uniform_index].get_num_samples()); + metal::float4 _e56 = v4_; + v4_ = _e56 + _e55; + metal::float4 _e65 = texture_array_depth[0].gather_compare(samp_comp[0], uv, 0.0); + metal::float4 _e66 = v4_; + v4_ = _e66 + _e65; + metal::float4 _e73 = texture_array_depth[uniform_index].gather_compare(samp_comp[uniform_index], uv, 0.0); + metal::float4 _e74 = v4_; + v4_ = _e74 + _e73; + metal::float4 _e81 = texture_array_depth[non_uniform_index].gather_compare(samp_comp[non_uniform_index], uv, 0.0); + metal::float4 _e82 = v4_; + v4_ = _e82 + _e81; + metal::float4 _e88 = (uint(0) < texture_array_unbounded[0].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[0].get_width(0), texture_array_unbounded[0].get_height(0))) ? texture_array_unbounded[0].read(metal::uint2(pix), 0): DefaultConstructible()); + metal::float4 _e89 = v4_; + v4_ = _e89 + _e88; + metal::float4 _e94 = (uint(0) < texture_array_unbounded[uniform_index].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[uniform_index].get_width(0), texture_array_unbounded[uniform_index].get_height(0))) ? texture_array_unbounded[uniform_index].read(metal::uint2(pix), 0): DefaultConstructible()); + metal::float4 _e95 = v4_; + v4_ = _e95 + _e94; + metal::float4 _e100 = (uint(0) < texture_array_unbounded[non_uniform_index].get_num_mip_levels() && metal::all(metal::uint2(pix) < metal::uint2(texture_array_unbounded[non_uniform_index].get_width(0), texture_array_unbounded[non_uniform_index].get_height(0))) ? texture_array_unbounded[non_uniform_index].read(metal::uint2(pix), 0): DefaultConstructible()); + metal::float4 _e101 = v4_; + v4_ = _e101 + _e100; + int _e107 = i1_; + i1_ = _e107 + int(texture_array_2darray[0].get_array_size()); + int _e112 = i1_; + i1_ = _e112 + int(texture_array_2darray[uniform_index].get_array_size()); + int _e117 = i1_; + i1_ = _e117 + int(texture_array_2darray[non_uniform_index].get_array_size()); + int _e123 = i1_; + i1_ = _e123 + int(texture_array_bounded[0].get_num_mip_levels()); int _e128 = i1_; - i1_ = _e128 + int(texture_array_multisampled[non_uniform_index].get_num_samples()); - metal::float4 _e132 = v4_; - metal::float4 _e137 = texture_array_bounded[0].sample(samp[0], uv); - v4_ = _e132 + _e137; - metal::float4 _e139 = v4_; - metal::float4 _e142 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv); - v4_ = _e139 + _e142; - metal::float4 _e144 = v4_; - metal::float4 _e147 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv); - v4_ = _e144 + _e147; - metal::float4 _e149 = v4_; - metal::float4 _e155 = texture_array_bounded[0].sample(samp[0], uv, metal::bias(0.0)); - v4_ = _e149 + _e155; - metal::float4 _e157 = v4_; - metal::float4 _e161 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::bias(0.0)); - v4_ = _e157 + _e161; - metal::float4 _e163 = v4_; - metal::float4 _e167 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::bias(0.0)); - v4_ = _e163 + _e167; - float _e169 = v1_; - float _e175 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); - v1_ = _e169 + _e175; - float _e177 = v1_; - float _e181 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); - v1_ = _e177 + _e181; - float _e183 = v1_; - float _e187 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); - v1_ = _e183 + _e187; - float _e189 = v1_; - float _e195 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); - v1_ = _e189 + _e195; - float _e197 = v1_; - float _e201 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); - v1_ = _e197 + _e201; - float _e203 = v1_; - float _e207 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); - v1_ = _e203 + _e207; - metal::float4 _e209 = v4_; - metal::float4 _e214 = texture_array_bounded[0].sample(samp[0], uv, metal::gradient2d(uv, uv)); - v4_ = _e209 + _e214; - metal::float4 _e216 = v4_; - metal::float4 _e219 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::gradient2d(uv, uv)); - v4_ = _e216 + _e219; - metal::float4 _e221 = v4_; - metal::float4 _e224 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::gradient2d(uv, uv)); - v4_ = _e221 + _e224; - metal::float4 _e226 = v4_; - metal::float4 _e232 = texture_array_bounded[0].sample(samp[0], uv, metal::level(0.0)); - v4_ = _e226 + _e232; - metal::float4 _e234 = v4_; - metal::float4 _e238 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::level(0.0)); - v4_ = _e234 + _e238; - metal::float4 _e240 = v4_; - metal::float4 _e244 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::level(0.0)); - v4_ = _e240 + _e244; - metal::float4 _e248 = v4_; + i1_ = _e128 + int(texture_array_bounded[uniform_index].get_num_mip_levels()); + int _e133 = i1_; + i1_ = _e133 + int(texture_array_bounded[non_uniform_index].get_num_mip_levels()); + int _e139 = i1_; + i1_ = _e139 + int(texture_array_multisampled[0].get_num_samples()); + int _e144 = i1_; + i1_ = _e144 + int(texture_array_multisampled[uniform_index].get_num_samples()); + int _e149 = i1_; + i1_ = _e149 + int(texture_array_multisampled[non_uniform_index].get_num_samples()); + metal::float4 _e157 = texture_array_bounded[0].sample(samp[0], uv); + metal::float4 _e158 = v4_; + v4_ = _e158 + _e157; + metal::float4 _e164 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv); + metal::float4 _e165 = v4_; + v4_ = _e165 + _e164; + metal::float4 _e171 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv); + metal::float4 _e172 = v4_; + v4_ = _e172 + _e171; + metal::float4 _e181 = texture_array_bounded[0].sample(samp[0], uv, metal::bias(0.0)); + metal::float4 _e182 = v4_; + v4_ = _e182 + _e181; + metal::float4 _e189 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::bias(0.0)); + metal::float4 _e190 = v4_; + v4_ = _e190 + _e189; + metal::float4 _e197 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::bias(0.0)); + metal::float4 _e198 = v4_; + v4_ = _e198 + _e197; + float _e207 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); + float _e208 = v1_; + v1_ = _e208 + _e207; + float _e215 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); + float _e216 = v1_; + v1_ = _e216 + _e215; + float _e223 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); + float _e224 = v1_; + v1_ = _e224 + _e223; + float _e233 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); + float _e234 = v1_; + v1_ = _e234 + _e233; + float _e241 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); + float _e242 = v1_; + v1_ = _e242 + _e241; + float _e249 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); + float _e250 = v1_; + v1_ = _e250 + _e249; + metal::float4 _e258 = texture_array_bounded[0].sample(samp[0], uv, metal::gradient2d(uv, uv)); + metal::float4 _e259 = v4_; + v4_ = _e259 + _e258; + metal::float4 _e265 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::gradient2d(uv, uv)); + metal::float4 _e266 = v4_; + v4_ = _e266 + _e265; + metal::float4 _e272 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::gradient2d(uv, uv)); + metal::float4 _e273 = v4_; + v4_ = _e273 + _e272; + metal::float4 _e282 = texture_array_bounded[0].sample(samp[0], uv, metal::level(0.0)); + metal::float4 _e283 = v4_; + v4_ = _e283 + _e282; + metal::float4 _e290 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::level(0.0)); + metal::float4 _e291 = v4_; + v4_ = _e291 + _e290; + metal::float4 _e298 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::level(0.0)); + metal::float4 _e299 = v4_; + v4_ = _e299 + _e298; + metal::float4 _e304 = v4_; if (metal::all(metal::uint2(pix) < metal::uint2(texture_array_storage[0].get_width(), texture_array_storage[0].get_height()))) { - texture_array_storage[0].write(_e248, metal::uint2(pix)); + texture_array_storage[0].write(_e304, metal::uint2(pix)); } - metal::float4 _e250 = v4_; + metal::float4 _e307 = v4_; if (metal::all(metal::uint2(pix) < metal::uint2(texture_array_storage[uniform_index].get_width(), texture_array_storage[uniform_index].get_height()))) { - texture_array_storage[uniform_index].write(_e250, metal::uint2(pix)); + texture_array_storage[uniform_index].write(_e307, metal::uint2(pix)); } - metal::float4 _e252 = v4_; + metal::float4 _e310 = v4_; if (metal::all(metal::uint2(pix) < metal::uint2(texture_array_storage[non_uniform_index].get_width(), texture_array_storage[non_uniform_index].get_height()))) { - texture_array_storage[non_uniform_index].write(_e252, metal::uint2(pix)); + texture_array_storage[non_uniform_index].write(_e310, metal::uint2(pix)); } - metal::int2 _e253 = i2_; - int _e254 = i1_; - metal::float2 v2_ = static_cast(_e253 + metal::int2(_e254)); - metal::float4 _e258 = v4_; - float _e265 = v1_; - return main_Output { (_e258 + metal::float4(v2_.x, v2_.y, v2_.x, v2_.y)) + metal::float4(_e265) }; + metal::int2 _e311 = i2_; + int _e312 = i1_; + metal::float2 v2_ = static_cast(_e311 + metal::int2(_e312)); + metal::float4 _e316 = v4_; + float _e323 = v1_; + return main_Output { (_e316 + metal::float4(v2_.x, v2_.y, v2_.x, v2_.y)) + metal::float4(_e323) }; } diff --git a/tests/out/msl/bits.msl b/tests/out/msl/bits.msl index 9c9eedaebf..2a95996c70 100644 --- a/tests/out/msl/bits.msl +++ b/tests/out/msl/bits.msl @@ -7,19 +7,21 @@ using metal::uint; kernel void main_( ) { - int i = 0; + int i = {}; metal::int2 i2_ = {}; metal::int3 i3_ = {}; metal::int4 i4_ = {}; - uint u = 0u; + uint u = {}; metal::uint2 u2_ = {}; metal::uint3 u3_ = {}; metal::uint4 u4_ = {}; metal::float2 f2_ = {}; metal::float4 f4_ = {}; + i = 0; i2_ = metal::int2(0); i3_ = metal::int3(0); i4_ = metal::int4(0); + u = 0u; u2_ = metal::uint2(0u); u3_ = metal::uint3(0u); u4_ = metal::uint4(0u); diff --git a/tests/out/msl/boids.msl b/tests/out/msl/boids.msl index fd46d1f21c..2b832c0f2b 100644 --- a/tests/out/msl/boids.msl +++ b/tests/out/msl/boids.msl @@ -42,120 +42,123 @@ kernel void main_( metal::float2 cMass = {}; metal::float2 cVel = {}; metal::float2 colVel = {}; - int cMassCount = 0; - int cVelCount = 0; + int cMassCount = {}; + int cVelCount = {}; metal::float2 pos = {}; metal::float2 vel = {}; - uint i = 0u; + uint i = {}; uint index = global_invocation_id.x; if (index >= NUM_PARTICLES) { return; } - metal::float2 _e10 = particlesSrc.particles[index].pos; - vPos = _e10; - metal::float2 _e15 = particlesSrc.particles[index].vel; - vVel = _e15; + metal::float2 _e8 = particlesSrc.particles[index].pos; + vPos = _e8; + metal::float2 _e14 = particlesSrc.particles[index].vel; + vVel = _e14; cMass = metal::float2(0.0, 0.0); cVel = metal::float2(0.0, 0.0); colVel = metal::float2(0.0, 0.0); + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e86 = i; - i = _e86 + 1u; + uint _e91 = i; + i = _e91 + 1u; } loop_init = false; - uint _e37 = i; - if (_e37 >= NUM_PARTICLES) { + uint _e36 = i; + if (_e36 >= NUM_PARTICLES) { break; } uint _e39 = i; if (_e39 == index) { continue; } - uint _e42 = i; - metal::float2 _e45 = particlesSrc.particles[_e42].pos; - pos = _e45; - uint _e47 = i; - metal::float2 _e50 = particlesSrc.particles[_e47].vel; - vel = _e50; - metal::float2 _e51 = pos; - metal::float2 _e52 = vPos; - float _e55 = params.rule1Distance; - if (metal::distance(_e51, _e52) < _e55) { - metal::float2 _e57 = cMass; - metal::float2 _e58 = pos; - cMass = _e57 + _e58; - int _e60 = cMassCount; - cMassCount = _e60 + 1; + uint _e43 = i; + metal::float2 _e46 = particlesSrc.particles[_e43].pos; + pos = _e46; + uint _e49 = i; + metal::float2 _e52 = particlesSrc.particles[_e49].vel; + vel = _e52; + metal::float2 _e53 = pos; + metal::float2 _e54 = vPos; + float _e58 = params.rule1Distance; + if (metal::distance(_e53, _e54) < _e58) { + metal::float2 _e60 = cMass; + metal::float2 _e61 = pos; + cMass = _e60 + _e61; + int _e63 = cMassCount; + cMassCount = _e63 + 1; } - metal::float2 _e63 = pos; - metal::float2 _e64 = vPos; - float _e67 = params.rule2Distance; - if (metal::distance(_e63, _e64) < _e67) { - metal::float2 _e69 = colVel; - metal::float2 _e70 = pos; - metal::float2 _e71 = vPos; - colVel = _e69 - (_e70 - _e71); + metal::float2 _e66 = pos; + metal::float2 _e67 = vPos; + float _e71 = params.rule2Distance; + if (metal::distance(_e66, _e67) < _e71) { + metal::float2 _e73 = colVel; + metal::float2 _e74 = pos; + metal::float2 _e75 = vPos; + colVel = _e73 - (_e74 - _e75); } - metal::float2 _e74 = pos; - metal::float2 _e75 = vPos; - float _e78 = params.rule3Distance; - if (metal::distance(_e74, _e75) < _e78) { - metal::float2 _e80 = cVel; - metal::float2 _e81 = vel; - cVel = _e80 + _e81; - int _e83 = cVelCount; - cVelCount = _e83 + 1; + metal::float2 _e78 = pos; + metal::float2 _e79 = vPos; + float _e83 = params.rule3Distance; + if (metal::distance(_e78, _e79) < _e83) { + metal::float2 _e85 = cVel; + metal::float2 _e86 = vel; + cVel = _e85 + _e86; + int _e88 = cVelCount; + cVelCount = _e88 + 1; } } - int _e89 = cMassCount; - if (_e89 > 0) { - metal::float2 _e92 = cMass; - int _e93 = cMassCount; - metal::float2 _e97 = vPos; - cMass = (_e92 / metal::float2(static_cast(_e93))) - _e97; + int _e94 = cMassCount; + if (_e94 > 0) { + metal::float2 _e97 = cMass; + int _e98 = cMassCount; + metal::float2 _e102 = vPos; + cMass = (_e97 / metal::float2(static_cast(_e98))) - _e102; } - int _e99 = cVelCount; - if (_e99 > 0) { - metal::float2 _e102 = cVel; - int _e103 = cVelCount; - cVel = _e102 / metal::float2(static_cast(_e103)); + int _e104 = cVelCount; + if (_e104 > 0) { + metal::float2 _e107 = cVel; + int _e108 = cVelCount; + cVel = _e107 / metal::float2(static_cast(_e108)); } - metal::float2 _e107 = vVel; - metal::float2 _e108 = cMass; - float _e110 = params.rule1Scale; - metal::float2 _e113 = colVel; - float _e115 = params.rule2Scale; - metal::float2 _e118 = cVel; - float _e120 = params.rule3Scale; - vVel = ((_e107 + (_e108 * _e110)) + (_e113 * _e115)) + (_e118 * _e120); - metal::float2 _e123 = vVel; - metal::float2 _e125 = vVel; - vVel = metal::normalize(_e123) * metal::clamp(metal::length(_e125), 0.0, 0.10000000149011612); - metal::float2 _e131 = vPos; - metal::float2 _e132 = vVel; - float _e134 = params.deltaT; - vPos = _e131 + (_e132 * _e134); - float _e138 = vPos.x; - if (_e138 < -1.0) { + metal::float2 _e112 = vVel; + metal::float2 _e113 = cMass; + float _e116 = params.rule1Scale; + metal::float2 _e119 = colVel; + float _e122 = params.rule2Scale; + metal::float2 _e125 = cVel; + float _e128 = params.rule3Scale; + vVel = ((_e112 + (_e113 * _e116)) + (_e119 * _e122)) + (_e125 * _e128); + metal::float2 _e131 = vVel; + metal::float2 _e133 = vVel; + vVel = metal::normalize(_e131) * metal::clamp(metal::length(_e133), 0.0, 0.10000000149011612); + metal::float2 _e139 = vPos; + metal::float2 _e140 = vVel; + float _e143 = params.deltaT; + vPos = _e139 + (_e140 * _e143); + float _e147 = vPos.x; + if (_e147 < -1.0) { vPos.x = 1.0; } - float _e144 = vPos.x; - if (_e144 > 1.0) { + float _e153 = vPos.x; + if (_e153 > 1.0) { vPos.x = -1.0; } - float _e150 = vPos.y; - if (_e150 < -1.0) { + float _e159 = vPos.y; + if (_e159 < -1.0) { vPos.y = 1.0; } - float _e156 = vPos.y; - if (_e156 > 1.0) { + float _e165 = vPos.y; + if (_e165 > 1.0) { vPos.y = -1.0; } - metal::float2 _e164 = vPos; - particlesDst.particles[index].pos = _e164; - metal::float2 _e168 = vVel; - particlesDst.particles[index].vel = _e168; + metal::float2 _e174 = vPos; + particlesDst.particles[index].pos = _e174; + metal::float2 _e179 = vVel; + particlesDst.particles[index].vel = _e179; return; } diff --git a/tests/out/msl/bounds-check-image-restrict.msl b/tests/out/msl/bounds-check-image-restrict.msl index b2f6eca4d8..c1e5b99df0 100644 --- a/tests/out/msl/bounds-check-image-restrict.msl +++ b/tests/out/msl/bounds-check-image-restrict.msl @@ -22,9 +22,9 @@ metal::float4 test_textureLoad_2d( int level_1, metal::texture2d image_2d ) { - uint clamped_lod_e4 = metal::min(uint(level_1), image_2d.get_num_mip_levels() - 1); - metal::float4 _e4 = image_2d.read(metal::min(metal::uint2(coords_1), metal::uint2(image_2d.get_width(clamped_lod_e4), image_2d.get_height(clamped_lod_e4)) - 1), clamped_lod_e4); - return _e4; + uint clamped_lod_e3 = metal::min(uint(level_1), image_2d.get_num_mip_levels() - 1); + metal::float4 _e3 = image_2d.read(metal::min(metal::uint2(coords_1), metal::uint2(image_2d.get_width(clamped_lod_e3), image_2d.get_height(clamped_lod_e3)) - 1), clamped_lod_e3); + return _e3; } metal::float4 test_textureLoad_2d_array( @@ -33,9 +33,9 @@ metal::float4 test_textureLoad_2d_array( int level_2, metal::texture2d_array image_2d_array ) { - uint clamped_lod_e6 = metal::min(uint(level_2), image_2d_array.get_num_mip_levels() - 1); - metal::float4 _e6 = image_2d_array.read(metal::min(metal::uint2(coords_2), metal::uint2(image_2d_array.get_width(clamped_lod_e6), image_2d_array.get_height(clamped_lod_e6)) - 1), metal::min(uint(index), image_2d_array.get_array_size() - 1), clamped_lod_e6); - return _e6; + uint clamped_lod_e4 = metal::min(uint(level_2), image_2d_array.get_num_mip_levels() - 1); + metal::float4 _e4 = image_2d_array.read(metal::min(metal::uint2(coords_2), metal::uint2(image_2d_array.get_width(clamped_lod_e4), image_2d_array.get_height(clamped_lod_e4)) - 1), metal::min(uint(index), image_2d_array.get_array_size() - 1), clamped_lod_e4); + return _e4; } metal::float4 test_textureLoad_3d( @@ -43,9 +43,9 @@ metal::float4 test_textureLoad_3d( int level_3, metal::texture3d image_3d ) { - uint clamped_lod_e6 = metal::min(uint(level_3), image_3d.get_num_mip_levels() - 1); - metal::float4 _e6 = image_3d.read(metal::min(metal::uint3(coords_3), metal::uint3(image_3d.get_width(clamped_lod_e6), image_3d.get_height(clamped_lod_e6), image_3d.get_depth(clamped_lod_e6)) - 1), clamped_lod_e6); - return _e6; + uint clamped_lod_e3 = metal::min(uint(level_3), image_3d.get_num_mip_levels() - 1); + metal::float4 _e3 = image_3d.read(metal::min(metal::uint3(coords_3), metal::uint3(image_3d.get_width(clamped_lod_e3), image_3d.get_height(clamped_lod_e3), image_3d.get_depth(clamped_lod_e3)) - 1), clamped_lod_e3); + return _e3; } metal::float4 test_textureLoad_multisampled_2d( @@ -53,8 +53,8 @@ metal::float4 test_textureLoad_multisampled_2d( int _sample, metal::texture2d_ms image_multisampled_2d ) { - metal::float4 _e7 = image_multisampled_2d.read(metal::min(metal::uint2(coords_4), metal::uint2(image_multisampled_2d.get_width(), image_multisampled_2d.get_height()) - 1), metal::min(uint(_sample), image_multisampled_2d.get_num_samples() - 1)); - return _e7; + metal::float4 _e3 = image_multisampled_2d.read(metal::min(metal::uint2(coords_4), metal::uint2(image_multisampled_2d.get_width(), image_multisampled_2d.get_height()) - 1), metal::min(uint(_sample), image_multisampled_2d.get_num_samples() - 1)); + return _e3; } float test_textureLoad_depth_2d( @@ -62,9 +62,9 @@ float test_textureLoad_depth_2d( int level_4, metal::depth2d image_depth_2d ) { - uint clamped_lod_e8 = metal::min(uint(level_4), image_depth_2d.get_num_mip_levels() - 1); - float _e8 = image_depth_2d.read(metal::min(metal::uint2(coords_5), metal::uint2(image_depth_2d.get_width(clamped_lod_e8), image_depth_2d.get_height(clamped_lod_e8)) - 1), clamped_lod_e8); - return _e8; + uint clamped_lod_e3 = metal::min(uint(level_4), image_depth_2d.get_num_mip_levels() - 1); + float _e3 = image_depth_2d.read(metal::min(metal::uint2(coords_5), metal::uint2(image_depth_2d.get_width(clamped_lod_e3), image_depth_2d.get_height(clamped_lod_e3)) - 1), clamped_lod_e3); + return _e3; } float test_textureLoad_depth_2d_array( @@ -73,9 +73,9 @@ float test_textureLoad_depth_2d_array( int level_5, metal::depth2d_array image_depth_2d_array ) { - uint clamped_lod_e10 = metal::min(uint(level_5), image_depth_2d_array.get_num_mip_levels() - 1); - float _e10 = image_depth_2d_array.read(metal::min(metal::uint2(coords_6), metal::uint2(image_depth_2d_array.get_width(clamped_lod_e10), image_depth_2d_array.get_height(clamped_lod_e10)) - 1), metal::min(uint(index_1), image_depth_2d_array.get_array_size() - 1), clamped_lod_e10); - return _e10; + uint clamped_lod_e4 = metal::min(uint(level_5), image_depth_2d_array.get_num_mip_levels() - 1); + float _e4 = image_depth_2d_array.read(metal::min(metal::uint2(coords_6), metal::uint2(image_depth_2d_array.get_width(clamped_lod_e4), image_depth_2d_array.get_height(clamped_lod_e4)) - 1), metal::min(uint(index_1), image_depth_2d_array.get_array_size() - 1), clamped_lod_e4); + return _e4; } float test_textureLoad_depth_multisampled_2d( @@ -83,8 +83,8 @@ float test_textureLoad_depth_multisampled_2d( int _sample_1, metal::depth2d_ms image_depth_multisampled_2d ) { - float _e10 = image_depth_multisampled_2d.read(metal::min(metal::uint2(coords_7), metal::uint2(image_depth_multisampled_2d.get_width(), image_depth_multisampled_2d.get_height()) - 1), metal::min(uint(_sample_1), image_depth_multisampled_2d.get_num_samples() - 1)); - return _e10; + float _e3 = image_depth_multisampled_2d.read(metal::min(metal::uint2(coords_7), metal::uint2(image_depth_multisampled_2d.get_width(), image_depth_multisampled_2d.get_height()) - 1), metal::min(uint(_sample_1), image_depth_multisampled_2d.get_num_samples() - 1)); + return _e3; } void test_textureStore_1d( @@ -138,11 +138,11 @@ fragment fragment_shaderOutput fragment_shader( , metal::texture2d_array image_storage_2d_array [[user(fake0)]] , metal::texture3d image_storage_3d [[user(fake0)]] ) { - metal::float4 _e14 = test_textureLoad_1d(0, 0, image_1d); - metal::float4 _e17 = test_textureLoad_2d(const_type_4_, 0, image_2d); - metal::float4 _e21 = test_textureLoad_2d_array(const_type_4_, 0, 0, image_2d_array); - metal::float4 _e24 = test_textureLoad_3d(const_type_7_, 0, image_3d); - metal::float4 _e27 = test_textureLoad_multisampled_2d(const_type_4_, 0, image_multisampled_2d); + metal::float4 _e2 = test_textureLoad_1d(0, 0, image_1d); + metal::float4 _e5 = test_textureLoad_2d(const_type_4_, 0, image_2d); + metal::float4 _e9 = test_textureLoad_2d_array(const_type_4_, 0, 0, image_2d_array); + metal::float4 _e12 = test_textureLoad_3d(const_type_7_, 0, image_3d); + metal::float4 _e15 = test_textureLoad_multisampled_2d(const_type_4_, 0, image_multisampled_2d); test_textureStore_1d(0, const_type_2_, image_storage_1d); test_textureStore_2d(const_type_4_, const_type_2_, image_storage_2d); test_textureStore_2d_array(const_type_4_, 0, const_type_2_, image_storage_2d_array); diff --git a/tests/out/msl/bounds-check-image-rzsw.msl b/tests/out/msl/bounds-check-image-rzsw.msl index 16cbf5c0a6..9032af14ca 100644 --- a/tests/out/msl/bounds-check-image-rzsw.msl +++ b/tests/out/msl/bounds-check-image-rzsw.msl @@ -28,8 +28,8 @@ metal::float4 test_textureLoad_2d( int level_1, metal::texture2d image_2d ) { - metal::float4 _e4 = (uint(level_1) < image_2d.get_num_mip_levels() && metal::all(metal::uint2(coords_1) < metal::uint2(image_2d.get_width(level_1), image_2d.get_height(level_1))) ? image_2d.read(metal::uint2(coords_1), level_1): DefaultConstructible()); - return _e4; + metal::float4 _e3 = (uint(level_1) < image_2d.get_num_mip_levels() && metal::all(metal::uint2(coords_1) < metal::uint2(image_2d.get_width(level_1), image_2d.get_height(level_1))) ? image_2d.read(metal::uint2(coords_1), level_1): DefaultConstructible()); + return _e3; } metal::float4 test_textureLoad_2d_array( @@ -38,8 +38,8 @@ metal::float4 test_textureLoad_2d_array( int level_2, metal::texture2d_array image_2d_array ) { - metal::float4 _e6 = (uint(level_2) < image_2d_array.get_num_mip_levels() && uint(index) < image_2d_array.get_array_size() && metal::all(metal::uint2(coords_2) < metal::uint2(image_2d_array.get_width(level_2), image_2d_array.get_height(level_2))) ? image_2d_array.read(metal::uint2(coords_2), index, level_2): DefaultConstructible()); - return _e6; + metal::float4 _e4 = (uint(level_2) < image_2d_array.get_num_mip_levels() && uint(index) < image_2d_array.get_array_size() && metal::all(metal::uint2(coords_2) < metal::uint2(image_2d_array.get_width(level_2), image_2d_array.get_height(level_2))) ? image_2d_array.read(metal::uint2(coords_2), index, level_2): DefaultConstructible()); + return _e4; } metal::float4 test_textureLoad_3d( @@ -47,8 +47,8 @@ metal::float4 test_textureLoad_3d( int level_3, metal::texture3d image_3d ) { - metal::float4 _e6 = (uint(level_3) < image_3d.get_num_mip_levels() && metal::all(metal::uint3(coords_3) < metal::uint3(image_3d.get_width(level_3), image_3d.get_height(level_3), image_3d.get_depth(level_3))) ? image_3d.read(metal::uint3(coords_3), level_3): DefaultConstructible()); - return _e6; + metal::float4 _e3 = (uint(level_3) < image_3d.get_num_mip_levels() && metal::all(metal::uint3(coords_3) < metal::uint3(image_3d.get_width(level_3), image_3d.get_height(level_3), image_3d.get_depth(level_3))) ? image_3d.read(metal::uint3(coords_3), level_3): DefaultConstructible()); + return _e3; } metal::float4 test_textureLoad_multisampled_2d( @@ -56,8 +56,8 @@ metal::float4 test_textureLoad_multisampled_2d( int _sample, metal::texture2d_ms image_multisampled_2d ) { - metal::float4 _e7 = (uint(_sample) < image_multisampled_2d.get_num_samples() && metal::all(metal::uint2(coords_4) < metal::uint2(image_multisampled_2d.get_width(), image_multisampled_2d.get_height())) ? image_multisampled_2d.read(metal::uint2(coords_4), _sample): DefaultConstructible()); - return _e7; + metal::float4 _e3 = (uint(_sample) < image_multisampled_2d.get_num_samples() && metal::all(metal::uint2(coords_4) < metal::uint2(image_multisampled_2d.get_width(), image_multisampled_2d.get_height())) ? image_multisampled_2d.read(metal::uint2(coords_4), _sample): DefaultConstructible()); + return _e3; } float test_textureLoad_depth_2d( @@ -65,8 +65,8 @@ float test_textureLoad_depth_2d( int level_4, metal::depth2d image_depth_2d ) { - float _e8 = (uint(level_4) < image_depth_2d.get_num_mip_levels() && metal::all(metal::uint2(coords_5) < metal::uint2(image_depth_2d.get_width(level_4), image_depth_2d.get_height(level_4))) ? image_depth_2d.read(metal::uint2(coords_5), level_4): DefaultConstructible()); - return _e8; + float _e3 = (uint(level_4) < image_depth_2d.get_num_mip_levels() && metal::all(metal::uint2(coords_5) < metal::uint2(image_depth_2d.get_width(level_4), image_depth_2d.get_height(level_4))) ? image_depth_2d.read(metal::uint2(coords_5), level_4): DefaultConstructible()); + return _e3; } float test_textureLoad_depth_2d_array( @@ -75,8 +75,8 @@ float test_textureLoad_depth_2d_array( int level_5, metal::depth2d_array image_depth_2d_array ) { - float _e10 = (uint(level_5) < image_depth_2d_array.get_num_mip_levels() && uint(index_1) < image_depth_2d_array.get_array_size() && metal::all(metal::uint2(coords_6) < metal::uint2(image_depth_2d_array.get_width(level_5), image_depth_2d_array.get_height(level_5))) ? image_depth_2d_array.read(metal::uint2(coords_6), index_1, level_5): DefaultConstructible()); - return _e10; + float _e4 = (uint(level_5) < image_depth_2d_array.get_num_mip_levels() && uint(index_1) < image_depth_2d_array.get_array_size() && metal::all(metal::uint2(coords_6) < metal::uint2(image_depth_2d_array.get_width(level_5), image_depth_2d_array.get_height(level_5))) ? image_depth_2d_array.read(metal::uint2(coords_6), index_1, level_5): DefaultConstructible()); + return _e4; } float test_textureLoad_depth_multisampled_2d( @@ -84,8 +84,8 @@ float test_textureLoad_depth_multisampled_2d( int _sample_1, metal::depth2d_ms image_depth_multisampled_2d ) { - float _e10 = (uint(_sample_1) < image_depth_multisampled_2d.get_num_samples() && metal::all(metal::uint2(coords_7) < metal::uint2(image_depth_multisampled_2d.get_width(), image_depth_multisampled_2d.get_height())) ? image_depth_multisampled_2d.read(metal::uint2(coords_7), _sample_1): DefaultConstructible()); - return _e10; + float _e3 = (uint(_sample_1) < image_depth_multisampled_2d.get_num_samples() && metal::all(metal::uint2(coords_7) < metal::uint2(image_depth_multisampled_2d.get_width(), image_depth_multisampled_2d.get_height())) ? image_depth_multisampled_2d.read(metal::uint2(coords_7), _sample_1): DefaultConstructible()); + return _e3; } void test_textureStore_1d( @@ -147,11 +147,11 @@ fragment fragment_shaderOutput fragment_shader( , metal::texture2d_array image_storage_2d_array [[user(fake0)]] , metal::texture3d image_storage_3d [[user(fake0)]] ) { - metal::float4 _e14 = test_textureLoad_1d(0, 0, image_1d); - metal::float4 _e17 = test_textureLoad_2d(const_type_4_, 0, image_2d); - metal::float4 _e21 = test_textureLoad_2d_array(const_type_4_, 0, 0, image_2d_array); - metal::float4 _e24 = test_textureLoad_3d(const_type_7_, 0, image_3d); - metal::float4 _e27 = test_textureLoad_multisampled_2d(const_type_4_, 0, image_multisampled_2d); + metal::float4 _e2 = test_textureLoad_1d(0, 0, image_1d); + metal::float4 _e5 = test_textureLoad_2d(const_type_4_, 0, image_2d); + metal::float4 _e9 = test_textureLoad_2d_array(const_type_4_, 0, 0, image_2d_array); + metal::float4 _e12 = test_textureLoad_3d(const_type_7_, 0, image_3d); + metal::float4 _e15 = test_textureLoad_multisampled_2d(const_type_4_, 0, image_multisampled_2d); test_textureStore_1d(0, const_type_2_, image_storage_1d); test_textureStore_2d(const_type_4_, const_type_2_, image_storage_2d); test_textureStore_2d_array(const_type_4_, 0, const_type_2_, image_storage_2d_array); diff --git a/tests/out/msl/bounds-check-restrict.msl b/tests/out/msl/bounds-check-restrict.msl index a614e59240..49a232e706 100644 --- a/tests/out/msl/bounds-check-restrict.msl +++ b/tests/out/msl/bounds-check-restrict.msl @@ -87,9 +87,9 @@ float index_in_bounds( constant _mslBufferSizes& _buffer_sizes ) { float _e4 = globals.a.inner[9]; - float _e8 = globals.v.w; - float _e15 = globals.m[2].w; - return (_e4 + _e8) + _e15; + float _e9 = globals.v.w; + float _e17 = globals.m[2].w; + return (_e4 + _e9) + _e17; } void set_array( diff --git a/tests/out/msl/bounds-check-zero.msl b/tests/out/msl/bounds-check-zero.msl index b45550d5ae..fece92de35 100644 --- a/tests/out/msl/bounds-check-zero.msl +++ b/tests/out/msl/bounds-check-zero.msl @@ -94,9 +94,9 @@ float index_in_bounds( constant _mslBufferSizes& _buffer_sizes ) { float _e4 = globals.a.inner[9]; - float _e8 = globals.v.w; - float _e15 = globals.m[2].w; - return (_e4 + _e8) + _e15; + float _e9 = globals.v.w; + float _e17 = globals.m[2].w; + return (_e4 + _e9) + _e17; } void set_array( diff --git a/tests/out/msl/collatz.msl b/tests/out/msl/collatz.msl index 2189632d08..88f9521a27 100644 --- a/tests/out/msl/collatz.msl +++ b/tests/out/msl/collatz.msl @@ -17,27 +17,30 @@ uint collatz_iterations( uint n_base ) { uint n = {}; - uint i = 0u; + uint i = {}; n = n_base; + i = 0u; while(true) { - uint _e5 = n; - if (_e5 > 1u) { + uint _e4 = n; + if (_e4 > 1u) { } else { break; } - uint _e8 = n; - if ((_e8 % 2u) == 0u) { - uint _e13 = n; - n = _e13 / 2u; - } else { - uint _e17 = n; - n = (3u * _e17) + 1u; + { + uint _e7 = n; + if ((_e7 % 2u) == 0u) { + uint _e12 = n; + n = _e12 / 2u; + } else { + uint _e16 = n; + n = (3u * _e16) + 1u; + } + uint _e20 = i; + i = _e20 + 1u; } - uint _e21 = i; - i = _e21 + 1u; } - uint _e24 = i; - return _e24; + uint _e23 = i; + return _e23; } struct main_Input { @@ -47,8 +50,8 @@ kernel void main_( , device PrimeIndices& v_indices [[user(fake0)]] , constant _mslBufferSizes& _buffer_sizes [[user(fake0)]] ) { - uint _e8 = v_indices.data[global_id.x]; - uint _e9 = collatz_iterations(_e8); - v_indices.data[global_id.x] = _e9; + uint _e9 = v_indices.data[global_id.x]; + uint _e10 = collatz_iterations(_e9); + v_indices.data[global_id.x] = _e10; return; } diff --git a/tests/out/msl/globals.msl b/tests/out/msl/globals.msl index b461cce3f4..b821cc9d5f 100644 --- a/tests/out/msl/globals.msl +++ b/tests/out/msl/globals.msl @@ -8,11 +8,11 @@ struct _mslBufferSizes { uint size3; }; -constexpr constant bool Foo_2 = true; +constexpr constant bool Foo_1 = true; struct type_2 { float inner[10u]; }; -struct Foo { +struct FooStruct { metal::packed_float3 v3_; float v1_; }; @@ -42,15 +42,16 @@ void test_msl_packed_vec3_as_arg( } void test_msl_packed_vec3_( - device Foo& alignment + device FooStruct& alignment ) { - int idx = 1; + int idx = {}; alignment.v3_ = metal::float3(1.0); + idx = 1; alignment.v3_[0] = 1.0; alignment.v3_[0] = 2.0; - int _e23 = idx; - alignment.v3_[_e23] = 3.0; - Foo data = alignment; + int _e17 = idx; + alignment.v3_[_e17] = 3.0; + FooStruct data = alignment; metal::float3 unnamed = data.v3_; metal::float2 unnamed_1 = metal::float3(data.v3_).zx; test_msl_packed_vec3_as_arg(data.v3_); @@ -63,7 +64,7 @@ void test_msl_packed_vec3_( kernel void main_( threadgroup type_2& wg , threadgroup metal::atomic_uint& at_1 -, device Foo& alignment [[user(fake0)]] +, device FooStruct& alignment [[user(fake0)]] , device type_6 const& dummy [[user(fake0)]] , constant type_8& float_vecs [[user(fake0)]] , constant metal::float3& global_vec [[user(fake0)]] @@ -72,25 +73,27 @@ kernel void main_( , constant type_15& global_nested_arrays_of_matrices_4x2_ [[user(fake0)]] , constant _mslBufferSizes& _buffer_sizes [[user(fake0)]] ) { - float Foo_1 = 1.0; - bool at = true; + float Foo = {}; + bool at = {}; test_msl_packed_vec3_(alignment); - metal::float4x2 _e16 = global_nested_arrays_of_matrices_4x2_.inner[0].inner[0]; - metal::float4 _e23 = global_nested_arrays_of_matrices_2x4_.inner[0].inner[0][0]; - wg.inner[7] = (_e16 * _e23).x; - metal::float3x2 _e28 = global_mat; - metal::float3 _e29 = global_vec; - wg.inner[6] = (_e28 * _e29).x; - float _e37 = dummy[1].y; - wg.inner[5] = _e37; + metal::float4x2 _e8 = global_nested_arrays_of_matrices_4x2_.inner[0].inner[0]; + metal::float4 _e16 = global_nested_arrays_of_matrices_2x4_.inner[0].inner[0][0]; + wg.inner[7] = (_e8 * _e16).x; + metal::float3x2 _e23 = global_mat; + metal::float3 _e25 = global_vec; + wg.inner[6] = (_e23 * _e25).x; + float _e35 = dummy[1].y; + wg.inner[5] = _e35; float _e43 = float_vecs.inner[0].w; wg.inner[4] = _e43; - float _e47 = alignment.v1_; - wg.inner[3] = _e47; - float _e52 = alignment.v3_[0]; - wg.inner[2] = _e52; + float _e49 = alignment.v1_; + wg.inner[3] = _e49; + float _e56 = alignment.v3_[0]; + wg.inner[2] = _e56; alignment.v1_ = 4.0; wg.inner[1] = static_cast(1 + (_buffer_sizes.size3 - 0 - 8) / 8); metal::atomic_store_explicit(&at_1, 2u, metal::memory_order_relaxed); + Foo = 1.0; + at = true; return; } diff --git a/tests/out/msl/interface.msl b/tests/out/msl/interface.msl index 9b8013531c..7eea0a4f00 100644 --- a/tests/out/msl/interface.msl +++ b/tests/out/msl/interface.msl @@ -93,7 +93,8 @@ vertex vertex_two_structsOutput vertex_two_structs( ) { const Input1_ in1_ = { index_1 }; const Input2_ in2_ = { index_2 }; - uint index = 2u; - uint _e9 = index; - return vertex_two_structsOutput { metal::float4(static_cast(in1_.index), static_cast(in2_.index), static_cast(_e9), 0.0), 1.0 }; + uint index = {}; + index = 2u; + uint _e8 = index; + return vertex_two_structsOutput { metal::float4(static_cast(in1_.index), static_cast(in2_.index), static_cast(_e8), 0.0), 1.0 }; } diff --git a/tests/out/msl/math-functions.msl b/tests/out/msl/math-functions.msl index 6ee0093d00..559d464681 100644 --- a/tests/out/msl/math-functions.msl +++ b/tests/out/msl/math-functions.msl @@ -4,7 +4,7 @@ using metal::uint; -constant metal::int2 const_type = {0, 0}; +constant metal::int2 const_type_1_ = {0, 0}; vertex void main_( ) { @@ -14,6 +14,6 @@ vertex void main_( metal::float4 c = ((v) * 57.295779513082322865); metal::float4 d = ((v) * 0.017453292519943295474); metal::float4 e = metal::saturate(v); - int const_dot = ( + const_type.x * const_type.x + const_type.y * const_type.y); + int const_dot = ( + const_type_1_.x * const_type_1_.x + const_type_1_.y * const_type_1_.y); uint first_leading_bit_abs = (((metal::clz(metal::abs(0u)) + 1) % 33) - 1); } diff --git a/tests/out/msl/operators.msl b/tests/out/msl/operators.msl index 72a0c30252..549ed49efe 100644 --- a/tests/out/msl/operators.msl +++ b/tests/out/msl/operators.msl @@ -8,28 +8,28 @@ struct Foo { metal::float4 a; int b; }; -struct type_12 { +struct type_13 { Foo inner[3]; }; -struct type_13 { +struct type_14 { int inner[4u]; }; constant metal::float4 v_f32_one = {1.0, 1.0, 1.0, 1.0}; constant metal::float4 v_f32_zero = {0.0, 0.0, 0.0, 0.0}; constant metal::float4 v_f32_half = {0.5, 0.5, 0.5, 0.5}; constant metal::int4 v_i32_one = {1, 1, 1, 1}; -constant metal::uint2 const_type_11_ = {0u, 0u}; +constant metal::uint2 const_type_12_ = {0u, 0u}; constant metal::float2 const_type_4_ = {0.0, 0.0}; -constant metal::float2x2 const_type_7_ = {const_type_4_, const_type_4_}; +constant metal::float2x2 const_type_8_ = {const_type_4_, const_type_4_}; constant metal::float4 const_type = {0.0, 0.0, 0.0, 0.0}; constant Foo const_Foo = {const_type, 0}; -constant type_12 const_type_12_ = {const_Foo, const_Foo, const_Foo}; +constant type_13 const_type_13_ = {const_Foo, const_Foo, const_Foo}; constant metal::float3 const_type_5_ = {0.0, 0.0, 0.0}; -constant metal::float2x3 const_type_14_ = {const_type_5_, const_type_5_}; -constant metal::float3x3 const_type_15_ = {const_type_5_, const_type_5_, const_type_5_}; -constant metal::float4x3 const_type_16_ = {const_type_5_, const_type_5_, const_type_5_, const_type_5_}; -constant metal::float3x4 const_type_17_ = {const_type, const_type, const_type}; -constant metal::int3 const_type_18_ = {0, 0, 0}; +constant metal::float2x3 const_type_15_ = {const_type_5_, const_type_5_}; +constant metal::float3x3 const_type_16_ = {const_type_5_, const_type_5_, const_type_5_}; +constant metal::float4x3 const_type_17_ = {const_type_5_, const_type_5_, const_type_5_, const_type_5_}; +constant metal::float3x4 const_type_18_ = {const_type, const_type, const_type}; +constant metal::int3 const_type_19_ = {0, 0, 0}; metal::float4 builtins( ) { @@ -55,14 +55,14 @@ metal::float2 splat_assignment( ) { metal::float2 a = {}; a = metal::float2(2.0); - metal::float2 _e7 = a; - a = _e7 + metal::float2(1.0); - metal::float2 _e11 = a; - a = _e11 - metal::float2(3.0); + metal::float2 _e4 = a; + a = _e4 + metal::float2(1.0); + metal::float2 _e8 = a; + a = _e8 - metal::float2(3.0); + metal::float2 _e12 = a; + a = _e12 / metal::float2(4.0); metal::float2 _e15 = a; - a = _e15 / metal::float2(4.0); - metal::float2 _e19 = a; - return _e19; + return _e15; } metal::float3 bool_cast( @@ -80,17 +80,17 @@ float constructors( metal::float4x4 mat4comp = metal::float4x4(metal::float4(1.0, 0.0, 0.0, 0.0), metal::float4(0.0, 1.0, 0.0, 0.0), metal::float4(0.0, 0.0, 1.0, 0.0), metal::float4(0.0, 0.0, 0.0, 1.0)); metal::uint2 unnamed = metal::uint2(0u); metal::float2x2 unnamed_1 = metal::float2x2(metal::float2(0.0), metal::float2(0.0)); - type_13 unnamed_2 = type_13 {0, 1, 2, 3}; + type_14 unnamed_2 = type_14 {0, 1, 2, 3}; bool unnamed_3 = static_cast(false); int unnamed_4 = static_cast(0); uint unnamed_5 = static_cast(0u); float unnamed_6 = static_cast(0.0); - metal::uint2 unnamed_7 = static_cast(const_type_11_); - metal::float2x3 unnamed_8 = metal::float2x3(const_type_14_); - metal::uint2 unnamed_9 = as_type(const_type_11_); - metal::float2x3 unnamed_10 = metal::float2x3(const_type_14_); - float _e75 = foo.a.x; - return _e75; + metal::uint2 unnamed_7 = static_cast(const_type_12_); + metal::float2x3 unnamed_8 = metal::float2x3(const_type_15_); + metal::uint2 unnamed_9 = as_type(const_type_12_); + metal::float2x3 unnamed_10 = metal::float2x3(const_type_15_); + float _e71 = foo.a.x; + return _e71; } void logical( @@ -169,13 +169,13 @@ void arithmetic( metal::uint2 unnamed_78 = metal::uint2(2u) % metal::uint2(1u); metal::float2 unnamed_79 = metal::fmod(metal::float2(2.0), metal::float2(1.0)); metal::float2 unnamed_80 = metal::fmod(metal::float2(2.0), metal::float2(1.0)); - metal::float3x3 unnamed_81 = const_type_15_ + const_type_15_; - metal::float3x3 unnamed_82 = const_type_15_ - const_type_15_; - metal::float3x3 unnamed_83 = const_type_15_ * 1.0; - metal::float3x3 unnamed_84 = 2.0 * const_type_15_; - metal::float3 unnamed_85 = const_type_16_ * metal::float4(1.0); - metal::float4 unnamed_86 = metal::float3(2.0) * const_type_16_; - metal::float3x3 unnamed_87 = const_type_16_ * const_type_17_; + metal::float3x3 unnamed_81 = const_type_16_ + const_type_16_; + metal::float3x3 unnamed_82 = const_type_16_ - const_type_16_; + metal::float3x3 unnamed_83 = const_type_16_ * 1.0; + metal::float3x3 unnamed_84 = 2.0 * const_type_16_; + metal::float3 unnamed_85 = const_type_17_ * metal::float4(1.0); + metal::float4 unnamed_86 = metal::float3(2.0) * const_type_17_; + metal::float3x3 unnamed_87 = const_type_17_ * const_type_18_; } void bit( @@ -248,38 +248,40 @@ void comparison( void assignment( ) { - int a_1 = 1; - metal::int3 vec0_ = const_type_18_; + int a_1 = {}; + metal::int3 vec0_ = {}; + a_1 = 1; + int _e3 = a_1; + a_1 = _e3 + 1; int _e6 = a_1; - a_1 = _e6 + 1; + a_1 = _e6 - 1; + int _e8 = a_1; int _e9 = a_1; - a_1 = _e9 - 1; + a_1 = _e9 * _e8; + int _e11 = a_1; int _e12 = a_1; - int _e13 = a_1; - a_1 = _e12 * _e13; + a_1 = _e12 / _e11; int _e15 = a_1; - int _e16 = a_1; - a_1 = _e15 / _e16; + a_1 = _e15 % 1; int _e18 = a_1; - a_1 = _e18 % 1; + a_1 = _e18 & 0; int _e21 = a_1; - a_1 = _e21 & 0; + a_1 = _e21 | 0; int _e24 = a_1; - a_1 = _e24 | 0; + a_1 = _e24 ^ 0; int _e27 = a_1; - a_1 = _e27 ^ 0; + a_1 = _e27 << 2u; int _e30 = a_1; - a_1 = _e30 << 2u; - int _e33 = a_1; - a_1 = _e33 >> 1u; - int _e36 = a_1; - a_1 = _e36 + 1; - int _e39 = a_1; - a_1 = _e39 - 1; - int _e46 = vec0_.y; - vec0_.y = _e46 + 1; - int _e51 = vec0_.y; - vec0_.y = _e51 - 1; + a_1 = _e30 >> 1u; + int _e32 = a_1; + a_1 = _e32 + 1; + int _e35 = a_1; + a_1 = _e35 - 1; + vec0_ = const_type_19_; + int _e42 = vec0_.y; + vec0_.y = _e42 + 1; + int _e47 = vec0_.y; + vec0_.y = _e47 - 1; return; } @@ -296,10 +298,10 @@ void negation_avoids_prefix_decrement( kernel void main_( ) { - metal::float4 _e4 = builtins(); - metal::float4 _e5 = splat(); - metal::float3 _e7 = bool_cast(v_f32_one.xyz); - float _e8 = constructors(); + metal::float4 _e0 = builtins(); + metal::float4 _e1 = splat(); + metal::float3 _e4 = bool_cast(v_f32_one.xyz); + float _e5 = constructors(); logical(); arithmetic(); bit(); diff --git a/tests/out/msl/padding.msl b/tests/out/msl/padding.msl index 90b2c2eb11..4d99bb4c4c 100644 --- a/tests/out/msl/padding.msl +++ b/tests/out/msl/padding.msl @@ -31,8 +31,8 @@ vertex vertex_Output vertex_( , constant Test2_& input2_ [[buffer(1)]] , constant Test3_& input3_ [[buffer(2)]] ) { - float _e6 = input1_.b; - float _e9 = input2_.b; + float _e4 = input1_.b; + float _e8 = input2_.b; float _e12 = input3_.b; - return vertex_Output { ((metal::float4(1.0) * _e6) * _e9) * _e12 }; + return vertex_Output { ((metal::float4(1.0) * _e4) * _e8) * _e12 }; } diff --git a/tests/out/msl/policy-mix.msl b/tests/out/msl/policy-mix.msl index dd780641fc..842c57e58c 100644 --- a/tests/out/msl/policy-mix.msl +++ b/tests/out/msl/policy-mix.msl @@ -44,11 +44,11 @@ metal::float4 mock_function( ) { type_9 in_function = {}; for(int _i=0; _i<2; ++_i) in_function.inner[_i] = type_9 {metal::float4(0.7070000171661377, 0.0, 0.0, 1.0), metal::float4(0.0, 0.7070000171661377, 0.0, 1.0)}.inner[_i]; - metal::float4 _e22 = in_storage.a.inner[i]; - metal::float4 _e25 = in_uniform.a.inner[i]; - metal::float4 _e27 = (uint(l) < image_2d_array.get_num_mip_levels() && uint(i) < image_2d_array.get_array_size() && metal::all(metal::uint2(c) < metal::uint2(image_2d_array.get_width(l), image_2d_array.get_height(l))) ? image_2d_array.read(metal::uint2(c), i, l): DefaultConstructible()); - float _e30 = in_workgroup.inner[metal::min(unsigned(i), 29u)]; + metal::float4 _e18 = in_storage.a.inner[i]; + metal::float4 _e22 = in_uniform.a.inner[i]; + metal::float4 _e25 = (uint(l) < image_2d_array.get_num_mip_levels() && uint(i) < image_2d_array.get_array_size() && metal::all(metal::uint2(c) < metal::uint2(image_2d_array.get_width(l), image_2d_array.get_height(l))) ? image_2d_array.read(metal::uint2(c), i, l): DefaultConstructible()); + float _e29 = in_workgroup.inner[metal::min(unsigned(i), 29u)]; float _e34 = in_private.inner[metal::min(unsigned(i), 39u)]; metal::float4 _e38 = in_function.inner[metal::min(unsigned(i), 1u)]; - return ((((_e22 + _e25) + _e27) + metal::float4(_e30)) + metal::float4(_e34)) + _e38; + return ((((_e18 + _e22) + _e25) + metal::float4(_e29)) + metal::float4(_e34)) + _e38; } diff --git a/tests/out/msl/shadow.msl b/tests/out/msl/shadow.msl index 651a89841a..fa1b284c6b 100644 --- a/tests/out/msl/shadow.msl +++ b/tests/out/msl/shadow.msl @@ -45,8 +45,8 @@ float fetch_shadow( metal::float2 flip_correction = metal::float2(0.5, -0.5); float proj_correction = 1.0 / homogeneous_coords.w; metal::float2 light_local = ((homogeneous_coords.xy * flip_correction) * proj_correction) + metal::float2(0.5, 0.5); - float _e28 = t_shadow.sample_compare(sampler_shadow, light_local, static_cast(light_id), homogeneous_coords.z * proj_correction); - return _e28; + float _e24 = t_shadow.sample_compare(sampler_shadow, light_local, static_cast(light_id), homogeneous_coords.z * proj_correction); + return _e24; } struct vs_mainInput { @@ -71,10 +71,10 @@ vertex vs_mainOutput vs_main( metal::float4 world_pos = _e7 * static_cast(position); out.world_normal = metal::float3x3(w[0].xyz, w[1].xyz, w[2].xyz) * static_cast(normal.xyz); out.world_position = world_pos; - metal::float4x4 _e25 = u_globals.view_proj; - out.proj_position = _e25 * world_pos; - VertexOutput _e27 = out; - const auto _tmp = _e27; + metal::float4x4 _e26 = u_globals.view_proj; + out.proj_position = _e26 * world_pos; + VertexOutput _e28 = out; + const auto _tmp = _e28; return vs_mainOutput { _tmp.proj_position, _tmp.world_normal, _tmp.world_position }; } @@ -97,34 +97,38 @@ fragment fs_mainOutput fs_main( , constant _mslBufferSizes& _buffer_sizes [[user(fake0)]] ) { const VertexOutput in = { proj_position, varyings_1.world_normal, varyings_1.world_position }; - metal::float3 color = c_ambient; - uint i = 0u; + metal::float3 color = {}; + uint i = {}; metal::float3 normal_1 = metal::normalize(in.world_normal); + color = c_ambient; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e20 = i; - i = _e20 + 1u; + uint _e39 = i; + i = _e39 + 1u; } loop_init = false; - uint _e14 = i; - uint _e17 = u_globals.num_lights.x; - if (_e14 < metal::min(_e17, c_max_lights)) { + uint _e7 = i; + uint _e11 = u_globals.num_lights.x; + if (_e7 < metal::min(_e11, c_max_lights)) { } else { break; } - uint _e23 = i; - Light light = s_lights[_e23]; - uint _e26 = i; - float _e30 = fetch_shadow(_e26, light.proj * in.world_position, t_shadow, sampler_shadow); - metal::float3 light_dir = metal::normalize(light.pos.xyz - in.world_position.xyz); - float diffuse = metal::max(0.0, metal::dot(normal_1, light_dir)); - metal::float3 _e40 = color; - color = _e40 + ((_e30 * diffuse) * light.color.xyz); + { + uint _e16 = i; + Light light = s_lights[_e16]; + uint _e19 = i; + float _e23 = fetch_shadow(_e19, light.proj * in.world_position, t_shadow, sampler_shadow); + metal::float3 light_dir = metal::normalize(light.pos.xyz - in.world_position.xyz); + float diffuse = metal::max(0.0, metal::dot(normal_1, light_dir)); + metal::float3 _e37 = color; + color = _e37 + ((_e23 * diffuse) * light.color.xyz); + } } - metal::float3 _e46 = color; - metal::float4 _e50 = u_entity.color; - return fs_mainOutput { metal::float4(_e46, 1.0) * _e50 }; + metal::float3 _e42 = color; + metal::float4 _e47 = u_entity.color; + return fs_mainOutput { metal::float4(_e42, 1.0) * _e47 }; } @@ -145,32 +149,36 @@ fragment fs_main_without_storageOutput fs_main_without_storage( , metal::sampler sampler_shadow [[user(fake0)]] ) { const VertexOutput in_1 = { proj_position_1, varyings_2.world_normal, varyings_2.world_position }; - metal::float3 color_1 = c_ambient; - uint i_1 = 0u; + metal::float3 color_1 = {}; + uint i_1 = {}; metal::float3 normal_2 = metal::normalize(in_1.world_normal); + color_1 = c_ambient; + i_1 = 0u; bool loop_init_1 = true; while(true) { if (!loop_init_1) { - uint _e20 = i_1; - i_1 = _e20 + 1u; + uint _e39 = i_1; + i_1 = _e39 + 1u; } loop_init_1 = false; - uint _e14 = i_1; - uint _e17 = u_globals.num_lights.x; - if (_e14 < metal::min(_e17, c_max_lights)) { + uint _e7 = i_1; + uint _e11 = u_globals.num_lights.x; + if (_e7 < metal::min(_e11, c_max_lights)) { } else { break; } - uint _e23 = i_1; - Light light_1 = u_lights.inner[_e23]; - uint _e26 = i_1; - float _e30 = fetch_shadow(_e26, light_1.proj * in_1.world_position, t_shadow, sampler_shadow); - metal::float3 light_dir_1 = metal::normalize(light_1.pos.xyz - in_1.world_position.xyz); - float diffuse_1 = metal::max(0.0, metal::dot(normal_2, light_dir_1)); - metal::float3 _e40 = color_1; - color_1 = _e40 + ((_e30 * diffuse_1) * light_1.color.xyz); + { + uint _e16 = i_1; + Light light_1 = u_lights.inner[_e16]; + uint _e19 = i_1; + float _e23 = fetch_shadow(_e19, light_1.proj * in_1.world_position, t_shadow, sampler_shadow); + metal::float3 light_dir_1 = metal::normalize(light_1.pos.xyz - in_1.world_position.xyz); + float diffuse_1 = metal::max(0.0, metal::dot(normal_2, light_dir_1)); + metal::float3 _e37 = color_1; + color_1 = _e37 + ((_e23 * diffuse_1) * light_1.color.xyz); + } } - metal::float3 _e46 = color_1; - metal::float4 _e50 = u_entity.color; - return fs_main_without_storageOutput { metal::float4(_e46, 1.0) * _e50 }; + metal::float3 _e42 = color_1; + metal::float4 _e47 = u_entity.color; + return fs_main_without_storageOutput { metal::float4(_e42, 1.0) * _e47 }; } diff --git a/tests/out/msl/skybox.msl b/tests/out/msl/skybox.msl index c25770d4ff..7b10ea23e7 100644 --- a/tests/out/msl/skybox.msl +++ b/tests/out/msl/skybox.msl @@ -27,15 +27,15 @@ vertex vs_mainOutput vs_main( int tmp2_ = {}; tmp1_ = static_cast(vertex_index) / 2; tmp2_ = static_cast(vertex_index) & 1; - int _e10 = tmp1_; - int _e16 = tmp2_; - metal::float4 pos = metal::float4((static_cast(_e10) * 4.0) - 1.0, (static_cast(_e16) * 4.0) - 1.0, 0.0, 1.0); + int _e9 = tmp1_; + int _e15 = tmp2_; + metal::float4 pos = metal::float4((static_cast(_e9) * 4.0) - 1.0, (static_cast(_e15) * 4.0) - 1.0, 0.0, 1.0); metal::float4 _e27 = r_data.view[0]; - metal::float4 _e31 = r_data.view[1]; - metal::float4 _e35 = r_data.view[2]; - metal::float3x3 inv_model_view = metal::transpose(metal::float3x3(_e27.xyz, _e31.xyz, _e35.xyz)); - metal::float4x4 _e40 = r_data.proj_inv; - metal::float4 unprojected = _e40 * pos; + metal::float4 _e32 = r_data.view[1]; + metal::float4 _e37 = r_data.view[2]; + metal::float3x3 inv_model_view = metal::transpose(metal::float3x3(_e27.xyz, _e32.xyz, _e37.xyz)); + metal::float4x4 _e43 = r_data.proj_inv; + metal::float4 unprojected = _e43 * pos; const auto _tmp = VertexOutput {pos, inv_model_view * unprojected.xyz}; return vs_mainOutput { _tmp.position, _tmp.uv }; } @@ -61,6 +61,6 @@ fragment fs_mainOutput fs_main( metal::coord::normalized ); const VertexOutput in = { position, varyings_1.uv }; - metal::float4 _e5 = r_texture.sample(r_sampler, in.uv); - return fs_mainOutput { _e5 }; + metal::float4 _e4 = r_texture.sample(r_sampler, in.uv); + return fs_mainOutput { _e4 }; } diff --git a/tests/out/msl/texture-arg.msl b/tests/out/msl/texture-arg.msl index ba0be05e18..5fb9b25649 100644 --- a/tests/out/msl/texture-arg.msl +++ b/tests/out/msl/texture-arg.msl @@ -9,8 +9,8 @@ metal::float4 test( metal::texture2d Passed_Texture, metal::sampler Passed_Sampler ) { - metal::float4 _e7 = Passed_Texture.sample(Passed_Sampler, metal::float2(0.0, 0.0)); - return _e7; + metal::float4 _e5 = Passed_Texture.sample(Passed_Sampler, metal::float2(0.0, 0.0)); + return _e5; } struct main_Output { diff --git a/tests/out/spv/access.spvasm b/tests/out/spv/access.spvasm index fe7e75d4a4..bc3cb6a504 100644 --- a/tests/out/spv/access.spvasm +++ b/tests/out/spv/access.spvasm @@ -1,18 +1,18 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 320 +; Bound: 323 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %233 "foo_vert" %228 %231 -OpEntryPoint Fragment %274 "foo_frag" %273 -OpEntryPoint GLCompute %293 "atomics" -OpEntryPoint GLCompute %317 "assign_through_ptr" -OpExecutionMode %274 OriginUpperLeft -OpExecutionMode %293 LocalSize 1 1 1 -OpExecutionMode %317 LocalSize 1 1 1 +OpEntryPoint Vertex %236 "foo_vert" %231 %234 +OpEntryPoint Fragment %277 "foo_frag" %276 +OpEntryPoint GLCompute %296 "atomics" +OpEntryPoint GLCompute %320 "assign_through_ptr" +OpExecutionMode %277 OriginUpperLeft +OpExecutionMode %296 LocalSize 1 1 1 +OpExecutionMode %320 LocalSize 1 1 1 OpSource GLSL 450 OpMemberName %36 0 "a" OpMemberName %36 1 "b" @@ -30,32 +30,32 @@ OpMemberName %48 0 "m" OpName %48 "Baz" OpMemberName %52 0 "am" OpName %52 "MatCx2InArray" -OpName %68 "global_const" -OpName %70 "bar" -OpName %72 "baz" -OpName %75 "qux" -OpName %78 "nested_mat_cx2" -OpName %81 "val" -OpName %82 "idx" -OpName %84 "t" -OpName %88 "test_matrix_within_struct_accesses" -OpName %146 "idx" -OpName %147 "t" -OpName %151 "test_matrix_within_array_within_struct_accesses" -OpName %206 "foo" -OpName %207 "read_from_private" -OpName %212 "a" -OpName %213 "test_arr_as_arg" -OpName %219 "p" -OpName %220 "assign_through_ptr_fn" -OpName %223 "foo" -OpName %224 "c" -OpName %228 "vi" -OpName %233 "foo_vert" -OpName %274 "foo_frag" -OpName %290 "tmp" -OpName %293 "atomics" -OpName %317 "assign_through_ptr" +OpName %69 "global_const" +OpName %71 "bar" +OpName %73 "baz" +OpName %76 "qux" +OpName %79 "nested_mat_cx2" +OpName %82 "val" +OpName %83 "idx" +OpName %86 "t" +OpName %90 "test_matrix_within_struct_accesses" +OpName %147 "idx" +OpName %149 "t" +OpName %153 "test_matrix_within_array_within_struct_accesses" +OpName %208 "foo" +OpName %209 "read_from_private" +OpName %214 "a" +OpName %215 "test_arr_as_arg" +OpName %221 "p" +OpName %222 "assign_through_ptr_fn" +OpName %225 "foo" +OpName %227 "c2" +OpName %231 "vi" +OpName %236 "foo_vert" +OpName %277 "foo_frag" +OpName %293 "tmp" +OpName %296 "atomics" +OpName %320 "assign_through_ptr" OpMemberDecorate %36 0 Offset 0 OpMemberDecorate %36 1 Offset 16 OpMemberDecorate %36 2 Offset 28 @@ -82,24 +82,24 @@ OpMemberDecorate %52 0 MatrixStride 8 OpDecorate %54 ArrayStride 4 OpDecorate %55 ArrayStride 40 OpDecorate %58 ArrayStride 4 -OpDecorate %70 DescriptorSet 0 -OpDecorate %70 Binding 0 +OpDecorate %71 DescriptorSet 0 +OpDecorate %71 Binding 0 OpDecorate %46 Block -OpDecorate %72 DescriptorSet 0 -OpDecorate %72 Binding 1 -OpDecorate %73 Block -OpMemberDecorate %73 0 Offset 0 -OpDecorate %75 DescriptorSet 0 -OpDecorate %75 Binding 2 -OpDecorate %76 Block -OpMemberDecorate %76 0 Offset 0 -OpDecorate %78 DescriptorSet 0 -OpDecorate %78 Binding 3 -OpDecorate %79 Block -OpMemberDecorate %79 0 Offset 0 -OpDecorate %228 BuiltIn VertexIndex -OpDecorate %231 BuiltIn Position -OpDecorate %273 Location 0 +OpDecorate %73 DescriptorSet 0 +OpDecorate %73 Binding 1 +OpDecorate %74 Block +OpMemberDecorate %74 0 Offset 0 +OpDecorate %76 DescriptorSet 0 +OpDecorate %76 Binding 2 +OpDecorate %77 Block +OpMemberDecorate %77 0 Offset 0 +OpDecorate %79 DescriptorSet 0 +OpDecorate %79 Binding 3 +OpDecorate %80 Block +OpMemberDecorate %80 0 Offset 0 +OpDecorate %231 BuiltIn VertexIndex +OpDecorate %234 BuiltIn Position +OpDecorate %276 Location 0 %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 0 @@ -157,332 +157,338 @@ OpDecorate %273 Location 0 %56 = OpTypeVector %10 4 %57 = OpTypePointer StorageBuffer %6 %58 = OpTypeArray %6 %26 -%59 = OpTypePointer Workgroup %4 -%60 = OpConstantComposite %35 %3 %3 %3 -%61 = OpConstantComposite %36 %3 %60 %5 -%62 = OpConstantComposite %41 %22 %22 -%63 = OpConstantComposite %50 %62 %62 %62 %62 -%64 = OpConstantComposite %51 %63 %63 -%65 = OpConstantComposite %54 %22 %22 %22 %22 %22 %22 %22 %22 %22 %22 -%66 = OpConstantComposite %55 %65 %65 %65 %65 %65 -%67 = OpConstantComposite %49 %5 %5 -%69 = OpTypePointer Private %36 -%68 = OpVariable %69 Private %61 -%71 = OpTypePointer StorageBuffer %46 -%70 = OpVariable %71 StorageBuffer -%73 = OpTypeStruct %48 -%74 = OpTypePointer Uniform %73 -%72 = OpVariable %74 Uniform -%76 = OpTypeStruct %49 -%77 = OpTypePointer StorageBuffer %76 -%75 = OpVariable %77 StorageBuffer -%79 = OpTypeStruct %52 -%80 = OpTypePointer Uniform %79 -%78 = OpVariable %80 Uniform -%81 = OpVariable %59 Workgroup -%83 = OpTypePointer Function %6 -%85 = OpTypePointer Function %48 -%86 = OpConstantNull %48 -%89 = OpTypeFunction %2 -%90 = OpTypePointer Uniform %48 -%92 = OpTypePointer StorageBuffer %49 -%96 = OpTypePointer Uniform %47 -%99 = OpTypePointer Uniform %41 -%105 = OpTypePointer Uniform %10 -%125 = OpTypePointer Function %47 -%131 = OpTypePointer Function %41 -%137 = OpTypePointer Function %10 -%148 = OpTypePointer Function %52 -%149 = OpConstantNull %52 -%152 = OpTypePointer Uniform %52 -%157 = OpTypePointer Uniform %51 -%160 = OpTypePointer Uniform %50 -%183 = OpTypePointer Function %51 -%185 = OpTypePointer Function %50 -%208 = OpTypeFunction %10 %53 -%214 = OpTypeFunction %10 %55 -%221 = OpTypeFunction %2 %59 -%225 = OpTypePointer Function %58 -%226 = OpConstantNull %58 -%229 = OpTypePointer Input %4 -%228 = OpVariable %229 Input -%232 = OpTypePointer Output %56 -%231 = OpVariable %232 Output -%241 = OpTypePointer StorageBuffer %38 -%244 = OpTypePointer StorageBuffer %44 -%247 = OpTypePointer StorageBuffer %39 -%248 = OpTypePointer StorageBuffer %10 -%251 = OpTypePointer StorageBuffer %45 -%254 = OpTypePointer StorageBuffer %37 -%255 = OpConstant %4 4 -%267 = OpTypeVector %6 4 -%273 = OpVariable %232 Output -%291 = OpConstantNull %6 -%295 = OpTypePointer StorageBuffer %6 -%298 = OpConstant %4 64 -%88 = OpFunction %2 None %89 -%87 = OpLabel -%82 = OpVariable %83 Function %8 -%84 = OpVariable %85 Function %86 -%91 = OpAccessChain %90 %72 %3 -OpBranch %93 -%93 = OpLabel -%94 = OpLoad %6 %82 -%95 = OpISub %6 %94 %8 -OpStore %82 %95 -%97 = OpAccessChain %96 %91 %3 -%98 = OpLoad %47 %97 -%100 = OpAccessChain %99 %91 %3 %3 -%101 = OpLoad %41 %100 -%102 = OpLoad %6 %82 -%103 = OpAccessChain %99 %91 %3 %102 -%104 = OpLoad %41 %103 -%106 = OpAccessChain %105 %91 %3 %3 %32 -%107 = OpLoad %10 %106 -%108 = OpLoad %6 %82 -%109 = OpAccessChain %105 %91 %3 %3 %108 -%110 = OpLoad %10 %109 -%111 = OpLoad %6 %82 -%112 = OpAccessChain %105 %91 %3 %111 %32 -%113 = OpLoad %10 %112 -%114 = OpLoad %6 %82 -%115 = OpLoad %6 %82 -%116 = OpAccessChain %105 %91 %3 %114 %115 -%117 = OpLoad %10 %116 -%118 = OpCompositeConstruct %41 %9 %9 -%119 = OpCompositeConstruct %41 %11 %11 -%120 = OpCompositeConstruct %41 %12 %12 -%121 = OpCompositeConstruct %47 %118 %119 %120 -%122 = OpCompositeConstruct %48 %121 -OpStore %84 %122 -%123 = OpLoad %6 %82 -%124 = OpIAdd %6 %123 %8 -OpStore %82 %124 -%126 = OpCompositeConstruct %41 %13 %13 -%127 = OpCompositeConstruct %41 %14 %14 -%128 = OpCompositeConstruct %41 %15 %15 -%129 = OpCompositeConstruct %47 %126 %127 %128 -%130 = OpAccessChain %125 %84 %3 -OpStore %130 %129 -%132 = OpCompositeConstruct %41 %16 %16 -%133 = OpAccessChain %131 %84 %3 %3 -OpStore %133 %132 -%134 = OpLoad %6 %82 -%135 = OpCompositeConstruct %41 %17 %17 -%136 = OpAccessChain %131 %84 %3 %134 -OpStore %136 %135 -%138 = OpAccessChain %137 %84 %3 %3 %32 -OpStore %138 %18 -%139 = OpLoad %6 %82 -%140 = OpAccessChain %137 %84 %3 %3 %139 -OpStore %140 %19 -%141 = OpLoad %6 %82 -%142 = OpAccessChain %137 %84 %3 %141 %32 -OpStore %142 %20 -%143 = OpLoad %6 %82 -%144 = OpLoad %6 %82 -%145 = OpAccessChain %137 %84 %3 %143 %144 -OpStore %145 %21 +%59 = OpTypeVector %6 4 +%60 = OpTypePointer Workgroup %4 +%61 = OpConstantComposite %35 %3 %3 %3 +%62 = OpConstantComposite %36 %3 %61 %5 +%63 = OpConstantComposite %41 %22 %22 +%64 = OpConstantComposite %50 %63 %63 %63 %63 +%65 = OpConstantComposite %51 %64 %64 +%66 = OpConstantComposite %54 %22 %22 %22 %22 %22 %22 %22 %22 %22 %22 +%67 = OpConstantComposite %55 %66 %66 %66 %66 %66 +%68 = OpConstantComposite %49 %5 %5 +%70 = OpTypePointer Private %36 +%69 = OpVariable %70 Private %62 +%72 = OpTypePointer StorageBuffer %46 +%71 = OpVariable %72 StorageBuffer +%74 = OpTypeStruct %48 +%75 = OpTypePointer Uniform %74 +%73 = OpVariable %75 Uniform +%77 = OpTypeStruct %49 +%78 = OpTypePointer StorageBuffer %77 +%76 = OpVariable %78 StorageBuffer +%80 = OpTypeStruct %52 +%81 = OpTypePointer Uniform %80 +%79 = OpVariable %81 Uniform +%82 = OpVariable %60 Workgroup +%84 = OpTypePointer Function %6 +%85 = OpConstantNull %6 +%87 = OpTypePointer Function %48 +%88 = OpConstantNull %48 +%91 = OpTypeFunction %2 +%92 = OpTypePointer Uniform %48 +%97 = OpTypePointer Uniform %47 +%100 = OpTypePointer Uniform %41 +%106 = OpTypePointer Uniform %10 +%126 = OpTypePointer Function %47 +%132 = OpTypePointer Function %41 +%138 = OpTypePointer Function %10 +%148 = OpConstantNull %6 +%150 = OpTypePointer Function %52 +%151 = OpConstantNull %52 +%154 = OpTypePointer Uniform %52 +%159 = OpTypePointer Uniform %51 +%162 = OpTypePointer Uniform %50 +%185 = OpTypePointer Function %51 +%187 = OpTypePointer Function %50 +%210 = OpTypeFunction %10 %53 +%216 = OpTypeFunction %10 %55 +%223 = OpTypeFunction %2 %60 +%226 = OpConstantNull %10 +%228 = OpTypePointer Function %58 +%229 = OpConstantNull %58 +%232 = OpTypePointer Input %4 +%231 = OpVariable %232 Input +%235 = OpTypePointer Output %56 +%234 = OpVariable %235 Output +%238 = OpTypePointer StorageBuffer %49 +%245 = OpTypePointer StorageBuffer %38 +%248 = OpTypePointer StorageBuffer %44 +%251 = OpTypePointer StorageBuffer %39 +%252 = OpTypePointer StorageBuffer %10 +%255 = OpTypePointer StorageBuffer %45 +%258 = OpTypePointer StorageBuffer %37 +%259 = OpConstant %4 4 +%276 = OpVariable %235 Output +%294 = OpConstantNull %6 +%298 = OpTypePointer StorageBuffer %6 +%301 = OpConstant %4 64 +%90 = OpFunction %2 None %91 +%89 = OpLabel +%83 = OpVariable %84 Function %85 +%86 = OpVariable %87 Function %88 +%93 = OpAccessChain %92 %73 %3 +OpBranch %94 +%94 = OpLabel +OpStore %83 %8 +%95 = OpLoad %6 %83 +%96 = OpISub %6 %95 %8 +OpStore %83 %96 +%98 = OpAccessChain %97 %93 %3 +%99 = OpLoad %47 %98 +%101 = OpAccessChain %100 %93 %3 %3 +%102 = OpLoad %41 %101 +%103 = OpLoad %6 %83 +%104 = OpAccessChain %100 %93 %3 %103 +%105 = OpLoad %41 %104 +%107 = OpAccessChain %106 %93 %3 %3 %32 +%108 = OpLoad %10 %107 +%109 = OpLoad %6 %83 +%110 = OpAccessChain %106 %93 %3 %3 %109 +%111 = OpLoad %10 %110 +%112 = OpLoad %6 %83 +%113 = OpAccessChain %106 %93 %3 %112 %32 +%114 = OpLoad %10 %113 +%115 = OpLoad %6 %83 +%116 = OpLoad %6 %83 +%117 = OpAccessChain %106 %93 %3 %115 %116 +%118 = OpLoad %10 %117 +%119 = OpCompositeConstruct %41 %9 %9 +%120 = OpCompositeConstruct %41 %11 %11 +%121 = OpCompositeConstruct %41 %12 %12 +%122 = OpCompositeConstruct %47 %119 %120 %121 +%123 = OpCompositeConstruct %48 %122 +OpStore %86 %123 +%124 = OpLoad %6 %83 +%125 = OpIAdd %6 %124 %8 +OpStore %83 %125 +%127 = OpCompositeConstruct %41 %13 %13 +%128 = OpCompositeConstruct %41 %14 %14 +%129 = OpCompositeConstruct %41 %15 %15 +%130 = OpCompositeConstruct %47 %127 %128 %129 +%131 = OpAccessChain %126 %86 %3 +OpStore %131 %130 +%133 = OpCompositeConstruct %41 %16 %16 +%134 = OpAccessChain %132 %86 %3 %3 +OpStore %134 %133 +%135 = OpLoad %6 %83 +%136 = OpCompositeConstruct %41 %17 %17 +%137 = OpAccessChain %132 %86 %3 %135 +OpStore %137 %136 +%139 = OpAccessChain %138 %86 %3 %3 %32 +OpStore %139 %18 +%140 = OpLoad %6 %83 +%141 = OpAccessChain %138 %86 %3 %3 %140 +OpStore %141 %19 +%142 = OpLoad %6 %83 +%143 = OpAccessChain %138 %86 %3 %142 %32 +OpStore %143 %20 +%144 = OpLoad %6 %83 +%145 = OpLoad %6 %83 +%146 = OpAccessChain %138 %86 %3 %144 %145 +OpStore %146 %21 OpReturn OpFunctionEnd -%151 = OpFunction %2 None %89 -%150 = OpLabel -%146 = OpVariable %83 Function %8 -%147 = OpVariable %148 Function %149 -%153 = OpAccessChain %152 %78 %3 -OpBranch %154 -%154 = OpLabel -%155 = OpLoad %6 %146 -%156 = OpISub %6 %155 %8 -OpStore %146 %156 -%158 = OpAccessChain %157 %153 %3 -%159 = OpLoad %51 %158 -%161 = OpAccessChain %160 %153 %3 %3 -%162 = OpLoad %50 %161 -%163 = OpAccessChain %99 %153 %3 %3 %3 -%164 = OpLoad %41 %163 -%165 = OpLoad %6 %146 -%166 = OpAccessChain %99 %153 %3 %3 %165 -%167 = OpLoad %41 %166 -%168 = OpAccessChain %105 %153 %3 %3 %3 %32 -%169 = OpLoad %10 %168 -%170 = OpLoad %6 %146 -%171 = OpAccessChain %105 %153 %3 %3 %3 %170 -%172 = OpLoad %10 %171 -%173 = OpLoad %6 %146 -%174 = OpAccessChain %105 %153 %3 %3 %173 %32 -%175 = OpLoad %10 %174 -%176 = OpLoad %6 %146 -%177 = OpLoad %6 %146 -%178 = OpAccessChain %105 %153 %3 %3 %176 %177 -%179 = OpLoad %10 %178 -%180 = OpCompositeConstruct %52 %64 -OpStore %147 %180 -%181 = OpLoad %6 %146 -%182 = OpIAdd %6 %181 %8 -OpStore %146 %182 -%184 = OpAccessChain %183 %147 %3 -OpStore %184 %64 -%186 = OpCompositeConstruct %41 %23 %23 -%187 = OpCompositeConstruct %41 %24 %24 -%188 = OpCompositeConstruct %41 %13 %13 -%189 = OpCompositeConstruct %41 %14 %14 -%190 = OpCompositeConstruct %50 %186 %187 %188 %189 -%191 = OpAccessChain %185 %147 %3 %3 -OpStore %191 %190 -%192 = OpCompositeConstruct %41 %16 %16 -%193 = OpAccessChain %131 %147 %3 %3 %3 +%153 = OpFunction %2 None %91 +%152 = OpLabel +%147 = OpVariable %84 Function %148 +%149 = OpVariable %150 Function %151 +%155 = OpAccessChain %154 %79 %3 +OpBranch %156 +%156 = OpLabel +OpStore %147 %8 +%157 = OpLoad %6 %147 +%158 = OpISub %6 %157 %8 +OpStore %147 %158 +%160 = OpAccessChain %159 %155 %3 +%161 = OpLoad %51 %160 +%163 = OpAccessChain %162 %155 %3 %3 +%164 = OpLoad %50 %163 +%165 = OpAccessChain %100 %155 %3 %3 %3 +%166 = OpLoad %41 %165 +%167 = OpLoad %6 %147 +%168 = OpAccessChain %100 %155 %3 %3 %167 +%169 = OpLoad %41 %168 +%170 = OpAccessChain %106 %155 %3 %3 %3 %32 +%171 = OpLoad %10 %170 +%172 = OpLoad %6 %147 +%173 = OpAccessChain %106 %155 %3 %3 %3 %172 +%174 = OpLoad %10 %173 +%175 = OpLoad %6 %147 +%176 = OpAccessChain %106 %155 %3 %3 %175 %32 +%177 = OpLoad %10 %176 +%178 = OpLoad %6 %147 +%179 = OpLoad %6 %147 +%180 = OpAccessChain %106 %155 %3 %3 %178 %179 +%181 = OpLoad %10 %180 +%182 = OpCompositeConstruct %52 %65 +OpStore %149 %182 +%183 = OpLoad %6 %147 +%184 = OpIAdd %6 %183 %8 +OpStore %147 %184 +%186 = OpAccessChain %185 %149 %3 +OpStore %186 %65 +%188 = OpCompositeConstruct %41 %23 %23 +%189 = OpCompositeConstruct %41 %24 %24 +%190 = OpCompositeConstruct %41 %13 %13 +%191 = OpCompositeConstruct %41 %14 %14 +%192 = OpCompositeConstruct %50 %188 %189 %190 %191 +%193 = OpAccessChain %187 %149 %3 %3 OpStore %193 %192 -%194 = OpLoad %6 %146 -%195 = OpCompositeConstruct %41 %17 %17 -%196 = OpAccessChain %131 %147 %3 %3 %194 -OpStore %196 %195 -%197 = OpAccessChain %137 %147 %3 %3 %3 %32 -OpStore %197 %18 -%198 = OpLoad %6 %146 -%199 = OpAccessChain %137 %147 %3 %3 %3 %198 -OpStore %199 %19 -%200 = OpLoad %6 %146 -%201 = OpAccessChain %137 %147 %3 %3 %200 %32 -OpStore %201 %20 -%202 = OpLoad %6 %146 -%203 = OpLoad %6 %146 -%204 = OpAccessChain %137 %147 %3 %3 %202 %203 -OpStore %204 %21 +%194 = OpCompositeConstruct %41 %16 %16 +%195 = OpAccessChain %132 %149 %3 %3 %3 +OpStore %195 %194 +%196 = OpLoad %6 %147 +%197 = OpCompositeConstruct %41 %17 %17 +%198 = OpAccessChain %132 %149 %3 %3 %196 +OpStore %198 %197 +%199 = OpAccessChain %138 %149 %3 %3 %3 %32 +OpStore %199 %18 +%200 = OpLoad %6 %147 +%201 = OpAccessChain %138 %149 %3 %3 %3 %200 +OpStore %201 %19 +%202 = OpLoad %6 %147 +%203 = OpAccessChain %138 %149 %3 %3 %202 %32 +OpStore %203 %20 +%204 = OpLoad %6 %147 +%205 = OpLoad %6 %147 +%206 = OpAccessChain %138 %149 %3 %3 %204 %205 +OpStore %206 %21 OpReturn OpFunctionEnd -%207 = OpFunction %10 None %208 -%206 = OpFunctionParameter %53 -%205 = OpLabel -OpBranch %209 -%209 = OpLabel -%210 = OpLoad %10 %206 -OpReturnValue %210 -OpFunctionEnd -%213 = OpFunction %10 None %214 -%212 = OpFunctionParameter %55 +%209 = OpFunction %10 None %210 +%208 = OpFunctionParameter %53 +%207 = OpLabel +OpBranch %211 %211 = OpLabel -OpBranch %215 -%215 = OpLabel -%216 = OpCompositeExtract %54 %212 4 -%217 = OpCompositeExtract %10 %216 9 -OpReturnValue %217 +%212 = OpLoad %10 %208 +OpReturnValue %212 OpFunctionEnd -%220 = OpFunction %2 None %221 -%219 = OpFunctionParameter %59 -%218 = OpLabel -OpBranch %222 -%222 = OpLabel -OpStore %219 %34 +%215 = OpFunction %10 None %216 +%214 = OpFunctionParameter %55 +%213 = OpLabel +OpBranch %217 +%217 = OpLabel +%218 = OpCompositeExtract %54 %214 4 +%219 = OpCompositeExtract %10 %218 9 +OpReturnValue %219 +OpFunctionEnd +%222 = OpFunction %2 None %223 +%221 = OpFunctionParameter %60 +%220 = OpLabel +OpBranch %224 +%224 = OpLabel +OpStore %221 %34 OpReturn OpFunctionEnd -%233 = OpFunction %2 None %89 -%227 = OpLabel -%223 = OpVariable %53 Function %22 -%224 = OpVariable %225 Function %226 -%230 = OpLoad %4 %228 -%234 = OpAccessChain %90 %72 %3 -%235 = OpAccessChain %92 %75 %3 -%236 = OpAccessChain %152 %78 %3 -OpBranch %237 -%237 = OpLabel -%238 = OpLoad %10 %223 -OpStore %223 %9 -%239 = OpFunctionCall %2 %88 -%240 = OpFunctionCall %2 %151 -%242 = OpAccessChain %241 %70 %3 -%243 = OpLoad %38 %242 -%245 = OpAccessChain %244 %70 %29 -%246 = OpLoad %44 %245 -%249 = OpAccessChain %248 %70 %3 %29 %3 -%250 = OpLoad %10 %249 -%252 = OpArrayLength %4 %70 4 -%253 = OpISub %4 %252 %30 -%256 = OpAccessChain %57 %70 %255 %253 %3 -%257 = OpLoad %6 %256 -%258 = OpLoad %49 %235 -%259 = OpFunctionCall %10 %207 %223 -%260 = OpConvertFToS %6 %250 -%261 = OpCompositeConstruct %58 %257 %260 %31 %27 %26 -OpStore %224 %261 -%262 = OpIAdd %4 %230 %32 -%263 = OpAccessChain %83 %224 %262 -OpStore %263 %33 -%264 = OpAccessChain %83 %224 %230 -%265 = OpLoad %6 %264 -%266 = OpFunctionCall %10 %213 %66 -%268 = OpCompositeConstruct %267 %265 %265 %265 %265 -%269 = OpConvertSToF %56 %268 -%270 = OpMatrixTimesVector %39 %243 %269 -%271 = OpCompositeConstruct %56 %270 %11 -OpStore %231 %271 +%236 = OpFunction %2 None %91 +%230 = OpLabel +%225 = OpVariable %53 Function %226 +%227 = OpVariable %228 Function %229 +%233 = OpLoad %4 %231 +%237 = OpAccessChain %92 %73 %3 +%239 = OpAccessChain %238 %76 %3 +%240 = OpAccessChain %154 %79 %3 +OpBranch %241 +%241 = OpLabel +OpStore %225 %22 +%242 = OpLoad %10 %225 +OpStore %225 %9 +%243 = OpFunctionCall %2 %90 +%244 = OpFunctionCall %2 %153 +%246 = OpAccessChain %245 %71 %3 +%247 = OpLoad %38 %246 +%249 = OpAccessChain %248 %71 %29 +%250 = OpLoad %44 %249 +%253 = OpAccessChain %252 %71 %3 %29 %3 +%254 = OpLoad %10 %253 +%256 = OpArrayLength %4 %71 4 +%257 = OpISub %4 %256 %30 +%260 = OpAccessChain %57 %71 %259 %257 %3 +%261 = OpLoad %6 %260 +%262 = OpLoad %49 %239 +%263 = OpFunctionCall %10 %209 %225 +%264 = OpConvertFToS %6 %254 +%265 = OpCompositeConstruct %58 %261 %264 %31 %27 %26 +OpStore %227 %265 +%266 = OpIAdd %4 %233 %32 +%267 = OpAccessChain %84 %227 %266 +OpStore %267 %33 +%268 = OpAccessChain %84 %227 %233 +%269 = OpLoad %6 %268 +%270 = OpFunctionCall %10 %215 %67 +%271 = OpCompositeConstruct %59 %269 %269 %269 %269 +%272 = OpConvertSToF %56 %271 +%273 = OpMatrixTimesVector %39 %247 %272 +%274 = OpCompositeConstruct %56 %273 %11 +OpStore %234 %274 OpReturn OpFunctionEnd -%274 = OpFunction %2 None %89 -%272 = OpLabel -%275 = OpAccessChain %92 %75 %3 -OpBranch %276 -%276 = OpLabel -%277 = OpAccessChain %248 %70 %3 %32 %30 -OpStore %277 %9 -%278 = OpCompositeConstruct %39 %22 %22 %22 -%279 = OpCompositeConstruct %39 %9 %9 %9 -%280 = OpCompositeConstruct %39 %11 %11 %11 -%281 = OpCompositeConstruct %39 %12 %12 %12 -%282 = OpCompositeConstruct %38 %278 %279 %280 %281 -%283 = OpAccessChain %241 %70 %3 -OpStore %283 %282 -%284 = OpCompositeConstruct %43 %3 %3 -%285 = OpCompositeConstruct %43 %32 %32 -%286 = OpCompositeConstruct %44 %284 %285 -%287 = OpAccessChain %244 %70 %29 -OpStore %287 %286 -%288 = OpAccessChain %57 %70 %255 %32 %3 -OpStore %288 %8 -OpStore %275 %67 -%289 = OpCompositeConstruct %56 %22 %22 %22 %22 -OpStore %273 %289 +%277 = OpFunction %2 None %91 +%275 = OpLabel +%278 = OpAccessChain %238 %76 %3 +OpBranch %279 +%279 = OpLabel +%280 = OpAccessChain %252 %71 %3 %32 %30 +OpStore %280 %9 +%281 = OpCompositeConstruct %39 %22 %22 %22 +%282 = OpCompositeConstruct %39 %9 %9 %9 +%283 = OpCompositeConstruct %39 %11 %11 %11 +%284 = OpCompositeConstruct %39 %12 %12 %12 +%285 = OpCompositeConstruct %38 %281 %282 %283 %284 +%286 = OpAccessChain %245 %71 %3 +OpStore %286 %285 +%287 = OpCompositeConstruct %43 %3 %3 +%288 = OpCompositeConstruct %43 %32 %32 +%289 = OpCompositeConstruct %44 %287 %288 +%290 = OpAccessChain %248 %71 %29 +OpStore %290 %289 +%291 = OpAccessChain %57 %71 %259 %32 %3 +OpStore %291 %8 +OpStore %278 %68 +%292 = OpCompositeConstruct %56 %22 %22 %22 %22 +OpStore %276 %292 OpReturn OpFunctionEnd -%293 = OpFunction %2 None %89 -%292 = OpLabel -%290 = OpVariable %83 Function %291 -OpBranch %294 -%294 = OpLabel -%296 = OpAccessChain %295 %70 %30 -%297 = OpAtomicLoad %6 %296 %8 %298 -%300 = OpAccessChain %295 %70 %30 -%299 = OpAtomicIAdd %6 %300 %8 %298 %26 -OpStore %290 %299 -%302 = OpAccessChain %295 %70 %30 -%301 = OpAtomicISub %6 %302 %8 %298 %26 -OpStore %290 %301 -%304 = OpAccessChain %295 %70 %30 -%303 = OpAtomicAnd %6 %304 %8 %298 %26 -OpStore %290 %303 -%306 = OpAccessChain %295 %70 %30 -%305 = OpAtomicOr %6 %306 %8 %298 %26 -OpStore %290 %305 -%308 = OpAccessChain %295 %70 %30 -%307 = OpAtomicXor %6 %308 %8 %298 %26 -OpStore %290 %307 -%310 = OpAccessChain %295 %70 %30 -%309 = OpAtomicSMin %6 %310 %8 %298 %26 -OpStore %290 %309 -%312 = OpAccessChain %295 %70 %30 -%311 = OpAtomicSMax %6 %312 %8 %298 %26 -OpStore %290 %311 -%314 = OpAccessChain %295 %70 %30 -%313 = OpAtomicExchange %6 %314 %8 %298 %26 -OpStore %290 %313 -%315 = OpAccessChain %295 %70 %30 -OpAtomicStore %315 %8 %298 %297 +%296 = OpFunction %2 None %91 +%295 = OpLabel +%293 = OpVariable %84 Function %294 +OpBranch %297 +%297 = OpLabel +%299 = OpAccessChain %298 %71 %30 +%300 = OpAtomicLoad %6 %299 %8 %301 +%303 = OpAccessChain %298 %71 %30 +%302 = OpAtomicIAdd %6 %303 %8 %301 %26 +OpStore %293 %302 +%305 = OpAccessChain %298 %71 %30 +%304 = OpAtomicISub %6 %305 %8 %301 %26 +OpStore %293 %304 +%307 = OpAccessChain %298 %71 %30 +%306 = OpAtomicAnd %6 %307 %8 %301 %26 +OpStore %293 %306 +%309 = OpAccessChain %298 %71 %30 +%308 = OpAtomicOr %6 %309 %8 %301 %26 +OpStore %293 %308 +%311 = OpAccessChain %298 %71 %30 +%310 = OpAtomicXor %6 %311 %8 %301 %26 +OpStore %293 %310 +%313 = OpAccessChain %298 %71 %30 +%312 = OpAtomicSMin %6 %313 %8 %301 %26 +OpStore %293 %312 +%315 = OpAccessChain %298 %71 %30 +%314 = OpAtomicSMax %6 %315 %8 %301 %26 +OpStore %293 %314 +%317 = OpAccessChain %298 %71 %30 +%316 = OpAtomicExchange %6 %317 %8 %301 %26 +OpStore %293 %316 +%318 = OpAccessChain %298 %71 %30 +OpAtomicStore %318 %8 %301 %300 OpReturn OpFunctionEnd -%317 = OpFunction %2 None %89 -%316 = OpLabel -OpBranch %318 -%318 = OpLabel -%319 = OpFunctionCall %2 %220 %81 +%320 = OpFunction %2 None %91 +%319 = OpLabel +OpBranch %321 +%321 = OpLabel +%322 = OpFunctionCall %2 %222 %82 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/atomicCompareExchange.spvasm b/tests/out/spv/atomicCompareExchange.spvasm index 9587f9aaa6..5af859324e 100644 --- a/tests/out/spv/atomicCompareExchange.spvasm +++ b/tests/out/spv/atomicCompareExchange.spvasm @@ -1,15 +1,15 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 116 +; Bound: 126 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %31 "test_atomic_compare_exchange_i32" -OpEntryPoint GLCompute %79 "test_atomic_compare_exchange_u32" -OpExecutionMode %31 LocalSize 1 1 1 -OpExecutionMode %79 LocalSize 1 1 1 +OpEntryPoint GLCompute %32 "test_atomic_compare_exchange_i32" +OpEntryPoint GLCompute %84 "test_atomic_compare_exchange_u32" +OpExecutionMode %32 LocalSize 1 1 1 +OpExecutionMode %84 LocalSize 1 1 1 OpDecorate %12 ArrayStride 4 OpDecorate %13 ArrayStride 4 OpMemberDecorate %14 0 Offset 0 @@ -28,16 +28,16 @@ OpMemberDecorate %20 0 Offset 0 %4 = OpTypeInt 32 0 %3 = OpConstant %4 128 %5 = OpConstant %4 0 -%6 = OpConstant %4 1 -%8 = OpTypeBool -%7 = OpConstantFalse %8 -%10 = OpTypeFloat 32 -%9 = OpConstant %10 1.0 +%7 = OpTypeBool +%6 = OpConstantFalse %7 +%9 = OpTypeFloat 32 +%8 = OpConstant %9 1.0 +%10 = OpConstant %4 1 %11 = OpTypeInt 32 1 %12 = OpTypeArray %11 %3 %13 = OpTypeArray %4 %3 -%14 = OpTypeStruct %11 %8 -%15 = OpTypeStruct %4 %8 +%14 = OpTypeStruct %11 %7 +%15 = OpTypeStruct %4 %7 %17 = OpTypeStruct %12 %18 = OpTypePointer StorageBuffer %17 %16 = OpVariable %18 StorageBuffer @@ -45,144 +45,164 @@ OpMemberDecorate %20 0 Offset 0 %21 = OpTypePointer StorageBuffer %20 %19 = OpVariable %21 StorageBuffer %23 = OpTypePointer Function %4 -%25 = OpTypePointer Function %11 -%26 = OpConstantNull %11 -%28 = OpTypePointer Function %8 -%29 = OpConstantNull %8 -%32 = OpTypeFunction %2 -%33 = OpTypePointer StorageBuffer %12 -%35 = OpTypePointer StorageBuffer %13 -%46 = OpTypePointer StorageBuffer %11 -%49 = OpConstant %11 1 -%50 = OpConstant %4 64 -%75 = OpConstantNull %4 -%77 = OpConstantNull %8 -%91 = OpTypePointer StorageBuffer %4 -%31 = OpFunction %2 None %32 -%30 = OpLabel -%22 = OpVariable %23 Function %5 -%24 = OpVariable %25 Function %26 -%27 = OpVariable %28 Function %29 -%34 = OpAccessChain %33 %16 %5 +%24 = OpConstantNull %4 +%26 = OpTypePointer Function %11 +%27 = OpConstantNull %11 +%29 = OpTypePointer Function %7 +%30 = OpConstantNull %7 +%33 = OpTypeFunction %2 +%34 = OpTypePointer StorageBuffer %12 +%48 = OpTypePointer StorageBuffer %11 +%51 = OpConstant %11 1 +%52 = OpConstant %4 64 +%78 = OpConstantNull %4 +%80 = OpConstantNull %4 +%82 = OpConstantNull %7 +%85 = OpTypePointer StorageBuffer %13 +%99 = OpTypePointer StorageBuffer %4 +%32 = OpFunction %2 None %33 +%31 = OpLabel +%22 = OpVariable %23 Function %24 +%25 = OpVariable %26 Function %27 +%28 = OpVariable %29 Function %30 +%35 = OpAccessChain %34 %16 %5 OpBranch %36 %36 = OpLabel +OpStore %22 %5 OpBranch %37 %37 = OpLabel OpLoopMerge %38 %40 None OpBranch %39 %39 = OpLabel %41 = OpLoad %4 %22 -%42 = OpULessThan %8 %41 %3 +%42 = OpULessThan %7 %41 %3 OpSelectionMerge %43 None OpBranchConditional %42 %43 %44 %44 = OpLabel OpBranch %38 %43 = OpLabel -%45 = OpLoad %4 %22 -%47 = OpAccessChain %46 %34 %45 -%48 = OpAtomicLoad %11 %47 %49 %50 -OpStore %24 %48 -OpStore %27 %7 -OpBranch %51 -%51 = OpLabel -OpLoopMerge %52 %54 None +OpBranch %45 +%45 = OpLabel +%47 = OpLoad %4 %22 +%49 = OpAccessChain %48 %35 %47 +%50 = OpAtomicLoad %11 %49 %51 %52 +OpStore %25 %50 +OpStore %28 %6 OpBranch %53 %53 = OpLabel -%55 = OpLoad %8 %27 -%56 = OpLogicalNot %8 %55 -OpSelectionMerge %57 None -OpBranchConditional %56 %57 %58 -%58 = OpLabel -OpBranch %52 -%57 = OpLabel -%59 = OpLoad %11 %24 -%60 = OpBitcast %10 %59 -%61 = OpFAdd %10 %60 %9 -%62 = OpBitcast %11 %61 -%63 = OpLoad %4 %22 -%64 = OpLoad %11 %24 -%66 = OpAccessChain %46 %34 %63 -%67 = OpAtomicCompareExchange %11 %66 %49 %50 %50 %62 %64 -%68 = OpIEqual %8 %67 %64 -%65 = OpCompositeConstruct %14 %67 %68 -%69 = OpCompositeExtract %11 %65 0 -OpStore %24 %69 -%70 = OpCompositeExtract %8 %65 1 -OpStore %27 %70 +OpLoopMerge %54 %56 None +OpBranch %55 +%55 = OpLabel +%57 = OpLoad %7 %28 +%58 = OpLogicalNot %7 %57 +OpSelectionMerge %59 None +OpBranchConditional %58 %59 %60 +%60 = OpLabel OpBranch %54 +%59 = OpLabel +OpBranch %61 +%61 = OpLabel +%63 = OpLoad %11 %25 +%64 = OpBitcast %9 %63 +%65 = OpFAdd %9 %64 %8 +%66 = OpBitcast %11 %65 +%67 = OpLoad %4 %22 +%68 = OpLoad %11 %25 +%70 = OpAccessChain %48 %35 %67 +%71 = OpAtomicCompareExchange %11 %70 %51 %52 %52 %66 %68 +%72 = OpIEqual %7 %71 %68 +%69 = OpCompositeConstruct %14 %71 %72 +%73 = OpCompositeExtract %11 %69 0 +OpStore %25 %73 +%74 = OpCompositeExtract %7 %69 1 +OpStore %28 %74 +OpBranch %62 +%62 = OpLabel +OpBranch %56 +%56 = OpLabel +OpBranch %53 %54 = OpLabel -OpBranch %51 -%52 = OpLabel +OpBranch %46 +%46 = OpLabel OpBranch %40 %40 = OpLabel -%71 = OpLoad %4 %22 -%72 = OpIAdd %4 %71 %6 -OpStore %22 %72 +%75 = OpLoad %4 %22 +%76 = OpIAdd %4 %75 %10 +OpStore %22 %76 OpBranch %37 %38 = OpLabel OpReturn OpFunctionEnd -%79 = OpFunction %2 None %32 -%78 = OpLabel -%73 = OpVariable %23 Function %5 -%74 = OpVariable %23 Function %75 -%76 = OpVariable %28 Function %77 -%80 = OpAccessChain %35 %19 %5 -OpBranch %81 -%81 = OpLabel -OpBranch %82 -%82 = OpLabel -OpLoopMerge %83 %85 None -OpBranch %84 -%84 = OpLabel -%86 = OpLoad %4 %73 -%87 = OpULessThan %8 %86 %3 -OpSelectionMerge %88 None -OpBranchConditional %87 %88 %89 -%89 = OpLabel -OpBranch %83 +%84 = OpFunction %2 None %33 +%83 = OpLabel +%77 = OpVariable %23 Function %78 +%79 = OpVariable %23 Function %80 +%81 = OpVariable %29 Function %82 +%86 = OpAccessChain %85 %19 %5 +OpBranch %87 +%87 = OpLabel +OpStore %77 %5 +OpBranch %88 %88 = OpLabel -%90 = OpLoad %4 %73 -%92 = OpAccessChain %91 %80 %90 -%93 = OpAtomicLoad %4 %92 %49 %50 -OpStore %74 %93 -OpStore %76 %7 -OpBranch %94 +OpLoopMerge %89 %91 None +OpBranch %90 +%90 = OpLabel +%92 = OpLoad %4 %77 +%93 = OpULessThan %7 %92 %3 +OpSelectionMerge %94 None +OpBranchConditional %93 %94 %95 +%95 = OpLabel +OpBranch %89 %94 = OpLabel -OpLoopMerge %95 %97 None OpBranch %96 %96 = OpLabel -%98 = OpLoad %8 %76 -%99 = OpLogicalNot %8 %98 -OpSelectionMerge %100 None -OpBranchConditional %99 %100 %101 -%101 = OpLabel -OpBranch %95 -%100 = OpLabel -%102 = OpLoad %4 %74 -%103 = OpBitcast %10 %102 -%104 = OpFAdd %10 %103 %9 -%105 = OpBitcast %4 %104 -%106 = OpLoad %4 %73 -%107 = OpLoad %4 %74 -%109 = OpAccessChain %91 %80 %106 -%110 = OpAtomicCompareExchange %4 %109 %49 %50 %50 %105 %107 -%111 = OpIEqual %8 %110 %107 -%108 = OpCompositeConstruct %15 %110 %111 -%112 = OpCompositeExtract %4 %108 0 -OpStore %74 %112 -%113 = OpCompositeExtract %8 %108 1 -OpStore %76 %113 +%98 = OpLoad %4 %77 +%100 = OpAccessChain %99 %86 %98 +%101 = OpAtomicLoad %4 %100 %51 %52 +OpStore %79 %101 +OpStore %81 %6 +OpBranch %102 +%102 = OpLabel +OpLoopMerge %103 %105 None +OpBranch %104 +%104 = OpLabel +%106 = OpLoad %7 %81 +%107 = OpLogicalNot %7 %106 +OpSelectionMerge %108 None +OpBranchConditional %107 %108 %109 +%109 = OpLabel +OpBranch %103 +%108 = OpLabel +OpBranch %110 +%110 = OpLabel +%112 = OpLoad %4 %79 +%113 = OpBitcast %9 %112 +%114 = OpFAdd %9 %113 %8 +%115 = OpBitcast %4 %114 +%116 = OpLoad %4 %77 +%117 = OpLoad %4 %79 +%119 = OpAccessChain %99 %86 %116 +%120 = OpAtomicCompareExchange %4 %119 %51 %52 %52 %115 %117 +%121 = OpIEqual %7 %120 %117 +%118 = OpCompositeConstruct %15 %120 %121 +%122 = OpCompositeExtract %4 %118 0 +OpStore %79 %122 +%123 = OpCompositeExtract %7 %118 1 +OpStore %81 %123 +OpBranch %111 +%111 = OpLabel +OpBranch %105 +%105 = OpLabel +OpBranch %102 +%103 = OpLabel OpBranch %97 %97 = OpLabel -OpBranch %94 -%95 = OpLabel -OpBranch %85 -%85 = OpLabel -%114 = OpLoad %4 %73 -%115 = OpIAdd %4 %114 %6 -OpStore %73 %115 -OpBranch %82 -%83 = OpLabel +OpBranch %91 +%91 = OpLabel +%124 = OpLoad %4 %77 +%125 = OpIAdd %4 %124 %10 +OpStore %77 %125 +OpBranch %88 +%89 = OpLabel OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/binding-arrays.spvasm b/tests/out/spv/binding-arrays.spvasm index a420eba46a..4c7ad3d226 100644 --- a/tests/out/spv/binding-arrays.spvasm +++ b/tests/out/spv/binding-arrays.spvasm @@ -1,62 +1,62 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 431 +; Bound: 433 OpCapability Shader OpCapability ImageQuery OpCapability ShaderNonUniform OpExtension "SPV_EXT_descriptor_indexing" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %65 "main" %60 %63 -OpExecutionMode %65 OriginUpperLeft +OpEntryPoint Fragment %68 "main" %63 %66 +OpExecutionMode %68 OriginUpperLeft OpMemberDecorate %9 0 Offset 0 OpMemberDecorate %24 0 Offset 0 -OpDecorate %27 DescriptorSet 0 -OpDecorate %27 Binding 0 -OpDecorate %31 DescriptorSet 0 -OpDecorate %31 Binding 1 -OpDecorate %33 DescriptorSet 0 -OpDecorate %33 Binding 2 -OpDecorate %35 DescriptorSet 0 -OpDecorate %35 Binding 3 -OpDecorate %37 DescriptorSet 0 -OpDecorate %37 Binding 4 -OpDecorate %39 DescriptorSet 0 -OpDecorate %39 Binding 5 -OpDecorate %41 DescriptorSet 0 -OpDecorate %41 Binding 6 -OpDecorate %43 DescriptorSet 0 -OpDecorate %43 Binding 7 -OpDecorate %45 DescriptorSet 0 -OpDecorate %45 Binding 8 -OpDecorate %46 Block -OpMemberDecorate %46 0 Offset 0 -OpDecorate %60 Location 0 -OpDecorate %60 Flat +OpDecorate %28 DescriptorSet 0 +OpDecorate %28 Binding 0 +OpDecorate %32 DescriptorSet 0 +OpDecorate %32 Binding 1 +OpDecorate %34 DescriptorSet 0 +OpDecorate %34 Binding 2 +OpDecorate %36 DescriptorSet 0 +OpDecorate %36 Binding 3 +OpDecorate %38 DescriptorSet 0 +OpDecorate %38 Binding 4 +OpDecorate %40 DescriptorSet 0 +OpDecorate %40 Binding 5 +OpDecorate %42 DescriptorSet 0 +OpDecorate %42 Binding 6 +OpDecorate %44 DescriptorSet 0 +OpDecorate %44 Binding 7 +OpDecorate %46 DescriptorSet 0 +OpDecorate %46 Binding 8 +OpDecorate %47 Block +OpMemberDecorate %47 0 Offset 0 OpDecorate %63 Location 0 -OpDecorate %93 NonUniform -OpDecorate %116 NonUniform -OpDecorate %118 NonUniform -OpDecorate %143 NonUniform -OpDecorate %145 NonUniform -OpDecorate %183 NonUniform -OpDecorate %212 NonUniform -OpDecorate %228 NonUniform -OpDecorate %244 NonUniform -OpDecorate %265 NonUniform -OpDecorate %267 NonUniform -OpDecorate %289 NonUniform -OpDecorate %291 NonUniform -OpDecorate %313 NonUniform -OpDecorate %315 NonUniform -OpDecorate %337 NonUniform -OpDecorate %339 NonUniform -OpDecorate %361 NonUniform -OpDecorate %363 NonUniform -OpDecorate %385 NonUniform -OpDecorate %387 NonUniform -OpDecorate %409 NonUniform +OpDecorate %63 Flat +OpDecorate %66 Location 0 +OpDecorate %94 NonUniform +OpDecorate %117 NonUniform +OpDecorate %119 NonUniform +OpDecorate %144 NonUniform +OpDecorate %146 NonUniform +OpDecorate %184 NonUniform +OpDecorate %213 NonUniform +OpDecorate %229 NonUniform +OpDecorate %245 NonUniform +OpDecorate %266 NonUniform +OpDecorate %268 NonUniform +OpDecorate %290 NonUniform +OpDecorate %292 NonUniform +OpDecorate %314 NonUniform +OpDecorate %316 NonUniform +OpDecorate %338 NonUniform +OpDecorate %340 NonUniform +OpDecorate %362 NonUniform +OpDecorate %364 NonUniform +OpDecorate %386 NonUniform +OpDecorate %388 NonUniform +OpDecorate %411 NonUniform %2 = OpTypeVoid %4 = OpTypeInt 32 1 %3 = OpConstant %4 5 @@ -82,476 +82,480 @@ OpDecorate %409 NonUniform %24 = OpTypeStruct %8 %25 = OpTypeVector %7 4 %26 = OpTypeVector %4 2 -%30 = OpConstant %8 10 -%29 = OpTypeArray %10 %30 -%28 = OpTypePointer UniformConstant %29 -%27 = OpVariable %28 UniformConstant -%32 = OpTypePointer UniformConstant %12 -%31 = OpVariable %32 UniformConstant -%34 = OpTypePointer UniformConstant %14 -%33 = OpVariable %34 UniformConstant -%36 = OpTypePointer UniformConstant %16 -%35 = OpVariable %36 UniformConstant -%38 = OpTypePointer UniformConstant %18 -%37 = OpVariable %38 UniformConstant -%40 = OpTypePointer UniformConstant %20 -%39 = OpVariable %40 UniformConstant -%42 = OpTypePointer UniformConstant %22 -%41 = OpVariable %42 UniformConstant -%44 = OpTypePointer UniformConstant %23 -%43 = OpVariable %44 UniformConstant -%46 = OpTypeStruct %9 -%47 = OpTypePointer Uniform %46 -%45 = OpVariable %47 Uniform -%49 = OpTypePointer Function %4 -%51 = OpTypePointer Function %26 -%52 = OpConstantNull %26 -%54 = OpTypePointer Function %7 -%56 = OpTypePointer Function %25 -%57 = OpConstantNull %25 -%61 = OpTypePointer Input %8 -%60 = OpVariable %61 Input -%64 = OpTypePointer Output %25 -%63 = OpVariable %64 Output -%66 = OpTypeFunction %2 -%67 = OpTypePointer Uniform %9 -%68 = OpConstant %8 0 -%71 = OpTypePointer Uniform %8 -%77 = OpTypeVector %7 2 -%81 = OpTypePointer UniformConstant %10 -%99 = OpTypePointer UniformConstant %21 -%102 = OpTypeSampledImage %10 -%123 = OpTypePointer UniformConstant %17 -%126 = OpTypePointer UniformConstant %21 -%129 = OpTypeSampledImage %17 -%152 = OpTypeBool -%153 = OpConstantNull %25 -%159 = OpTypeVector %152 2 -%169 = OpConstantNull %25 -%184 = OpConstantNull %25 -%197 = OpTypePointer UniformConstant %13 -%200 = OpTypeVector %4 3 -%232 = OpTypePointer UniformConstant %15 -%391 = OpTypePointer UniformConstant %19 -%65 = OpFunction %2 None %66 -%58 = OpLabel -%50 = OpVariable %51 Function %52 +%27 = OpTypeVector %7 2 +%31 = OpConstant %8 10 +%30 = OpTypeArray %10 %31 +%29 = OpTypePointer UniformConstant %30 +%28 = OpVariable %29 UniformConstant +%33 = OpTypePointer UniformConstant %12 +%32 = OpVariable %33 UniformConstant +%35 = OpTypePointer UniformConstant %14 +%34 = OpVariable %35 UniformConstant +%37 = OpTypePointer UniformConstant %16 +%36 = OpVariable %37 UniformConstant +%39 = OpTypePointer UniformConstant %18 +%38 = OpVariable %39 UniformConstant +%41 = OpTypePointer UniformConstant %20 +%40 = OpVariable %41 UniformConstant +%43 = OpTypePointer UniformConstant %22 +%42 = OpVariable %43 UniformConstant +%45 = OpTypePointer UniformConstant %23 +%44 = OpVariable %45 UniformConstant +%47 = OpTypeStruct %9 +%48 = OpTypePointer Uniform %47 +%46 = OpVariable %48 Uniform +%50 = OpTypePointer Function %4 +%51 = OpConstantNull %4 +%53 = OpTypePointer Function %26 +%54 = OpConstantNull %26 +%56 = OpTypePointer Function %7 +%57 = OpConstantNull %7 +%59 = OpTypePointer Function %25 +%60 = OpConstantNull %25 +%64 = OpTypePointer Input %8 +%63 = OpVariable %64 Input +%67 = OpTypePointer Output %25 +%66 = OpVariable %67 Output +%69 = OpTypeFunction %2 +%70 = OpTypePointer Uniform %9 +%71 = OpConstant %8 0 +%74 = OpTypePointer Uniform %8 +%82 = OpTypePointer UniformConstant %10 +%100 = OpTypePointer UniformConstant %21 +%103 = OpTypeSampledImage %10 +%124 = OpTypePointer UniformConstant %17 +%127 = OpTypePointer UniformConstant %21 +%130 = OpTypeSampledImage %17 +%153 = OpTypeBool +%154 = OpConstantNull %25 +%160 = OpTypeVector %153 2 +%170 = OpConstantNull %25 +%185 = OpConstantNull %25 +%198 = OpTypePointer UniformConstant %13 +%201 = OpTypeVector %4 3 +%233 = OpTypePointer UniformConstant %15 +%393 = OpTypePointer UniformConstant %19 +%68 = OpFunction %2 None %69 +%61 = OpLabel +%52 = OpVariable %53 Function %54 +%58 = OpVariable %59 Function %60 +%49 = OpVariable %50 Function %51 %55 = OpVariable %56 Function %57 -%48 = OpVariable %49 Function %5 -%53 = OpVariable %54 Function %6 -%62 = OpLoad %8 %60 -%59 = OpCompositeConstruct %24 %62 -%69 = OpAccessChain %67 %45 %68 -OpBranch %70 -%70 = OpLabel -%72 = OpAccessChain %71 %69 %68 -%73 = OpLoad %8 %72 -%74 = OpCompositeExtract %8 %59 0 -%75 = OpCompositeConstruct %26 %5 %5 -OpStore %50 %75 -%76 = OpCompositeConstruct %25 %6 %6 %6 %6 -OpStore %55 %76 -%78 = OpCompositeConstruct %77 %6 %6 -%79 = OpCompositeConstruct %26 %5 %5 -%80 = OpLoad %26 %50 -%82 = OpAccessChain %81 %27 %68 -%83 = OpLoad %10 %82 -%84 = OpImageQuerySizeLod %26 %83 %68 -%85 = OpIAdd %26 %80 %84 -OpStore %50 %85 -%86 = OpLoad %26 %50 -%87 = OpAccessChain %81 %27 %73 -%88 = OpLoad %10 %87 -%89 = OpImageQuerySizeLod %26 %88 %68 -%90 = OpIAdd %26 %86 %89 -OpStore %50 %90 -%91 = OpLoad %26 %50 -%92 = OpAccessChain %81 %27 %74 -%93 = OpLoad %10 %92 -%94 = OpImageQuerySizeLod %26 %93 %68 -%95 = OpIAdd %26 %91 %94 -OpStore %50 %95 -%96 = OpLoad %25 %55 -%97 = OpAccessChain %81 %31 %68 -%98 = OpLoad %10 %97 -%100 = OpAccessChain %99 %41 %68 -%101 = OpLoad %21 %100 -%103 = OpSampledImage %102 %98 %101 -%104 = OpImageGather %25 %103 %78 %68 -%105 = OpFAdd %25 %96 %104 -OpStore %55 %105 -%106 = OpLoad %25 %55 -%107 = OpAccessChain %81 %31 %73 -%108 = OpLoad %10 %107 -%109 = OpAccessChain %99 %41 %73 -%110 = OpLoad %21 %109 -%111 = OpSampledImage %102 %108 %110 -%112 = OpImageGather %25 %111 %78 %68 -%113 = OpFAdd %25 %106 %112 -OpStore %55 %113 -%114 = OpLoad %25 %55 -%115 = OpAccessChain %81 %31 %74 -%116 = OpLoad %10 %115 -%117 = OpAccessChain %99 %41 %74 -%118 = OpLoad %21 %117 -%119 = OpSampledImage %102 %116 %118 -%120 = OpImageGather %25 %119 %78 %68 -%121 = OpFAdd %25 %114 %120 -OpStore %55 %121 -%122 = OpLoad %25 %55 -%124 = OpAccessChain %123 %37 %68 -%125 = OpLoad %17 %124 -%127 = OpAccessChain %126 %43 %68 -%128 = OpLoad %21 %127 -%130 = OpSampledImage %129 %125 %128 -%131 = OpImageDrefGather %25 %130 %78 %6 -%132 = OpFAdd %25 %122 %131 -OpStore %55 %132 -%133 = OpLoad %25 %55 -%134 = OpAccessChain %123 %37 %73 -%135 = OpLoad %17 %134 -%136 = OpAccessChain %126 %43 %73 -%137 = OpLoad %21 %136 -%138 = OpSampledImage %129 %135 %137 -%139 = OpImageDrefGather %25 %138 %78 %6 -%140 = OpFAdd %25 %133 %139 -OpStore %55 %140 -%141 = OpLoad %25 %55 -%142 = OpAccessChain %123 %37 %74 -%143 = OpLoad %17 %142 -%144 = OpAccessChain %126 %43 %74 -%145 = OpLoad %21 %144 -%146 = OpSampledImage %129 %143 %145 -%147 = OpImageDrefGather %25 %146 %78 %6 -%148 = OpFAdd %25 %141 %147 -OpStore %55 %148 -%149 = OpLoad %25 %55 -%150 = OpAccessChain %81 %27 %68 -%151 = OpLoad %10 %150 -%154 = OpImageQueryLevels %4 %151 -%155 = OpULessThan %152 %5 %154 -OpSelectionMerge %156 None -OpBranchConditional %155 %157 %156 +%65 = OpLoad %8 %63 +%62 = OpCompositeConstruct %24 %65 +%72 = OpAccessChain %70 %46 %71 +OpBranch %73 +%73 = OpLabel +%75 = OpAccessChain %74 %72 %71 +%76 = OpLoad %8 %75 +%77 = OpCompositeExtract %8 %62 0 +OpStore %49 %5 +%78 = OpCompositeConstruct %26 %5 %5 +OpStore %52 %78 +OpStore %55 %6 +%79 = OpCompositeConstruct %25 %6 %6 %6 %6 +OpStore %58 %79 +%80 = OpCompositeConstruct %27 %6 %6 +%81 = OpCompositeConstruct %26 %5 %5 +%83 = OpAccessChain %82 %28 %71 +%84 = OpLoad %10 %83 +%85 = OpImageQuerySizeLod %26 %84 %71 +%86 = OpLoad %26 %52 +%87 = OpIAdd %26 %86 %85 +OpStore %52 %87 +%88 = OpAccessChain %82 %28 %76 +%89 = OpLoad %10 %88 +%90 = OpImageQuerySizeLod %26 %89 %71 +%91 = OpLoad %26 %52 +%92 = OpIAdd %26 %91 %90 +OpStore %52 %92 +%93 = OpAccessChain %82 %28 %77 +%94 = OpLoad %10 %93 +%95 = OpImageQuerySizeLod %26 %94 %71 +%96 = OpLoad %26 %52 +%97 = OpIAdd %26 %96 %95 +OpStore %52 %97 +%98 = OpAccessChain %82 %32 %71 +%99 = OpLoad %10 %98 +%101 = OpAccessChain %100 %42 %71 +%102 = OpLoad %21 %101 +%104 = OpSampledImage %103 %99 %102 +%105 = OpImageGather %25 %104 %80 %71 +%106 = OpLoad %25 %58 +%107 = OpFAdd %25 %106 %105 +OpStore %58 %107 +%108 = OpAccessChain %82 %32 %76 +%109 = OpLoad %10 %108 +%110 = OpAccessChain %100 %42 %76 +%111 = OpLoad %21 %110 +%112 = OpSampledImage %103 %109 %111 +%113 = OpImageGather %25 %112 %80 %71 +%114 = OpLoad %25 %58 +%115 = OpFAdd %25 %114 %113 +OpStore %58 %115 +%116 = OpAccessChain %82 %32 %77 +%117 = OpLoad %10 %116 +%118 = OpAccessChain %100 %42 %77 +%119 = OpLoad %21 %118 +%120 = OpSampledImage %103 %117 %119 +%121 = OpImageGather %25 %120 %80 %71 +%122 = OpLoad %25 %58 +%123 = OpFAdd %25 %122 %121 +OpStore %58 %123 +%125 = OpAccessChain %124 %38 %71 +%126 = OpLoad %17 %125 +%128 = OpAccessChain %127 %44 %71 +%129 = OpLoad %21 %128 +%131 = OpSampledImage %130 %126 %129 +%132 = OpImageDrefGather %25 %131 %80 %6 +%133 = OpLoad %25 %58 +%134 = OpFAdd %25 %133 %132 +OpStore %58 %134 +%135 = OpAccessChain %124 %38 %76 +%136 = OpLoad %17 %135 +%137 = OpAccessChain %127 %44 %76 +%138 = OpLoad %21 %137 +%139 = OpSampledImage %130 %136 %138 +%140 = OpImageDrefGather %25 %139 %80 %6 +%141 = OpLoad %25 %58 +%142 = OpFAdd %25 %141 %140 +OpStore %58 %142 +%143 = OpAccessChain %124 %38 %77 +%144 = OpLoad %17 %143 +%145 = OpAccessChain %127 %44 %77 +%146 = OpLoad %21 %145 +%147 = OpSampledImage %130 %144 %146 +%148 = OpImageDrefGather %25 %147 %80 %6 +%149 = OpLoad %25 %58 +%150 = OpFAdd %25 %149 %148 +OpStore %58 %150 +%151 = OpAccessChain %82 %28 %71 +%152 = OpLoad %10 %151 +%155 = OpImageQueryLevels %4 %152 +%156 = OpULessThan %153 %5 %155 +OpSelectionMerge %157 None +OpBranchConditional %156 %158 %157 +%158 = OpLabel +%159 = OpImageQuerySizeLod %26 %152 %5 +%161 = OpULessThan %160 %81 %159 +%162 = OpAll %153 %161 +OpBranchConditional %162 %163 %157 +%163 = OpLabel +%164 = OpImageFetch %25 %152 %81 Lod %5 +OpBranch %157 %157 = OpLabel -%158 = OpImageQuerySizeLod %26 %151 %5 -%160 = OpULessThan %159 %79 %158 -%161 = OpAll %152 %160 -OpBranchConditional %161 %162 %156 -%162 = OpLabel -%163 = OpImageFetch %25 %151 %79 Lod %5 -OpBranch %156 -%156 = OpLabel -%164 = OpPhi %25 %153 %70 %153 %157 %163 %162 -%165 = OpFAdd %25 %149 %164 -OpStore %55 %165 -%166 = OpLoad %25 %55 -%167 = OpAccessChain %81 %27 %73 -%168 = OpLoad %10 %167 -%170 = OpImageQueryLevels %4 %168 -%171 = OpULessThan %152 %5 %170 -OpSelectionMerge %172 None -OpBranchConditional %171 %173 %172 +%165 = OpPhi %25 %154 %73 %154 %158 %164 %163 +%166 = OpLoad %25 %58 +%167 = OpFAdd %25 %166 %165 +OpStore %58 %167 +%168 = OpAccessChain %82 %28 %76 +%169 = OpLoad %10 %168 +%171 = OpImageQueryLevels %4 %169 +%172 = OpULessThan %153 %5 %171 +OpSelectionMerge %173 None +OpBranchConditional %172 %174 %173 +%174 = OpLabel +%175 = OpImageQuerySizeLod %26 %169 %5 +%176 = OpULessThan %160 %81 %175 +%177 = OpAll %153 %176 +OpBranchConditional %177 %178 %173 +%178 = OpLabel +%179 = OpImageFetch %25 %169 %81 Lod %5 +OpBranch %173 %173 = OpLabel -%174 = OpImageQuerySizeLod %26 %168 %5 -%175 = OpULessThan %159 %79 %174 -%176 = OpAll %152 %175 -OpBranchConditional %176 %177 %172 -%177 = OpLabel -%178 = OpImageFetch %25 %168 %79 Lod %5 -OpBranch %172 -%172 = OpLabel -%179 = OpPhi %25 %169 %156 %169 %173 %178 %177 -%180 = OpFAdd %25 %166 %179 -OpStore %55 %180 -%181 = OpLoad %25 %55 -%182 = OpAccessChain %81 %27 %74 -%183 = OpLoad %10 %182 -%185 = OpImageQueryLevels %4 %183 -%186 = OpULessThan %152 %5 %185 -OpSelectionMerge %187 None -OpBranchConditional %186 %188 %187 +%180 = OpPhi %25 %170 %157 %170 %174 %179 %178 +%181 = OpLoad %25 %58 +%182 = OpFAdd %25 %181 %180 +OpStore %58 %182 +%183 = OpAccessChain %82 %28 %77 +%184 = OpLoad %10 %183 +%186 = OpImageQueryLevels %4 %184 +%187 = OpULessThan %153 %5 %186 +OpSelectionMerge %188 None +OpBranchConditional %187 %189 %188 +%189 = OpLabel +%190 = OpImageQuerySizeLod %26 %184 %5 +%191 = OpULessThan %160 %81 %190 +%192 = OpAll %153 %191 +OpBranchConditional %192 %193 %188 +%193 = OpLabel +%194 = OpImageFetch %25 %184 %81 Lod %5 +OpBranch %188 %188 = OpLabel -%189 = OpImageQuerySizeLod %26 %183 %5 -%190 = OpULessThan %159 %79 %189 -%191 = OpAll %152 %190 -OpBranchConditional %191 %192 %187 -%192 = OpLabel -%193 = OpImageFetch %25 %183 %79 Lod %5 -OpBranch %187 -%187 = OpLabel -%194 = OpPhi %25 %184 %172 %184 %188 %193 %192 -%195 = OpFAdd %25 %181 %194 -OpStore %55 %195 -%196 = OpLoad %4 %48 -%198 = OpAccessChain %197 %33 %68 -%199 = OpLoad %13 %198 -%201 = OpImageQuerySizeLod %200 %199 %68 -%202 = OpCompositeExtract %4 %201 2 -%203 = OpIAdd %4 %196 %202 -OpStore %48 %203 -%204 = OpLoad %4 %48 -%205 = OpAccessChain %197 %33 %73 -%206 = OpLoad %13 %205 -%207 = OpImageQuerySizeLod %200 %206 %68 -%208 = OpCompositeExtract %4 %207 2 -%209 = OpIAdd %4 %204 %208 -OpStore %48 %209 -%210 = OpLoad %4 %48 -%211 = OpAccessChain %197 %33 %74 -%212 = OpLoad %13 %211 -%213 = OpImageQuerySizeLod %200 %212 %68 -%214 = OpCompositeExtract %4 %213 2 -%215 = OpIAdd %4 %210 %214 -OpStore %48 %215 -%216 = OpLoad %4 %48 -%217 = OpAccessChain %81 %31 %68 -%218 = OpLoad %10 %217 -%219 = OpImageQueryLevels %4 %218 -%220 = OpIAdd %4 %216 %219 -OpStore %48 %220 -%221 = OpLoad %4 %48 -%222 = OpAccessChain %81 %31 %73 -%223 = OpLoad %10 %222 -%224 = OpImageQueryLevels %4 %223 -%225 = OpIAdd %4 %221 %224 -OpStore %48 %225 -%226 = OpLoad %4 %48 -%227 = OpAccessChain %81 %31 %74 -%228 = OpLoad %10 %227 -%229 = OpImageQueryLevels %4 %228 -%230 = OpIAdd %4 %226 %229 -OpStore %48 %230 -%231 = OpLoad %4 %48 -%233 = OpAccessChain %232 %35 %68 -%234 = OpLoad %15 %233 -%235 = OpImageQuerySamples %4 %234 -%236 = OpIAdd %4 %231 %235 -OpStore %48 %236 -%237 = OpLoad %4 %48 -%238 = OpAccessChain %232 %35 %73 -%239 = OpLoad %15 %238 -%240 = OpImageQuerySamples %4 %239 -%241 = OpIAdd %4 %237 %240 -OpStore %48 %241 -%242 = OpLoad %4 %48 -%243 = OpAccessChain %232 %35 %74 -%244 = OpLoad %15 %243 -%245 = OpImageQuerySamples %4 %244 -%246 = OpIAdd %4 %242 %245 -OpStore %48 %246 -%247 = OpLoad %25 %55 -%248 = OpAccessChain %81 %31 %68 -%249 = OpLoad %10 %248 -%250 = OpAccessChain %99 %41 %68 -%251 = OpLoad %21 %250 -%252 = OpSampledImage %102 %249 %251 -%253 = OpImageSampleImplicitLod %25 %252 %78 -%254 = OpFAdd %25 %247 %253 -OpStore %55 %254 -%255 = OpLoad %25 %55 -%256 = OpAccessChain %81 %31 %73 -%257 = OpLoad %10 %256 -%258 = OpAccessChain %99 %41 %73 -%259 = OpLoad %21 %258 -%260 = OpSampledImage %102 %257 %259 -%261 = OpImageSampleImplicitLod %25 %260 %78 -%262 = OpFAdd %25 %255 %261 -OpStore %55 %262 -%263 = OpLoad %25 %55 -%264 = OpAccessChain %81 %31 %74 -%265 = OpLoad %10 %264 -%266 = OpAccessChain %99 %41 %74 -%267 = OpLoad %21 %266 -%268 = OpSampledImage %102 %265 %267 -%269 = OpImageSampleImplicitLod %25 %268 %78 -%270 = OpFAdd %25 %263 %269 -OpStore %55 %270 -%271 = OpLoad %25 %55 -%272 = OpAccessChain %81 %31 %68 -%273 = OpLoad %10 %272 -%274 = OpAccessChain %99 %41 %68 -%275 = OpLoad %21 %274 -%276 = OpSampledImage %102 %273 %275 -%277 = OpImageSampleImplicitLod %25 %276 %78 Bias %6 -%278 = OpFAdd %25 %271 %277 -OpStore %55 %278 -%279 = OpLoad %25 %55 -%280 = OpAccessChain %81 %31 %73 -%281 = OpLoad %10 %280 -%282 = OpAccessChain %99 %41 %73 -%283 = OpLoad %21 %282 -%284 = OpSampledImage %102 %281 %283 -%285 = OpImageSampleImplicitLod %25 %284 %78 Bias %6 -%286 = OpFAdd %25 %279 %285 -OpStore %55 %286 -%287 = OpLoad %25 %55 -%288 = OpAccessChain %81 %31 %74 -%289 = OpLoad %10 %288 -%290 = OpAccessChain %99 %41 %74 -%291 = OpLoad %21 %290 -%292 = OpSampledImage %102 %289 %291 -%293 = OpImageSampleImplicitLod %25 %292 %78 Bias %6 -%294 = OpFAdd %25 %287 %293 -OpStore %55 %294 -%295 = OpLoad %7 %53 -%296 = OpAccessChain %123 %37 %68 -%297 = OpLoad %17 %296 -%298 = OpAccessChain %126 %43 %68 -%299 = OpLoad %21 %298 -%300 = OpSampledImage %129 %297 %299 -%301 = OpImageSampleDrefImplicitLod %7 %300 %78 %6 -%302 = OpFAdd %7 %295 %301 -OpStore %53 %302 -%303 = OpLoad %7 %53 -%304 = OpAccessChain %123 %37 %73 -%305 = OpLoad %17 %304 -%306 = OpAccessChain %126 %43 %73 -%307 = OpLoad %21 %306 -%308 = OpSampledImage %129 %305 %307 -%309 = OpImageSampleDrefImplicitLod %7 %308 %78 %6 -%310 = OpFAdd %7 %303 %309 -OpStore %53 %310 -%311 = OpLoad %7 %53 -%312 = OpAccessChain %123 %37 %74 -%313 = OpLoad %17 %312 -%314 = OpAccessChain %126 %43 %74 -%315 = OpLoad %21 %314 -%316 = OpSampledImage %129 %313 %315 -%317 = OpImageSampleDrefImplicitLod %7 %316 %78 %6 -%318 = OpFAdd %7 %311 %317 -OpStore %53 %318 -%319 = OpLoad %7 %53 -%320 = OpAccessChain %123 %37 %68 -%321 = OpLoad %17 %320 -%322 = OpAccessChain %126 %43 %68 -%323 = OpLoad %21 %322 -%324 = OpSampledImage %129 %321 %323 -%325 = OpImageSampleDrefExplicitLod %7 %324 %78 %6 Lod %6 -%326 = OpFAdd %7 %319 %325 -OpStore %53 %326 -%327 = OpLoad %7 %53 -%328 = OpAccessChain %123 %37 %73 -%329 = OpLoad %17 %328 -%330 = OpAccessChain %126 %43 %73 -%331 = OpLoad %21 %330 -%332 = OpSampledImage %129 %329 %331 -%333 = OpImageSampleDrefExplicitLod %7 %332 %78 %6 Lod %6 -%334 = OpFAdd %7 %327 %333 -OpStore %53 %334 -%335 = OpLoad %7 %53 -%336 = OpAccessChain %123 %37 %74 -%337 = OpLoad %17 %336 -%338 = OpAccessChain %126 %43 %74 -%339 = OpLoad %21 %338 -%340 = OpSampledImage %129 %337 %339 -%341 = OpImageSampleDrefExplicitLod %7 %340 %78 %6 Lod %6 -%342 = OpFAdd %7 %335 %341 -OpStore %53 %342 -%343 = OpLoad %25 %55 -%344 = OpAccessChain %81 %31 %68 -%345 = OpLoad %10 %344 -%346 = OpAccessChain %99 %41 %68 -%347 = OpLoad %21 %346 -%348 = OpSampledImage %102 %345 %347 -%349 = OpImageSampleExplicitLod %25 %348 %78 Grad %78 %78 -%350 = OpFAdd %25 %343 %349 -OpStore %55 %350 -%351 = OpLoad %25 %55 -%352 = OpAccessChain %81 %31 %73 -%353 = OpLoad %10 %352 -%354 = OpAccessChain %99 %41 %73 -%355 = OpLoad %21 %354 -%356 = OpSampledImage %102 %353 %355 -%357 = OpImageSampleExplicitLod %25 %356 %78 Grad %78 %78 -%358 = OpFAdd %25 %351 %357 -OpStore %55 %358 -%359 = OpLoad %25 %55 -%360 = OpAccessChain %81 %31 %74 -%361 = OpLoad %10 %360 -%362 = OpAccessChain %99 %41 %74 -%363 = OpLoad %21 %362 -%364 = OpSampledImage %102 %361 %363 -%365 = OpImageSampleExplicitLod %25 %364 %78 Grad %78 %78 -%366 = OpFAdd %25 %359 %365 -OpStore %55 %366 -%367 = OpLoad %25 %55 -%368 = OpAccessChain %81 %31 %68 -%369 = OpLoad %10 %368 -%370 = OpAccessChain %99 %41 %68 -%371 = OpLoad %21 %370 -%372 = OpSampledImage %102 %369 %371 -%373 = OpImageSampleExplicitLod %25 %372 %78 Lod %6 -%374 = OpFAdd %25 %367 %373 -OpStore %55 %374 -%375 = OpLoad %25 %55 -%376 = OpAccessChain %81 %31 %73 -%377 = OpLoad %10 %376 -%378 = OpAccessChain %99 %41 %73 -%379 = OpLoad %21 %378 -%380 = OpSampledImage %102 %377 %379 -%381 = OpImageSampleExplicitLod %25 %380 %78 Lod %6 -%382 = OpFAdd %25 %375 %381 -OpStore %55 %382 -%383 = OpLoad %25 %55 -%384 = OpAccessChain %81 %31 %74 -%385 = OpLoad %10 %384 -%386 = OpAccessChain %99 %41 %74 -%387 = OpLoad %21 %386 -%388 = OpSampledImage %102 %385 %387 -%389 = OpImageSampleExplicitLod %25 %388 %78 Lod %6 -%390 = OpFAdd %25 %383 %389 -OpStore %55 %390 -%392 = OpAccessChain %391 %39 %68 -%393 = OpLoad %19 %392 -%394 = OpLoad %25 %55 -%395 = OpImageQuerySize %26 %393 -%396 = OpULessThan %159 %79 %395 -%397 = OpAll %152 %396 -OpSelectionMerge %398 None -OpBranchConditional %397 %399 %398 -%399 = OpLabel -OpImageWrite %393 %79 %394 -OpBranch %398 -%398 = OpLabel -%400 = OpAccessChain %391 %39 %73 -%401 = OpLoad %19 %400 -%402 = OpLoad %25 %55 -%403 = OpImageQuerySize %26 %401 -%404 = OpULessThan %159 %79 %403 -%405 = OpAll %152 %404 -OpSelectionMerge %406 None -OpBranchConditional %405 %407 %406 -%407 = OpLabel -OpImageWrite %401 %79 %402 -OpBranch %406 -%406 = OpLabel -%408 = OpAccessChain %391 %39 %74 -%409 = OpLoad %19 %408 -%410 = OpLoad %25 %55 -%411 = OpImageQuerySize %26 %409 -%412 = OpULessThan %159 %79 %411 -%413 = OpAll %152 %412 -OpSelectionMerge %414 None -OpBranchConditional %413 %415 %414 -%415 = OpLabel -OpImageWrite %409 %79 %410 -OpBranch %414 -%414 = OpLabel -%416 = OpLoad %26 %50 -%417 = OpLoad %4 %48 -%418 = OpCompositeConstruct %26 %417 %417 -%419 = OpIAdd %26 %416 %418 -%420 = OpConvertSToF %77 %419 -%421 = OpLoad %25 %55 -%422 = OpCompositeExtract %7 %420 0 -%423 = OpCompositeExtract %7 %420 1 -%424 = OpCompositeExtract %7 %420 0 -%425 = OpCompositeExtract %7 %420 1 -%426 = OpCompositeConstruct %25 %422 %423 %424 %425 -%427 = OpFAdd %25 %421 %426 -%428 = OpLoad %7 %53 -%429 = OpCompositeConstruct %25 %428 %428 %428 %428 -%430 = OpFAdd %25 %427 %429 -OpStore %63 %430 +%195 = OpPhi %25 %185 %173 %185 %189 %194 %193 +%196 = OpLoad %25 %58 +%197 = OpFAdd %25 %196 %195 +OpStore %58 %197 +%199 = OpAccessChain %198 %34 %71 +%200 = OpLoad %13 %199 +%202 = OpImageQuerySizeLod %201 %200 %71 +%203 = OpCompositeExtract %4 %202 2 +%204 = OpLoad %4 %49 +%205 = OpIAdd %4 %204 %203 +OpStore %49 %205 +%206 = OpAccessChain %198 %34 %76 +%207 = OpLoad %13 %206 +%208 = OpImageQuerySizeLod %201 %207 %71 +%209 = OpCompositeExtract %4 %208 2 +%210 = OpLoad %4 %49 +%211 = OpIAdd %4 %210 %209 +OpStore %49 %211 +%212 = OpAccessChain %198 %34 %77 +%213 = OpLoad %13 %212 +%214 = OpImageQuerySizeLod %201 %213 %71 +%215 = OpCompositeExtract %4 %214 2 +%216 = OpLoad %4 %49 +%217 = OpIAdd %4 %216 %215 +OpStore %49 %217 +%218 = OpAccessChain %82 %32 %71 +%219 = OpLoad %10 %218 +%220 = OpImageQueryLevels %4 %219 +%221 = OpLoad %4 %49 +%222 = OpIAdd %4 %221 %220 +OpStore %49 %222 +%223 = OpAccessChain %82 %32 %76 +%224 = OpLoad %10 %223 +%225 = OpImageQueryLevels %4 %224 +%226 = OpLoad %4 %49 +%227 = OpIAdd %4 %226 %225 +OpStore %49 %227 +%228 = OpAccessChain %82 %32 %77 +%229 = OpLoad %10 %228 +%230 = OpImageQueryLevels %4 %229 +%231 = OpLoad %4 %49 +%232 = OpIAdd %4 %231 %230 +OpStore %49 %232 +%234 = OpAccessChain %233 %36 %71 +%235 = OpLoad %15 %234 +%236 = OpImageQuerySamples %4 %235 +%237 = OpLoad %4 %49 +%238 = OpIAdd %4 %237 %236 +OpStore %49 %238 +%239 = OpAccessChain %233 %36 %76 +%240 = OpLoad %15 %239 +%241 = OpImageQuerySamples %4 %240 +%242 = OpLoad %4 %49 +%243 = OpIAdd %4 %242 %241 +OpStore %49 %243 +%244 = OpAccessChain %233 %36 %77 +%245 = OpLoad %15 %244 +%246 = OpImageQuerySamples %4 %245 +%247 = OpLoad %4 %49 +%248 = OpIAdd %4 %247 %246 +OpStore %49 %248 +%249 = OpAccessChain %82 %32 %71 +%250 = OpLoad %10 %249 +%251 = OpAccessChain %100 %42 %71 +%252 = OpLoad %21 %251 +%253 = OpSampledImage %103 %250 %252 +%254 = OpImageSampleImplicitLod %25 %253 %80 +%255 = OpLoad %25 %58 +%256 = OpFAdd %25 %255 %254 +OpStore %58 %256 +%257 = OpAccessChain %82 %32 %76 +%258 = OpLoad %10 %257 +%259 = OpAccessChain %100 %42 %76 +%260 = OpLoad %21 %259 +%261 = OpSampledImage %103 %258 %260 +%262 = OpImageSampleImplicitLod %25 %261 %80 +%263 = OpLoad %25 %58 +%264 = OpFAdd %25 %263 %262 +OpStore %58 %264 +%265 = OpAccessChain %82 %32 %77 +%266 = OpLoad %10 %265 +%267 = OpAccessChain %100 %42 %77 +%268 = OpLoad %21 %267 +%269 = OpSampledImage %103 %266 %268 +%270 = OpImageSampleImplicitLod %25 %269 %80 +%271 = OpLoad %25 %58 +%272 = OpFAdd %25 %271 %270 +OpStore %58 %272 +%273 = OpAccessChain %82 %32 %71 +%274 = OpLoad %10 %273 +%275 = OpAccessChain %100 %42 %71 +%276 = OpLoad %21 %275 +%277 = OpSampledImage %103 %274 %276 +%278 = OpImageSampleImplicitLod %25 %277 %80 Bias %6 +%279 = OpLoad %25 %58 +%280 = OpFAdd %25 %279 %278 +OpStore %58 %280 +%281 = OpAccessChain %82 %32 %76 +%282 = OpLoad %10 %281 +%283 = OpAccessChain %100 %42 %76 +%284 = OpLoad %21 %283 +%285 = OpSampledImage %103 %282 %284 +%286 = OpImageSampleImplicitLod %25 %285 %80 Bias %6 +%287 = OpLoad %25 %58 +%288 = OpFAdd %25 %287 %286 +OpStore %58 %288 +%289 = OpAccessChain %82 %32 %77 +%290 = OpLoad %10 %289 +%291 = OpAccessChain %100 %42 %77 +%292 = OpLoad %21 %291 +%293 = OpSampledImage %103 %290 %292 +%294 = OpImageSampleImplicitLod %25 %293 %80 Bias %6 +%295 = OpLoad %25 %58 +%296 = OpFAdd %25 %295 %294 +OpStore %58 %296 +%297 = OpAccessChain %124 %38 %71 +%298 = OpLoad %17 %297 +%299 = OpAccessChain %127 %44 %71 +%300 = OpLoad %21 %299 +%301 = OpSampledImage %130 %298 %300 +%302 = OpImageSampleDrefImplicitLod %7 %301 %80 %6 +%303 = OpLoad %7 %55 +%304 = OpFAdd %7 %303 %302 +OpStore %55 %304 +%305 = OpAccessChain %124 %38 %76 +%306 = OpLoad %17 %305 +%307 = OpAccessChain %127 %44 %76 +%308 = OpLoad %21 %307 +%309 = OpSampledImage %130 %306 %308 +%310 = OpImageSampleDrefImplicitLod %7 %309 %80 %6 +%311 = OpLoad %7 %55 +%312 = OpFAdd %7 %311 %310 +OpStore %55 %312 +%313 = OpAccessChain %124 %38 %77 +%314 = OpLoad %17 %313 +%315 = OpAccessChain %127 %44 %77 +%316 = OpLoad %21 %315 +%317 = OpSampledImage %130 %314 %316 +%318 = OpImageSampleDrefImplicitLod %7 %317 %80 %6 +%319 = OpLoad %7 %55 +%320 = OpFAdd %7 %319 %318 +OpStore %55 %320 +%321 = OpAccessChain %124 %38 %71 +%322 = OpLoad %17 %321 +%323 = OpAccessChain %127 %44 %71 +%324 = OpLoad %21 %323 +%325 = OpSampledImage %130 %322 %324 +%326 = OpImageSampleDrefExplicitLod %7 %325 %80 %6 Lod %6 +%327 = OpLoad %7 %55 +%328 = OpFAdd %7 %327 %326 +OpStore %55 %328 +%329 = OpAccessChain %124 %38 %76 +%330 = OpLoad %17 %329 +%331 = OpAccessChain %127 %44 %76 +%332 = OpLoad %21 %331 +%333 = OpSampledImage %130 %330 %332 +%334 = OpImageSampleDrefExplicitLod %7 %333 %80 %6 Lod %6 +%335 = OpLoad %7 %55 +%336 = OpFAdd %7 %335 %334 +OpStore %55 %336 +%337 = OpAccessChain %124 %38 %77 +%338 = OpLoad %17 %337 +%339 = OpAccessChain %127 %44 %77 +%340 = OpLoad %21 %339 +%341 = OpSampledImage %130 %338 %340 +%342 = OpImageSampleDrefExplicitLod %7 %341 %80 %6 Lod %6 +%343 = OpLoad %7 %55 +%344 = OpFAdd %7 %343 %342 +OpStore %55 %344 +%345 = OpAccessChain %82 %32 %71 +%346 = OpLoad %10 %345 +%347 = OpAccessChain %100 %42 %71 +%348 = OpLoad %21 %347 +%349 = OpSampledImage %103 %346 %348 +%350 = OpImageSampleExplicitLod %25 %349 %80 Grad %80 %80 +%351 = OpLoad %25 %58 +%352 = OpFAdd %25 %351 %350 +OpStore %58 %352 +%353 = OpAccessChain %82 %32 %76 +%354 = OpLoad %10 %353 +%355 = OpAccessChain %100 %42 %76 +%356 = OpLoad %21 %355 +%357 = OpSampledImage %103 %354 %356 +%358 = OpImageSampleExplicitLod %25 %357 %80 Grad %80 %80 +%359 = OpLoad %25 %58 +%360 = OpFAdd %25 %359 %358 +OpStore %58 %360 +%361 = OpAccessChain %82 %32 %77 +%362 = OpLoad %10 %361 +%363 = OpAccessChain %100 %42 %77 +%364 = OpLoad %21 %363 +%365 = OpSampledImage %103 %362 %364 +%366 = OpImageSampleExplicitLod %25 %365 %80 Grad %80 %80 +%367 = OpLoad %25 %58 +%368 = OpFAdd %25 %367 %366 +OpStore %58 %368 +%369 = OpAccessChain %82 %32 %71 +%370 = OpLoad %10 %369 +%371 = OpAccessChain %100 %42 %71 +%372 = OpLoad %21 %371 +%373 = OpSampledImage %103 %370 %372 +%374 = OpImageSampleExplicitLod %25 %373 %80 Lod %6 +%375 = OpLoad %25 %58 +%376 = OpFAdd %25 %375 %374 +OpStore %58 %376 +%377 = OpAccessChain %82 %32 %76 +%378 = OpLoad %10 %377 +%379 = OpAccessChain %100 %42 %76 +%380 = OpLoad %21 %379 +%381 = OpSampledImage %103 %378 %380 +%382 = OpImageSampleExplicitLod %25 %381 %80 Lod %6 +%383 = OpLoad %25 %58 +%384 = OpFAdd %25 %383 %382 +OpStore %58 %384 +%385 = OpAccessChain %82 %32 %77 +%386 = OpLoad %10 %385 +%387 = OpAccessChain %100 %42 %77 +%388 = OpLoad %21 %387 +%389 = OpSampledImage %103 %386 %388 +%390 = OpImageSampleExplicitLod %25 %389 %80 Lod %6 +%391 = OpLoad %25 %58 +%392 = OpFAdd %25 %391 %390 +OpStore %58 %392 +%394 = OpAccessChain %393 %40 %71 +%395 = OpLoad %19 %394 +%396 = OpLoad %25 %58 +%397 = OpImageQuerySize %26 %395 +%398 = OpULessThan %160 %81 %397 +%399 = OpAll %153 %398 +OpSelectionMerge %400 None +OpBranchConditional %399 %401 %400 +%401 = OpLabel +OpImageWrite %395 %81 %396 +OpBranch %400 +%400 = OpLabel +%402 = OpAccessChain %393 %40 %76 +%403 = OpLoad %19 %402 +%404 = OpLoad %25 %58 +%405 = OpImageQuerySize %26 %403 +%406 = OpULessThan %160 %81 %405 +%407 = OpAll %153 %406 +OpSelectionMerge %408 None +OpBranchConditional %407 %409 %408 +%409 = OpLabel +OpImageWrite %403 %81 %404 +OpBranch %408 +%408 = OpLabel +%410 = OpAccessChain %393 %40 %77 +%411 = OpLoad %19 %410 +%412 = OpLoad %25 %58 +%413 = OpImageQuerySize %26 %411 +%414 = OpULessThan %160 %81 %413 +%415 = OpAll %153 %414 +OpSelectionMerge %416 None +OpBranchConditional %415 %417 %416 +%417 = OpLabel +OpImageWrite %411 %81 %412 +OpBranch %416 +%416 = OpLabel +%418 = OpLoad %26 %52 +%419 = OpLoad %4 %49 +%420 = OpCompositeConstruct %26 %419 %419 +%421 = OpIAdd %26 %418 %420 +%422 = OpConvertSToF %27 %421 +%423 = OpLoad %25 %58 +%424 = OpCompositeExtract %7 %422 0 +%425 = OpCompositeExtract %7 %422 1 +%426 = OpCompositeExtract %7 %422 0 +%427 = OpCompositeExtract %7 %422 1 +%428 = OpCompositeConstruct %25 %424 %425 %426 %427 +%429 = OpFAdd %25 %423 %428 +%430 = OpLoad %7 %55 +%431 = OpCompositeConstruct %25 %430 %430 %430 %430 +%432 = OpFAdd %25 %429 %431 +OpStore %66 %432 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/bits.spvasm b/tests/out/spv/bits.spvasm index c705d82767..b8c17d8709 100644 --- a/tests/out/spv/bits.spvasm +++ b/tests/out/spv/bits.spvasm @@ -1,12 +1,12 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 159 +; Bound: 161 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %48 "main" -OpExecutionMode %48 LocalSize 1 1 1 +OpEntryPoint GLCompute %50 "main" +OpExecutionMode %50 LocalSize 1 1 1 %2 = OpTypeVoid %4 = OpTypeInt 32 1 %3 = OpConstant %4 0 @@ -25,199 +25,203 @@ OpExecutionMode %48 LocalSize 1 1 1 %17 = OpTypeVector %8 2 %18 = OpTypeVector %8 4 %20 = OpTypePointer Function %4 -%22 = OpTypePointer Function %11 -%23 = OpConstantNull %11 -%25 = OpTypePointer Function %12 -%26 = OpConstantNull %12 -%28 = OpTypePointer Function %13 -%29 = OpConstantNull %13 -%31 = OpTypePointer Function %6 -%33 = OpTypePointer Function %14 -%34 = OpConstantNull %14 -%36 = OpTypePointer Function %15 -%37 = OpConstantNull %15 -%39 = OpTypePointer Function %16 -%40 = OpConstantNull %16 -%42 = OpTypePointer Function %17 -%43 = OpConstantNull %17 -%45 = OpTypePointer Function %18 -%46 = OpConstantNull %18 -%49 = OpTypeFunction %2 -%48 = OpFunction %2 None %49 -%47 = OpLabel -%44 = OpVariable %45 Function %46 -%35 = OpVariable %36 Function %37 -%27 = OpVariable %28 Function %29 -%19 = OpVariable %20 Function %3 -%38 = OpVariable %39 Function %40 -%30 = OpVariable %31 Function %5 -%21 = OpVariable %22 Function %23 -%41 = OpVariable %42 Function %43 -%32 = OpVariable %33 Function %34 -%24 = OpVariable %25 Function %26 -OpBranch %50 -%50 = OpLabel -%51 = OpCompositeConstruct %11 %3 %3 -OpStore %21 %51 -%52 = OpCompositeConstruct %12 %3 %3 %3 -OpStore %24 %52 -%53 = OpCompositeConstruct %13 %3 %3 %3 %3 -OpStore %27 %53 -%54 = OpCompositeConstruct %14 %5 %5 -OpStore %32 %54 -%55 = OpCompositeConstruct %15 %5 %5 %5 -OpStore %35 %55 -%56 = OpCompositeConstruct %16 %5 %5 %5 %5 -OpStore %38 %56 -%57 = OpCompositeConstruct %17 %7 %7 -OpStore %41 %57 -%58 = OpCompositeConstruct %18 %7 %7 %7 %7 -OpStore %44 %58 -%59 = OpLoad %18 %44 -%60 = OpExtInst %6 %1 PackSnorm4x8 %59 -OpStore %30 %60 -%61 = OpLoad %18 %44 -%62 = OpExtInst %6 %1 PackUnorm4x8 %61 -OpStore %30 %62 -%63 = OpLoad %17 %41 -%64 = OpExtInst %6 %1 PackSnorm2x16 %63 -OpStore %30 %64 -%65 = OpLoad %17 %41 -%66 = OpExtInst %6 %1 PackUnorm2x16 %65 -OpStore %30 %66 -%67 = OpLoad %17 %41 -%68 = OpExtInst %6 %1 PackHalf2x16 %67 -OpStore %30 %68 -%69 = OpLoad %6 %30 -%70 = OpExtInst %18 %1 UnpackSnorm4x8 %69 -OpStore %44 %70 -%71 = OpLoad %6 %30 -%72 = OpExtInst %18 %1 UnpackUnorm4x8 %71 -OpStore %44 %72 -%73 = OpLoad %6 %30 -%74 = OpExtInst %17 %1 UnpackSnorm2x16 %73 -OpStore %41 %74 -%75 = OpLoad %6 %30 -%76 = OpExtInst %17 %1 UnpackUnorm2x16 %75 -OpStore %41 %76 -%77 = OpLoad %6 %30 -%78 = OpExtInst %17 %1 UnpackHalf2x16 %77 -OpStore %41 %78 -%79 = OpLoad %4 %19 -%80 = OpLoad %4 %19 -%81 = OpBitFieldInsert %4 %79 %80 %9 %10 -OpStore %19 %81 -%82 = OpLoad %11 %21 -%83 = OpLoad %11 %21 -%84 = OpBitFieldInsert %11 %82 %83 %9 %10 -OpStore %21 %84 -%85 = OpLoad %12 %24 -%86 = OpLoad %12 %24 -%87 = OpBitFieldInsert %12 %85 %86 %9 %10 -OpStore %24 %87 -%88 = OpLoad %13 %27 -%89 = OpLoad %13 %27 -%90 = OpBitFieldInsert %13 %88 %89 %9 %10 -OpStore %27 %90 -%91 = OpLoad %6 %30 -%92 = OpLoad %6 %30 -%93 = OpBitFieldInsert %6 %91 %92 %9 %10 -OpStore %30 %93 -%94 = OpLoad %14 %32 -%95 = OpLoad %14 %32 -%96 = OpBitFieldInsert %14 %94 %95 %9 %10 -OpStore %32 %96 -%97 = OpLoad %15 %35 -%98 = OpLoad %15 %35 -%99 = OpBitFieldInsert %15 %97 %98 %9 %10 -OpStore %35 %99 -%100 = OpLoad %16 %38 -%101 = OpLoad %16 %38 -%102 = OpBitFieldInsert %16 %100 %101 %9 %10 -OpStore %38 %102 -%103 = OpLoad %4 %19 -%104 = OpBitFieldSExtract %4 %103 %9 %10 -OpStore %19 %104 -%105 = OpLoad %11 %21 -%106 = OpBitFieldSExtract %11 %105 %9 %10 -OpStore %21 %106 -%107 = OpLoad %12 %24 -%108 = OpBitFieldSExtract %12 %107 %9 %10 -OpStore %24 %108 -%109 = OpLoad %13 %27 -%110 = OpBitFieldSExtract %13 %109 %9 %10 -OpStore %27 %110 -%111 = OpLoad %6 %30 -%112 = OpBitFieldUExtract %6 %111 %9 %10 -OpStore %30 %112 -%113 = OpLoad %14 %32 -%114 = OpBitFieldUExtract %14 %113 %9 %10 -OpStore %32 %114 -%115 = OpLoad %15 %35 -%116 = OpBitFieldUExtract %15 %115 %9 %10 -OpStore %35 %116 -%117 = OpLoad %16 %38 -%118 = OpBitFieldUExtract %16 %117 %9 %10 -OpStore %38 %118 -%119 = OpLoad %4 %19 -%120 = OpExtInst %4 %1 FindILsb %119 -OpStore %19 %120 -%121 = OpLoad %14 %32 -%122 = OpExtInst %14 %1 FindILsb %121 -OpStore %32 %122 -%123 = OpLoad %12 %24 -%124 = OpExtInst %12 %1 FindSMsb %123 -OpStore %24 %124 -%125 = OpLoad %6 %30 -%126 = OpExtInst %6 %1 FindUMsb %125 -OpStore %30 %126 -%127 = OpLoad %4 %19 -%128 = OpBitCount %4 %127 -OpStore %19 %128 -%129 = OpLoad %11 %21 -%130 = OpBitCount %11 %129 -OpStore %21 %130 -%131 = OpLoad %12 %24 -%132 = OpBitCount %12 %131 -OpStore %24 %132 -%133 = OpLoad %13 %27 -%134 = OpBitCount %13 %133 -OpStore %27 %134 -%135 = OpLoad %6 %30 -%136 = OpBitCount %6 %135 -OpStore %30 %136 -%137 = OpLoad %14 %32 -%138 = OpBitCount %14 %137 -OpStore %32 %138 -%139 = OpLoad %15 %35 -%140 = OpBitCount %15 %139 -OpStore %35 %140 -%141 = OpLoad %16 %38 -%142 = OpBitCount %16 %141 -OpStore %38 %142 -%143 = OpLoad %4 %19 -%144 = OpBitReverse %4 %143 -OpStore %19 %144 -%145 = OpLoad %11 %21 -%146 = OpBitReverse %11 %145 -OpStore %21 %146 -%147 = OpLoad %12 %24 -%148 = OpBitReverse %12 %147 -OpStore %24 %148 -%149 = OpLoad %13 %27 -%150 = OpBitReverse %13 %149 -OpStore %27 %150 -%151 = OpLoad %6 %30 -%152 = OpBitReverse %6 %151 -OpStore %30 %152 -%153 = OpLoad %14 %32 -%154 = OpBitReverse %14 %153 -OpStore %32 %154 -%155 = OpLoad %15 %35 -%156 = OpBitReverse %15 %155 -OpStore %35 %156 -%157 = OpLoad %16 %38 -%158 = OpBitReverse %16 %157 -OpStore %38 %158 +%21 = OpConstantNull %4 +%23 = OpTypePointer Function %11 +%24 = OpConstantNull %11 +%26 = OpTypePointer Function %12 +%27 = OpConstantNull %12 +%29 = OpTypePointer Function %13 +%30 = OpConstantNull %13 +%32 = OpTypePointer Function %6 +%33 = OpConstantNull %6 +%35 = OpTypePointer Function %14 +%36 = OpConstantNull %14 +%38 = OpTypePointer Function %15 +%39 = OpConstantNull %15 +%41 = OpTypePointer Function %16 +%42 = OpConstantNull %16 +%44 = OpTypePointer Function %17 +%45 = OpConstantNull %17 +%47 = OpTypePointer Function %18 +%48 = OpConstantNull %18 +%51 = OpTypeFunction %2 +%50 = OpFunction %2 None %51 +%49 = OpLabel +%46 = OpVariable %47 Function %48 +%37 = OpVariable %38 Function %39 +%28 = OpVariable %29 Function %30 +%19 = OpVariable %20 Function %21 +%40 = OpVariable %41 Function %42 +%31 = OpVariable %32 Function %33 +%22 = OpVariable %23 Function %24 +%43 = OpVariable %44 Function %45 +%34 = OpVariable %35 Function %36 +%25 = OpVariable %26 Function %27 +OpBranch %52 +%52 = OpLabel +OpStore %19 %3 +%53 = OpCompositeConstruct %11 %3 %3 +OpStore %22 %53 +%54 = OpCompositeConstruct %12 %3 %3 %3 +OpStore %25 %54 +%55 = OpCompositeConstruct %13 %3 %3 %3 %3 +OpStore %28 %55 +OpStore %31 %5 +%56 = OpCompositeConstruct %14 %5 %5 +OpStore %34 %56 +%57 = OpCompositeConstruct %15 %5 %5 %5 +OpStore %37 %57 +%58 = OpCompositeConstruct %16 %5 %5 %5 %5 +OpStore %40 %58 +%59 = OpCompositeConstruct %17 %7 %7 +OpStore %43 %59 +%60 = OpCompositeConstruct %18 %7 %7 %7 %7 +OpStore %46 %60 +%61 = OpLoad %18 %46 +%62 = OpExtInst %6 %1 PackSnorm4x8 %61 +OpStore %31 %62 +%63 = OpLoad %18 %46 +%64 = OpExtInst %6 %1 PackUnorm4x8 %63 +OpStore %31 %64 +%65 = OpLoad %17 %43 +%66 = OpExtInst %6 %1 PackSnorm2x16 %65 +OpStore %31 %66 +%67 = OpLoad %17 %43 +%68 = OpExtInst %6 %1 PackUnorm2x16 %67 +OpStore %31 %68 +%69 = OpLoad %17 %43 +%70 = OpExtInst %6 %1 PackHalf2x16 %69 +OpStore %31 %70 +%71 = OpLoad %6 %31 +%72 = OpExtInst %18 %1 UnpackSnorm4x8 %71 +OpStore %46 %72 +%73 = OpLoad %6 %31 +%74 = OpExtInst %18 %1 UnpackUnorm4x8 %73 +OpStore %46 %74 +%75 = OpLoad %6 %31 +%76 = OpExtInst %17 %1 UnpackSnorm2x16 %75 +OpStore %43 %76 +%77 = OpLoad %6 %31 +%78 = OpExtInst %17 %1 UnpackUnorm2x16 %77 +OpStore %43 %78 +%79 = OpLoad %6 %31 +%80 = OpExtInst %17 %1 UnpackHalf2x16 %79 +OpStore %43 %80 +%81 = OpLoad %4 %19 +%82 = OpLoad %4 %19 +%83 = OpBitFieldInsert %4 %81 %82 %9 %10 +OpStore %19 %83 +%84 = OpLoad %11 %22 +%85 = OpLoad %11 %22 +%86 = OpBitFieldInsert %11 %84 %85 %9 %10 +OpStore %22 %86 +%87 = OpLoad %12 %25 +%88 = OpLoad %12 %25 +%89 = OpBitFieldInsert %12 %87 %88 %9 %10 +OpStore %25 %89 +%90 = OpLoad %13 %28 +%91 = OpLoad %13 %28 +%92 = OpBitFieldInsert %13 %90 %91 %9 %10 +OpStore %28 %92 +%93 = OpLoad %6 %31 +%94 = OpLoad %6 %31 +%95 = OpBitFieldInsert %6 %93 %94 %9 %10 +OpStore %31 %95 +%96 = OpLoad %14 %34 +%97 = OpLoad %14 %34 +%98 = OpBitFieldInsert %14 %96 %97 %9 %10 +OpStore %34 %98 +%99 = OpLoad %15 %37 +%100 = OpLoad %15 %37 +%101 = OpBitFieldInsert %15 %99 %100 %9 %10 +OpStore %37 %101 +%102 = OpLoad %16 %40 +%103 = OpLoad %16 %40 +%104 = OpBitFieldInsert %16 %102 %103 %9 %10 +OpStore %40 %104 +%105 = OpLoad %4 %19 +%106 = OpBitFieldSExtract %4 %105 %9 %10 +OpStore %19 %106 +%107 = OpLoad %11 %22 +%108 = OpBitFieldSExtract %11 %107 %9 %10 +OpStore %22 %108 +%109 = OpLoad %12 %25 +%110 = OpBitFieldSExtract %12 %109 %9 %10 +OpStore %25 %110 +%111 = OpLoad %13 %28 +%112 = OpBitFieldSExtract %13 %111 %9 %10 +OpStore %28 %112 +%113 = OpLoad %6 %31 +%114 = OpBitFieldUExtract %6 %113 %9 %10 +OpStore %31 %114 +%115 = OpLoad %14 %34 +%116 = OpBitFieldUExtract %14 %115 %9 %10 +OpStore %34 %116 +%117 = OpLoad %15 %37 +%118 = OpBitFieldUExtract %15 %117 %9 %10 +OpStore %37 %118 +%119 = OpLoad %16 %40 +%120 = OpBitFieldUExtract %16 %119 %9 %10 +OpStore %40 %120 +%121 = OpLoad %4 %19 +%122 = OpExtInst %4 %1 FindILsb %121 +OpStore %19 %122 +%123 = OpLoad %14 %34 +%124 = OpExtInst %14 %1 FindILsb %123 +OpStore %34 %124 +%125 = OpLoad %12 %25 +%126 = OpExtInst %12 %1 FindSMsb %125 +OpStore %25 %126 +%127 = OpLoad %6 %31 +%128 = OpExtInst %6 %1 FindUMsb %127 +OpStore %31 %128 +%129 = OpLoad %4 %19 +%130 = OpBitCount %4 %129 +OpStore %19 %130 +%131 = OpLoad %11 %22 +%132 = OpBitCount %11 %131 +OpStore %22 %132 +%133 = OpLoad %12 %25 +%134 = OpBitCount %12 %133 +OpStore %25 %134 +%135 = OpLoad %13 %28 +%136 = OpBitCount %13 %135 +OpStore %28 %136 +%137 = OpLoad %6 %31 +%138 = OpBitCount %6 %137 +OpStore %31 %138 +%139 = OpLoad %14 %34 +%140 = OpBitCount %14 %139 +OpStore %34 %140 +%141 = OpLoad %15 %37 +%142 = OpBitCount %15 %141 +OpStore %37 %142 +%143 = OpLoad %16 %40 +%144 = OpBitCount %16 %143 +OpStore %40 %144 +%145 = OpLoad %4 %19 +%146 = OpBitReverse %4 %145 +OpStore %19 %146 +%147 = OpLoad %11 %22 +%148 = OpBitReverse %11 %147 +OpStore %22 %148 +%149 = OpLoad %12 %25 +%150 = OpBitReverse %12 %149 +OpStore %25 %150 +%151 = OpLoad %13 %28 +%152 = OpBitReverse %13 %151 +OpStore %28 %152 +%153 = OpLoad %6 %31 +%154 = OpBitReverse %6 %153 +OpStore %31 %154 +%155 = OpLoad %14 %34 +%156 = OpBitReverse %14 %155 +OpStore %34 %156 +%157 = OpLoad %15 %37 +%158 = OpBitReverse %15 %157 +OpStore %37 %158 +%159 = OpLoad %16 %40 +%160 = OpBitReverse %16 %159 +OpStore %40 %160 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/boids.spvasm b/tests/out/spv/boids.spvasm index 887cdb6adb..0705044369 100644 --- a/tests/out/spv/boids.spvasm +++ b/tests/out/spv/boids.spvasm @@ -1,13 +1,13 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 213 +; Bound: 216 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %51 "main" %48 -OpExecutionMode %51 LocalSize 64 1 1 +OpEntryPoint GLCompute %54 "main" %51 +OpExecutionMode %54 LocalSize 64 1 1 OpSource GLSL 450 OpName %3 "NUM_PARTICLES" OpMemberName %16 0 "pos" @@ -32,12 +32,12 @@ OpName %32 "cMass" OpName %34 "cVel" OpName %36 "colVel" OpName %38 "cMassCount" -OpName %40 "cVelCount" -OpName %41 "pos" -OpName %43 "vel" -OpName %45 "i" -OpName %48 "global_invocation_id" -OpName %51 "main" +OpName %41 "cVelCount" +OpName %43 "pos" +OpName %45 "vel" +OpName %47 "i" +OpName %51 "global_invocation_id" +OpName %54 "main" OpMemberDecorate %16 0 Offset 0 OpMemberDecorate %16 1 Offset 8 OpMemberDecorate %17 0 Offset 0 @@ -60,7 +60,7 @@ OpDecorate %19 Block OpDecorate %26 DescriptorSet 0 OpDecorate %26 Binding 2 OpDecorate %19 Block -OpDecorate %48 BuiltIn GlobalInvocationId +OpDecorate %51 BuiltIn GlobalInvocationId %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 1500 @@ -93,250 +93,256 @@ OpDecorate %48 BuiltIn GlobalInvocationId %35 = OpConstantNull %15 %37 = OpConstantNull %15 %39 = OpTypePointer Function %8 -%42 = OpConstantNull %15 +%40 = OpConstantNull %8 +%42 = OpConstantNull %8 %44 = OpConstantNull %15 -%46 = OpTypePointer Function %4 -%49 = OpTypePointer Input %20 -%48 = OpVariable %49 Input -%52 = OpTypeFunction %2 -%53 = OpTypePointer Uniform %17 -%57 = OpTypeBool -%61 = OpTypePointer StorageBuffer %18 -%62 = OpTypePointer StorageBuffer %16 -%63 = OpTypePointer StorageBuffer %15 -%92 = OpTypePointer Uniform %6 -%106 = OpConstant %4 2 -%120 = OpConstant %4 3 -%155 = OpConstant %4 4 -%161 = OpConstant %4 5 -%167 = OpConstant %4 6 -%184 = OpTypePointer Function %6 -%51 = OpFunction %2 None %52 -%47 = OpLabel -%45 = OpVariable %46 Function %9 -%40 = OpVariable %39 Function %7 +%46 = OpConstantNull %15 +%48 = OpTypePointer Function %4 +%49 = OpConstantNull %4 +%52 = OpTypePointer Input %20 +%51 = OpVariable %52 Input +%55 = OpTypeFunction %2 +%56 = OpTypePointer Uniform %17 +%60 = OpTypeBool +%64 = OpTypePointer StorageBuffer %18 +%65 = OpTypePointer StorageBuffer %16 +%66 = OpTypePointer StorageBuffer %15 +%95 = OpTypePointer Uniform %6 +%109 = OpConstant %4 2 +%123 = OpConstant %4 3 +%158 = OpConstant %4 4 +%164 = OpConstant %4 5 +%170 = OpConstant %4 6 +%187 = OpTypePointer Function %6 +%54 = OpFunction %2 None %55 +%50 = OpLabel +%47 = OpVariable %48 Function %49 +%41 = OpVariable %39 Function %42 %34 = OpVariable %28 Function %35 %27 = OpVariable %28 Function %29 -%41 = OpVariable %28 Function %42 +%43 = OpVariable %28 Function %44 %36 = OpVariable %28 Function %37 %30 = OpVariable %28 Function %31 -%43 = OpVariable %28 Function %44 -%38 = OpVariable %39 Function %7 +%45 = OpVariable %28 Function %46 +%38 = OpVariable %39 Function %40 %32 = OpVariable %28 Function %33 -%50 = OpLoad %20 %48 -%54 = OpAccessChain %53 %21 %9 -OpBranch %55 -%55 = OpLabel -%56 = OpCompositeExtract %4 %50 0 -%58 = OpUGreaterThanEqual %57 %56 %3 -OpSelectionMerge %59 None -OpBranchConditional %58 %60 %59 -%60 = OpLabel +%53 = OpLoad %20 %51 +%57 = OpAccessChain %56 %21 %9 +OpBranch %58 +%58 = OpLabel +%59 = OpCompositeExtract %4 %53 0 +%61 = OpUGreaterThanEqual %60 %59 %3 +OpSelectionMerge %62 None +OpBranchConditional %61 %63 %62 +%63 = OpLabel OpReturn -%59 = OpLabel -%64 = OpAccessChain %63 %24 %9 %56 %9 -%65 = OpLoad %15 %64 -OpStore %27 %65 -%66 = OpAccessChain %63 %24 %9 %56 %11 -%67 = OpLoad %15 %66 -OpStore %30 %67 -%68 = OpCompositeConstruct %15 %5 %5 -OpStore %32 %68 -%69 = OpCompositeConstruct %15 %5 %5 -OpStore %34 %69 -%70 = OpCompositeConstruct %15 %5 %5 -OpStore %36 %70 -OpBranch %71 -%71 = OpLabel -OpLoopMerge %72 %74 None -OpBranch %73 -%73 = OpLabel -%75 = OpLoad %4 %45 -%76 = OpUGreaterThanEqual %57 %75 %3 -OpSelectionMerge %77 None -OpBranchConditional %76 %78 %77 -%78 = OpLabel -OpBranch %72 -%77 = OpLabel -%79 = OpLoad %4 %45 -%80 = OpIEqual %57 %79 %56 -OpSelectionMerge %81 None -OpBranchConditional %80 %82 %81 -%82 = OpLabel -OpBranch %74 -%81 = OpLabel -%83 = OpLoad %4 %45 -%84 = OpAccessChain %63 %24 %9 %83 %9 -%85 = OpLoad %15 %84 -OpStore %41 %85 -%86 = OpLoad %4 %45 -%87 = OpAccessChain %63 %24 %9 %86 %11 -%88 = OpLoad %15 %87 -OpStore %43 %88 -%89 = OpLoad %15 %41 -%90 = OpLoad %15 %27 -%91 = OpExtInst %6 %1 Distance %89 %90 -%93 = OpAccessChain %92 %54 %11 -%94 = OpLoad %6 %93 -%95 = OpFOrdLessThan %57 %91 %94 -OpSelectionMerge %96 None -OpBranchConditional %95 %97 %96 -%97 = OpLabel -%98 = OpLoad %15 %32 -%99 = OpLoad %15 %41 -%100 = OpFAdd %15 %98 %99 -OpStore %32 %100 -%101 = OpLoad %8 %38 -%102 = OpIAdd %8 %101 %10 -OpStore %38 %102 -OpBranch %96 -%96 = OpLabel -%103 = OpLoad %15 %41 -%104 = OpLoad %15 %27 -%105 = OpExtInst %6 %1 Distance %103 %104 -%107 = OpAccessChain %92 %54 %106 -%108 = OpLoad %6 %107 -%109 = OpFOrdLessThan %57 %105 %108 -OpSelectionMerge %110 None -OpBranchConditional %109 %111 %110 -%111 = OpLabel -%112 = OpLoad %15 %36 -%113 = OpLoad %15 %41 -%114 = OpLoad %15 %27 -%115 = OpFSub %15 %113 %114 -%116 = OpFSub %15 %112 %115 -OpStore %36 %116 -OpBranch %110 -%110 = OpLabel -%117 = OpLoad %15 %41 -%118 = OpLoad %15 %27 -%119 = OpExtInst %6 %1 Distance %117 %118 -%121 = OpAccessChain %92 %54 %120 -%122 = OpLoad %6 %121 -%123 = OpFOrdLessThan %57 %119 %122 -OpSelectionMerge %124 None -OpBranchConditional %123 %125 %124 -%125 = OpLabel -%126 = OpLoad %15 %34 -%127 = OpLoad %15 %43 -%128 = OpFAdd %15 %126 %127 -OpStore %34 %128 -%129 = OpLoad %8 %40 -%130 = OpIAdd %8 %129 %10 -OpStore %40 %130 -OpBranch %124 -%124 = OpLabel +%62 = OpLabel +%67 = OpAccessChain %66 %24 %9 %59 %9 +%68 = OpLoad %15 %67 +OpStore %27 %68 +%69 = OpAccessChain %66 %24 %9 %59 %11 +%70 = OpLoad %15 %69 +OpStore %30 %70 +%71 = OpCompositeConstruct %15 %5 %5 +OpStore %32 %71 +%72 = OpCompositeConstruct %15 %5 %5 +OpStore %34 %72 +%73 = OpCompositeConstruct %15 %5 %5 +OpStore %36 %73 +OpStore %38 %7 +OpStore %41 %7 +OpStore %47 %9 OpBranch %74 %74 = OpLabel -%131 = OpLoad %4 %45 -%132 = OpIAdd %4 %131 %11 -OpStore %45 %132 -OpBranch %71 -%72 = OpLabel -%133 = OpLoad %8 %38 -%134 = OpSGreaterThan %57 %133 %7 -OpSelectionMerge %135 None -OpBranchConditional %134 %136 %135 -%136 = OpLabel -%137 = OpLoad %15 %32 -%138 = OpLoad %8 %38 -%139 = OpConvertSToF %6 %138 -%140 = OpCompositeConstruct %15 %139 %139 -%141 = OpFDiv %15 %137 %140 -%142 = OpLoad %15 %27 -%143 = OpFSub %15 %141 %142 -OpStore %32 %143 -OpBranch %135 -%135 = OpLabel -%144 = OpLoad %8 %40 -%145 = OpSGreaterThan %57 %144 %7 -OpSelectionMerge %146 None -OpBranchConditional %145 %147 %146 -%147 = OpLabel -%148 = OpLoad %15 %34 -%149 = OpLoad %8 %40 -%150 = OpConvertSToF %6 %149 -%151 = OpCompositeConstruct %15 %150 %150 -%152 = OpFDiv %15 %148 %151 -OpStore %34 %152 -OpBranch %146 -%146 = OpLabel -%153 = OpLoad %15 %30 -%154 = OpLoad %15 %32 -%156 = OpAccessChain %92 %54 %155 -%157 = OpLoad %6 %156 -%158 = OpVectorTimesScalar %15 %154 %157 -%159 = OpFAdd %15 %153 %158 -%160 = OpLoad %15 %36 -%162 = OpAccessChain %92 %54 %161 -%163 = OpLoad %6 %162 -%164 = OpVectorTimesScalar %15 %160 %163 -%165 = OpFAdd %15 %159 %164 -%166 = OpLoad %15 %34 -%168 = OpAccessChain %92 %54 %167 -%169 = OpLoad %6 %168 -%170 = OpVectorTimesScalar %15 %166 %169 -%171 = OpFAdd %15 %165 %170 -OpStore %30 %171 -%172 = OpLoad %15 %30 -%173 = OpExtInst %15 %1 Normalize %172 -%174 = OpLoad %15 %30 -%175 = OpExtInst %6 %1 Length %174 -%176 = OpExtInst %6 %1 FClamp %175 %5 %12 -%177 = OpVectorTimesScalar %15 %173 %176 -OpStore %30 %177 -%178 = OpLoad %15 %27 -%179 = OpLoad %15 %30 -%180 = OpAccessChain %92 %54 %9 -%181 = OpLoad %6 %180 -%182 = OpVectorTimesScalar %15 %179 %181 -%183 = OpFAdd %15 %178 %182 -OpStore %27 %183 -%185 = OpAccessChain %184 %27 %9 -%186 = OpLoad %6 %185 -%187 = OpFOrdLessThan %57 %186 %13 -OpSelectionMerge %188 None -OpBranchConditional %187 %189 %188 -%189 = OpLabel -%190 = OpAccessChain %184 %27 %9 -OpStore %190 %14 -OpBranch %188 -%188 = OpLabel -%191 = OpAccessChain %184 %27 %9 -%192 = OpLoad %6 %191 -%193 = OpFOrdGreaterThan %57 %192 %14 -OpSelectionMerge %194 None -OpBranchConditional %193 %195 %194 -%195 = OpLabel -%196 = OpAccessChain %184 %27 %9 -OpStore %196 %13 -OpBranch %194 -%194 = OpLabel -%197 = OpAccessChain %184 %27 %11 -%198 = OpLoad %6 %197 -%199 = OpFOrdLessThan %57 %198 %13 -OpSelectionMerge %200 None -OpBranchConditional %199 %201 %200 -%201 = OpLabel -%202 = OpAccessChain %184 %27 %11 -OpStore %202 %14 -OpBranch %200 -%200 = OpLabel -%203 = OpAccessChain %184 %27 %11 -%204 = OpLoad %6 %203 -%205 = OpFOrdGreaterThan %57 %204 %14 -OpSelectionMerge %206 None -OpBranchConditional %205 %207 %206 -%207 = OpLabel -%208 = OpAccessChain %184 %27 %11 -OpStore %208 %13 -OpBranch %206 -%206 = OpLabel -%209 = OpLoad %15 %27 -%210 = OpAccessChain %63 %26 %9 %56 %9 -OpStore %210 %209 -%211 = OpLoad %15 %30 -%212 = OpAccessChain %63 %26 %9 %56 %11 -OpStore %212 %211 +OpLoopMerge %75 %77 None +OpBranch %76 +%76 = OpLabel +%78 = OpLoad %4 %47 +%79 = OpUGreaterThanEqual %60 %78 %3 +OpSelectionMerge %80 None +OpBranchConditional %79 %81 %80 +%81 = OpLabel +OpBranch %75 +%80 = OpLabel +%82 = OpLoad %4 %47 +%83 = OpIEqual %60 %82 %59 +OpSelectionMerge %84 None +OpBranchConditional %83 %85 %84 +%85 = OpLabel +OpBranch %77 +%84 = OpLabel +%86 = OpLoad %4 %47 +%87 = OpAccessChain %66 %24 %9 %86 %9 +%88 = OpLoad %15 %87 +OpStore %43 %88 +%89 = OpLoad %4 %47 +%90 = OpAccessChain %66 %24 %9 %89 %11 +%91 = OpLoad %15 %90 +OpStore %45 %91 +%92 = OpLoad %15 %43 +%93 = OpLoad %15 %27 +%94 = OpExtInst %6 %1 Distance %92 %93 +%96 = OpAccessChain %95 %57 %11 +%97 = OpLoad %6 %96 +%98 = OpFOrdLessThan %60 %94 %97 +OpSelectionMerge %99 None +OpBranchConditional %98 %100 %99 +%100 = OpLabel +%101 = OpLoad %15 %32 +%102 = OpLoad %15 %43 +%103 = OpFAdd %15 %101 %102 +OpStore %32 %103 +%104 = OpLoad %8 %38 +%105 = OpIAdd %8 %104 %10 +OpStore %38 %105 +OpBranch %99 +%99 = OpLabel +%106 = OpLoad %15 %43 +%107 = OpLoad %15 %27 +%108 = OpExtInst %6 %1 Distance %106 %107 +%110 = OpAccessChain %95 %57 %109 +%111 = OpLoad %6 %110 +%112 = OpFOrdLessThan %60 %108 %111 +OpSelectionMerge %113 None +OpBranchConditional %112 %114 %113 +%114 = OpLabel +%115 = OpLoad %15 %36 +%116 = OpLoad %15 %43 +%117 = OpLoad %15 %27 +%118 = OpFSub %15 %116 %117 +%119 = OpFSub %15 %115 %118 +OpStore %36 %119 +OpBranch %113 +%113 = OpLabel +%120 = OpLoad %15 %43 +%121 = OpLoad %15 %27 +%122 = OpExtInst %6 %1 Distance %120 %121 +%124 = OpAccessChain %95 %57 %123 +%125 = OpLoad %6 %124 +%126 = OpFOrdLessThan %60 %122 %125 +OpSelectionMerge %127 None +OpBranchConditional %126 %128 %127 +%128 = OpLabel +%129 = OpLoad %15 %34 +%130 = OpLoad %15 %45 +%131 = OpFAdd %15 %129 %130 +OpStore %34 %131 +%132 = OpLoad %8 %41 +%133 = OpIAdd %8 %132 %10 +OpStore %41 %133 +OpBranch %127 +%127 = OpLabel +OpBranch %77 +%77 = OpLabel +%134 = OpLoad %4 %47 +%135 = OpIAdd %4 %134 %11 +OpStore %47 %135 +OpBranch %74 +%75 = OpLabel +%136 = OpLoad %8 %38 +%137 = OpSGreaterThan %60 %136 %7 +OpSelectionMerge %138 None +OpBranchConditional %137 %139 %138 +%139 = OpLabel +%140 = OpLoad %15 %32 +%141 = OpLoad %8 %38 +%142 = OpConvertSToF %6 %141 +%143 = OpCompositeConstruct %15 %142 %142 +%144 = OpFDiv %15 %140 %143 +%145 = OpLoad %15 %27 +%146 = OpFSub %15 %144 %145 +OpStore %32 %146 +OpBranch %138 +%138 = OpLabel +%147 = OpLoad %8 %41 +%148 = OpSGreaterThan %60 %147 %7 +OpSelectionMerge %149 None +OpBranchConditional %148 %150 %149 +%150 = OpLabel +%151 = OpLoad %15 %34 +%152 = OpLoad %8 %41 +%153 = OpConvertSToF %6 %152 +%154 = OpCompositeConstruct %15 %153 %153 +%155 = OpFDiv %15 %151 %154 +OpStore %34 %155 +OpBranch %149 +%149 = OpLabel +%156 = OpLoad %15 %30 +%157 = OpLoad %15 %32 +%159 = OpAccessChain %95 %57 %158 +%160 = OpLoad %6 %159 +%161 = OpVectorTimesScalar %15 %157 %160 +%162 = OpFAdd %15 %156 %161 +%163 = OpLoad %15 %36 +%165 = OpAccessChain %95 %57 %164 +%166 = OpLoad %6 %165 +%167 = OpVectorTimesScalar %15 %163 %166 +%168 = OpFAdd %15 %162 %167 +%169 = OpLoad %15 %34 +%171 = OpAccessChain %95 %57 %170 +%172 = OpLoad %6 %171 +%173 = OpVectorTimesScalar %15 %169 %172 +%174 = OpFAdd %15 %168 %173 +OpStore %30 %174 +%175 = OpLoad %15 %30 +%176 = OpExtInst %15 %1 Normalize %175 +%177 = OpLoad %15 %30 +%178 = OpExtInst %6 %1 Length %177 +%179 = OpExtInst %6 %1 FClamp %178 %5 %12 +%180 = OpVectorTimesScalar %15 %176 %179 +OpStore %30 %180 +%181 = OpLoad %15 %27 +%182 = OpLoad %15 %30 +%183 = OpAccessChain %95 %57 %9 +%184 = OpLoad %6 %183 +%185 = OpVectorTimesScalar %15 %182 %184 +%186 = OpFAdd %15 %181 %185 +OpStore %27 %186 +%188 = OpAccessChain %187 %27 %9 +%189 = OpLoad %6 %188 +%190 = OpFOrdLessThan %60 %189 %13 +OpSelectionMerge %191 None +OpBranchConditional %190 %192 %191 +%192 = OpLabel +%193 = OpAccessChain %187 %27 %9 +OpStore %193 %14 +OpBranch %191 +%191 = OpLabel +%194 = OpAccessChain %187 %27 %9 +%195 = OpLoad %6 %194 +%196 = OpFOrdGreaterThan %60 %195 %14 +OpSelectionMerge %197 None +OpBranchConditional %196 %198 %197 +%198 = OpLabel +%199 = OpAccessChain %187 %27 %9 +OpStore %199 %13 +OpBranch %197 +%197 = OpLabel +%200 = OpAccessChain %187 %27 %11 +%201 = OpLoad %6 %200 +%202 = OpFOrdLessThan %60 %201 %13 +OpSelectionMerge %203 None +OpBranchConditional %202 %204 %203 +%204 = OpLabel +%205 = OpAccessChain %187 %27 %11 +OpStore %205 %14 +OpBranch %203 +%203 = OpLabel +%206 = OpAccessChain %187 %27 %11 +%207 = OpLoad %6 %206 +%208 = OpFOrdGreaterThan %60 %207 %14 +OpSelectionMerge %209 None +OpBranchConditional %208 %210 %209 +%210 = OpLabel +%211 = OpAccessChain %187 %27 %11 +OpStore %211 %13 +OpBranch %209 +%209 = OpLabel +%212 = OpLoad %15 %27 +%213 = OpAccessChain %66 %26 %9 %59 %9 +OpStore %213 %212 +%214 = OpLoad %15 %30 +%215 = OpAccessChain %66 %26 %9 %59 %11 +OpStore %215 %214 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/collatz.spvasm b/tests/out/spv/collatz.spvasm index 6e6483da10..7be8c912ca 100644 --- a/tests/out/spv/collatz.spvasm +++ b/tests/out/spv/collatz.spvasm @@ -1,29 +1,29 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 60 +; Bound: 63 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %49 "main" %46 -OpExecutionMode %49 LocalSize 1 1 1 +OpEntryPoint GLCompute %52 "main" %49 +OpExecutionMode %52 LocalSize 1 1 1 OpSource GLSL 450 OpMemberName %9 0 "data" OpName %9 "PrimeIndices" OpName %11 "v_indices" OpName %13 "n" OpName %16 "i" -OpName %18 "n_base" -OpName %19 "collatz_iterations" -OpName %46 "global_id" -OpName %49 "main" +OpName %19 "n_base" +OpName %20 "collatz_iterations" +OpName %49 "global_id" +OpName %52 "main" OpDecorate %8 ArrayStride 4 OpMemberDecorate %9 0 Offset 0 OpDecorate %11 DescriptorSet 0 OpDecorate %11 Binding 0 OpDecorate %9 Block -OpDecorate %46 BuiltIn GlobalInvocationId +OpDecorate %49 BuiltIn GlobalInvocationId %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 0 @@ -37,71 +37,77 @@ OpDecorate %46 BuiltIn GlobalInvocationId %11 = OpVariable %12 StorageBuffer %14 = OpTypePointer Function %4 %15 = OpConstantNull %4 -%20 = OpTypeFunction %4 %4 -%27 = OpTypeBool -%47 = OpTypePointer Input %10 -%46 = OpVariable %47 Input -%50 = OpTypeFunction %2 -%52 = OpTypePointer StorageBuffer %8 -%54 = OpTypePointer StorageBuffer %4 -%19 = OpFunction %4 None %20 -%18 = OpFunctionParameter %4 -%17 = OpLabel +%17 = OpConstantNull %4 +%21 = OpTypeFunction %4 %4 +%28 = OpTypeBool +%50 = OpTypePointer Input %10 +%49 = OpVariable %50 Input +%53 = OpTypeFunction %2 +%55 = OpTypePointer StorageBuffer %8 +%57 = OpTypePointer StorageBuffer %4 +%20 = OpFunction %4 None %21 +%19 = OpFunctionParameter %4 +%18 = OpLabel %13 = OpVariable %14 Function %15 -%16 = OpVariable %14 Function %3 -OpBranch %21 -%21 = OpLabel -OpStore %13 %18 +%16 = OpVariable %14 Function %17 OpBranch %22 %22 = OpLabel -OpLoopMerge %23 %25 None -OpBranch %24 -%24 = OpLabel -%26 = OpLoad %4 %13 -%28 = OpUGreaterThan %27 %26 %5 -OpSelectionMerge %29 None -OpBranchConditional %28 %29 %30 -%30 = OpLabel +OpStore %13 %19 +OpStore %16 %3 OpBranch %23 -%29 = OpLabel -%31 = OpLoad %4 %13 -%32 = OpUMod %4 %31 %6 -%33 = OpIEqual %27 %32 %3 -OpSelectionMerge %34 None -OpBranchConditional %33 %35 %36 -%35 = OpLabel -%37 = OpLoad %4 %13 -%38 = OpUDiv %4 %37 %6 -OpStore %13 %38 -OpBranch %34 -%36 = OpLabel -%39 = OpLoad %4 %13 -%40 = OpIMul %4 %7 %39 -%41 = OpIAdd %4 %40 %5 -OpStore %13 %41 -OpBranch %34 -%34 = OpLabel -%42 = OpLoad %4 %16 -%43 = OpIAdd %4 %42 %5 -OpStore %16 %43 +%23 = OpLabel +OpLoopMerge %24 %26 None OpBranch %25 %25 = OpLabel -OpBranch %22 -%23 = OpLabel -%44 = OpLoad %4 %16 -OpReturnValue %44 +%27 = OpLoad %4 %13 +%29 = OpUGreaterThan %28 %27 %5 +OpSelectionMerge %30 None +OpBranchConditional %29 %30 %31 +%31 = OpLabel +OpBranch %24 +%30 = OpLabel +OpBranch %32 +%32 = OpLabel +%34 = OpLoad %4 %13 +%35 = OpUMod %4 %34 %6 +%36 = OpIEqual %28 %35 %3 +OpSelectionMerge %37 None +OpBranchConditional %36 %38 %39 +%38 = OpLabel +%40 = OpLoad %4 %13 +%41 = OpUDiv %4 %40 %6 +OpStore %13 %41 +OpBranch %37 +%39 = OpLabel +%42 = OpLoad %4 %13 +%43 = OpIMul %4 %7 %42 +%44 = OpIAdd %4 %43 %5 +OpStore %13 %44 +OpBranch %37 +%37 = OpLabel +%45 = OpLoad %4 %16 +%46 = OpIAdd %4 %45 %5 +OpStore %16 %46 +OpBranch %33 +%33 = OpLabel +OpBranch %26 +%26 = OpLabel +OpBranch %23 +%24 = OpLabel +%47 = OpLoad %4 %16 +OpReturnValue %47 OpFunctionEnd -%49 = OpFunction %2 None %50 -%45 = OpLabel -%48 = OpLoad %10 %46 -OpBranch %51 -%51 = OpLabel -%53 = OpCompositeExtract %4 %48 0 -%55 = OpCompositeExtract %4 %48 0 -%56 = OpAccessChain %54 %11 %3 %55 -%57 = OpLoad %4 %56 -%58 = OpFunctionCall %4 %19 %57 -%59 = OpAccessChain %54 %11 %3 %53 -OpStore %59 %58 +%52 = OpFunction %2 None %53 +%48 = OpLabel +%51 = OpLoad %10 %49 +OpBranch %54 +%54 = OpLabel +%56 = OpCompositeExtract %4 %51 0 +%58 = OpCompositeExtract %4 %51 0 +%59 = OpAccessChain %57 %11 %3 %58 +%60 = OpLoad %4 %59 +%61 = OpFunctionCall %4 %20 %60 +%62 = OpAccessChain %57 %11 %3 %56 +OpStore %62 %61 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/extra.spvasm b/tests/out/spv/extra.spvasm index 99a367c64e..0c4f7a1d7e 100644 --- a/tests/out/spv/extra.spvasm +++ b/tests/out/spv/extra.spvasm @@ -7,18 +7,18 @@ OpCapability Float64 OpCapability Geometry %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %24 "main" %16 %19 %22 -OpExecutionMode %24 OriginUpperLeft +OpEntryPoint Fragment %25 "main" %17 %20 %23 +OpExecutionMode %25 OriginUpperLeft OpMemberDecorate %8 0 Offset 0 OpMemberDecorate %8 1 Offset 16 OpMemberDecorate %10 0 Offset 0 OpMemberDecorate %10 1 Offset 16 -OpDecorate %12 Block -OpMemberDecorate %12 0 Offset 0 -OpDecorate %16 Location 0 -OpDecorate %19 BuiltIn PrimitiveId -OpDecorate %19 Flat -OpDecorate %22 Location 0 +OpDecorate %13 Block +OpMemberDecorate %13 0 Offset 0 +OpDecorate %17 Location 0 +OpDecorate %20 BuiltIn PrimitiveId +OpDecorate %20 Flat +OpDecorate %23 Location 0 %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -28,49 +28,49 @@ OpDecorate %22 Location 0 %8 = OpTypeStruct %5 %6 %9 = OpTypeVector %4 4 %10 = OpTypeStruct %9 %5 -%12 = OpTypeStruct %8 -%13 = OpTypePointer PushConstant %12 -%11 = OpVariable %13 PushConstant -%17 = OpTypePointer Input %9 -%16 = OpVariable %17 Input -%20 = OpTypePointer Input %5 -%19 = OpVariable %20 Input -%23 = OpTypePointer Output %9 -%22 = OpVariable %23 Output -%25 = OpTypeFunction %2 -%26 = OpTypePointer PushConstant %8 -%27 = OpConstant %5 0 -%31 = OpTypePointer PushConstant %5 -%34 = OpTypeBool -%40 = OpTypeVector %4 3 -%24 = OpFunction %2 None %25 -%14 = OpLabel -%18 = OpLoad %9 %16 -%21 = OpLoad %5 %19 -%15 = OpCompositeConstruct %10 %18 %21 -%28 = OpAccessChain %26 %11 %27 -OpBranch %29 -%29 = OpLabel -%30 = OpCompositeExtract %5 %15 1 -%32 = OpAccessChain %31 %28 %27 -%33 = OpLoad %5 %32 -%35 = OpIEqual %34 %30 %33 -OpSelectionMerge %36 None -OpBranchConditional %35 %37 %38 -%37 = OpLabel -%39 = OpCompositeExtract %9 %15 0 -OpStore %22 %39 -OpReturn +%11 = OpTypeVector %4 3 +%13 = OpTypeStruct %8 +%14 = OpTypePointer PushConstant %13 +%12 = OpVariable %14 PushConstant +%18 = OpTypePointer Input %9 +%17 = OpVariable %18 Input +%21 = OpTypePointer Input %5 +%20 = OpVariable %21 Input +%24 = OpTypePointer Output %9 +%23 = OpVariable %24 Output +%26 = OpTypeFunction %2 +%27 = OpTypePointer PushConstant %8 +%28 = OpConstant %5 0 +%32 = OpTypePointer PushConstant %5 +%35 = OpTypeBool +%25 = OpFunction %2 None %26 +%15 = OpLabel +%19 = OpLoad %9 %17 +%22 = OpLoad %5 %20 +%16 = OpCompositeConstruct %10 %19 %22 +%29 = OpAccessChain %27 %12 %28 +OpBranch %30 +%30 = OpLabel +%31 = OpCompositeExtract %5 %16 1 +%33 = OpAccessChain %32 %29 %28 +%34 = OpLoad %5 %33 +%36 = OpIEqual %35 %31 %34 +OpSelectionMerge %37 None +OpBranchConditional %36 %38 %39 %38 = OpLabel -%41 = OpCompositeConstruct %40 %3 %3 %3 -%42 = OpCompositeExtract %9 %15 0 -%43 = OpVectorShuffle %40 %42 %42 0 1 2 -%44 = OpFSub %40 %41 %43 -%45 = OpCompositeExtract %9 %15 0 +%40 = OpCompositeExtract %9 %16 0 +OpStore %23 %40 +OpReturn +%39 = OpLabel +%41 = OpCompositeConstruct %11 %3 %3 %3 +%42 = OpCompositeExtract %9 %16 0 +%43 = OpVectorShuffle %11 %42 %42 0 1 2 +%44 = OpFSub %11 %41 %43 +%45 = OpCompositeExtract %9 %16 0 %46 = OpCompositeExtract %4 %45 3 %47 = OpCompositeConstruct %9 %44 %46 -OpStore %22 %47 +OpStore %23 %47 OpReturn -%36 = OpLabel +%37 = OpLabel OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/functions.spvasm b/tests/out/spv/functions.spvasm index da2d240aab..bfebd09f84 100644 --- a/tests/out/spv/functions.spvasm +++ b/tests/out/spv/functions.spvasm @@ -18,55 +18,55 @@ OpExecutionMode %74 LocalSize 1 1 1 %10 = OpConstant %7 4 %11 = OpConstant %7 2 %12 = OpTypeVector %4 2 -%15 = OpTypeFunction %12 -%23 = OpTypeFunction %7 -%25 = OpTypeVector %7 2 -%37 = OpTypeVector %9 3 -%53 = OpTypeVector %7 4 +%13 = OpTypeVector %7 2 +%14 = OpTypeVector %9 3 +%15 = OpTypeVector %7 4 +%18 = OpTypeFunction %12 +%26 = OpTypeFunction %7 %75 = OpTypeFunction %2 -%29 = OpConstantNull %7 -%41 = OpConstantNull %9 +%31 = OpConstantNull %7 +%42 = OpConstantNull %9 %57 = OpConstantNull %7 -%14 = OpFunction %12 None %15 -%13 = OpLabel -OpBranch %16 +%17 = OpFunction %12 None %18 %16 = OpLabel -%17 = OpCompositeConstruct %12 %3 %3 -%18 = OpCompositeConstruct %12 %5 %5 -%19 = OpCompositeConstruct %12 %5 %5 -%20 = OpExtInst %12 %1 Fma %17 %18 %19 -OpReturnValue %20 +OpBranch %19 +%19 = OpLabel +%20 = OpCompositeConstruct %12 %3 %3 +%21 = OpCompositeConstruct %12 %5 %5 +%22 = OpCompositeConstruct %12 %5 %5 +%23 = OpExtInst %12 %1 Fma %20 %21 %22 +OpReturnValue %23 OpFunctionEnd -%22 = OpFunction %7 None %23 -%21 = OpLabel -OpBranch %24 +%25 = OpFunction %7 None %26 %24 = OpLabel -%26 = OpCompositeConstruct %25 %6 %6 -%27 = OpCompositeConstruct %25 %6 %6 -%30 = OpCompositeExtract %7 %26 0 -%31 = OpCompositeExtract %7 %27 0 -%32 = OpIMul %7 %30 %31 -%33 = OpIAdd %7 %29 %32 -%34 = OpCompositeExtract %7 %26 1 -%35 = OpCompositeExtract %7 %27 1 -%36 = OpIMul %7 %34 %35 -%28 = OpIAdd %7 %33 %36 -%38 = OpCompositeConstruct %37 %8 %8 %8 -%39 = OpCompositeConstruct %37 %8 %8 %8 -%42 = OpCompositeExtract %9 %38 0 +OpBranch %27 +%27 = OpLabel +%28 = OpCompositeConstruct %13 %6 %6 +%29 = OpCompositeConstruct %13 %6 %6 +%32 = OpCompositeExtract %7 %28 0 +%33 = OpCompositeExtract %7 %29 0 +%34 = OpIMul %7 %32 %33 +%35 = OpIAdd %7 %31 %34 +%36 = OpCompositeExtract %7 %28 1 +%37 = OpCompositeExtract %7 %29 1 +%38 = OpIMul %7 %36 %37 +%30 = OpIAdd %7 %35 %38 +%39 = OpCompositeConstruct %14 %8 %8 %8 +%40 = OpCompositeConstruct %14 %8 %8 %8 %43 = OpCompositeExtract %9 %39 0 -%44 = OpIMul %9 %42 %43 -%45 = OpIAdd %9 %41 %44 -%46 = OpCompositeExtract %9 %38 1 +%44 = OpCompositeExtract %9 %40 0 +%45 = OpIMul %9 %43 %44 +%46 = OpIAdd %9 %42 %45 %47 = OpCompositeExtract %9 %39 1 -%48 = OpIMul %9 %46 %47 -%49 = OpIAdd %9 %45 %48 -%50 = OpCompositeExtract %9 %38 2 +%48 = OpCompositeExtract %9 %40 1 +%49 = OpIMul %9 %47 %48 +%50 = OpIAdd %9 %46 %49 %51 = OpCompositeExtract %9 %39 2 -%52 = OpIMul %9 %50 %51 -%40 = OpIAdd %9 %49 %52 -%54 = OpCompositeConstruct %53 %10 %10 %10 %10 -%55 = OpCompositeConstruct %53 %11 %11 %11 %11 +%52 = OpCompositeExtract %9 %40 2 +%53 = OpIMul %9 %51 %52 +%41 = OpIAdd %9 %50 %53 +%54 = OpCompositeConstruct %15 %10 %10 %10 %10 +%55 = OpCompositeConstruct %15 %11 %11 %11 %11 %58 = OpCompositeExtract %7 %54 0 %59 = OpCompositeExtract %7 %55 0 %60 = OpIMul %7 %58 %59 @@ -89,7 +89,7 @@ OpFunctionEnd %73 = OpLabel OpBranch %76 %76 = OpLabel -%77 = OpFunctionCall %12 %14 -%78 = OpFunctionCall %7 %22 +%77 = OpFunctionCall %12 %17 +%78 = OpFunctionCall %7 %25 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/globals.spvasm b/tests/out/spv/globals.spvasm index 2c1691c0cf..ba39fa05c5 100644 --- a/tests/out/spv/globals.spvasm +++ b/tests/out/spv/globals.spvasm @@ -1,13 +1,13 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 169 +; Bound: 172 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %114 "main" -OpExecutionMode %114 LocalSize 1 1 1 +OpEntryPoint GLCompute %111 "main" +OpExecutionMode %111 LocalSize 1 1 1 OpDecorate %25 ArrayStride 4 OpMemberDecorate %27 0 Offset 0 OpMemberDecorate %27 1 Offset 12 @@ -114,126 +114,132 @@ OpMemberDecorate %65 0 Offset 0 %66 = OpTypePointer Uniform %65 %64 = OpVariable %66 Uniform %70 = OpTypeFunction %2 %26 -%71 = OpTypePointer StorageBuffer %29 -%72 = OpTypePointer Uniform %26 -%73 = OpTypePointer StorageBuffer %27 -%74 = OpTypePointer Uniform %35 -%75 = OpTypePointer Uniform %31 -%76 = OpTypePointer Uniform %38 -%77 = OpTypePointer Uniform %32 -%80 = OpTypePointer Function %8 -%83 = OpTypeFunction %2 -%84 = OpConstant %6 0 -%87 = OpTypePointer StorageBuffer %26 -%90 = OpTypePointer StorageBuffer %11 -%110 = OpTypePointer Function %11 -%112 = OpTypePointer Function %4 -%124 = OpTypePointer Workgroup %11 -%125 = OpTypePointer Uniform %37 -%126 = OpTypePointer Uniform %36 -%129 = OpTypePointer Uniform %34 -%130 = OpTypePointer Uniform %33 -%131 = OpTypePointer Uniform %30 -%136 = OpConstant %6 7 -%142 = OpConstant %6 6 -%144 = OpTypePointer StorageBuffer %28 -%145 = OpConstant %6 1 -%148 = OpConstant %6 5 -%150 = OpTypePointer Uniform %30 -%151 = OpTypePointer Uniform %11 -%152 = OpConstant %6 3 -%155 = OpConstant %6 4 -%157 = OpTypePointer StorageBuffer %11 -%168 = OpConstant %6 256 +%73 = OpTypePointer Function %8 +%74 = OpConstantNull %8 +%77 = OpTypeFunction %2 +%78 = OpTypePointer StorageBuffer %27 +%79 = OpConstant %6 0 +%82 = OpTypePointer StorageBuffer %26 +%85 = OpTypePointer StorageBuffer %11 +%105 = OpTypePointer Function %11 +%106 = OpConstantNull %11 +%108 = OpTypePointer Function %4 +%109 = OpConstantNull %4 +%113 = OpTypePointer StorageBuffer %29 +%115 = OpTypePointer Uniform %31 +%117 = OpTypePointer Uniform %26 +%119 = OpTypePointer Uniform %32 +%121 = OpTypePointer Uniform %35 +%123 = OpTypePointer Uniform %38 +%127 = OpTypePointer Workgroup %11 +%128 = OpTypePointer Uniform %37 +%129 = OpTypePointer Uniform %36 +%132 = OpTypePointer Uniform %34 +%133 = OpTypePointer Uniform %33 +%134 = OpTypePointer Uniform %30 +%139 = OpConstant %6 7 +%145 = OpConstant %6 6 +%147 = OpTypePointer StorageBuffer %28 +%148 = OpConstant %6 1 +%151 = OpConstant %6 5 +%153 = OpTypePointer Uniform %30 +%154 = OpTypePointer Uniform %11 +%155 = OpConstant %6 3 +%158 = OpConstant %6 4 +%160 = OpTypePointer StorageBuffer %11 +%171 = OpConstant %6 256 %69 = OpFunction %2 None %70 %68 = OpFunctionParameter %26 %67 = OpLabel -OpBranch %78 -%78 = OpLabel +OpBranch %71 +%71 = OpLabel OpReturn OpFunctionEnd -%82 = OpFunction %2 None %83 +%76 = OpFunction %2 None %77 +%75 = OpLabel +%72 = OpVariable %73 Function %74 +%80 = OpAccessChain %78 %46 %79 +OpBranch %81 %81 = OpLabel -%79 = OpVariable %80 Function %12 -%85 = OpAccessChain %73 %46 %84 -OpBranch %86 -%86 = OpLabel -%88 = OpCompositeConstruct %26 %10 %10 %10 -%89 = OpAccessChain %87 %85 %84 -OpStore %89 %88 -%91 = OpAccessChain %90 %85 %84 %84 -OpStore %91 %10 -%92 = OpAccessChain %90 %85 %84 %84 -OpStore %92 %14 -%93 = OpLoad %8 %79 -%94 = OpAccessChain %90 %85 %84 %93 -OpStore %94 %15 -%95 = OpLoad %27 %85 -%96 = OpCompositeExtract %26 %95 0 -%97 = OpCompositeExtract %26 %95 0 -%98 = OpVectorShuffle %28 %97 %97 2 0 -%99 = OpCompositeExtract %26 %95 0 -%100 = OpFunctionCall %2 %69 %99 -%101 = OpCompositeExtract %26 %95 0 -%102 = OpVectorTimesMatrix %26 %101 %41 -%103 = OpCompositeExtract %26 %95 0 -%104 = OpMatrixTimesVector %26 %41 %103 -%105 = OpCompositeExtract %26 %95 0 -%106 = OpVectorTimesScalar %26 %105 %14 -%107 = OpCompositeExtract %26 %95 0 -%108 = OpVectorTimesScalar %26 %107 %14 +%83 = OpCompositeConstruct %26 %10 %10 %10 +%84 = OpAccessChain %82 %80 %79 +OpStore %84 %83 +OpStore %72 %12 +%86 = OpAccessChain %85 %80 %79 %79 +OpStore %86 %10 +%87 = OpAccessChain %85 %80 %79 %79 +OpStore %87 %14 +%88 = OpLoad %8 %72 +%89 = OpAccessChain %85 %80 %79 %88 +OpStore %89 %15 +%90 = OpLoad %27 %80 +%91 = OpCompositeExtract %26 %90 0 +%92 = OpCompositeExtract %26 %90 0 +%93 = OpVectorShuffle %28 %92 %92 2 0 +%94 = OpCompositeExtract %26 %90 0 +%95 = OpFunctionCall %2 %69 %94 +%96 = OpCompositeExtract %26 %90 0 +%97 = OpVectorTimesMatrix %26 %96 %41 +%98 = OpCompositeExtract %26 %90 0 +%99 = OpMatrixTimesVector %26 %41 %98 +%100 = OpCompositeExtract %26 %90 0 +%101 = OpVectorTimesScalar %26 %100 %14 +%102 = OpCompositeExtract %26 %90 0 +%103 = OpVectorTimesScalar %26 %102 %14 OpReturn OpFunctionEnd -%114 = OpFunction %2 None %83 -%113 = OpLabel -%109 = OpVariable %110 Function %10 -%111 = OpVariable %112 Function %24 -%115 = OpAccessChain %73 %46 %84 -%116 = OpAccessChain %71 %49 %84 -%117 = OpAccessChain %75 %52 %84 -%118 = OpAccessChain %72 %55 %84 -%119 = OpAccessChain %77 %58 %84 -%120 = OpAccessChain %74 %61 %84 -%121 = OpAccessChain %76 %64 %84 -OpBranch %122 -%122 = OpLabel -%123 = OpFunctionCall %2 %82 -%127 = OpAccessChain %126 %121 %84 %84 -%128 = OpLoad %36 %127 -%132 = OpAccessChain %131 %120 %84 %84 %84 -%133 = OpLoad %30 %132 -%134 = OpMatrixTimesVector %28 %128 %133 -%135 = OpCompositeExtract %11 %134 0 -%137 = OpAccessChain %124 %42 %136 -OpStore %137 %135 -%138 = OpLoad %32 %119 -%139 = OpLoad %26 %118 -%140 = OpMatrixTimesVector %28 %138 %139 -%141 = OpCompositeExtract %11 %140 0 -%143 = OpAccessChain %124 %42 %142 -OpStore %143 %141 -%146 = OpAccessChain %90 %116 %145 %145 -%147 = OpLoad %11 %146 -%149 = OpAccessChain %124 %42 %148 -OpStore %149 %147 -%153 = OpAccessChain %151 %117 %84 %152 -%154 = OpLoad %11 %153 -%156 = OpAccessChain %124 %42 %155 -OpStore %156 %154 -%158 = OpAccessChain %157 %115 %145 -%159 = OpLoad %11 %158 -%160 = OpAccessChain %124 %42 %152 -OpStore %160 %159 -%161 = OpAccessChain %90 %115 %84 %84 +%111 = OpFunction %2 None %77 +%110 = OpLabel +%104 = OpVariable %105 Function %106 +%107 = OpVariable %108 Function %109 +%112 = OpAccessChain %78 %46 %79 +%114 = OpAccessChain %113 %49 %79 +%116 = OpAccessChain %115 %52 %79 +%118 = OpAccessChain %117 %55 %79 +%120 = OpAccessChain %119 %58 %79 +%122 = OpAccessChain %121 %61 %79 +%124 = OpAccessChain %123 %64 %79 +OpBranch %125 +%125 = OpLabel +%126 = OpFunctionCall %2 %76 +%130 = OpAccessChain %129 %124 %79 %79 +%131 = OpLoad %36 %130 +%135 = OpAccessChain %134 %122 %79 %79 %79 +%136 = OpLoad %30 %135 +%137 = OpMatrixTimesVector %28 %131 %136 +%138 = OpCompositeExtract %11 %137 0 +%140 = OpAccessChain %127 %42 %139 +OpStore %140 %138 +%141 = OpLoad %32 %120 +%142 = OpLoad %26 %118 +%143 = OpMatrixTimesVector %28 %141 %142 +%144 = OpCompositeExtract %11 %143 0 +%146 = OpAccessChain %127 %42 %145 +OpStore %146 %144 +%149 = OpAccessChain %85 %114 %148 %148 +%150 = OpLoad %11 %149 +%152 = OpAccessChain %127 %42 %151 +OpStore %152 %150 +%156 = OpAccessChain %154 %116 %79 %155 +%157 = OpLoad %11 %156 +%159 = OpAccessChain %127 %42 %158 +OpStore %159 %157 +%161 = OpAccessChain %160 %112 %148 %162 = OpLoad %11 %161 -%163 = OpAccessChain %124 %42 %23 +%163 = OpAccessChain %127 %42 %155 OpStore %163 %162 -%164 = OpAccessChain %157 %115 %145 -OpStore %164 %22 -%165 = OpArrayLength %6 %49 0 -%166 = OpConvertUToF %11 %165 -%167 = OpAccessChain %124 %42 %145 -OpStore %167 %166 -OpAtomicStore %44 %9 %168 %23 +%164 = OpAccessChain %85 %112 %79 %79 +%165 = OpLoad %11 %164 +%166 = OpAccessChain %127 %42 %23 +OpStore %166 %165 +%167 = OpAccessChain %160 %112 %148 +OpStore %167 %22 +%168 = OpArrayLength %6 %49 0 +%169 = OpConvertUToF %11 %168 +%170 = OpAccessChain %127 %42 %148 +OpStore %170 %169 +OpAtomicStore %44 %9 %171 %23 +OpStore %104 %10 +OpStore %107 %24 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/image.spvasm b/tests/out/spv/image.spvasm index 7a50df4a8e..f6cd159d60 100644 --- a/tests/out/spv/image.spvasm +++ b/tests/out/spv/image.spvasm @@ -9,103 +9,103 @@ OpCapability Shader OpCapability Sampled1D %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %80 "main" %77 -OpEntryPoint GLCompute %155 "depth_load" %153 -OpEntryPoint Vertex %176 "queries" %174 -OpEntryPoint Vertex %228 "levels_queries" %227 -OpEntryPoint Fragment %257 "texture_sample" %256 -OpEntryPoint Fragment %286 "texture_sample_comparison" %284 +OpEntryPoint GLCompute %84 "main" %81 +OpEntryPoint GLCompute %157 "depth_load" %155 +OpEntryPoint Vertex %178 "queries" %176 +OpEntryPoint Vertex %230 "levels_queries" %229 +OpEntryPoint Fragment %259 "texture_sample" %258 +OpEntryPoint Fragment %287 "texture_sample_comparison" %285 OpEntryPoint Fragment %306 "gather" %305 OpEntryPoint Fragment %341 "depth_no_comparison" %340 -OpExecutionMode %80 LocalSize 16 1 1 -OpExecutionMode %155 LocalSize 16 1 1 -OpExecutionMode %257 OriginUpperLeft -OpExecutionMode %286 OriginUpperLeft +OpExecutionMode %84 LocalSize 16 1 1 +OpExecutionMode %157 LocalSize 16 1 1 +OpExecutionMode %259 OriginUpperLeft +OpExecutionMode %287 OriginUpperLeft OpExecutionMode %306 OriginUpperLeft OpExecutionMode %341 OriginUpperLeft OpSource GLSL 450 -OpName %35 "image_mipmapped_src" -OpName %37 "image_multisampled_src" -OpName %39 "image_depth_multisampled_src" -OpName %41 "image_storage_src" -OpName %43 "image_array_src" -OpName %45 "image_dup_src" -OpName %47 "image_1d_src" -OpName %49 "image_dst" -OpName %51 "image_1d" -OpName %53 "image_2d" -OpName %55 "image_2d_u32" -OpName %56 "image_2d_i32" -OpName %58 "image_2d_array" -OpName %60 "image_cube" -OpName %62 "image_cube_array" -OpName %64 "image_3d" -OpName %66 "image_aa" -OpName %68 "sampler_reg" -OpName %70 "sampler_cmp" -OpName %72 "image_2d_depth" -OpName %74 "image_cube_depth" -OpName %77 "local_id" -OpName %80 "main" -OpName %153 "local_id" -OpName %155 "depth_load" -OpName %176 "queries" -OpName %228 "levels_queries" -OpName %257 "texture_sample" -OpName %286 "texture_sample_comparison" +OpName %39 "image_mipmapped_src" +OpName %41 "image_multisampled_src" +OpName %43 "image_depth_multisampled_src" +OpName %45 "image_storage_src" +OpName %47 "image_array_src" +OpName %49 "image_dup_src" +OpName %51 "image_1d_src" +OpName %53 "image_dst" +OpName %55 "image_1d" +OpName %57 "image_2d" +OpName %59 "image_2d_u32" +OpName %60 "image_2d_i32" +OpName %62 "image_2d_array" +OpName %64 "image_cube" +OpName %66 "image_cube_array" +OpName %68 "image_3d" +OpName %70 "image_aa" +OpName %72 "sampler_reg" +OpName %74 "sampler_cmp" +OpName %76 "image_2d_depth" +OpName %78 "image_cube_depth" +OpName %81 "local_id" +OpName %84 "main" +OpName %155 "local_id" +OpName %157 "depth_load" +OpName %178 "queries" +OpName %230 "levels_queries" +OpName %259 "texture_sample" +OpName %287 "texture_sample_comparison" OpName %306 "gather" OpName %341 "depth_no_comparison" -OpDecorate %35 DescriptorSet 0 -OpDecorate %35 Binding 0 -OpDecorate %37 DescriptorSet 0 -OpDecorate %37 Binding 3 OpDecorate %39 DescriptorSet 0 -OpDecorate %39 Binding 4 -OpDecorate %41 NonWritable +OpDecorate %39 Binding 0 OpDecorate %41 DescriptorSet 0 -OpDecorate %41 Binding 1 +OpDecorate %41 Binding 3 OpDecorate %43 DescriptorSet 0 -OpDecorate %43 Binding 5 +OpDecorate %43 Binding 4 OpDecorate %45 NonWritable OpDecorate %45 DescriptorSet 0 -OpDecorate %45 Binding 6 +OpDecorate %45 Binding 1 OpDecorate %47 DescriptorSet 0 -OpDecorate %47 Binding 7 -OpDecorate %49 NonReadable +OpDecorate %47 Binding 5 +OpDecorate %49 NonWritable OpDecorate %49 DescriptorSet 0 -OpDecorate %49 Binding 2 +OpDecorate %49 Binding 6 OpDecorate %51 DescriptorSet 0 -OpDecorate %51 Binding 0 +OpDecorate %51 Binding 7 +OpDecorate %53 NonReadable OpDecorate %53 DescriptorSet 0 -OpDecorate %53 Binding 1 +OpDecorate %53 Binding 2 OpDecorate %55 DescriptorSet 0 -OpDecorate %55 Binding 2 -OpDecorate %56 DescriptorSet 0 -OpDecorate %56 Binding 3 -OpDecorate %58 DescriptorSet 0 -OpDecorate %58 Binding 4 +OpDecorate %55 Binding 0 +OpDecorate %57 DescriptorSet 0 +OpDecorate %57 Binding 1 +OpDecorate %59 DescriptorSet 0 +OpDecorate %59 Binding 2 OpDecorate %60 DescriptorSet 0 -OpDecorate %60 Binding 5 +OpDecorate %60 Binding 3 OpDecorate %62 DescriptorSet 0 -OpDecorate %62 Binding 6 +OpDecorate %62 Binding 4 OpDecorate %64 DescriptorSet 0 -OpDecorate %64 Binding 7 +OpDecorate %64 Binding 5 OpDecorate %66 DescriptorSet 0 -OpDecorate %66 Binding 8 -OpDecorate %68 DescriptorSet 1 -OpDecorate %68 Binding 0 -OpDecorate %70 DescriptorSet 1 -OpDecorate %70 Binding 1 +OpDecorate %66 Binding 6 +OpDecorate %68 DescriptorSet 0 +OpDecorate %68 Binding 7 +OpDecorate %70 DescriptorSet 0 +OpDecorate %70 Binding 8 OpDecorate %72 DescriptorSet 1 -OpDecorate %72 Binding 2 +OpDecorate %72 Binding 0 OpDecorate %74 DescriptorSet 1 -OpDecorate %74 Binding 3 -OpDecorate %77 BuiltIn LocalInvocationId -OpDecorate %153 BuiltIn LocalInvocationId -OpDecorate %174 BuiltIn Position -OpDecorate %227 BuiltIn Position -OpDecorate %256 Location 0 -OpDecorate %284 Location 0 +OpDecorate %74 Binding 1 +OpDecorate %76 DescriptorSet 1 +OpDecorate %76 Binding 2 +OpDecorate %78 DescriptorSet 1 +OpDecorate %78 Binding 3 +OpDecorate %81 BuiltIn LocalInvocationId +OpDecorate %155 BuiltIn LocalInvocationId +OpDecorate %176 BuiltIn Position +OpDecorate %229 BuiltIn Position +OpDecorate %258 Location 0 +OpDecorate %285 Location 0 OpDecorate %305 Location 0 OpDecorate %340 Location 0 %2 = OpTypeVoid @@ -128,44 +128,44 @@ OpDecorate %340 Location 0 %19 = OpTypeImage %13 1D 0 0 0 1 Unknown %20 = OpTypeVector %13 3 %21 = OpTypeVector %4 2 -%22 = OpTypeImage %8 1D 0 0 0 1 Unknown -%23 = OpTypeImage %8 2D 0 0 0 1 Unknown -%24 = OpTypeImage %4 2D 0 0 0 1 Unknown -%25 = OpTypeImage %8 2D 0 1 0 1 Unknown -%26 = OpTypeImage %8 Cube 0 0 0 1 Unknown -%27 = OpTypeImage %8 Cube 0 1 0 1 Unknown -%28 = OpTypeImage %8 3D 0 0 0 1 Unknown -%29 = OpTypeImage %8 2D 0 0 1 1 Unknown -%30 = OpTypeVector %8 4 -%31 = OpTypeSampler -%32 = OpTypeImage %8 2D 1 0 0 1 Unknown -%33 = OpTypeImage %8 Cube 1 0 0 1 Unknown -%34 = OpConstantComposite %21 %10 %6 -%36 = OpTypePointer UniformConstant %12 -%35 = OpVariable %36 UniformConstant -%38 = OpTypePointer UniformConstant %14 -%37 = OpVariable %38 UniformConstant -%40 = OpTypePointer UniformConstant %15 +%22 = OpTypeVector %13 2 +%23 = OpTypeVector %13 4 +%24 = OpTypeImage %8 1D 0 0 0 1 Unknown +%25 = OpTypeImage %8 2D 0 0 0 1 Unknown +%26 = OpTypeImage %4 2D 0 0 0 1 Unknown +%27 = OpTypeImage %8 2D 0 1 0 1 Unknown +%28 = OpTypeImage %8 Cube 0 0 0 1 Unknown +%29 = OpTypeImage %8 Cube 0 1 0 1 Unknown +%30 = OpTypeImage %8 3D 0 0 0 1 Unknown +%31 = OpTypeImage %8 2D 0 0 1 1 Unknown +%32 = OpTypeVector %8 4 +%33 = OpTypeSampler +%34 = OpTypeVector %8 2 +%35 = OpTypeImage %8 2D 1 0 0 1 Unknown +%36 = OpTypeImage %8 Cube 1 0 0 1 Unknown +%37 = OpTypeVector %8 3 +%38 = OpConstantComposite %21 %10 %6 +%40 = OpTypePointer UniformConstant %12 %39 = OpVariable %40 UniformConstant -%42 = OpTypePointer UniformConstant %16 +%42 = OpTypePointer UniformConstant %14 %41 = OpVariable %42 UniformConstant -%44 = OpTypePointer UniformConstant %17 +%44 = OpTypePointer UniformConstant %15 %43 = OpVariable %44 UniformConstant -%46 = OpTypePointer UniformConstant %18 +%46 = OpTypePointer UniformConstant %16 %45 = OpVariable %46 UniformConstant -%48 = OpTypePointer UniformConstant %19 +%48 = OpTypePointer UniformConstant %17 %47 = OpVariable %48 UniformConstant %50 = OpTypePointer UniformConstant %18 %49 = OpVariable %50 UniformConstant -%52 = OpTypePointer UniformConstant %22 +%52 = OpTypePointer UniformConstant %19 %51 = OpVariable %52 UniformConstant -%54 = OpTypePointer UniformConstant %23 +%54 = OpTypePointer UniformConstant %18 %53 = OpVariable %54 UniformConstant -%55 = OpVariable %36 UniformConstant -%57 = OpTypePointer UniformConstant %24 -%56 = OpVariable %57 UniformConstant -%59 = OpTypePointer UniformConstant %25 -%58 = OpVariable %59 UniformConstant +%56 = OpTypePointer UniformConstant %24 +%55 = OpVariable %56 UniformConstant +%58 = OpTypePointer UniformConstant %25 +%57 = OpVariable %58 UniformConstant +%59 = OpVariable %40 UniformConstant %61 = OpTypePointer UniformConstant %26 %60 = OpVariable %61 UniformConstant %63 = OpTypePointer UniformConstant %27 @@ -174,319 +174,319 @@ OpDecorate %340 Location 0 %64 = OpVariable %65 UniformConstant %67 = OpTypePointer UniformConstant %29 %66 = OpVariable %67 UniformConstant -%69 = OpTypePointer UniformConstant %31 +%69 = OpTypePointer UniformConstant %30 %68 = OpVariable %69 UniformConstant %71 = OpTypePointer UniformConstant %31 %70 = OpVariable %71 UniformConstant -%73 = OpTypePointer UniformConstant %32 +%73 = OpTypePointer UniformConstant %33 %72 = OpVariable %73 UniformConstant %75 = OpTypePointer UniformConstant %33 %74 = OpVariable %75 UniformConstant -%78 = OpTypePointer Input %20 -%77 = OpVariable %78 Input -%81 = OpTypeFunction %2 -%90 = OpTypeVector %13 2 -%98 = OpTypeVector %13 4 -%109 = OpTypeVector %4 3 -%153 = OpVariable %78 Input -%175 = OpTypePointer Output %30 -%174 = OpVariable %175 Output -%185 = OpConstant %13 0 -%227 = OpVariable %175 Output -%256 = OpVariable %175 Output -%262 = OpTypeVector %8 2 -%265 = OpTypeSampledImage %22 -%268 = OpTypeSampledImage %23 -%285 = OpTypePointer Output %8 -%284 = OpVariable %285 Output -%292 = OpTypeSampledImage %32 -%297 = OpConstant %8 0.0 -%298 = OpTypeVector %8 3 -%300 = OpTypeSampledImage %33 -%305 = OpVariable %175 Output +%77 = OpTypePointer UniformConstant %35 +%76 = OpVariable %77 UniformConstant +%79 = OpTypePointer UniformConstant %36 +%78 = OpVariable %79 UniformConstant +%82 = OpTypePointer Input %20 +%81 = OpVariable %82 Input +%85 = OpTypeFunction %2 +%111 = OpTypeVector %4 3 +%155 = OpVariable %82 Input +%177 = OpTypePointer Output %32 +%176 = OpVariable %177 Output +%187 = OpConstant %13 0 +%229 = OpVariable %177 Output +%258 = OpVariable %177 Output +%266 = OpTypeSampledImage %24 +%269 = OpTypeSampledImage %25 +%286 = OpTypePointer Output %8 +%285 = OpVariable %286 Output +%293 = OpTypeSampledImage %35 +%298 = OpConstant %8 0.0 +%300 = OpTypeSampledImage %36 +%305 = OpVariable %177 Output %317 = OpConstant %13 1 %320 = OpConstant %13 3 %325 = OpTypeSampledImage %12 %328 = OpTypeVector %4 4 -%329 = OpTypeSampledImage %24 -%340 = OpVariable %175 Output -%80 = OpFunction %2 None %81 -%76 = OpLabel -%79 = OpLoad %20 %77 -%82 = OpLoad %12 %35 -%83 = OpLoad %14 %37 -%84 = OpLoad %16 %41 -%85 = OpLoad %17 %43 -%86 = OpLoad %19 %47 -%87 = OpLoad %18 %49 -OpBranch %88 -%88 = OpLabel -%89 = OpImageQuerySize %21 %84 -%91 = OpVectorShuffle %90 %79 %79 0 1 -%92 = OpBitcast %21 %91 -%93 = OpIMul %21 %89 %92 -%94 = OpCompositeConstruct %21 %3 %5 -%95 = OpSRem %21 %93 %94 -%96 = OpCompositeExtract %13 %79 2 -%97 = OpBitcast %4 %96 -%99 = OpImageFetch %98 %82 %95 Lod %97 -%100 = OpCompositeExtract %13 %79 2 -%101 = OpBitcast %4 %100 -%102 = OpImageFetch %98 %83 %95 Sample %101 -%103 = OpImageRead %98 %84 %95 -%104 = OpCompositeExtract %13 %79 2 -%105 = OpBitcast %4 %104 -%106 = OpCompositeExtract %13 %79 2 +%329 = OpTypeSampledImage %26 +%340 = OpVariable %177 Output +%84 = OpFunction %2 None %85 +%80 = OpLabel +%83 = OpLoad %20 %81 +%86 = OpLoad %12 %39 +%87 = OpLoad %14 %41 +%88 = OpLoad %16 %45 +%89 = OpLoad %17 %47 +%90 = OpLoad %19 %51 +%91 = OpLoad %18 %53 +OpBranch %92 +%92 = OpLabel +%93 = OpImageQuerySize %21 %88 +%94 = OpVectorShuffle %22 %83 %83 0 1 +%95 = OpBitcast %21 %94 +%96 = OpIMul %21 %93 %95 +%97 = OpCompositeConstruct %21 %3 %5 +%98 = OpSRem %21 %96 %97 +%99 = OpCompositeExtract %13 %83 2 +%100 = OpBitcast %4 %99 +%101 = OpImageFetch %23 %86 %98 Lod %100 +%102 = OpCompositeExtract %13 %83 2 +%103 = OpBitcast %4 %102 +%104 = OpImageFetch %23 %87 %98 Sample %103 +%105 = OpImageRead %23 %88 %98 +%106 = OpCompositeExtract %13 %83 2 %107 = OpBitcast %4 %106 -%108 = OpIAdd %4 %107 %6 -%110 = OpCompositeConstruct %109 %95 %105 -%111 = OpImageFetch %98 %85 %110 Lod %108 -%112 = OpCompositeExtract %13 %79 0 -%113 = OpBitcast %4 %112 -%114 = OpCompositeExtract %13 %79 2 +%108 = OpCompositeExtract %13 %83 2 +%109 = OpBitcast %4 %108 +%110 = OpIAdd %4 %109 %6 +%112 = OpCompositeConstruct %111 %98 %107 +%113 = OpImageFetch %23 %89 %112 Lod %110 +%114 = OpCompositeExtract %13 %83 0 %115 = OpBitcast %4 %114 -%116 = OpImageFetch %98 %86 %113 Lod %115 -%117 = OpBitcast %90 %95 -%118 = OpCompositeExtract %13 %79 2 -%119 = OpBitcast %4 %118 -%120 = OpImageFetch %98 %82 %117 Lod %119 -%121 = OpBitcast %90 %95 -%122 = OpCompositeExtract %13 %79 2 -%123 = OpBitcast %4 %122 -%124 = OpImageFetch %98 %83 %121 Sample %123 -%125 = OpBitcast %90 %95 -%126 = OpImageRead %98 %84 %125 -%127 = OpBitcast %90 %95 -%128 = OpCompositeExtract %13 %79 2 -%129 = OpBitcast %4 %128 -%130 = OpCompositeExtract %13 %79 2 +%116 = OpCompositeExtract %13 %83 2 +%117 = OpBitcast %4 %116 +%118 = OpImageFetch %23 %90 %115 Lod %117 +%119 = OpBitcast %22 %98 +%120 = OpCompositeExtract %13 %83 2 +%121 = OpBitcast %4 %120 +%122 = OpImageFetch %23 %86 %119 Lod %121 +%123 = OpBitcast %22 %98 +%124 = OpCompositeExtract %13 %83 2 +%125 = OpBitcast %4 %124 +%126 = OpImageFetch %23 %87 %123 Sample %125 +%127 = OpBitcast %22 %98 +%128 = OpImageRead %23 %88 %127 +%129 = OpBitcast %22 %98 +%130 = OpCompositeExtract %13 %83 2 %131 = OpBitcast %4 %130 -%132 = OpIAdd %4 %131 %6 -%133 = OpBitcast %13 %129 -%134 = OpCompositeConstruct %20 %127 %133 -%135 = OpImageFetch %98 %85 %134 Lod %132 -%136 = OpCompositeExtract %13 %79 0 -%138 = OpCompositeExtract %13 %79 2 -%139 = OpBitcast %4 %138 -%140 = OpImageFetch %98 %86 %136 Lod %139 -%141 = OpCompositeExtract %4 %95 0 -%142 = OpIAdd %98 %99 %102 -%143 = OpIAdd %98 %142 %103 -%144 = OpIAdd %98 %143 %111 -%145 = OpIAdd %98 %144 %116 -OpImageWrite %87 %141 %145 -%146 = OpCompositeExtract %4 %95 0 -%147 = OpBitcast %13 %146 -%148 = OpIAdd %98 %120 %124 -%149 = OpIAdd %98 %148 %126 -%150 = OpIAdd %98 %149 %135 -%151 = OpIAdd %98 %150 %140 -OpImageWrite %87 %147 %151 +%132 = OpCompositeExtract %13 %83 2 +%133 = OpBitcast %4 %132 +%134 = OpIAdd %4 %133 %6 +%135 = OpBitcast %13 %131 +%136 = OpCompositeConstruct %20 %129 %135 +%137 = OpImageFetch %23 %89 %136 Lod %134 +%138 = OpCompositeExtract %13 %83 0 +%140 = OpCompositeExtract %13 %83 2 +%141 = OpBitcast %4 %140 +%142 = OpImageFetch %23 %90 %138 Lod %141 +%143 = OpCompositeExtract %4 %98 0 +%144 = OpIAdd %23 %101 %104 +%145 = OpIAdd %23 %144 %105 +%146 = OpIAdd %23 %145 %113 +%147 = OpIAdd %23 %146 %118 +OpImageWrite %91 %143 %147 +%148 = OpCompositeExtract %4 %98 0 +%149 = OpBitcast %13 %148 +%150 = OpIAdd %23 %122 %126 +%151 = OpIAdd %23 %150 %128 +%152 = OpIAdd %23 %151 %137 +%153 = OpIAdd %23 %152 %142 +OpImageWrite %91 %149 %153 OpReturn OpFunctionEnd -%155 = OpFunction %2 None %81 -%152 = OpLabel -%154 = OpLoad %20 %153 -%156 = OpLoad %15 %39 -%157 = OpLoad %16 %41 -%158 = OpLoad %18 %49 -OpBranch %159 -%159 = OpLabel -%160 = OpImageQuerySize %21 %157 -%161 = OpVectorShuffle %90 %154 %154 0 1 -%162 = OpBitcast %21 %161 -%163 = OpIMul %21 %160 %162 -%164 = OpCompositeConstruct %21 %3 %5 -%165 = OpSRem %21 %163 %164 -%166 = OpCompositeExtract %13 %154 2 -%167 = OpBitcast %4 %166 -%168 = OpImageFetch %30 %156 %165 Sample %167 -%169 = OpCompositeExtract %8 %168 0 -%170 = OpCompositeExtract %4 %165 0 -%171 = OpConvertFToU %13 %169 -%172 = OpCompositeConstruct %98 %171 %171 %171 %171 -OpImageWrite %158 %170 %172 +%157 = OpFunction %2 None %85 +%154 = OpLabel +%156 = OpLoad %20 %155 +%158 = OpLoad %15 %43 +%159 = OpLoad %16 %45 +%160 = OpLoad %18 %53 +OpBranch %161 +%161 = OpLabel +%162 = OpImageQuerySize %21 %159 +%163 = OpVectorShuffle %22 %156 %156 0 1 +%164 = OpBitcast %21 %163 +%165 = OpIMul %21 %162 %164 +%166 = OpCompositeConstruct %21 %3 %5 +%167 = OpSRem %21 %165 %166 +%168 = OpCompositeExtract %13 %156 2 +%169 = OpBitcast %4 %168 +%170 = OpImageFetch %32 %158 %167 Sample %169 +%171 = OpCompositeExtract %8 %170 0 +%172 = OpCompositeExtract %4 %167 0 +%173 = OpConvertFToU %13 %171 +%174 = OpCompositeConstruct %23 %173 %173 %173 %173 +OpImageWrite %160 %172 %174 OpReturn OpFunctionEnd -%176 = OpFunction %2 None %81 -%173 = OpLabel -%177 = OpLoad %22 %51 -%178 = OpLoad %23 %53 -%179 = OpLoad %25 %58 -%180 = OpLoad %26 %60 +%178 = OpFunction %2 None %85 +%175 = OpLabel +%179 = OpLoad %24 %55 +%180 = OpLoad %25 %57 %181 = OpLoad %27 %62 %182 = OpLoad %28 %64 %183 = OpLoad %29 %66 -OpBranch %184 -%184 = OpLabel -%186 = OpImageQuerySizeLod %4 %177 %185 -%188 = OpImageQuerySizeLod %4 %177 %186 -%189 = OpImageQuerySizeLod %21 %178 %185 -%190 = OpImageQuerySizeLod %21 %178 %6 -%191 = OpImageQuerySizeLod %109 %179 %185 -%192 = OpVectorShuffle %21 %191 %191 0 1 -%193 = OpImageQuerySizeLod %109 %179 %6 +%184 = OpLoad %30 %68 +%185 = OpLoad %31 %70 +OpBranch %186 +%186 = OpLabel +%188 = OpImageQuerySizeLod %4 %179 %187 +%190 = OpImageQuerySizeLod %4 %179 %188 +%191 = OpImageQuerySizeLod %21 %180 %187 +%192 = OpImageQuerySizeLod %21 %180 %6 +%193 = OpImageQuerySizeLod %111 %181 %187 %194 = OpVectorShuffle %21 %193 %193 0 1 -%195 = OpImageQuerySizeLod %21 %180 %185 -%196 = OpImageQuerySizeLod %21 %180 %6 -%197 = OpImageQuerySizeLod %109 %181 %185 -%198 = OpVectorShuffle %21 %197 %197 0 0 -%199 = OpImageQuerySizeLod %109 %181 %6 +%195 = OpImageQuerySizeLod %111 %181 %6 +%196 = OpVectorShuffle %21 %195 %195 0 1 +%197 = OpImageQuerySizeLod %21 %182 %187 +%198 = OpImageQuerySizeLod %21 %182 %6 +%199 = OpImageQuerySizeLod %111 %183 %187 %200 = OpVectorShuffle %21 %199 %199 0 0 -%201 = OpImageQuerySizeLod %109 %182 %185 -%202 = OpImageQuerySizeLod %109 %182 %6 -%203 = OpImageQuerySize %21 %183 -%204 = OpCompositeExtract %4 %189 1 -%205 = OpIAdd %4 %186 %204 -%206 = OpCompositeExtract %4 %190 1 -%207 = OpIAdd %4 %205 %206 +%201 = OpImageQuerySizeLod %111 %183 %6 +%202 = OpVectorShuffle %21 %201 %201 0 0 +%203 = OpImageQuerySizeLod %111 %184 %187 +%204 = OpImageQuerySizeLod %111 %184 %6 +%205 = OpImageQuerySize %21 %185 +%206 = OpCompositeExtract %4 %191 1 +%207 = OpIAdd %4 %188 %206 %208 = OpCompositeExtract %4 %192 1 %209 = OpIAdd %4 %207 %208 %210 = OpCompositeExtract %4 %194 1 %211 = OpIAdd %4 %209 %210 -%212 = OpCompositeExtract %4 %195 1 +%212 = OpCompositeExtract %4 %196 1 %213 = OpIAdd %4 %211 %212 -%214 = OpCompositeExtract %4 %196 1 +%214 = OpCompositeExtract %4 %197 1 %215 = OpIAdd %4 %213 %214 %216 = OpCompositeExtract %4 %198 1 %217 = OpIAdd %4 %215 %216 %218 = OpCompositeExtract %4 %200 1 %219 = OpIAdd %4 %217 %218 -%220 = OpCompositeExtract %4 %201 2 +%220 = OpCompositeExtract %4 %202 1 %221 = OpIAdd %4 %219 %220 -%222 = OpCompositeExtract %4 %202 2 +%222 = OpCompositeExtract %4 %203 2 %223 = OpIAdd %4 %221 %222 -%224 = OpConvertSToF %8 %223 -%225 = OpCompositeConstruct %30 %224 %224 %224 %224 -OpStore %174 %225 +%224 = OpCompositeExtract %4 %204 2 +%225 = OpIAdd %4 %223 %224 +%226 = OpConvertSToF %8 %225 +%227 = OpCompositeConstruct %32 %226 %226 %226 %226 +OpStore %176 %227 OpReturn OpFunctionEnd -%228 = OpFunction %2 None %81 -%226 = OpLabel -%229 = OpLoad %23 %53 -%230 = OpLoad %25 %58 -%231 = OpLoad %26 %60 +%230 = OpFunction %2 None %85 +%228 = OpLabel +%231 = OpLoad %25 %57 %232 = OpLoad %27 %62 %233 = OpLoad %28 %64 %234 = OpLoad %29 %66 -OpBranch %235 -%235 = OpLabel -%236 = OpImageQueryLevels %4 %229 -%237 = OpImageQueryLevels %4 %230 -%238 = OpImageQuerySizeLod %109 %230 %185 -%239 = OpCompositeExtract %4 %238 2 -%240 = OpImageQueryLevels %4 %231 -%241 = OpImageQueryLevels %4 %232 -%242 = OpImageQuerySizeLod %109 %232 %185 -%243 = OpCompositeExtract %4 %242 2 -%244 = OpImageQueryLevels %4 %233 -%245 = OpImageQuerySamples %4 %234 -%246 = OpIAdd %4 %239 %243 -%247 = OpIAdd %4 %246 %245 -%248 = OpIAdd %4 %247 %236 -%249 = OpIAdd %4 %248 %237 -%250 = OpIAdd %4 %249 %244 -%251 = OpIAdd %4 %250 %240 -%252 = OpIAdd %4 %251 %241 -%253 = OpConvertSToF %8 %252 -%254 = OpCompositeConstruct %30 %253 %253 %253 %253 -OpStore %227 %254 +%235 = OpLoad %30 %68 +%236 = OpLoad %31 %70 +OpBranch %237 +%237 = OpLabel +%238 = OpImageQueryLevels %4 %231 +%239 = OpImageQueryLevels %4 %232 +%240 = OpImageQuerySizeLod %111 %232 %187 +%241 = OpCompositeExtract %4 %240 2 +%242 = OpImageQueryLevels %4 %233 +%243 = OpImageQueryLevels %4 %234 +%244 = OpImageQuerySizeLod %111 %234 %187 +%245 = OpCompositeExtract %4 %244 2 +%246 = OpImageQueryLevels %4 %235 +%247 = OpImageQuerySamples %4 %236 +%248 = OpIAdd %4 %241 %245 +%249 = OpIAdd %4 %248 %247 +%250 = OpIAdd %4 %249 %238 +%251 = OpIAdd %4 %250 %239 +%252 = OpIAdd %4 %251 %246 +%253 = OpIAdd %4 %252 %242 +%254 = OpIAdd %4 %253 %243 +%255 = OpConvertSToF %8 %254 +%256 = OpCompositeConstruct %32 %255 %255 %255 %255 +OpStore %229 %256 OpReturn OpFunctionEnd -%257 = OpFunction %2 None %81 -%255 = OpLabel -%258 = OpLoad %22 %51 -%259 = OpLoad %23 %53 -%260 = OpLoad %31 %68 -OpBranch %261 -%261 = OpLabel -%263 = OpCompositeConstruct %262 %7 %7 -%264 = OpCompositeExtract %8 %263 0 -%266 = OpSampledImage %265 %258 %260 -%267 = OpImageSampleImplicitLod %30 %266 %264 -%269 = OpSampledImage %268 %259 %260 -%270 = OpImageSampleImplicitLod %30 %269 %263 -%271 = OpSampledImage %268 %259 %260 -%272 = OpImageSampleImplicitLod %30 %271 %263 ConstOffset %34 -%273 = OpSampledImage %268 %259 %260 -%274 = OpImageSampleExplicitLod %30 %273 %263 Lod %9 -%275 = OpSampledImage %268 %259 %260 -%276 = OpImageSampleExplicitLod %30 %275 %263 Lod|ConstOffset %9 %34 -%277 = OpSampledImage %268 %259 %260 -%278 = OpImageSampleImplicitLod %30 %277 %263 Bias|ConstOffset %11 %34 -%279 = OpFAdd %30 %267 %270 -%280 = OpFAdd %30 %279 %272 -%281 = OpFAdd %30 %280 %274 -%282 = OpFAdd %30 %281 %276 -OpStore %256 %282 +%259 = OpFunction %2 None %85 +%257 = OpLabel +%260 = OpLoad %24 %55 +%261 = OpLoad %25 %57 +%262 = OpLoad %33 %72 +OpBranch %263 +%263 = OpLabel +%264 = OpCompositeConstruct %34 %7 %7 +%265 = OpCompositeExtract %8 %264 0 +%267 = OpSampledImage %266 %260 %262 +%268 = OpImageSampleImplicitLod %32 %267 %265 +%270 = OpSampledImage %269 %261 %262 +%271 = OpImageSampleImplicitLod %32 %270 %264 +%272 = OpSampledImage %269 %261 %262 +%273 = OpImageSampleImplicitLod %32 %272 %264 ConstOffset %38 +%274 = OpSampledImage %269 %261 %262 +%275 = OpImageSampleExplicitLod %32 %274 %264 Lod %9 +%276 = OpSampledImage %269 %261 %262 +%277 = OpImageSampleExplicitLod %32 %276 %264 Lod|ConstOffset %9 %38 +%278 = OpSampledImage %269 %261 %262 +%279 = OpImageSampleImplicitLod %32 %278 %264 Bias|ConstOffset %11 %38 +%280 = OpFAdd %32 %268 %271 +%281 = OpFAdd %32 %280 %273 +%282 = OpFAdd %32 %281 %275 +%283 = OpFAdd %32 %282 %277 +OpStore %258 %283 OpReturn OpFunctionEnd -%286 = OpFunction %2 None %81 -%283 = OpLabel -%287 = OpLoad %31 %70 -%288 = OpLoad %32 %72 -%289 = OpLoad %33 %74 -OpBranch %290 -%290 = OpLabel -%291 = OpCompositeConstruct %262 %7 %7 -%293 = OpSampledImage %292 %288 %287 -%294 = OpImageSampleDrefImplicitLod %8 %293 %291 %7 -%295 = OpSampledImage %292 %288 %287 -%296 = OpImageSampleDrefExplicitLod %8 %295 %291 %7 Lod %297 -%299 = OpCompositeConstruct %298 %7 %7 %7 -%301 = OpSampledImage %300 %289 %287 -%302 = OpImageSampleDrefExplicitLod %8 %301 %299 %7 Lod %297 -%303 = OpFAdd %8 %294 %296 -OpStore %284 %303 +%287 = OpFunction %2 None %85 +%284 = OpLabel +%288 = OpLoad %33 %74 +%289 = OpLoad %35 %76 +%290 = OpLoad %36 %78 +OpBranch %291 +%291 = OpLabel +%292 = OpCompositeConstruct %34 %7 %7 +%294 = OpSampledImage %293 %289 %288 +%295 = OpImageSampleDrefImplicitLod %8 %294 %292 %7 +%296 = OpSampledImage %293 %289 %288 +%297 = OpImageSampleDrefExplicitLod %8 %296 %292 %7 Lod %298 +%299 = OpCompositeConstruct %37 %7 %7 %7 +%301 = OpSampledImage %300 %290 %288 +%302 = OpImageSampleDrefExplicitLod %8 %301 %299 %7 Lod %298 +%303 = OpFAdd %8 %295 %297 +OpStore %285 %303 OpReturn OpFunctionEnd -%306 = OpFunction %2 None %81 +%306 = OpFunction %2 None %85 %304 = OpLabel -%307 = OpLoad %23 %53 -%308 = OpLoad %12 %55 -%309 = OpLoad %24 %56 -%310 = OpLoad %31 %68 -%311 = OpLoad %31 %70 -%312 = OpLoad %32 %72 +%307 = OpLoad %25 %57 +%308 = OpLoad %12 %59 +%309 = OpLoad %26 %60 +%310 = OpLoad %33 %72 +%311 = OpLoad %33 %74 +%312 = OpLoad %35 %76 OpBranch %313 %313 = OpLabel -%314 = OpCompositeConstruct %262 %7 %7 -%315 = OpSampledImage %268 %307 %310 -%316 = OpImageGather %30 %315 %314 %317 -%318 = OpSampledImage %268 %307 %310 -%319 = OpImageGather %30 %318 %314 %320 ConstOffset %34 -%321 = OpSampledImage %292 %312 %311 -%322 = OpImageDrefGather %30 %321 %314 %7 -%323 = OpSampledImage %292 %312 %311 -%324 = OpImageDrefGather %30 %323 %314 %7 ConstOffset %34 +%314 = OpCompositeConstruct %34 %7 %7 +%315 = OpSampledImage %269 %307 %310 +%316 = OpImageGather %32 %315 %314 %317 +%318 = OpSampledImage %269 %307 %310 +%319 = OpImageGather %32 %318 %314 %320 ConstOffset %38 +%321 = OpSampledImage %293 %312 %311 +%322 = OpImageDrefGather %32 %321 %314 %7 +%323 = OpSampledImage %293 %312 %311 +%324 = OpImageDrefGather %32 %323 %314 %7 ConstOffset %38 %326 = OpSampledImage %325 %308 %310 -%327 = OpImageGather %98 %326 %314 %185 +%327 = OpImageGather %23 %326 %314 %187 %330 = OpSampledImage %329 %309 %310 -%331 = OpImageGather %328 %330 %314 %185 -%332 = OpConvertUToF %30 %327 -%333 = OpConvertSToF %30 %331 -%334 = OpFAdd %30 %332 %333 -%335 = OpFAdd %30 %316 %319 -%336 = OpFAdd %30 %335 %322 -%337 = OpFAdd %30 %336 %324 -%338 = OpFAdd %30 %337 %334 +%331 = OpImageGather %328 %330 %314 %187 +%332 = OpConvertUToF %32 %327 +%333 = OpConvertSToF %32 %331 +%334 = OpFAdd %32 %332 %333 +%335 = OpFAdd %32 %316 %319 +%336 = OpFAdd %32 %335 %322 +%337 = OpFAdd %32 %336 %324 +%338 = OpFAdd %32 %337 %334 OpStore %305 %338 OpReturn OpFunctionEnd -%341 = OpFunction %2 None %81 +%341 = OpFunction %2 None %85 %339 = OpLabel -%342 = OpLoad %31 %68 -%343 = OpLoad %32 %72 +%342 = OpLoad %33 %72 +%343 = OpLoad %35 %76 OpBranch %344 %344 = OpLabel -%345 = OpCompositeConstruct %262 %7 %7 -%346 = OpSampledImage %292 %343 %342 -%347 = OpImageSampleImplicitLod %30 %346 %345 +%345 = OpCompositeConstruct %34 %7 %7 +%346 = OpSampledImage %293 %343 %342 +%347 = OpImageSampleImplicitLod %32 %346 %345 %348 = OpCompositeExtract %8 %347 0 -%349 = OpSampledImage %292 %343 %342 -%350 = OpImageGather %30 %349 %345 %185 -%351 = OpCompositeConstruct %30 %348 %348 %348 %348 -%352 = OpFAdd %30 %351 %350 +%349 = OpSampledImage %293 %343 %342 +%350 = OpImageGather %32 %349 %345 %187 +%351 = OpCompositeConstruct %32 %348 %348 %348 %348 +%352 = OpFAdd %32 %351 %350 OpStore %340 %352 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/interface.vertex_two_structs.spvasm b/tests/out/spv/interface.vertex_two_structs.spvasm index 190f391c39..1455090aba 100644 --- a/tests/out/spv/interface.vertex_two_structs.spvasm +++ b/tests/out/spv/interface.vertex_two_structs.spvasm @@ -5,7 +5,7 @@ OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %34 "vertex_two_structs" %24 %28 %30 %32 +OpEntryPoint Vertex %35 "vertex_two_structs" %25 %29 %31 %33 OpMemberDecorate %13 0 Offset 0 OpMemberDecorate %13 1 Offset 16 OpMemberDecorate %14 0 Offset 0 @@ -14,11 +14,11 @@ OpMemberDecorate %14 2 Offset 8 OpDecorate %16 ArrayStride 4 OpMemberDecorate %18 0 Offset 0 OpMemberDecorate %19 0 Offset 0 -OpDecorate %24 BuiltIn VertexIndex -OpDecorate %28 BuiltIn InstanceIndex -OpDecorate %30 Invariant -OpDecorate %30 BuiltIn Position -OpDecorate %32 BuiltIn PointSize +OpDecorate %25 BuiltIn VertexIndex +OpDecorate %29 BuiltIn InstanceIndex +OpDecorate %31 Invariant +OpDecorate %31 BuiltIn Position +OpDecorate %33 BuiltIn PointSize %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -38,32 +38,33 @@ OpDecorate %32 BuiltIn PointSize %18 = OpTypeStruct %6 %19 = OpTypeStruct %6 %21 = OpTypePointer Function %6 -%25 = OpTypePointer Input %6 -%24 = OpVariable %25 Input -%28 = OpVariable %25 Input -%31 = OpTypePointer Output %12 -%30 = OpVariable %31 Output -%33 = OpTypePointer Output %4 -%32 = OpVariable %33 Output -%35 = OpTypeFunction %2 -%36 = OpTypePointer Workgroup %16 -%34 = OpFunction %2 None %35 -%22 = OpLabel -%20 = OpVariable %21 Function %11 -%26 = OpLoad %6 %24 -%23 = OpCompositeConstruct %18 %26 -%29 = OpLoad %6 %28 -%27 = OpCompositeConstruct %19 %29 -OpStore %32 %3 +%22 = OpConstantNull %6 +%26 = OpTypePointer Input %6 +%25 = OpVariable %26 Input +%29 = OpVariable %26 Input +%32 = OpTypePointer Output %12 +%31 = OpVariable %32 Output +%34 = OpTypePointer Output %4 +%33 = OpVariable %34 Output +%36 = OpTypeFunction %2 +%35 = OpFunction %2 None %36 +%23 = OpLabel +%20 = OpVariable %21 Function %22 +%27 = OpLoad %6 %25 +%24 = OpCompositeConstruct %18 %27 +%30 = OpLoad %6 %29 +%28 = OpCompositeConstruct %19 %30 +OpStore %33 %3 OpBranch %37 %37 = OpLabel -%38 = OpCompositeExtract %6 %23 0 +OpStore %20 %11 +%38 = OpCompositeExtract %6 %24 0 %39 = OpConvertUToF %4 %38 -%40 = OpCompositeExtract %6 %27 0 +%40 = OpCompositeExtract %6 %28 0 %41 = OpConvertUToF %4 %40 %42 = OpLoad %6 %20 %43 = OpConvertUToF %4 %42 %44 = OpCompositeConstruct %12 %39 %41 %43 %7 -OpStore %30 %44 +OpStore %31 %44 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/math-functions.spvasm b/tests/out/spv/math-functions.spvasm index fc970f8631..194024b769 100644 --- a/tests/out/spv/math-functions.spvasm +++ b/tests/out/spv/math-functions.spvasm @@ -5,7 +5,7 @@ OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %13 "main" +OpEntryPoint Vertex %14 "main" %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -14,29 +14,29 @@ OpEntryPoint Vertex %13 "main" %6 = OpConstant %7 0 %9 = OpTypeInt 32 0 %8 = OpConstant %9 0 -%10 = OpTypeVector %7 2 -%11 = OpConstantComposite %10 %6 %6 -%14 = OpTypeFunction %2 -%16 = OpTypeVector %4 4 +%10 = OpTypeVector %4 4 +%11 = OpTypeVector %7 2 +%12 = OpConstantComposite %11 %6 %6 +%15 = OpTypeFunction %2 %26 = OpConstantNull %7 -%13 = OpFunction %2 None %14 -%12 = OpLabel -OpBranch %15 -%15 = OpLabel -%17 = OpCompositeConstruct %16 %5 %5 %5 %5 +%14 = OpFunction %2 None %15 +%13 = OpLabel +OpBranch %16 +%16 = OpLabel +%17 = OpCompositeConstruct %10 %5 %5 %5 %5 %18 = OpExtInst %4 %1 Degrees %3 %19 = OpExtInst %4 %1 Radians %3 -%20 = OpExtInst %16 %1 Degrees %17 -%21 = OpExtInst %16 %1 Radians %17 -%23 = OpCompositeConstruct %16 %5 %5 %5 %5 -%24 = OpCompositeConstruct %16 %3 %3 %3 %3 -%22 = OpExtInst %16 %1 FClamp %17 %23 %24 -%27 = OpCompositeExtract %7 %11 0 -%28 = OpCompositeExtract %7 %11 0 +%20 = OpExtInst %10 %1 Degrees %17 +%21 = OpExtInst %10 %1 Radians %17 +%23 = OpCompositeConstruct %10 %5 %5 %5 %5 +%24 = OpCompositeConstruct %10 %3 %3 %3 %3 +%22 = OpExtInst %10 %1 FClamp %17 %23 %24 +%27 = OpCompositeExtract %7 %12 0 +%28 = OpCompositeExtract %7 %12 0 %29 = OpIMul %7 %27 %28 %30 = OpIAdd %7 %26 %29 -%31 = OpCompositeExtract %7 %11 1 -%32 = OpCompositeExtract %7 %11 1 +%31 = OpCompositeExtract %7 %12 1 +%32 = OpCompositeExtract %7 %12 1 %33 = OpIMul %7 %31 %32 %25 = OpIAdd %7 %30 %33 %34 = OpCopyObject %9 %8 diff --git a/tests/out/spv/operators.spvasm b/tests/out/spv/operators.spvasm index 87f6ce3093..3263e223f4 100644 --- a/tests/out/spv/operators.spvasm +++ b/tests/out/spv/operators.spvasm @@ -1,16 +1,16 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 572 +; Bound: 574 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %560 "main" -OpExecutionMode %560 LocalSize 1 1 1 -OpMemberDecorate %39 0 Offset 0 -OpMemberDecorate %39 1 Offset 16 -OpDecorate %43 ArrayStride 32 -OpDecorate %44 ArrayStride 4 +OpEntryPoint GLCompute %562 "main" +OpExecutionMode %562 LocalSize 1 1 1 +OpMemberDecorate %40 0 Offset 0 +OpMemberDecorate %40 1 Offset 16 +OpDecorate %44 ArrayStride 32 +OpDecorate %45 ArrayStride 4 %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -48,41 +48,41 @@ OpDecorate %44 ArrayStride 4 %36 = OpTypeVector %10 4 %37 = OpTypeVector %4 2 %38 = OpTypeVector %4 3 -%39 = OpTypeStruct %34 %8 -%40 = OpTypeMatrix %37 2 -%41 = OpTypeMatrix %34 4 -%42 = OpTypeVector %20 2 -%43 = OpTypeArray %39 %21 -%44 = OpTypeArray %8 %22 -%45 = OpTypeMatrix %38 2 -%46 = OpTypeMatrix %38 3 -%47 = OpTypeMatrix %38 4 -%48 = OpTypeMatrix %34 3 -%49 = OpTypeVector %8 3 -%50 = OpConstantComposite %34 %3 %3 %3 %3 -%51 = OpConstantComposite %34 %5 %5 %5 %5 -%52 = OpConstantComposite %34 %6 %6 %6 %6 -%53 = OpConstantComposite %35 %7 %7 %7 %7 -%54 = OpConstantComposite %42 %19 %19 -%55 = OpConstantComposite %37 %5 %5 -%56 = OpConstantComposite %40 %55 %55 -%57 = OpConstantComposite %34 %5 %5 %5 %5 -%58 = OpConstantComposite %39 %57 %11 -%59 = OpConstantComposite %43 %58 %58 %58 -%60 = OpConstantComposite %38 %5 %5 %5 -%61 = OpConstantComposite %45 %60 %60 -%62 = OpConstantComposite %46 %60 %60 %60 -%63 = OpConstantComposite %47 %60 %60 %60 %60 -%64 = OpConstantComposite %48 %57 %57 %57 -%65 = OpConstantComposite %49 %11 %11 %11 -%68 = OpTypeFunction %34 -%108 = OpTypePointer Function %37 -%109 = OpConstantNull %37 -%112 = OpTypeFunction %37 -%128 = OpTypeFunction %38 %38 -%130 = OpTypeVector %10 3 -%137 = OpTypePointer Function %39 -%138 = OpConstantNull %39 +%39 = OpTypeVector %10 3 +%40 = OpTypeStruct %34 %8 +%41 = OpTypeMatrix %37 2 +%42 = OpTypeMatrix %34 4 +%43 = OpTypeVector %20 2 +%44 = OpTypeArray %40 %21 +%45 = OpTypeArray %8 %22 +%46 = OpTypeMatrix %38 2 +%47 = OpTypeMatrix %38 3 +%48 = OpTypeMatrix %38 4 +%49 = OpTypeMatrix %34 3 +%50 = OpTypeVector %8 3 +%51 = OpConstantComposite %34 %3 %3 %3 %3 +%52 = OpConstantComposite %34 %5 %5 %5 %5 +%53 = OpConstantComposite %34 %6 %6 %6 %6 +%54 = OpConstantComposite %35 %7 %7 %7 %7 +%55 = OpConstantComposite %43 %19 %19 +%56 = OpConstantComposite %37 %5 %5 +%57 = OpConstantComposite %41 %56 %56 +%58 = OpConstantComposite %34 %5 %5 %5 %5 +%59 = OpConstantComposite %40 %58 %11 +%60 = OpConstantComposite %44 %59 %59 %59 +%61 = OpConstantComposite %38 %5 %5 %5 +%62 = OpConstantComposite %46 %61 %61 +%63 = OpConstantComposite %47 %61 %61 %61 +%64 = OpConstantComposite %48 %61 %61 %61 %61 +%65 = OpConstantComposite %49 %58 %58 %58 +%66 = OpConstantComposite %50 %11 %11 %11 +%69 = OpTypeFunction %34 +%109 = OpTypePointer Function %37 +%110 = OpConstantNull %37 +%113 = OpTypeFunction %37 +%129 = OpTypeFunction %38 %38 +%137 = OpTypePointer Function %40 +%138 = OpConstantNull %40 %141 = OpTypeFunction %4 %166 = OpTypePointer Function %34 %167 = OpTypePointer Function %4 @@ -91,83 +91,85 @@ OpDecorate %44 ArrayStride 4 %191 = OpTypeVector %8 2 %202 = OpTypeVector %20 3 %497 = OpTypePointer Function %8 -%499 = OpTypePointer Function %49 -%529 = OpTypePointer Function %8 -%67 = OpFunction %34 None %68 -%66 = OpLabel -OpBranch %69 -%69 = OpLabel -%70 = OpSelect %8 %9 %7 %11 -%72 = OpCompositeConstruct %36 %9 %9 %9 %9 -%71 = OpSelect %34 %72 %50 %51 -%73 = OpCompositeConstruct %36 %12 %12 %12 %12 -%74 = OpSelect %34 %73 %51 %50 -%75 = OpExtInst %34 %1 FMix %51 %50 %52 -%77 = OpCompositeConstruct %34 %13 %13 %13 %13 -%76 = OpExtInst %34 %1 FMix %51 %50 %77 -%78 = OpCompositeExtract %8 %53 0 -%79 = OpBitcast %4 %78 -%80 = OpBitcast %34 %53 -%81 = OpConvertFToS %35 %51 -%82 = OpCompositeConstruct %35 %70 %70 %70 %70 -%83 = OpIAdd %35 %82 %81 -%84 = OpConvertSToF %34 %83 -%85 = OpFAdd %34 %84 %71 -%86 = OpFAdd %34 %85 %75 +%498 = OpConstantNull %8 +%500 = OpTypePointer Function %50 +%501 = OpConstantNull %50 +%531 = OpTypePointer Function %8 +%68 = OpFunction %34 None %69 +%67 = OpLabel +OpBranch %70 +%70 = OpLabel +%71 = OpSelect %8 %9 %7 %11 +%73 = OpCompositeConstruct %36 %9 %9 %9 %9 +%72 = OpSelect %34 %73 %51 %52 +%74 = OpCompositeConstruct %36 %12 %12 %12 %12 +%75 = OpSelect %34 %74 %52 %51 +%76 = OpExtInst %34 %1 FMix %52 %51 %53 +%78 = OpCompositeConstruct %34 %13 %13 %13 %13 +%77 = OpExtInst %34 %1 FMix %52 %51 %78 +%79 = OpCompositeExtract %8 %54 0 +%80 = OpBitcast %4 %79 +%81 = OpBitcast %34 %54 +%82 = OpConvertFToS %35 %52 +%83 = OpCompositeConstruct %35 %71 %71 %71 %71 +%84 = OpIAdd %35 %83 %82 +%85 = OpConvertSToF %34 %84 +%86 = OpFAdd %34 %85 %72 %87 = OpFAdd %34 %86 %76 -%88 = OpCompositeConstruct %34 %79 %79 %79 %79 -%89 = OpFAdd %34 %87 %88 -%90 = OpFAdd %34 %89 %80 -OpReturnValue %90 +%88 = OpFAdd %34 %87 %77 +%89 = OpCompositeConstruct %34 %80 %80 %80 %80 +%90 = OpFAdd %34 %88 %89 +%91 = OpFAdd %34 %90 %81 +OpReturnValue %91 OpFunctionEnd -%92 = OpFunction %34 None %68 -%91 = OpLabel -OpBranch %93 -%93 = OpLabel -%94 = OpCompositeConstruct %37 %14 %14 -%95 = OpCompositeConstruct %37 %3 %3 -%96 = OpFAdd %37 %95 %94 -%97 = OpCompositeConstruct %37 %15 %15 -%98 = OpFSub %37 %96 %97 -%99 = OpCompositeConstruct %37 %16 %16 -%100 = OpFDiv %37 %98 %99 -%101 = OpCompositeConstruct %35 %17 %17 %17 %17 -%102 = OpCompositeConstruct %35 %18 %18 %18 %18 -%103 = OpSRem %35 %101 %102 -%104 = OpVectorShuffle %34 %100 %100 0 1 0 1 -%105 = OpConvertSToF %34 %103 -%106 = OpFAdd %34 %104 %105 -OpReturnValue %106 +%93 = OpFunction %34 None %69 +%92 = OpLabel +OpBranch %94 +%94 = OpLabel +%95 = OpCompositeConstruct %37 %14 %14 +%96 = OpCompositeConstruct %37 %3 %3 +%97 = OpFAdd %37 %96 %95 +%98 = OpCompositeConstruct %37 %15 %15 +%99 = OpFSub %37 %97 %98 +%100 = OpCompositeConstruct %37 %16 %16 +%101 = OpFDiv %37 %99 %100 +%102 = OpCompositeConstruct %35 %17 %17 %17 %17 +%103 = OpCompositeConstruct %35 %18 %18 %18 %18 +%104 = OpSRem %35 %102 %103 +%105 = OpVectorShuffle %34 %101 %101 0 1 0 1 +%106 = OpConvertSToF %34 %104 +%107 = OpFAdd %34 %105 %106 +OpReturnValue %107 OpFunctionEnd -%111 = OpFunction %37 None %112 -%110 = OpLabel -%107 = OpVariable %108 Function %109 -OpBranch %113 -%113 = OpLabel -%114 = OpCompositeConstruct %37 %14 %14 -OpStore %107 %114 -%115 = OpLoad %37 %107 -%116 = OpCompositeConstruct %37 %3 %3 -%117 = OpFAdd %37 %115 %116 -OpStore %107 %117 -%118 = OpLoad %37 %107 -%119 = OpCompositeConstruct %37 %15 %15 -%120 = OpFSub %37 %118 %119 -OpStore %107 %120 -%121 = OpLoad %37 %107 -%122 = OpCompositeConstruct %37 %16 %16 -%123 = OpFDiv %37 %121 %122 -OpStore %107 %123 -%124 = OpLoad %37 %107 -OpReturnValue %124 +%112 = OpFunction %37 None %113 +%111 = OpLabel +%108 = OpVariable %109 Function %110 +OpBranch %114 +%114 = OpLabel +%115 = OpCompositeConstruct %37 %14 %14 +OpStore %108 %115 +%116 = OpLoad %37 %108 +%117 = OpCompositeConstruct %37 %3 %3 +%118 = OpFAdd %37 %116 %117 +OpStore %108 %118 +%119 = OpLoad %37 %108 +%120 = OpCompositeConstruct %37 %15 %15 +%121 = OpFSub %37 %119 %120 +OpStore %108 %121 +%122 = OpLoad %37 %108 +%123 = OpCompositeConstruct %37 %16 %16 +%124 = OpFDiv %37 %122 %123 +OpStore %108 %124 +%125 = OpLoad %37 %108 +OpReturnValue %125 OpFunctionEnd -%127 = OpFunction %38 None %128 -%126 = OpFunctionParameter %38 -%125 = OpLabel -OpBranch %129 -%129 = OpLabel +%128 = OpFunction %38 None %129 +%127 = OpFunctionParameter %38 +%126 = OpLabel +OpBranch %130 +%130 = OpLabel %131 = OpCompositeConstruct %38 %5 %5 %5 -%132 = OpFUnordNotEqual %130 %126 %131 +%132 = OpFUnordNotEqual %39 %127 %131 %133 = OpCompositeConstruct %38 %5 %5 %5 %134 = OpCompositeConstruct %38 %3 %3 %3 %135 = OpSelect %38 %132 %134 %133 @@ -179,23 +181,23 @@ OpFunctionEnd OpBranch %142 %142 = OpLabel %143 = OpCompositeConstruct %34 %3 %3 %3 %3 -%144 = OpCompositeConstruct %39 %143 %7 +%144 = OpCompositeConstruct %40 %143 %7 OpStore %136 %144 %145 = OpCompositeConstruct %37 %3 %5 %146 = OpCompositeConstruct %37 %5 %3 -%147 = OpCompositeConstruct %40 %145 %146 +%147 = OpCompositeConstruct %41 %145 %146 %148 = OpCompositeConstruct %34 %3 %5 %5 %5 %149 = OpCompositeConstruct %34 %5 %3 %5 %5 %150 = OpCompositeConstruct %34 %5 %5 %3 %5 %151 = OpCompositeConstruct %34 %5 %5 %5 %3 -%152 = OpCompositeConstruct %41 %148 %149 %150 %151 -%153 = OpCompositeConstruct %42 %19 %19 +%152 = OpCompositeConstruct %42 %148 %149 %150 %151 +%153 = OpCompositeConstruct %43 %19 %19 %154 = OpCompositeConstruct %37 %5 %5 %155 = OpCompositeConstruct %37 %5 %5 -%156 = OpCompositeConstruct %40 %154 %155 -%157 = OpCompositeConstruct %44 %11 %7 %18 %21 -%163 = OpCopyObject %45 %61 -%165 = OpCopyObject %45 %61 +%156 = OpCompositeConstruct %41 %154 %155 +%157 = OpCompositeConstruct %45 %11 %7 %18 %21 +%163 = OpCopyObject %46 %62 +%165 = OpCopyObject %46 %62 %168 = OpAccessChain %167 %136 %19 %19 %169 = OpLoad %4 %168 OpReturnValue %169 @@ -210,9 +212,9 @@ OpBranch %173 %178 = OpLogicalOr %10 %9 %12 %179 = OpLogicalAnd %10 %9 %12 %180 = OpLogicalOr %10 %9 %12 -%181 = OpCompositeConstruct %130 %9 %9 %9 -%182 = OpCompositeConstruct %130 %12 %12 %12 -%183 = OpLogicalOr %130 %181 %182 +%181 = OpCompositeConstruct %39 %9 %9 %9 +%182 = OpCompositeConstruct %39 %12 %12 %12 +%183 = OpLogicalOr %39 %181 %182 %184 = OpLogicalAnd %10 %9 %12 %185 = OpCompositeConstruct %36 %9 %9 %9 %9 %186 = OpCompositeConstruct %36 %12 %12 %12 %12 @@ -293,12 +295,12 @@ OpBranch %190 %260 = OpCompositeConstruct %191 %7 %7 %261 = OpCompositeConstruct %191 %18 %18 %262 = OpIAdd %191 %261 %260 -%263 = OpCompositeConstruct %42 %24 %24 -%264 = OpCompositeConstruct %42 %25 %25 -%265 = OpIAdd %42 %263 %264 -%266 = OpCompositeConstruct %42 %25 %25 -%267 = OpCompositeConstruct %42 %24 %24 -%268 = OpIAdd %42 %267 %266 +%263 = OpCompositeConstruct %43 %24 %24 +%264 = OpCompositeConstruct %43 %25 %25 +%265 = OpIAdd %43 %263 %264 +%266 = OpCompositeConstruct %43 %25 %25 +%267 = OpCompositeConstruct %43 %24 %24 +%268 = OpIAdd %43 %267 %266 %269 = OpCompositeConstruct %37 %14 %14 %270 = OpCompositeConstruct %37 %3 %3 %271 = OpFAdd %37 %269 %270 @@ -311,12 +313,12 @@ OpBranch %190 %278 = OpCompositeConstruct %191 %7 %7 %279 = OpCompositeConstruct %191 %18 %18 %280 = OpISub %191 %279 %278 -%281 = OpCompositeConstruct %42 %24 %24 -%282 = OpCompositeConstruct %42 %25 %25 -%283 = OpISub %42 %281 %282 -%284 = OpCompositeConstruct %42 %25 %25 -%285 = OpCompositeConstruct %42 %24 %24 -%286 = OpISub %42 %285 %284 +%281 = OpCompositeConstruct %43 %24 %24 +%282 = OpCompositeConstruct %43 %25 %25 +%283 = OpISub %43 %281 %282 +%284 = OpCompositeConstruct %43 %25 %25 +%285 = OpCompositeConstruct %43 %24 %24 +%286 = OpISub %43 %285 %284 %287 = OpCompositeConstruct %37 %14 %14 %288 = OpCompositeConstruct %37 %3 %3 %289 = OpFSub %37 %287 %288 @@ -329,12 +331,12 @@ OpBranch %190 %296 = OpCompositeConstruct %191 %7 %7 %298 = OpCompositeConstruct %191 %18 %18 %297 = OpIMul %191 %296 %298 -%299 = OpCompositeConstruct %42 %24 %24 -%301 = OpCompositeConstruct %42 %25 %25 -%300 = OpIMul %42 %299 %301 -%302 = OpCompositeConstruct %42 %25 %25 -%304 = OpCompositeConstruct %42 %24 %24 -%303 = OpIMul %42 %302 %304 +%299 = OpCompositeConstruct %43 %24 %24 +%301 = OpCompositeConstruct %43 %25 %25 +%300 = OpIMul %43 %299 %301 +%302 = OpCompositeConstruct %43 %25 %25 +%304 = OpCompositeConstruct %43 %24 %24 +%303 = OpIMul %43 %302 %304 %305 = OpCompositeConstruct %37 %14 %14 %306 = OpVectorTimesScalar %37 %305 %3 %307 = OpCompositeConstruct %37 %3 %3 @@ -345,12 +347,12 @@ OpBranch %190 %312 = OpCompositeConstruct %191 %7 %7 %313 = OpCompositeConstruct %191 %18 %18 %314 = OpSDiv %191 %313 %312 -%315 = OpCompositeConstruct %42 %24 %24 -%316 = OpCompositeConstruct %42 %25 %25 -%317 = OpUDiv %42 %315 %316 -%318 = OpCompositeConstruct %42 %25 %25 -%319 = OpCompositeConstruct %42 %24 %24 -%320 = OpUDiv %42 %319 %318 +%315 = OpCompositeConstruct %43 %24 %24 +%316 = OpCompositeConstruct %43 %25 %25 +%317 = OpUDiv %43 %315 %316 +%318 = OpCompositeConstruct %43 %25 %25 +%319 = OpCompositeConstruct %43 %24 %24 +%320 = OpUDiv %43 %319 %318 %321 = OpCompositeConstruct %37 %14 %14 %322 = OpCompositeConstruct %37 %3 %3 %323 = OpFDiv %37 %321 %322 @@ -363,45 +365,45 @@ OpBranch %190 %330 = OpCompositeConstruct %191 %7 %7 %331 = OpCompositeConstruct %191 %18 %18 %332 = OpSRem %191 %331 %330 -%333 = OpCompositeConstruct %42 %24 %24 -%334 = OpCompositeConstruct %42 %25 %25 -%335 = OpUMod %42 %333 %334 -%336 = OpCompositeConstruct %42 %25 %25 -%337 = OpCompositeConstruct %42 %24 %24 -%338 = OpUMod %42 %337 %336 +%333 = OpCompositeConstruct %43 %24 %24 +%334 = OpCompositeConstruct %43 %25 %25 +%335 = OpUMod %43 %333 %334 +%336 = OpCompositeConstruct %43 %25 %25 +%337 = OpCompositeConstruct %43 %24 %24 +%338 = OpUMod %43 %337 %336 %339 = OpCompositeConstruct %37 %14 %14 %340 = OpCompositeConstruct %37 %3 %3 %341 = OpFRem %37 %339 %340 %342 = OpCompositeConstruct %37 %3 %3 %343 = OpCompositeConstruct %37 %14 %14 %344 = OpFRem %37 %343 %342 -%346 = OpCompositeExtract %38 %62 0 -%347 = OpCompositeExtract %38 %62 0 +%346 = OpCompositeExtract %38 %63 0 +%347 = OpCompositeExtract %38 %63 0 %348 = OpFAdd %38 %346 %347 -%349 = OpCompositeExtract %38 %62 1 -%350 = OpCompositeExtract %38 %62 1 +%349 = OpCompositeExtract %38 %63 1 +%350 = OpCompositeExtract %38 %63 1 %351 = OpFAdd %38 %349 %350 -%352 = OpCompositeExtract %38 %62 2 -%353 = OpCompositeExtract %38 %62 2 +%352 = OpCompositeExtract %38 %63 2 +%353 = OpCompositeExtract %38 %63 2 %354 = OpFAdd %38 %352 %353 -%345 = OpCompositeConstruct %46 %348 %351 %354 -%356 = OpCompositeExtract %38 %62 0 -%357 = OpCompositeExtract %38 %62 0 +%345 = OpCompositeConstruct %47 %348 %351 %354 +%356 = OpCompositeExtract %38 %63 0 +%357 = OpCompositeExtract %38 %63 0 %358 = OpFSub %38 %356 %357 -%359 = OpCompositeExtract %38 %62 1 -%360 = OpCompositeExtract %38 %62 1 +%359 = OpCompositeExtract %38 %63 1 +%360 = OpCompositeExtract %38 %63 1 %361 = OpFSub %38 %359 %360 -%362 = OpCompositeExtract %38 %62 2 -%363 = OpCompositeExtract %38 %62 2 +%362 = OpCompositeExtract %38 %63 2 +%363 = OpCompositeExtract %38 %63 2 %364 = OpFSub %38 %362 %363 -%355 = OpCompositeConstruct %46 %358 %361 %364 -%365 = OpMatrixTimesScalar %46 %62 %3 -%366 = OpMatrixTimesScalar %46 %62 %14 +%355 = OpCompositeConstruct %47 %358 %361 %364 +%365 = OpMatrixTimesScalar %47 %63 %3 +%366 = OpMatrixTimesScalar %47 %63 %14 %367 = OpCompositeConstruct %34 %3 %3 %3 %3 -%368 = OpMatrixTimesVector %38 %63 %367 +%368 = OpMatrixTimesVector %38 %64 %367 %369 = OpCompositeConstruct %38 %14 %14 %14 -%370 = OpVectorTimesMatrix %34 %369 %63 -%371 = OpMatrixTimesMatrix %46 %63 %64 +%370 = OpVectorTimesMatrix %34 %369 %64 +%371 = OpMatrixTimesMatrix %47 %64 %65 OpReturn OpFunctionEnd %373 = OpFunction %2 None %172 @@ -441,7 +443,7 @@ OpBranch %374 %405 = OpShiftLeftLogical %8 %18 %25 %406 = OpShiftLeftLogical %20 %24 %25 %407 = OpCompositeConstruct %191 %18 %18 -%408 = OpCompositeConstruct %42 %25 %25 +%408 = OpCompositeConstruct %43 %25 %25 %409 = OpShiftLeftLogical %191 %407 %408 %410 = OpCompositeConstruct %202 %24 %24 %24 %411 = OpCompositeConstruct %202 %25 %25 %25 @@ -449,7 +451,7 @@ OpBranch %374 %413 = OpShiftRightArithmetic %8 %18 %25 %414 = OpShiftRightLogical %20 %24 %25 %415 = OpCompositeConstruct %191 %18 %18 -%416 = OpCompositeConstruct %42 %25 %25 +%416 = OpCompositeConstruct %43 %25 %25 %417 = OpShiftRightArithmetic %191 %415 %416 %418 = OpCompositeConstruct %202 %24 %24 %24 %419 = OpCompositeConstruct %202 %25 %25 %25 @@ -468,7 +470,7 @@ OpBranch %423 %429 = OpIEqual %175 %427 %428 %430 = OpCompositeConstruct %202 %24 %24 %24 %431 = OpCompositeConstruct %202 %25 %25 %25 -%432 = OpIEqual %130 %430 %431 +%432 = OpIEqual %39 %430 %431 %433 = OpCompositeConstruct %34 %14 %14 %14 %14 %434 = OpCompositeConstruct %34 %3 %3 %3 %3 %435 = OpFOrdEqual %36 %433 %434 @@ -480,7 +482,7 @@ OpBranch %423 %441 = OpINotEqual %175 %439 %440 %442 = OpCompositeConstruct %202 %24 %24 %24 %443 = OpCompositeConstruct %202 %25 %25 %25 -%444 = OpINotEqual %130 %442 %443 +%444 = OpINotEqual %39 %442 %443 %445 = OpCompositeConstruct %34 %14 %14 %14 %14 %446 = OpCompositeConstruct %34 %3 %3 %3 %3 %447 = OpFOrdNotEqual %36 %445 %446 @@ -492,7 +494,7 @@ OpBranch %423 %453 = OpSLessThan %175 %451 %452 %454 = OpCompositeConstruct %202 %24 %24 %24 %455 = OpCompositeConstruct %202 %25 %25 %25 -%456 = OpULessThan %130 %454 %455 +%456 = OpULessThan %39 %454 %455 %457 = OpCompositeConstruct %34 %14 %14 %14 %14 %458 = OpCompositeConstruct %34 %3 %3 %3 %3 %459 = OpFOrdLessThan %36 %457 %458 @@ -504,7 +506,7 @@ OpBranch %423 %465 = OpSLessThanEqual %175 %463 %464 %466 = OpCompositeConstruct %202 %24 %24 %24 %467 = OpCompositeConstruct %202 %25 %25 %25 -%468 = OpULessThanEqual %130 %466 %467 +%468 = OpULessThanEqual %39 %466 %467 %469 = OpCompositeConstruct %34 %14 %14 %14 %14 %470 = OpCompositeConstruct %34 %3 %3 %3 %3 %471 = OpFOrdLessThanEqual %36 %469 %470 @@ -516,7 +518,7 @@ OpBranch %423 %477 = OpSGreaterThan %175 %475 %476 %478 = OpCompositeConstruct %202 %24 %24 %24 %479 = OpCompositeConstruct %202 %25 %25 %25 -%480 = OpUGreaterThan %130 %478 %479 +%480 = OpUGreaterThan %39 %478 %479 %481 = OpCompositeConstruct %34 %14 %14 %14 %14 %482 = OpCompositeConstruct %34 %3 %3 %3 %3 %483 = OpFOrdGreaterThan %36 %481 %482 @@ -528,105 +530,107 @@ OpBranch %423 %489 = OpSGreaterThanEqual %175 %487 %488 %490 = OpCompositeConstruct %202 %24 %24 %24 %491 = OpCompositeConstruct %202 %25 %25 %25 -%492 = OpUGreaterThanEqual %130 %490 %491 +%492 = OpUGreaterThanEqual %39 %490 %491 %493 = OpCompositeConstruct %34 %14 %14 %14 %14 %494 = OpCompositeConstruct %34 %3 %3 %3 %3 %495 = OpFOrdGreaterThanEqual %36 %493 %494 OpReturn OpFunctionEnd -%501 = OpFunction %2 None %172 -%500 = OpLabel -%496 = OpVariable %497 Function %7 -%498 = OpVariable %499 Function %65 -OpBranch %502 +%503 = OpFunction %2 None %172 %502 = OpLabel -%503 = OpLoad %8 %496 -%504 = OpIAdd %8 %503 %7 -OpStore %496 %504 +%496 = OpVariable %497 Function %498 +%499 = OpVariable %500 Function %501 +OpBranch %504 +%504 = OpLabel +OpStore %496 %7 %505 = OpLoad %8 %496 -%506 = OpISub %8 %505 %7 +%506 = OpIAdd %8 %505 %7 OpStore %496 %506 %507 = OpLoad %8 %496 -%508 = OpLoad %8 %496 -%509 = OpIMul %8 %507 %508 -OpStore %496 %509 +%508 = OpISub %8 %507 %7 +OpStore %496 %508 +%509 = OpLoad %8 %496 %510 = OpLoad %8 %496 -%511 = OpLoad %8 %496 -%512 = OpSDiv %8 %510 %511 -OpStore %496 %512 +%511 = OpIMul %8 %510 %509 +OpStore %496 %511 +%512 = OpLoad %8 %496 %513 = OpLoad %8 %496 -%514 = OpSRem %8 %513 %7 +%514 = OpSDiv %8 %513 %512 OpStore %496 %514 %515 = OpLoad %8 %496 -%516 = OpBitwiseAnd %8 %515 %11 +%516 = OpSRem %8 %515 %7 OpStore %496 %516 %517 = OpLoad %8 %496 -%518 = OpBitwiseOr %8 %517 %11 +%518 = OpBitwiseAnd %8 %517 %11 OpStore %496 %518 %519 = OpLoad %8 %496 -%520 = OpBitwiseXor %8 %519 %11 +%520 = OpBitwiseOr %8 %519 %11 OpStore %496 %520 %521 = OpLoad %8 %496 -%522 = OpShiftLeftLogical %8 %521 %24 +%522 = OpBitwiseXor %8 %521 %11 OpStore %496 %522 %523 = OpLoad %8 %496 -%524 = OpShiftRightArithmetic %8 %523 %25 +%524 = OpShiftLeftLogical %8 %523 %24 OpStore %496 %524 %525 = OpLoad %8 %496 -%526 = OpIAdd %8 %525 %7 +%526 = OpShiftRightArithmetic %8 %525 %25 OpStore %496 %526 %527 = OpLoad %8 %496 -%528 = OpISub %8 %527 %7 +%528 = OpIAdd %8 %527 %7 OpStore %496 %528 -%530 = OpAccessChain %529 %498 %25 -%531 = OpLoad %8 %530 -%532 = OpIAdd %8 %531 %7 -%533 = OpAccessChain %529 %498 %25 -OpStore %533 %532 -%534 = OpAccessChain %529 %498 %25 -%535 = OpLoad %8 %534 -%536 = OpISub %8 %535 %7 -%537 = OpAccessChain %529 %498 %25 -OpStore %537 %536 +%529 = OpLoad %8 %496 +%530 = OpISub %8 %529 %7 +OpStore %496 %530 +OpStore %499 %66 +%532 = OpAccessChain %531 %499 %25 +%533 = OpLoad %8 %532 +%534 = OpIAdd %8 %533 %7 +%535 = OpAccessChain %531 %499 %25 +OpStore %535 %534 +%536 = OpAccessChain %531 %499 %25 +%537 = OpLoad %8 %536 +%538 = OpISub %8 %537 %7 +%539 = OpAccessChain %531 %499 %25 +OpStore %539 %538 OpReturn OpFunctionEnd -%539 = OpFunction %2 None %172 -%538 = OpLabel -OpBranch %540 +%541 = OpFunction %2 None %172 %540 = OpLabel -%541 = OpSNegate %8 %27 -%542 = OpSNegate %8 %28 -%543 = OpSNegate %8 %29 -%544 = OpSNegate %8 %543 -%545 = OpSNegate %8 %30 +OpBranch %542 +%542 = OpLabel +%543 = OpSNegate %8 %27 +%544 = OpSNegate %8 %28 +%545 = OpSNegate %8 %29 %546 = OpSNegate %8 %545 -%547 = OpSNegate %8 %31 +%547 = OpSNegate %8 %30 %548 = OpSNegate %8 %547 -%549 = OpSNegate %8 %548 +%549 = OpSNegate %8 %31 %550 = OpSNegate %8 %549 -%551 = OpSNegate %8 %32 +%551 = OpSNegate %8 %550 %552 = OpSNegate %8 %551 -%553 = OpSNegate %8 %552 +%553 = OpSNegate %8 %32 %554 = OpSNegate %8 %553 -%555 = OpSNegate %8 %33 +%555 = OpSNegate %8 %554 %556 = OpSNegate %8 %555 -%557 = OpSNegate %8 %556 +%557 = OpSNegate %8 %33 %558 = OpSNegate %8 %557 +%559 = OpSNegate %8 %558 +%560 = OpSNegate %8 %559 OpReturn OpFunctionEnd -%560 = OpFunction %2 None %172 -%559 = OpLabel -OpBranch %561 +%562 = OpFunction %2 None %172 %561 = OpLabel -%562 = OpFunctionCall %34 %67 -%563 = OpFunctionCall %34 %92 -%564 = OpVectorShuffle %38 %50 %50 0 1 2 -%565 = OpFunctionCall %38 %127 %564 -%566 = OpFunctionCall %4 %140 -%567 = OpFunctionCall %2 %171 -%568 = OpFunctionCall %2 %189 -%569 = OpFunctionCall %2 %373 -%570 = OpFunctionCall %2 %422 -%571 = OpFunctionCall %2 %501 +OpBranch %563 +%563 = OpLabel +%564 = OpFunctionCall %34 %68 +%565 = OpFunctionCall %34 %93 +%566 = OpVectorShuffle %38 %51 %51 0 1 2 +%567 = OpFunctionCall %38 %128 %566 +%568 = OpFunctionCall %4 %140 +%569 = OpFunctionCall %2 %171 +%570 = OpFunctionCall %2 %189 +%571 = OpFunctionCall %2 %373 +%572 = OpFunctionCall %2 %422 +%573 = OpFunctionCall %2 %503 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/shadow.spvasm b/tests/out/spv/shadow.spvasm index e20fcebc5e..15f18c4f55 100644 --- a/tests/out/spv/shadow.spvasm +++ b/tests/out/spv/shadow.spvasm @@ -1,16 +1,16 @@ ; SPIR-V ; Version: 1.2 ; Generator: rspirv -; Bound: 262 +; Bound: 270 OpCapability Shader OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %94 "vs_main" %84 %87 %89 %91 %93 +OpEntryPoint Vertex %90 "vs_main" %80 %83 %85 %87 %89 OpEntryPoint Fragment %148 "fs_main" %139 %142 %145 %147 -OpEntryPoint Fragment %212 "fs_main_without_storage" %205 %207 %209 %211 +OpEntryPoint Fragment %217 "fs_main_without_storage" %210 %212 %214 %216 OpExecutionMode %148 OriginUpperLeft -OpExecutionMode %212 OriginUpperLeft +OpExecutionMode %217 OriginUpperLeft OpSource GLSL 450 OpName %11 "c_max_lights" OpMemberName %18 0 "view_proj" @@ -37,25 +37,25 @@ OpName %45 "sampler_shadow" OpName %48 "light_id" OpName %49 "homogeneous_coords" OpName %50 "fetch_shadow" -OpName %80 "out" -OpName %84 "position" -OpName %87 "normal" -OpName %89 "proj_position" -OpName %91 "world_normal" -OpName %93 "world_position" -OpName %94 "vs_main" -OpName %134 "color" -OpName %135 "i" +OpName %76 "out" +OpName %80 "position" +OpName %83 "normal" +OpName %85 "proj_position" +OpName %87 "world_normal" +OpName %89 "world_position" +OpName %90 "vs_main" +OpName %132 "color" +OpName %134 "i" OpName %139 "proj_position" OpName %142 "world_normal" OpName %145 "world_position" OpName %148 "fs_main" -OpName %201 "color" -OpName %202 "i" -OpName %205 "proj_position" -OpName %207 "world_normal" -OpName %209 "world_position" -OpName %212 "fs_main_without_storage" +OpName %204 "color" +OpName %206 "i" +OpName %210 "proj_position" +OpName %212 "world_normal" +OpName %214 "world_position" +OpName %217 "fs_main_without_storage" OpMemberDecorate %18 0 Offset 0 OpMemberDecorate %18 0 ColMajor OpMemberDecorate %18 0 MatrixStride 16 @@ -95,19 +95,19 @@ OpDecorate %43 DescriptorSet 0 OpDecorate %43 Binding 2 OpDecorate %45 DescriptorSet 0 OpDecorate %45 Binding 3 -OpDecorate %84 Location 0 -OpDecorate %87 Location 1 -OpDecorate %89 BuiltIn Position -OpDecorate %91 Location 0 -OpDecorate %93 Location 1 +OpDecorate %80 Location 0 +OpDecorate %83 Location 1 +OpDecorate %85 BuiltIn Position +OpDecorate %87 Location 0 +OpDecorate %89 Location 1 OpDecorate %139 BuiltIn FragCoord OpDecorate %142 Location 0 OpDecorate %145 Location 1 OpDecorate %147 Location 0 -OpDecorate %205 BuiltIn FragCoord -OpDecorate %207 Location 0 -OpDecorate %209 Location 1 -OpDecorate %211 Location 0 +OpDecorate %210 BuiltIn FragCoord +OpDecorate %212 Location 0 +OpDecorate %214 Location 1 +OpDecorate %216 Location 0 %2 = OpTypeVoid %4 = OpTypeInt 32 1 %3 = OpConstant %4 10 @@ -154,261 +154,277 @@ OpDecorate %211 Location 0 %46 = OpTypePointer UniformConstant %28 %45 = OpVariable %46 UniformConstant %51 = OpTypeFunction %6 %12 %16 -%54 = OpTypePointer Uniform %19 -%55 = OpTypePointer Uniform %18 -%56 = OpTypePointer Uniform %26 -%57 = OpTypePointer StorageBuffer %25 -%60 = OpTypeBool -%75 = OpTypeSampledImage %27 -%81 = OpTypePointer Function %21 -%82 = OpConstantNull %21 -%85 = OpTypePointer Input %22 -%84 = OpVariable %85 Input -%87 = OpVariable %85 Input -%90 = OpTypePointer Output %16 -%89 = OpVariable %90 Output -%92 = OpTypePointer Output %20 -%91 = OpVariable %92 Output -%93 = OpVariable %90 Output -%95 = OpTypeFunction %2 -%99 = OpTypePointer Uniform %15 -%106 = OpTypePointer Function %20 -%114 = OpTypeVector %4 3 -%119 = OpTypePointer Function %16 -%120 = OpConstant %12 2 -%128 = OpTypePointer Output %6 -%136 = OpTypePointer Function %12 +%56 = OpTypeBool +%71 = OpTypeSampledImage %27 +%77 = OpTypePointer Function %21 +%78 = OpConstantNull %21 +%81 = OpTypePointer Input %22 +%80 = OpVariable %81 Input +%83 = OpVariable %81 Input +%86 = OpTypePointer Output %16 +%85 = OpVariable %86 Output +%88 = OpTypePointer Output %20 +%87 = OpVariable %88 Output +%89 = OpVariable %86 Output +%91 = OpTypeFunction %2 +%92 = OpTypePointer Uniform %18 +%94 = OpTypePointer Uniform %19 +%97 = OpTypePointer Uniform %15 +%104 = OpTypePointer Function %20 +%112 = OpTypeVector %4 3 +%117 = OpTypePointer Function %16 +%118 = OpConstant %12 2 +%126 = OpTypePointer Output %6 +%133 = OpConstantNull %20 +%135 = OpTypePointer Function %12 +%136 = OpConstantNull %12 %140 = OpTypePointer Input %16 %139 = OpVariable %140 Input %143 = OpTypePointer Input %20 %142 = OpVariable %143 Input %145 = OpVariable %140 Input -%147 = OpVariable %90 Output -%162 = OpTypePointer Uniform %17 -%163 = OpTypePointer Uniform %12 -%171 = OpTypePointer StorageBuffer %24 -%197 = OpTypePointer Uniform %16 -%205 = OpVariable %140 Input -%207 = OpVariable %143 Input -%209 = OpVariable %140 Input -%211 = OpVariable %90 Output -%233 = OpTypePointer Uniform %24 +%147 = OpVariable %86 Output +%151 = OpTypePointer StorageBuffer %25 +%163 = OpTypePointer Uniform %17 +%164 = OpTypePointer Uniform %12 +%174 = OpTypePointer StorageBuffer %24 +%200 = OpTypePointer Uniform %16 +%205 = OpConstantNull %20 +%207 = OpConstantNull %12 +%210 = OpVariable %140 Input +%212 = OpVariable %143 Input +%214 = OpVariable %140 Input +%216 = OpVariable %86 Output +%220 = OpTypePointer Uniform %26 +%241 = OpTypePointer Uniform %24 %50 = OpFunction %6 None %51 %48 = OpFunctionParameter %12 %49 = OpFunctionParameter %16 %47 = OpLabel %52 = OpLoad %27 %43 %53 = OpLoad %28 %45 -OpBranch %58 -%58 = OpLabel -%59 = OpCompositeExtract %6 %49 3 -%61 = OpFOrdLessThanEqual %60 %59 %5 -OpSelectionMerge %62 None -OpBranchConditional %61 %63 %62 -%63 = OpLabel +OpBranch %54 +%54 = OpLabel +%55 = OpCompositeExtract %6 %49 3 +%57 = OpFOrdLessThanEqual %56 %55 %5 +OpSelectionMerge %58 None +OpBranchConditional %57 %59 %58 +%59 = OpLabel OpReturnValue %7 -%62 = OpLabel -%64 = OpCompositeConstruct %29 %8 %9 -%65 = OpCompositeExtract %6 %49 3 -%66 = OpFDiv %6 %7 %65 -%67 = OpVectorShuffle %29 %49 %49 0 1 -%68 = OpFMul %29 %67 %64 -%69 = OpVectorTimesScalar %29 %68 %66 -%70 = OpCompositeConstruct %29 %8 %8 -%71 = OpFAdd %29 %69 %70 -%72 = OpBitcast %4 %48 -%73 = OpCompositeExtract %6 %49 2 -%74 = OpFMul %6 %73 %66 -%76 = OpConvertUToF %6 %72 -%77 = OpCompositeConstruct %20 %71 %76 -%78 = OpSampledImage %75 %52 %53 -%79 = OpImageSampleDrefExplicitLod %6 %78 %77 %74 Lod %5 -OpReturnValue %79 +%58 = OpLabel +%60 = OpCompositeConstruct %29 %8 %9 +%61 = OpCompositeExtract %6 %49 3 +%62 = OpFDiv %6 %7 %61 +%63 = OpVectorShuffle %29 %49 %49 0 1 +%64 = OpFMul %29 %63 %60 +%65 = OpVectorTimesScalar %29 %64 %62 +%66 = OpCompositeConstruct %29 %8 %8 +%67 = OpFAdd %29 %65 %66 +%68 = OpBitcast %4 %48 +%69 = OpCompositeExtract %6 %49 2 +%70 = OpFMul %6 %69 %62 +%72 = OpConvertUToF %6 %68 +%73 = OpCompositeConstruct %20 %67 %72 +%74 = OpSampledImage %71 %52 %53 +%75 = OpImageSampleDrefExplicitLod %6 %74 %73 %70 Lod %5 +OpReturnValue %75 OpFunctionEnd -%94 = OpFunction %2 None %95 -%83 = OpLabel -%80 = OpVariable %81 Function %82 -%86 = OpLoad %22 %84 -%88 = OpLoad %22 %87 -%96 = OpAccessChain %55 %31 %13 -%97 = OpAccessChain %54 %34 %13 -OpBranch %98 -%98 = OpLabel -%100 = OpAccessChain %99 %97 %13 +%90 = OpFunction %2 None %91 +%79 = OpLabel +%76 = OpVariable %77 Function %78 +%82 = OpLoad %22 %80 +%84 = OpLoad %22 %83 +%93 = OpAccessChain %92 %31 %13 +%95 = OpAccessChain %94 %34 %13 +OpBranch %96 +%96 = OpLabel +%98 = OpAccessChain %97 %95 %13 +%99 = OpLoad %15 %98 +%100 = OpAccessChain %97 %95 %13 %101 = OpLoad %15 %100 -%102 = OpAccessChain %99 %97 %13 -%103 = OpLoad %15 %102 -%104 = OpConvertSToF %16 %86 -%105 = OpMatrixTimesVector %16 %103 %104 -%107 = OpCompositeExtract %16 %101 0 +%102 = OpConvertSToF %16 %82 +%103 = OpMatrixTimesVector %16 %101 %102 +%105 = OpCompositeExtract %16 %99 0 +%106 = OpVectorShuffle %20 %105 %105 0 1 2 +%107 = OpCompositeExtract %16 %99 1 %108 = OpVectorShuffle %20 %107 %107 0 1 2 -%109 = OpCompositeExtract %16 %101 1 +%109 = OpCompositeExtract %16 %99 2 %110 = OpVectorShuffle %20 %109 %109 0 1 2 -%111 = OpCompositeExtract %16 %101 2 -%112 = OpVectorShuffle %20 %111 %111 0 1 2 -%113 = OpCompositeConstruct %23 %108 %110 %112 -%115 = OpVectorShuffle %114 %88 %88 0 1 2 -%116 = OpConvertSToF %20 %115 -%117 = OpMatrixTimesVector %20 %113 %116 -%118 = OpAccessChain %106 %80 %14 -OpStore %118 %117 -%121 = OpAccessChain %119 %80 %120 -OpStore %121 %105 -%122 = OpAccessChain %99 %96 %13 -%123 = OpLoad %15 %122 -%124 = OpMatrixTimesVector %16 %123 %105 -%125 = OpAccessChain %119 %80 %13 -OpStore %125 %124 -%126 = OpLoad %21 %80 -%127 = OpCompositeExtract %16 %126 0 -OpStore %89 %127 -%129 = OpAccessChain %128 %89 %14 -%130 = OpLoad %6 %129 -%131 = OpFNegate %6 %130 -OpStore %129 %131 -%132 = OpCompositeExtract %20 %126 1 -OpStore %91 %132 -%133 = OpCompositeExtract %16 %126 2 -OpStore %93 %133 +%111 = OpCompositeConstruct %23 %106 %108 %110 +%113 = OpVectorShuffle %112 %84 %84 0 1 2 +%114 = OpConvertSToF %20 %113 +%115 = OpMatrixTimesVector %20 %111 %114 +%116 = OpAccessChain %104 %76 %14 +OpStore %116 %115 +%119 = OpAccessChain %117 %76 %118 +OpStore %119 %103 +%120 = OpAccessChain %97 %93 %13 +%121 = OpLoad %15 %120 +%122 = OpMatrixTimesVector %16 %121 %103 +%123 = OpAccessChain %117 %76 %13 +OpStore %123 %122 +%124 = OpLoad %21 %76 +%125 = OpCompositeExtract %16 %124 0 +OpStore %85 %125 +%127 = OpAccessChain %126 %85 %14 +%128 = OpLoad %6 %127 +%129 = OpFNegate %6 %128 +OpStore %127 %129 +%130 = OpCompositeExtract %20 %124 1 +OpStore %87 %130 +%131 = OpCompositeExtract %16 %124 2 +OpStore %89 %131 OpReturn OpFunctionEnd -%148 = OpFunction %2 None %95 +%148 = OpFunction %2 None %91 %137 = OpLabel -%134 = OpVariable %106 Function %30 -%135 = OpVariable %136 Function %13 +%132 = OpVariable %104 Function %133 +%134 = OpVariable %135 Function %136 %141 = OpLoad %16 %139 %144 = OpLoad %20 %142 %146 = OpLoad %16 %145 %138 = OpCompositeConstruct %21 %141 %144 %146 -%149 = OpAccessChain %55 %31 %13 -%150 = OpAccessChain %54 %34 %13 -%151 = OpAccessChain %57 %37 %13 -%152 = OpLoad %27 %43 -%153 = OpLoad %28 %45 -OpBranch %154 -%154 = OpLabel -%155 = OpCompositeExtract %20 %138 1 -%156 = OpExtInst %20 %1 Normalize %155 -OpBranch %157 -%157 = OpLabel -OpLoopMerge %158 %160 None -OpBranch %159 -%159 = OpLabel -%161 = OpLoad %12 %135 -%164 = OpAccessChain %163 %149 %14 %13 -%165 = OpLoad %12 %164 -%166 = OpExtInst %12 %1 UMin %165 %11 -%167 = OpULessThan %60 %161 %166 -OpSelectionMerge %168 None -OpBranchConditional %167 %168 %169 -%169 = OpLabel +%149 = OpAccessChain %92 %31 %13 +%150 = OpAccessChain %94 %34 %13 +%152 = OpAccessChain %151 %37 %13 +%153 = OpLoad %27 %43 +%154 = OpLoad %28 %45 +OpBranch %155 +%155 = OpLabel +%156 = OpCompositeExtract %20 %138 1 +%157 = OpExtInst %20 %1 Normalize %156 +OpStore %132 %30 +OpStore %134 %13 OpBranch %158 -%168 = OpLabel -%170 = OpLoad %12 %135 -%172 = OpAccessChain %171 %151 %170 -%173 = OpLoad %24 %172 -%174 = OpLoad %12 %135 -%175 = OpCompositeExtract %15 %173 0 -%176 = OpCompositeExtract %16 %138 2 -%177 = OpMatrixTimesVector %16 %175 %176 -%178 = OpFunctionCall %6 %50 %174 %177 -%179 = OpCompositeExtract %16 %173 1 -%180 = OpVectorShuffle %20 %179 %179 0 1 2 -%181 = OpCompositeExtract %16 %138 2 -%182 = OpVectorShuffle %20 %181 %181 0 1 2 -%183 = OpFSub %20 %180 %182 -%184 = OpExtInst %20 %1 Normalize %183 -%185 = OpDot %6 %156 %184 -%186 = OpExtInst %6 %1 FMax %5 %185 -%187 = OpLoad %20 %134 -%188 = OpFMul %6 %178 %186 -%189 = OpCompositeExtract %16 %173 2 -%190 = OpVectorShuffle %20 %189 %189 0 1 2 -%191 = OpVectorTimesScalar %20 %190 %188 -%192 = OpFAdd %20 %187 %191 -OpStore %134 %192 +%158 = OpLabel +OpLoopMerge %159 %161 None OpBranch %160 %160 = OpLabel -%193 = OpLoad %12 %135 -%194 = OpIAdd %12 %193 %14 -OpStore %135 %194 -OpBranch %157 -%158 = OpLabel -%195 = OpLoad %20 %134 -%196 = OpCompositeConstruct %16 %195 %7 -%198 = OpAccessChain %197 %150 %14 -%199 = OpLoad %16 %198 -%200 = OpFMul %16 %196 %199 -OpStore %147 %200 +%162 = OpLoad %12 %134 +%165 = OpAccessChain %164 %149 %14 %13 +%166 = OpLoad %12 %165 +%167 = OpExtInst %12 %1 UMin %166 %11 +%168 = OpULessThan %56 %162 %167 +OpSelectionMerge %169 None +OpBranchConditional %168 %169 %170 +%170 = OpLabel +OpBranch %159 +%169 = OpLabel +OpBranch %171 +%171 = OpLabel +%173 = OpLoad %12 %134 +%175 = OpAccessChain %174 %152 %173 +%176 = OpLoad %24 %175 +%177 = OpLoad %12 %134 +%178 = OpCompositeExtract %15 %176 0 +%179 = OpCompositeExtract %16 %138 2 +%180 = OpMatrixTimesVector %16 %178 %179 +%181 = OpFunctionCall %6 %50 %177 %180 +%182 = OpCompositeExtract %16 %176 1 +%183 = OpVectorShuffle %20 %182 %182 0 1 2 +%184 = OpCompositeExtract %16 %138 2 +%185 = OpVectorShuffle %20 %184 %184 0 1 2 +%186 = OpFSub %20 %183 %185 +%187 = OpExtInst %20 %1 Normalize %186 +%188 = OpDot %6 %157 %187 +%189 = OpExtInst %6 %1 FMax %5 %188 +%190 = OpFMul %6 %181 %189 +%191 = OpCompositeExtract %16 %176 2 +%192 = OpVectorShuffle %20 %191 %191 0 1 2 +%193 = OpVectorTimesScalar %20 %192 %190 +%194 = OpLoad %20 %132 +%195 = OpFAdd %20 %194 %193 +OpStore %132 %195 +OpBranch %172 +%172 = OpLabel +OpBranch %161 +%161 = OpLabel +%196 = OpLoad %12 %134 +%197 = OpIAdd %12 %196 %14 +OpStore %134 %197 +OpBranch %158 +%159 = OpLabel +%198 = OpLoad %20 %132 +%199 = OpCompositeConstruct %16 %198 %7 +%201 = OpAccessChain %200 %150 %14 +%202 = OpLoad %16 %201 +%203 = OpFMul %16 %199 %202 +OpStore %147 %203 OpReturn OpFunctionEnd -%212 = OpFunction %2 None %95 -%203 = OpLabel -%201 = OpVariable %106 Function %30 -%202 = OpVariable %136 Function %13 -%206 = OpLoad %16 %205 -%208 = OpLoad %20 %207 -%210 = OpLoad %16 %209 -%204 = OpCompositeConstruct %21 %206 %208 %210 -%213 = OpAccessChain %55 %31 %13 -%214 = OpAccessChain %54 %34 %13 -%215 = OpAccessChain %56 %40 %13 -%216 = OpLoad %27 %43 -%217 = OpLoad %28 %45 -OpBranch %218 -%218 = OpLabel -%219 = OpCompositeExtract %20 %204 1 -%220 = OpExtInst %20 %1 Normalize %219 -OpBranch %221 -%221 = OpLabel -OpLoopMerge %222 %224 None -OpBranch %223 -%223 = OpLabel -%225 = OpLoad %12 %202 -%226 = OpAccessChain %163 %213 %14 %13 -%227 = OpLoad %12 %226 -%228 = OpExtInst %12 %1 UMin %227 %11 -%229 = OpULessThan %60 %225 %228 -OpSelectionMerge %230 None -OpBranchConditional %229 %230 %231 -%231 = OpLabel -OpBranch %222 -%230 = OpLabel -%232 = OpLoad %12 %202 -%234 = OpAccessChain %233 %215 %232 -%235 = OpLoad %24 %234 -%236 = OpLoad %12 %202 -%237 = OpCompositeExtract %15 %235 0 -%238 = OpCompositeExtract %16 %204 2 -%239 = OpMatrixTimesVector %16 %237 %238 -%240 = OpFunctionCall %6 %50 %236 %239 -%241 = OpCompositeExtract %16 %235 1 -%242 = OpVectorShuffle %20 %241 %241 0 1 2 -%243 = OpCompositeExtract %16 %204 2 -%244 = OpVectorShuffle %20 %243 %243 0 1 2 -%245 = OpFSub %20 %242 %244 -%246 = OpExtInst %20 %1 Normalize %245 -%247 = OpDot %6 %220 %246 -%248 = OpExtInst %6 %1 FMax %5 %247 -%249 = OpLoad %20 %201 -%250 = OpFMul %6 %240 %248 -%251 = OpCompositeExtract %16 %235 2 -%252 = OpVectorShuffle %20 %251 %251 0 1 2 -%253 = OpVectorTimesScalar %20 %252 %250 -%254 = OpFAdd %20 %249 %253 -OpStore %201 %254 +%217 = OpFunction %2 None %91 +%208 = OpLabel +%204 = OpVariable %104 Function %205 +%206 = OpVariable %135 Function %207 +%211 = OpLoad %16 %210 +%213 = OpLoad %20 %212 +%215 = OpLoad %16 %214 +%209 = OpCompositeConstruct %21 %211 %213 %215 +%218 = OpAccessChain %92 %31 %13 +%219 = OpAccessChain %94 %34 %13 +%221 = OpAccessChain %220 %40 %13 +%222 = OpLoad %27 %43 +%223 = OpLoad %28 %45 OpBranch %224 %224 = OpLabel -%255 = OpLoad %12 %202 -%256 = OpIAdd %12 %255 %14 -OpStore %202 %256 -OpBranch %221 -%222 = OpLabel -%257 = OpLoad %20 %201 -%258 = OpCompositeConstruct %16 %257 %7 -%259 = OpAccessChain %197 %214 %14 -%260 = OpLoad %16 %259 -%261 = OpFMul %16 %258 %260 -OpStore %211 %261 +%225 = OpCompositeExtract %20 %209 1 +%226 = OpExtInst %20 %1 Normalize %225 +OpStore %204 %30 +OpStore %206 %13 +OpBranch %227 +%227 = OpLabel +OpLoopMerge %228 %230 None +OpBranch %229 +%229 = OpLabel +%231 = OpLoad %12 %206 +%232 = OpAccessChain %164 %218 %14 %13 +%233 = OpLoad %12 %232 +%234 = OpExtInst %12 %1 UMin %233 %11 +%235 = OpULessThan %56 %231 %234 +OpSelectionMerge %236 None +OpBranchConditional %235 %236 %237 +%237 = OpLabel +OpBranch %228 +%236 = OpLabel +OpBranch %238 +%238 = OpLabel +%240 = OpLoad %12 %206 +%242 = OpAccessChain %241 %221 %240 +%243 = OpLoad %24 %242 +%244 = OpLoad %12 %206 +%245 = OpCompositeExtract %15 %243 0 +%246 = OpCompositeExtract %16 %209 2 +%247 = OpMatrixTimesVector %16 %245 %246 +%248 = OpFunctionCall %6 %50 %244 %247 +%249 = OpCompositeExtract %16 %243 1 +%250 = OpVectorShuffle %20 %249 %249 0 1 2 +%251 = OpCompositeExtract %16 %209 2 +%252 = OpVectorShuffle %20 %251 %251 0 1 2 +%253 = OpFSub %20 %250 %252 +%254 = OpExtInst %20 %1 Normalize %253 +%255 = OpDot %6 %226 %254 +%256 = OpExtInst %6 %1 FMax %5 %255 +%257 = OpFMul %6 %248 %256 +%258 = OpCompositeExtract %16 %243 2 +%259 = OpVectorShuffle %20 %258 %258 0 1 2 +%260 = OpVectorTimesScalar %20 %259 %257 +%261 = OpLoad %20 %204 +%262 = OpFAdd %20 %261 %260 +OpStore %204 %262 +OpBranch %239 +%239 = OpLabel +OpBranch %230 +%230 = OpLabel +%263 = OpLoad %12 %206 +%264 = OpIAdd %12 %263 %14 +OpStore %206 %264 +OpBranch %227 +%228 = OpLabel +%265 = OpLoad %20 %204 +%266 = OpCompositeConstruct %16 %265 %7 +%267 = OpAccessChain %200 %219 %14 +%268 = OpLoad %16 %267 +%269 = OpFMul %16 %266 %268 +OpStore %216 %269 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/wgsl/access.wgsl b/tests/out/wgsl/access.wgsl index 2a25704545..31054c870f 100644 --- a/tests/out/wgsl/access.wgsl +++ b/tests/out/wgsl/access.wgsl @@ -36,82 +36,84 @@ var nested_mat_cx2_: MatCx2InArray; var val: u32; fn test_matrix_within_struct_accesses() { - var idx: i32 = 1; + var idx: i32; var t: Baz; - let _e6 = idx; - idx = (_e6 - 1); + idx = 1; + let _e2 = idx; + idx = (_e2 - 1); _ = baz.m; _ = baz.m[0]; - let _e16 = idx; - _ = baz.m[_e16]; + let _e15 = idx; + _ = baz.m[_e15]; _ = baz.m[0][1]; - let _e28 = idx; - _ = baz.m[0][_e28]; - let _e32 = idx; - _ = baz.m[_e32][1]; - let _e38 = idx; - let _e40 = idx; - _ = baz.m[_e38][_e40]; + let _e29 = idx; + _ = baz.m[0][_e29]; + let _e34 = idx; + _ = baz.m[_e34][1]; + let _e41 = idx; + let _e43 = idx; + _ = baz.m[_e41][_e43]; t = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); - let _e52 = idx; - idx = (_e52 + 1); + let _e55 = idx; + idx = (_e55 + 1); t.m = mat3x2(vec2(6.0), vec2(5.0), vec2(4.0)); t.m[0] = vec2(9.0); - let _e69 = idx; - t.m[_e69] = vec2(90.0); + let _e72 = idx; + t.m[_e72] = vec2(90.0); t.m[0][1] = 10.0; - let _e82 = idx; - t.m[0][_e82] = 20.0; - let _e86 = idx; - t.m[_e86][1] = 30.0; - let _e92 = idx; - let _e94 = idx; - t.m[_e92][_e94] = 40.0; + let _e85 = idx; + t.m[0][_e85] = 20.0; + let _e89 = idx; + t.m[_e89][1] = 30.0; + let _e95 = idx; + let _e97 = idx; + t.m[_e95][_e97] = 40.0; return; } fn test_matrix_within_array_within_struct_accesses() { - var idx_1: i32 = 1; + var idx_1: i32; var t_1: MatCx2InArray; - let _e7 = idx_1; - idx_1 = (_e7 - 1); + idx_1 = 1; + let _e2 = idx_1; + idx_1 = (_e2 - 1); _ = nested_mat_cx2_.am; _ = nested_mat_cx2_.am[0]; _ = nested_mat_cx2_.am[0][0]; - let _e25 = idx_1; - _ = nested_mat_cx2_.am[0][_e25]; + let _e24 = idx_1; + _ = nested_mat_cx2_.am[0][_e24]; _ = nested_mat_cx2_.am[0][0][1]; - let _e41 = idx_1; - _ = nested_mat_cx2_.am[0][0][_e41]; - let _e47 = idx_1; - _ = nested_mat_cx2_.am[0][_e47][1]; - let _e55 = idx_1; - let _e57 = idx_1; - _ = nested_mat_cx2_.am[0][_e55][_e57]; + let _e42 = idx_1; + _ = nested_mat_cx2_.am[0][0][_e42]; + let _e49 = idx_1; + _ = nested_mat_cx2_.am[0][_e49][1]; + let _e58 = idx_1; + let _e60 = idx_1; + _ = nested_mat_cx2_.am[0][_e58][_e60]; t_1 = MatCx2InArray(array,2>(mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)), mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)))); - let _e63 = idx_1; - idx_1 = (_e63 + 1); + let _e66 = idx_1; + idx_1 = (_e66 + 1); t_1.am = array,2>(mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0)), mat4x2(vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0), vec2(0.0, 0.0))); t_1.am[0] = mat4x2(vec2(8.0), vec2(7.0), vec2(6.0), vec2(5.0)); t_1.am[0][0] = vec2(9.0); - let _e90 = idx_1; - t_1.am[0][_e90] = vec2(90.0); + let _e93 = idx_1; + t_1.am[0][_e93] = vec2(90.0); t_1.am[0][0][1] = 10.0; - let _e107 = idx_1; - t_1.am[0][0][_e107] = 20.0; - let _e113 = idx_1; - t_1.am[0][_e113][1] = 30.0; - let _e121 = idx_1; - let _e123 = idx_1; - t_1.am[0][_e121][_e123] = 40.0; + let _e110 = idx_1; + t_1.am[0][0][_e110] = 20.0; + let _e116 = idx_1; + t_1.am[0][_e116][1] = 30.0; + let _e124 = idx_1; + let _e126 = idx_1; + t_1.am[0][_e124][_e126] = 40.0; return; } fn read_from_private(foo_1: ptr) -> f32 { - let _e6 = (*foo_1); - return _e6; + let _e1 = (*foo_1); + return _e1; } fn test_arr_as_arg(a: array,5>) -> f32 { @@ -125,9 +127,10 @@ fn assign_through_ptr_fn(p: ptr) { @vertex fn foo_vert(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4 { - var foo: f32 = 0.0; - var c: array; + var foo: f32; + var c2_: array; + foo = 0.0; let baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(); @@ -136,13 +139,13 @@ fn foo_vert(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4 { let arr = bar.arr; let b = bar._matrix[3][0]; let a_1 = bar.data[(arrayLength((&bar.data)) - 2u)].value; - let c_1 = qux; + let c = qux; let data_pointer = (&bar.data[0].value); - let _e32 = read_from_private((&foo)); - c = array(a_1, i32(b), 3, 4, 5); - c[(vi + 1u)] = 42; - let value = c[vi]; - let _e46 = test_arr_as_arg(array,5>(array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); + let _e34 = read_from_private((&foo)); + c2_ = array(a_1, i32(b), 3, 4, 5); + c2_[(vi + 1u)] = 42; + let value = c2_[vi]; + let _e48 = test_arr_as_arg(array,5>(array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), array(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); return vec4((_matrix * vec4(vec4(value))), 2.0); } @@ -161,22 +164,22 @@ fn atomics() { var tmp: i32; let value_1 = atomicLoad((&bar.atom)); - let _e10 = atomicAdd((&bar.atom), 5); - tmp = _e10; - let _e13 = atomicSub((&bar.atom), 5); - tmp = _e13; - let _e16 = atomicAnd((&bar.atom), 5); - tmp = _e16; + let _e7 = atomicAdd((&bar.atom), 5); + tmp = _e7; + let _e11 = atomicSub((&bar.atom), 5); + tmp = _e11; + let _e15 = atomicAnd((&bar.atom), 5); + tmp = _e15; let _e19 = atomicOr((&bar.atom), 5); tmp = _e19; - let _e22 = atomicXor((&bar.atom), 5); - tmp = _e22; - let _e25 = atomicMin((&bar.atom), 5); - tmp = _e25; - let _e28 = atomicMax((&bar.atom), 5); - tmp = _e28; - let _e31 = atomicExchange((&bar.atom), 5); + let _e23 = atomicXor((&bar.atom), 5); + tmp = _e23; + let _e27 = atomicMin((&bar.atom), 5); + tmp = _e27; + let _e31 = atomicMax((&bar.atom), 5); tmp = _e31; + let _e35 = atomicExchange((&bar.atom), 5); + tmp = _e35; atomicStore((&bar.atom), value_1); return; } diff --git a/tests/out/wgsl/atomicCompareExchange.wgsl b/tests/out/wgsl/atomicCompareExchange.wgsl index b1e2d06a4a..2c213c8fec 100644 --- a/tests/out/wgsl/atomicCompareExchange.wgsl +++ b/tests/out/wgsl/atomicCompareExchange.wgsl @@ -8,7 +8,7 @@ struct gen___atomic_compare_exchange_result_1 { exchanged: bool, } -let SIZE: u32 = 128u; +const SIZE: u32 = 128u; @group(0) @binding(0) var arr_i32_: array,SIZE>; @@ -17,37 +17,42 @@ var arr_u32_: array,SIZE>; @compute @workgroup_size(1, 1, 1) fn test_atomic_compare_exchange_i32_() { - var i: u32 = 0u; + var i: u32; var old: i32; var exchanged: bool; + i = 0u; loop { - let _e5 = i; - if (_e5 < SIZE) { + let _e2 = i; + if (_e2 < SIZE) { } else { break; } - let _e10 = i; - let _e12 = atomicLoad((&arr_i32_[_e10])); - old = _e12; - exchanged = false; - loop { - let _e16 = exchanged; - if !(_e16) { - } else { - break; + { + let _e6 = i; + let _e8 = atomicLoad((&arr_i32_[_e6])); + old = _e8; + exchanged = false; + loop { + let _e12 = exchanged; + if !(_e12) { + } else { + break; + } + { + let _e14 = old; + let new_ = bitcast((bitcast(_e14) + 1.0)); + let _e20 = i; + let _e22 = old; + let _e23 = atomicCompareExchangeWeak((&arr_i32_[_e20]), _e22, new_); + old = _e23.old_value; + exchanged = _e23.exchanged; + } } - let _e18 = old; - let new_ = bitcast((bitcast(_e18) + 1.0)); - let _e23 = i; - let _e25 = old; - let _e26 = atomicCompareExchangeWeak((&arr_i32_[_e23]), _e25, new_); - old = _e26.old_value; - exchanged = _e26.exchanged; } continuing { - let _e7 = i; - i = (_e7 + 1u); + let _e26 = i; + i = (_e26 + 1u); } } return; @@ -55,37 +60,42 @@ fn test_atomic_compare_exchange_i32_() { @compute @workgroup_size(1, 1, 1) fn test_atomic_compare_exchange_u32_() { - var i_1: u32 = 0u; + var i_1: u32; var old_1: u32; var exchanged_1: bool; + i_1 = 0u; loop { - let _e5 = i_1; - if (_e5 < SIZE) { + let _e2 = i_1; + if (_e2 < SIZE) { } else { break; } - let _e10 = i_1; - let _e12 = atomicLoad((&arr_u32_[_e10])); - old_1 = _e12; - exchanged_1 = false; - loop { - let _e16 = exchanged_1; - if !(_e16) { - } else { - break; + { + let _e6 = i_1; + let _e8 = atomicLoad((&arr_u32_[_e6])); + old_1 = _e8; + exchanged_1 = false; + loop { + let _e12 = exchanged_1; + if !(_e12) { + } else { + break; + } + { + let _e14 = old_1; + let new_1 = bitcast((bitcast(_e14) + 1.0)); + let _e20 = i_1; + let _e22 = old_1; + let _e23 = atomicCompareExchangeWeak((&arr_u32_[_e20]), _e22, new_1); + old_1 = _e23.old_value; + exchanged_1 = _e23.exchanged; + } } - let _e18 = old_1; - let new_1 = bitcast((bitcast(_e18) + 1.0)); - let _e23 = i_1; - let _e25 = old_1; - let _e26 = atomicCompareExchangeWeak((&arr_u32_[_e23]), _e25, new_1); - old_1 = _e26.old_value; - exchanged_1 = _e26.exchanged; } continuing { - let _e7 = i_1; - i_1 = (_e7 + 1u); + let _e26 = i_1; + i_1 = (_e26 + 1u); } } return; diff --git a/tests/out/wgsl/binding-arrays.wgsl b/tests/out/wgsl/binding-arrays.wgsl index 0760aef72b..e3abd5c355 100644 --- a/tests/out/wgsl/binding-arrays.wgsl +++ b/tests/out/wgsl/binding-arrays.wgsl @@ -27,144 +27,146 @@ var uni: UniformIndex; @fragment fn main(fragment_in: FragmentIn) -> @location(0) vec4 { - var i1_: i32 = 0; + var i1_: i32; var i2_: vec2; - var v1_: f32 = 0.0; + var v1_: f32; var v4_: vec4; let uniform_index = uni.index; let non_uniform_index = fragment_in.index; + i1_ = 0; i2_ = vec2(0); + v1_ = 0.0; v4_ = vec4(0.0); let uv = vec2(0.0); let pix = vec2(0); - let _e27 = i2_; - let _e30 = textureDimensions(texture_array_unbounded[0]); - i2_ = (_e27 + _e30); - let _e32 = i2_; - let _e34 = textureDimensions(texture_array_unbounded[uniform_index]); - i2_ = (_e32 + _e34); - let _e36 = i2_; - let _e38 = textureDimensions(texture_array_unbounded[non_uniform_index]); - i2_ = (_e36 + _e38); - let _e40 = v4_; - let _e45 = textureGather(0, texture_array_bounded[0], samp[0], uv); - v4_ = (_e40 + _e45); - let _e47 = v4_; - let _e50 = textureGather(0, texture_array_bounded[uniform_index], samp[uniform_index], uv); - v4_ = (_e47 + _e50); - let _e52 = v4_; + let _e22 = textureDimensions(texture_array_unbounded[0]); + let _e23 = i2_; + i2_ = (_e23 + _e22); + let _e27 = textureDimensions(texture_array_unbounded[uniform_index]); + let _e28 = i2_; + i2_ = (_e28 + _e27); + let _e32 = textureDimensions(texture_array_unbounded[non_uniform_index]); + let _e33 = i2_; + i2_ = (_e33 + _e32); + let _e41 = textureGather(0, texture_array_bounded[0], samp[0], uv); + let _e42 = v4_; + v4_ = (_e42 + _e41); + let _e48 = textureGather(0, texture_array_bounded[uniform_index], samp[uniform_index], uv); + let _e49 = v4_; + v4_ = (_e49 + _e48); let _e55 = textureGather(0, texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); - v4_ = (_e52 + _e55); - let _e57 = v4_; - let _e63 = textureGatherCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); - v4_ = (_e57 + _e63); - let _e65 = v4_; - let _e69 = textureGatherCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); - v4_ = (_e65 + _e69); - let _e71 = v4_; - let _e75 = textureGatherCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); - v4_ = (_e71 + _e75); - let _e77 = v4_; - let _e81 = textureLoad(texture_array_unbounded[0], pix, 0); - v4_ = (_e77 + _e81); - let _e83 = v4_; - let _e86 = textureLoad(texture_array_unbounded[uniform_index], pix, 0); - v4_ = (_e83 + _e86); - let _e88 = v4_; - let _e91 = textureLoad(texture_array_unbounded[non_uniform_index], pix, 0); - v4_ = (_e88 + _e91); - let _e93 = i1_; - let _e96 = textureNumLayers(texture_array_2darray[0]); - i1_ = (_e93 + _e96); - let _e98 = i1_; - let _e100 = textureNumLayers(texture_array_2darray[uniform_index]); - i1_ = (_e98 + _e100); - let _e102 = i1_; - let _e104 = textureNumLayers(texture_array_2darray[non_uniform_index]); - i1_ = (_e102 + _e104); - let _e106 = i1_; - let _e109 = textureNumLevels(texture_array_bounded[0]); - i1_ = (_e106 + _e109); - let _e111 = i1_; - let _e113 = textureNumLevels(texture_array_bounded[uniform_index]); - i1_ = (_e111 + _e113); - let _e115 = i1_; - let _e117 = textureNumLevels(texture_array_bounded[non_uniform_index]); - i1_ = (_e115 + _e117); - let _e119 = i1_; - let _e122 = textureNumSamples(texture_array_multisampled[0]); - i1_ = (_e119 + _e122); - let _e124 = i1_; - let _e126 = textureNumSamples(texture_array_multisampled[uniform_index]); - i1_ = (_e124 + _e126); + let _e56 = v4_; + v4_ = (_e56 + _e55); + let _e65 = textureGatherCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); + let _e66 = v4_; + v4_ = (_e66 + _e65); + let _e73 = textureGatherCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e74 = v4_; + v4_ = (_e74 + _e73); + let _e81 = textureGatherCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e82 = v4_; + v4_ = (_e82 + _e81); + let _e88 = textureLoad(texture_array_unbounded[0], pix, 0); + let _e89 = v4_; + v4_ = (_e89 + _e88); + let _e94 = textureLoad(texture_array_unbounded[uniform_index], pix, 0); + let _e95 = v4_; + v4_ = (_e95 + _e94); + let _e100 = textureLoad(texture_array_unbounded[non_uniform_index], pix, 0); + let _e101 = v4_; + v4_ = (_e101 + _e100); + let _e106 = textureNumLayers(texture_array_2darray[0]); + let _e107 = i1_; + i1_ = (_e107 + _e106); + let _e111 = textureNumLayers(texture_array_2darray[uniform_index]); + let _e112 = i1_; + i1_ = (_e112 + _e111); + let _e116 = textureNumLayers(texture_array_2darray[non_uniform_index]); + let _e117 = i1_; + i1_ = (_e117 + _e116); + let _e122 = textureNumLevels(texture_array_bounded[0]); + let _e123 = i1_; + i1_ = (_e123 + _e122); + let _e127 = textureNumLevels(texture_array_bounded[uniform_index]); let _e128 = i1_; - let _e130 = textureNumSamples(texture_array_multisampled[non_uniform_index]); - i1_ = (_e128 + _e130); - let _e132 = v4_; - let _e137 = textureSample(texture_array_bounded[0], samp[0], uv); - v4_ = (_e132 + _e137); - let _e139 = v4_; - let _e142 = textureSample(texture_array_bounded[uniform_index], samp[uniform_index], uv); - v4_ = (_e139 + _e142); - let _e144 = v4_; - let _e147 = textureSample(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); - v4_ = (_e144 + _e147); - let _e149 = v4_; - let _e155 = textureSampleBias(texture_array_bounded[0], samp[0], uv, 0.0); - v4_ = (_e149 + _e155); - let _e157 = v4_; - let _e161 = textureSampleBias(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); - v4_ = (_e157 + _e161); - let _e163 = v4_; - let _e167 = textureSampleBias(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); - v4_ = (_e163 + _e167); - let _e169 = v1_; - let _e175 = textureSampleCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); - v1_ = (_e169 + _e175); - let _e177 = v1_; - let _e181 = textureSampleCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); - v1_ = (_e177 + _e181); - let _e183 = v1_; - let _e187 = textureSampleCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); - v1_ = (_e183 + _e187); - let _e189 = v1_; - let _e195 = textureSampleCompareLevel(texture_array_depth[0], samp_comp[0], uv, 0.0); - v1_ = (_e189 + _e195); - let _e197 = v1_; - let _e201 = textureSampleCompareLevel(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); - v1_ = (_e197 + _e201); - let _e203 = v1_; - let _e207 = textureSampleCompareLevel(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); - v1_ = (_e203 + _e207); - let _e209 = v4_; - let _e214 = textureSampleGrad(texture_array_bounded[0], samp[0], uv, uv, uv); - v4_ = (_e209 + _e214); - let _e216 = v4_; - let _e219 = textureSampleGrad(texture_array_bounded[uniform_index], samp[uniform_index], uv, uv, uv); - v4_ = (_e216 + _e219); - let _e221 = v4_; - let _e224 = textureSampleGrad(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, uv, uv); - v4_ = (_e221 + _e224); - let _e226 = v4_; - let _e232 = textureSampleLevel(texture_array_bounded[0], samp[0], uv, 0.0); - v4_ = (_e226 + _e232); - let _e234 = v4_; - let _e238 = textureSampleLevel(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); - v4_ = (_e234 + _e238); - let _e240 = v4_; - let _e244 = textureSampleLevel(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); - v4_ = (_e240 + _e244); - let _e248 = v4_; - textureStore(texture_array_storage[0], pix, _e248); - let _e250 = v4_; - textureStore(texture_array_storage[uniform_index], pix, _e250); - let _e252 = v4_; - textureStore(texture_array_storage[non_uniform_index], pix, _e252); - let _e253 = i2_; - let _e254 = i1_; - let v2_ = vec2((_e253 + vec2(_e254))); - let _e258 = v4_; - let _e265 = v1_; - return ((_e258 + vec4(v2_.x, v2_.y, v2_.x, v2_.y)) + vec4(_e265)); + i1_ = (_e128 + _e127); + let _e132 = textureNumLevels(texture_array_bounded[non_uniform_index]); + let _e133 = i1_; + i1_ = (_e133 + _e132); + let _e138 = textureNumSamples(texture_array_multisampled[0]); + let _e139 = i1_; + i1_ = (_e139 + _e138); + let _e143 = textureNumSamples(texture_array_multisampled[uniform_index]); + let _e144 = i1_; + i1_ = (_e144 + _e143); + let _e148 = textureNumSamples(texture_array_multisampled[non_uniform_index]); + let _e149 = i1_; + i1_ = (_e149 + _e148); + let _e157 = textureSample(texture_array_bounded[0], samp[0], uv); + let _e158 = v4_; + v4_ = (_e158 + _e157); + let _e164 = textureSample(texture_array_bounded[uniform_index], samp[uniform_index], uv); + let _e165 = v4_; + v4_ = (_e165 + _e164); + let _e171 = textureSample(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); + let _e172 = v4_; + v4_ = (_e172 + _e171); + let _e181 = textureSampleBias(texture_array_bounded[0], samp[0], uv, 0.0); + let _e182 = v4_; + v4_ = (_e182 + _e181); + let _e189 = textureSampleBias(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); + let _e190 = v4_; + v4_ = (_e190 + _e189); + let _e197 = textureSampleBias(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); + let _e198 = v4_; + v4_ = (_e198 + _e197); + let _e207 = textureSampleCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); + let _e208 = v1_; + v1_ = (_e208 + _e207); + let _e215 = textureSampleCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e216 = v1_; + v1_ = (_e216 + _e215); + let _e223 = textureSampleCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e224 = v1_; + v1_ = (_e224 + _e223); + let _e233 = textureSampleCompareLevel(texture_array_depth[0], samp_comp[0], uv, 0.0); + let _e234 = v1_; + v1_ = (_e234 + _e233); + let _e241 = textureSampleCompareLevel(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e242 = v1_; + v1_ = (_e242 + _e241); + let _e249 = textureSampleCompareLevel(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e250 = v1_; + v1_ = (_e250 + _e249); + let _e258 = textureSampleGrad(texture_array_bounded[0], samp[0], uv, uv, uv); + let _e259 = v4_; + v4_ = (_e259 + _e258); + let _e265 = textureSampleGrad(texture_array_bounded[uniform_index], samp[uniform_index], uv, uv, uv); + let _e266 = v4_; + v4_ = (_e266 + _e265); + let _e272 = textureSampleGrad(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, uv, uv); + let _e273 = v4_; + v4_ = (_e273 + _e272); + let _e282 = textureSampleLevel(texture_array_bounded[0], samp[0], uv, 0.0); + let _e283 = v4_; + v4_ = (_e283 + _e282); + let _e290 = textureSampleLevel(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); + let _e291 = v4_; + v4_ = (_e291 + _e290); + let _e298 = textureSampleLevel(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); + let _e299 = v4_; + v4_ = (_e299 + _e298); + let _e304 = v4_; + textureStore(texture_array_storage[0], pix, _e304); + let _e307 = v4_; + textureStore(texture_array_storage[uniform_index], pix, _e307); + let _e310 = v4_; + textureStore(texture_array_storage[non_uniform_index], pix, _e310); + let _e311 = i2_; + let _e312 = i1_; + let v2_ = vec2((_e311 + vec2(_e312))); + let _e316 = v4_; + let _e323 = v1_; + return ((_e316 + vec4(v2_.x, v2_.y, v2_.x, v2_.y)) + vec4(_e323)); } diff --git a/tests/out/wgsl/bits.wgsl b/tests/out/wgsl/bits.wgsl index ccaebff41e..88876ec05c 100644 --- a/tests/out/wgsl/bits.wgsl +++ b/tests/out/wgsl/bits.wgsl @@ -1,19 +1,21 @@ @compute @workgroup_size(1, 1, 1) fn main() { - var i: i32 = 0; + var i: i32; var i2_: vec2; var i3_: vec3; var i4_: vec4; - var u: u32 = 0u; + var u: u32; var u2_: vec2; var u3_: vec3; var u4_: vec4; var f2_: vec2; var f4_: vec4; + i = 0; i2_ = vec2(0); i3_ = vec3(0); i4_ = vec4(0); + u = 0u; u2_ = vec2(0u); u3_ = vec3(0u); u4_ = vec4(0u); diff --git a/tests/out/wgsl/boids.wgsl b/tests/out/wgsl/boids.wgsl index fd143f79fb..a3f03dd2df 100644 --- a/tests/out/wgsl/boids.wgsl +++ b/tests/out/wgsl/boids.wgsl @@ -17,7 +17,7 @@ struct Particles { particles: array, } -let NUM_PARTICLES: u32 = 1500u; +const NUM_PARTICLES: u32 = 1500u; @group(0) @binding(0) var params: SimParams; @@ -33,119 +33,122 @@ fn main(@builtin(global_invocation_id) global_invocation_id: vec3) { var cMass: vec2; var cVel: vec2; var colVel: vec2; - var cMassCount: i32 = 0; - var cVelCount: i32 = 0; + var cMassCount: i32; + var cVelCount: i32; var pos: vec2; var vel: vec2; - var i: u32 = 0u; + var i: u32; let index = global_invocation_id.x; if (index >= NUM_PARTICLES) { return; } - let _e10 = particlesSrc.particles[index].pos; - vPos = _e10; - let _e15 = particlesSrc.particles[index].vel; - vVel = _e15; + let _e8 = particlesSrc.particles[index].pos; + vPos = _e8; + let _e14 = particlesSrc.particles[index].vel; + vVel = _e14; cMass = vec2(0.0, 0.0); cVel = vec2(0.0, 0.0); colVel = vec2(0.0, 0.0); + cMassCount = 0; + cVelCount = 0; + i = 0u; loop { - let _e37 = i; - if (_e37 >= NUM_PARTICLES) { + let _e36 = i; + if (_e36 >= NUM_PARTICLES) { break; } let _e39 = i; if (_e39 == index) { continue; } - let _e42 = i; - let _e45 = particlesSrc.particles[_e42].pos; - pos = _e45; - let _e47 = i; - let _e50 = particlesSrc.particles[_e47].vel; - vel = _e50; - let _e51 = pos; - let _e52 = vPos; - let _e55 = params.rule1Distance; - if (distance(_e51, _e52) < _e55) { - let _e57 = cMass; - let _e58 = pos; - cMass = (_e57 + _e58); - let _e60 = cMassCount; - cMassCount = (_e60 + 1); + let _e43 = i; + let _e46 = particlesSrc.particles[_e43].pos; + pos = _e46; + let _e49 = i; + let _e52 = particlesSrc.particles[_e49].vel; + vel = _e52; + let _e53 = pos; + let _e54 = vPos; + let _e58 = params.rule1Distance; + if (distance(_e53, _e54) < _e58) { + let _e60 = cMass; + let _e61 = pos; + cMass = (_e60 + _e61); + let _e63 = cMassCount; + cMassCount = (_e63 + 1); } - let _e63 = pos; - let _e64 = vPos; - let _e67 = params.rule2Distance; - if (distance(_e63, _e64) < _e67) { - let _e69 = colVel; - let _e70 = pos; - let _e71 = vPos; - colVel = (_e69 - (_e70 - _e71)); + let _e66 = pos; + let _e67 = vPos; + let _e71 = params.rule2Distance; + if (distance(_e66, _e67) < _e71) { + let _e73 = colVel; + let _e74 = pos; + let _e75 = vPos; + colVel = (_e73 - (_e74 - _e75)); } - let _e74 = pos; - let _e75 = vPos; - let _e78 = params.rule3Distance; - if (distance(_e74, _e75) < _e78) { - let _e80 = cVel; - let _e81 = vel; - cVel = (_e80 + _e81); - let _e83 = cVelCount; - cVelCount = (_e83 + 1); + let _e78 = pos; + let _e79 = vPos; + let _e83 = params.rule3Distance; + if (distance(_e78, _e79) < _e83) { + let _e85 = cVel; + let _e86 = vel; + cVel = (_e85 + _e86); + let _e88 = cVelCount; + cVelCount = (_e88 + 1); } continuing { - let _e86 = i; - i = (_e86 + 1u); + let _e91 = i; + i = (_e91 + 1u); } } - let _e89 = cMassCount; - if (_e89 > 0) { - let _e92 = cMass; - let _e93 = cMassCount; - let _e97 = vPos; - cMass = ((_e92 / vec2(f32(_e93))) - _e97); + let _e94 = cMassCount; + if (_e94 > 0) { + let _e97 = cMass; + let _e98 = cMassCount; + let _e102 = vPos; + cMass = ((_e97 / vec2(f32(_e98))) - _e102); } - let _e99 = cVelCount; - if (_e99 > 0) { - let _e102 = cVel; - let _e103 = cVelCount; - cVel = (_e102 / vec2(f32(_e103))); + let _e104 = cVelCount; + if (_e104 > 0) { + let _e107 = cVel; + let _e108 = cVelCount; + cVel = (_e107 / vec2(f32(_e108))); } - let _e107 = vVel; - let _e108 = cMass; - let _e110 = params.rule1Scale; - let _e113 = colVel; - let _e115 = params.rule2Scale; - let _e118 = cVel; - let _e120 = params.rule3Scale; - vVel = (((_e107 + (_e108 * _e110)) + (_e113 * _e115)) + (_e118 * _e120)); - let _e123 = vVel; - let _e125 = vVel; - vVel = (normalize(_e123) * clamp(length(_e125), 0.0, 0.10000000149011612)); - let _e131 = vPos; - let _e132 = vVel; - let _e134 = params.deltaT; - vPos = (_e131 + (_e132 * _e134)); - let _e138 = vPos.x; - if (_e138 < -1.0) { + let _e112 = vVel; + let _e113 = cMass; + let _e116 = params.rule1Scale; + let _e119 = colVel; + let _e122 = params.rule2Scale; + let _e125 = cVel; + let _e128 = params.rule3Scale; + vVel = (((_e112 + (_e113 * _e116)) + (_e119 * _e122)) + (_e125 * _e128)); + let _e131 = vVel; + let _e133 = vVel; + vVel = (normalize(_e131) * clamp(length(_e133), 0.0, 0.10000000149011612)); + let _e139 = vPos; + let _e140 = vVel; + let _e143 = params.deltaT; + vPos = (_e139 + (_e140 * _e143)); + let _e147 = vPos.x; + if (_e147 < -1.0) { vPos.x = 1.0; } - let _e144 = vPos.x; - if (_e144 > 1.0) { + let _e153 = vPos.x; + if (_e153 > 1.0) { vPos.x = -1.0; } - let _e150 = vPos.y; - if (_e150 < -1.0) { + let _e159 = vPos.y; + if (_e159 < -1.0) { vPos.y = 1.0; } - let _e156 = vPos.y; - if (_e156 > 1.0) { + let _e165 = vPos.y; + if (_e165 > 1.0) { vPos.y = -1.0; } - let _e164 = vPos; - particlesDst.particles[index].pos = _e164; - let _e168 = vVel; - particlesDst.particles[index].vel = _e168; + let _e174 = vPos; + particlesDst.particles[index].pos = _e174; + let _e179 = vVel; + particlesDst.particles[index].vel = _e179; return; } diff --git a/tests/out/wgsl/collatz.wgsl b/tests/out/wgsl/collatz.wgsl index ea16c79618..a25f795360 100644 --- a/tests/out/wgsl/collatz.wgsl +++ b/tests/out/wgsl/collatz.wgsl @@ -7,34 +7,37 @@ var v_indices: PrimeIndices; fn collatz_iterations(n_base: u32) -> u32 { var n: u32; - var i: u32 = 0u; + var i: u32; n = n_base; + i = 0u; loop { - let _e5 = n; - if (_e5 > 1u) { + let _e4 = n; + if (_e4 > 1u) { } else { break; } - let _e8 = n; - if ((_e8 % 2u) == 0u) { - let _e13 = n; - n = (_e13 / 2u); - } else { - let _e17 = n; - n = ((3u * _e17) + 1u); + { + let _e7 = n; + if ((_e7 % 2u) == 0u) { + let _e12 = n; + n = (_e12 / 2u); + } else { + let _e16 = n; + n = ((3u * _e16) + 1u); + } + let _e20 = i; + i = (_e20 + 1u); } - let _e21 = i; - i = (_e21 + 1u); } - let _e24 = i; - return _e24; + let _e23 = i; + return _e23; } @compute @workgroup_size(1, 1, 1) fn main(@builtin(global_invocation_id) global_id: vec3) { - let _e8 = v_indices.data[global_id.x]; - let _e9 = collatz_iterations(_e8); - v_indices.data[global_id.x] = _e9; + let _e9 = v_indices.data[global_id.x]; + let _e10 = collatz_iterations(_e9); + v_indices.data[global_id.x] = _e10; return; } diff --git a/tests/out/wgsl/globals.wgsl b/tests/out/wgsl/globals.wgsl index 147f6ec322..d961db81b2 100644 --- a/tests/out/wgsl/globals.wgsl +++ b/tests/out/wgsl/globals.wgsl @@ -1,14 +1,14 @@ -struct Foo { +struct FooStruct { v3_: vec3, v1_: f32, } -let Foo_2: bool = true; +const Foo_1: bool = true; var wg: array; var at_1: atomic; @group(0) @binding(1) -var alignment: Foo; +var alignment: FooStruct; @group(0) @binding(2) var dummy: array>; @group(0) @binding(3) @@ -27,13 +27,14 @@ fn test_msl_packed_vec3_as_arg(arg: vec3) { } fn test_msl_packed_vec3_() { - var idx: i32 = 1; + var idx: i32; alignment.v3_ = vec3(1.0); + idx = 1; alignment.v3_.x = 1.0; alignment.v3_.x = 2.0; - let _e23 = idx; - alignment.v3_[_e23] = 3.0; + let _e17 = idx; + alignment.v3_[_e17] = 3.0; let data = alignment; _ = data.v3_; _ = data.v3_.zx; @@ -46,26 +47,28 @@ fn test_msl_packed_vec3_() { @compute @workgroup_size(1, 1, 1) fn main() { - var Foo_1: f32 = 1.0; - var at: bool = true; + var Foo: f32; + var at: bool; test_msl_packed_vec3_(); - let _e16 = global_nested_arrays_of_matrices_4x2_[0][0]; - let _e23 = global_nested_arrays_of_matrices_2x4_[0][0][0]; - wg[7] = (_e16 * _e23).x; - let _e28 = global_mat; - let _e29 = global_vec; - wg[6] = (_e28 * _e29).x; - let _e37 = dummy[1].y; - wg[5] = _e37; + let _e8 = global_nested_arrays_of_matrices_4x2_[0][0]; + let _e16 = global_nested_arrays_of_matrices_2x4_[0][0][0]; + wg[7] = (_e8 * _e16).x; + let _e23 = global_mat; + let _e25 = global_vec; + wg[6] = (_e23 * _e25).x; + let _e35 = dummy[1].y; + wg[5] = _e35; let _e43 = float_vecs[0].w; wg[4] = _e43; - let _e47 = alignment.v1_; - wg[3] = _e47; - let _e52 = alignment.v3_.x; - wg[2] = _e52; + let _e49 = alignment.v1_; + wg[3] = _e49; + let _e56 = alignment.v3_.x; + wg[2] = _e56; alignment.v1_ = 4.0; wg[1] = f32(arrayLength((&dummy))); atomicStore((&at_1), 2u); + Foo = 1.0; + at = true; return; } diff --git a/tests/out/wgsl/interface.wgsl b/tests/out/wgsl/interface.wgsl index a17865c5a8..7c06d1db5f 100644 --- a/tests/out/wgsl/interface.wgsl +++ b/tests/out/wgsl/interface.wgsl @@ -40,8 +40,9 @@ fn compute(@builtin(global_invocation_id) global_id: vec3, @builtin(local_i @vertex fn vertex_two_structs(in1_: Input1_, in2_: Input2_) -> @builtin(position) @invariant vec4 { - var index: u32 = 2u; + var index: u32; - let _e9: u32 = index; - return vec4(f32(in1_.index), f32(in2_.index), f32(_e9), 0.0); + index = 2u; + let _e8: u32 = index; + return vec4(f32(in1_.index), f32(in2_.index), f32(_e8), 0.0); } diff --git a/tests/out/wgsl/lexical-scopes.wgsl b/tests/out/wgsl/lexical-scopes.wgsl index 39f033cb1e..3d645f5ae9 100644 --- a/tests/out/wgsl/lexical-scopes.wgsl +++ b/tests/out/wgsl/lexical-scopes.wgsl @@ -20,17 +20,20 @@ fn loopLexicalScope(a_2: bool) { } fn forLexicalScope(a_3: f32) { - var a_4: i32 = 0; + var a_4: i32; + a_4 = 0; loop { let _e4 = a_4; if (_e4 < 1) { } else { break; } + { + } continuing { - let _e7 = a_4; - a_4 = (_e7 + 1); + let _e8 = a_4; + a_4 = (_e8 + 1); } } let test_4 = (false == true); @@ -42,6 +45,8 @@ fn whileLexicalScope(a_5: i32) { } else { break; } + { + } } let test_5 = (a_5 == 1); } diff --git a/tests/out/wgsl/module-scope.wgsl b/tests/out/wgsl/module-scope.wgsl new file mode 100644 index 0000000000..91a13718dd --- /dev/null +++ b/tests/out/wgsl/module-scope.wgsl @@ -0,0 +1,26 @@ +struct S { + x: i32, +} + +const Value: i32 = 1; + +@group(0) @binding(0) +var Texture: texture_2d; +@group(0) @binding(1) +var Sampler: sampler; + +fn returns() -> S { + return S(Value); +} + +fn statement() { + return; +} + +fn call() { + statement(); + let _e0 = returns(); + let vf = f32(Value); + let s = textureSample(Texture, Sampler, vec2(vf)); +} + diff --git a/tests/out/wgsl/operators.wgsl b/tests/out/wgsl/operators.wgsl index 9b7d647e3f..4877049274 100644 --- a/tests/out/wgsl/operators.wgsl +++ b/tests/out/wgsl/operators.wgsl @@ -3,10 +3,10 @@ struct Foo { b: i32, } -let v_f32_one: vec4 = vec4(1.0, 1.0, 1.0, 1.0); -let v_f32_zero: vec4 = vec4(0.0, 0.0, 0.0, 0.0); -let v_f32_half: vec4 = vec4(0.5, 0.5, 0.5, 0.5); -let v_i32_one: vec4 = vec4(1, 1, 1, 1); +const v_f32_one: vec4 = vec4(1.0, 1.0, 1.0, 1.0); +const v_f32_zero: vec4 = vec4(0.0, 0.0, 0.0, 0.0); +const v_f32_half: vec4 = vec4(0.5, 0.5, 0.5, 0.5); +const v_i32_one: vec4 = vec4(1, 1, 1, 1); fn builtins() -> vec4 { let s1_ = select(0, 1, true); let s2_ = select(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), true); @@ -29,14 +29,14 @@ fn splat_assignment() -> vec2 { var a: vec2; a = vec2(2.0); - let _e7 = a; - a = (_e7 + vec2(1.0)); - let _e11 = a; - a = (_e11 - vec2(3.0)); + let _e4 = a; + a = (_e4 + vec2(1.0)); + let _e8 = a; + a = (_e8 - vec2(3.0)); + let _e12 = a; + a = (_e12 / vec2(4.0)); let _e15 = a; - a = (_e15 / vec2(4.0)); - let _e19 = a; - return _e19; + return _e15; } fn bool_cast(x: vec3) -> vec3 { @@ -61,8 +61,8 @@ fn constructors() -> f32 { _ = mat2x3(mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); _ = bitcast>(vec2(0u, 0u)); _ = mat2x3(mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - let _e75 = foo.a.x; - return _e75; + let _e71 = foo.a.x; + return _e71; } fn logical() { @@ -215,39 +215,41 @@ fn comparison() { } fn assignment() { - var a_1: i32 = 1; - var vec0_: vec3 = vec3(0, 0, 0); + var a_1: i32; + var vec0_: vec3; + a_1 = 1; + let _e3 = a_1; + a_1 = (_e3 + 1); let _e6 = a_1; - a_1 = (_e6 + 1); + a_1 = (_e6 - 1); + let _e8 = a_1; let _e9 = a_1; - a_1 = (_e9 - 1); + a_1 = (_e9 * _e8); + let _e11 = a_1; let _e12 = a_1; - let _e13 = a_1; - a_1 = (_e12 * _e13); + a_1 = (_e12 / _e11); let _e15 = a_1; - let _e16 = a_1; - a_1 = (_e15 / _e16); + a_1 = (_e15 % 1); let _e18 = a_1; - a_1 = (_e18 % 1); + a_1 = (_e18 & 0); let _e21 = a_1; - a_1 = (_e21 & 0); + a_1 = (_e21 | 0); let _e24 = a_1; - a_1 = (_e24 | 0); + a_1 = (_e24 ^ 0); let _e27 = a_1; - a_1 = (_e27 ^ 0); + a_1 = (_e27 << 2u); let _e30 = a_1; - a_1 = (_e30 << 2u); - let _e33 = a_1; - a_1 = (_e33 >> 1u); - let _e36 = a_1; - a_1 = (_e36 + 1); - let _e39 = a_1; - a_1 = (_e39 - 1); - let _e46 = vec0_.y; - vec0_.y = (_e46 + 1); - let _e51 = vec0_.y; - vec0_.y = (_e51 - 1); + a_1 = (_e30 >> 1u); + let _e32 = a_1; + a_1 = (_e32 + 1); + let _e35 = a_1; + a_1 = (_e35 - 1); + vec0_ = vec3(0, 0, 0); + let _e42 = vec0_.y; + vec0_.y = (_e42 + 1); + let _e47 = vec0_.y; + vec0_.y = (_e47 - 1); return; } @@ -263,10 +265,10 @@ fn negation_avoids_prefix_decrement() { @compute @workgroup_size(1, 1, 1) fn main() { - let _e4 = builtins(); - let _e5 = splat(); - let _e7 = bool_cast(vec4(1.0, 1.0, 1.0, 1.0).xyz); - let _e8 = constructors(); + let _e0 = builtins(); + let _e1 = splat(); + let _e4 = bool_cast(vec4(1.0, 1.0, 1.0, 1.0).xyz); + let _e5 = constructors(); logical(); arithmetic(); bit(); diff --git a/tests/out/wgsl/padding.wgsl b/tests/out/wgsl/padding.wgsl index 4f2b8d4b7d..a4c0a968df 100644 --- a/tests/out/wgsl/padding.wgsl +++ b/tests/out/wgsl/padding.wgsl @@ -26,8 +26,8 @@ var input3_: Test3_; @vertex fn vertex() -> @builtin(position) vec4 { - let _e6 = input1_.b; - let _e9 = input2_.b; + let _e4 = input1_.b; + let _e8 = input2_.b; let _e12 = input3_.b; - return (((vec4(1.0) * _e6) * _e9) * _e12); + return (((vec4(1.0) * _e4) * _e8) * _e12); } diff --git a/tests/out/wgsl/quad.wgsl b/tests/out/wgsl/quad.wgsl index 98a4c61068..b4cf4dd28d 100644 --- a/tests/out/wgsl/quad.wgsl +++ b/tests/out/wgsl/quad.wgsl @@ -3,7 +3,7 @@ struct VertexOutput { @builtin(position) position: vec4, } -let c_scale: f32 = 1.2000000476837158; +const c_scale: f32 = 1.2000000476837158; @group(0) @binding(0) var u_texture: texture_2d; diff --git a/tests/out/wgsl/shadow.wgsl b/tests/out/wgsl/shadow.wgsl index 8bb6b5813f..df042d9e1d 100644 --- a/tests/out/wgsl/shadow.wgsl +++ b/tests/out/wgsl/shadow.wgsl @@ -20,8 +20,8 @@ struct Light { color: vec4, } -let c_ambient: vec3 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); -let c_max_lights: u32 = 10u; +const c_ambient: vec3 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); +const c_max_lights: u32 = 10u; @group(0) @binding(0) var u_globals: Globals; @@ -43,8 +43,8 @@ fn fetch_shadow(light_id: u32, homogeneous_coords: vec4) -> f32 { let flip_correction = vec2(0.5, -0.5); let proj_correction = (1.0 / homogeneous_coords.w); let light_local = (((homogeneous_coords.xy * flip_correction) * proj_correction) + vec2(0.5, 0.5)); - let _e28 = textureSampleCompareLevel(t_shadow, sampler_shadow, light_local, i32(light_id), (homogeneous_coords.z * proj_correction)); - return _e28; + let _e24 = textureSampleCompareLevel(t_shadow, sampler_shadow, light_local, i32(light_id), (homogeneous_coords.z * proj_correction)); + return _e24; } @vertex @@ -56,70 +56,78 @@ fn vs_main(@location(0) position: vec4, @location(1) normal: vec4) -> let world_pos = (_e7 * vec4(position)); out.world_normal = (mat3x3(w[0].xyz, w[1].xyz, w[2].xyz) * vec3(normal.xyz)); out.world_position = world_pos; - let _e25 = u_globals.view_proj; - out.proj_position = (_e25 * world_pos); - let _e27 = out; - return _e27; + let _e26 = u_globals.view_proj; + out.proj_position = (_e26 * world_pos); + let _e28 = out; + return _e28; } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - var color: vec3 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); - var i: u32 = 0u; + var color: vec3; + var i: u32; let normal_1 = normalize(in.world_normal); + color = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i = 0u; loop { - let _e14 = i; - let _e17 = u_globals.num_lights.x; - if (_e14 < min(_e17, c_max_lights)) { + let _e7 = i; + let _e11 = u_globals.num_lights.x; + if (_e7 < min(_e11, c_max_lights)) { } else { break; } - let _e23 = i; - let light = s_lights[_e23]; - let _e26 = i; - let _e30 = fetch_shadow(_e26, (light.proj * in.world_position)); - let light_dir = normalize((light.pos.xyz - in.world_position.xyz)); - let diffuse = max(0.0, dot(normal_1, light_dir)); - let _e40 = color; - color = (_e40 + ((_e30 * diffuse) * light.color.xyz)); + { + let _e16 = i; + let light = s_lights[_e16]; + let _e19 = i; + let _e23 = fetch_shadow(_e19, (light.proj * in.world_position)); + let light_dir = normalize((light.pos.xyz - in.world_position.xyz)); + let diffuse = max(0.0, dot(normal_1, light_dir)); + let _e37 = color; + color = (_e37 + ((_e23 * diffuse) * light.color.xyz)); + } continuing { - let _e20 = i; - i = (_e20 + 1u); + let _e39 = i; + i = (_e39 + 1u); } } - let _e46 = color; - let _e50 = u_entity.color; - return (vec4(_e46, 1.0) * _e50); + let _e42 = color; + let _e47 = u_entity.color; + return (vec4(_e42, 1.0) * _e47); } @fragment fn fs_main_without_storage(in_1: VertexOutput) -> @location(0) vec4 { - var color_1: vec3 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); - var i_1: u32 = 0u; + var color_1: vec3; + var i_1: u32; let normal_2 = normalize(in_1.world_normal); + color_1 = vec3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); + i_1 = 0u; loop { - let _e14 = i_1; - let _e17 = u_globals.num_lights.x; - if (_e14 < min(_e17, c_max_lights)) { + let _e7 = i_1; + let _e11 = u_globals.num_lights.x; + if (_e7 < min(_e11, c_max_lights)) { } else { break; } - let _e23 = i_1; - let light_1 = u_lights[_e23]; - let _e26 = i_1; - let _e30 = fetch_shadow(_e26, (light_1.proj * in_1.world_position)); - let light_dir_1 = normalize((light_1.pos.xyz - in_1.world_position.xyz)); - let diffuse_1 = max(0.0, dot(normal_2, light_dir_1)); - let _e40 = color_1; - color_1 = (_e40 + ((_e30 * diffuse_1) * light_1.color.xyz)); + { + let _e16 = i_1; + let light_1 = u_lights[_e16]; + let _e19 = i_1; + let _e23 = fetch_shadow(_e19, (light_1.proj * in_1.world_position)); + let light_dir_1 = normalize((light_1.pos.xyz - in_1.world_position.xyz)); + let diffuse_1 = max(0.0, dot(normal_2, light_dir_1)); + let _e37 = color_1; + color_1 = (_e37 + ((_e23 * diffuse_1) * light_1.color.xyz)); + } continuing { - let _e20 = i_1; - i_1 = (_e20 + 1u); + let _e39 = i_1; + i_1 = (_e39 + 1u); } } - let _e46 = color_1; - let _e50 = u_entity.color; - return (vec4(_e46, 1.0) * _e50); + let _e42 = color_1; + let _e47 = u_entity.color; + return (vec4(_e42, 1.0) * _e47); } diff --git a/tests/out/wgsl/skybox.wgsl b/tests/out/wgsl/skybox.wgsl index c9be90196e..73d4da78a4 100644 --- a/tests/out/wgsl/skybox.wgsl +++ b/tests/out/wgsl/skybox.wgsl @@ -22,20 +22,20 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { tmp1_ = (i32(vertex_index) / 2); tmp2_ = (i32(vertex_index) & 1); - let _e10 = tmp1_; - let _e16 = tmp2_; - let pos = vec4(((f32(_e10) * 4.0) - 1.0), ((f32(_e16) * 4.0) - 1.0), 0.0, 1.0); + let _e9 = tmp1_; + let _e15 = tmp2_; + let pos = vec4(((f32(_e9) * 4.0) - 1.0), ((f32(_e15) * 4.0) - 1.0), 0.0, 1.0); let _e27 = r_data.view[0]; - let _e31 = r_data.view[1]; - let _e35 = r_data.view[2]; - let inv_model_view = transpose(mat3x3(_e27.xyz, _e31.xyz, _e35.xyz)); - let _e40 = r_data.proj_inv; - let unprojected = (_e40 * pos); + let _e32 = r_data.view[1]; + let _e37 = r_data.view[2]; + let inv_model_view = transpose(mat3x3(_e27.xyz, _e32.xyz, _e37.xyz)); + let _e43 = r_data.proj_inv; + let unprojected = (_e43 * pos); return VertexOutput(pos, (inv_model_view * unprojected.xyz)); } @fragment fn fs_main(in: VertexOutput) -> @location(0) vec4 { - let _e5 = textureSample(r_texture, r_sampler, in.uv); - return _e5; + let _e4 = textureSample(r_texture, r_sampler, in.uv); + return _e4; } diff --git a/tests/out/wgsl/texture-arg.wgsl b/tests/out/wgsl/texture-arg.wgsl index 09924d5eb6..6edf0250e1 100644 --- a/tests/out/wgsl/texture-arg.wgsl +++ b/tests/out/wgsl/texture-arg.wgsl @@ -4,8 +4,8 @@ var Texture: texture_2d; var Sampler: sampler; fn test(Passed_Texture: texture_2d, Passed_Sampler: sampler) -> vec4 { - let _e7 = textureSample(Passed_Texture, Passed_Sampler, vec2(0.0, 0.0)); - return _e7; + let _e5 = textureSample(Passed_Texture, Passed_Sampler, vec2(0.0, 0.0)); + return _e5; } @fragment diff --git a/tests/out/wgsl/type-alias.wgsl b/tests/out/wgsl/type-alias.wgsl new file mode 100644 index 0000000000..b9c551cc97 --- /dev/null +++ b/tests/out/wgsl/type-alias.wgsl @@ -0,0 +1,9 @@ +fn main() { + let a = vec3(0.0, 0.0, 0.0); + let c = vec3(0.0); + let b = vec3(vec2(0.0), 0.0); + let d = vec3(vec2(0.0), 0.0); + let e = vec3(d); + let f = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +} + diff --git a/tests/snapshots.rs b/tests/snapshots.rs index c38c23f8bc..34c881f0b6 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -548,6 +548,8 @@ fn convert_wgsl() { Targets::WGSL | Targets::GLSL | Targets::SPIRV | Targets::HLSL | Targets::METAL, ), ("lexical-scopes", Targets::WGSL), + ("type-alias", Targets::WGSL), + ("module-scope", Targets::WGSL), ]; for &(name, targets) in inputs.iter() { diff --git a/tests/wgsl-errors.rs b/tests/wgsl-errors.rs index 7085ac156e..917628b279 100644 --- a/tests/wgsl-errors.rs +++ b/tests/wgsl-errors.rs @@ -64,12 +64,12 @@ fn invalid_integer() { #[test] fn invalid_float() { check( - "let scale: f32 = 1.1.;", - r###"error: expected ';', found '.' - ┌─ wgsl:1:21 + "const scale: f32 = 1.1.;", + r###"error: expected identifier, found ';' + ┌─ wgsl:1:24 │ -1 │ let scale: f32 = 1.1.; - │ ^ expected ';' +1 │ const scale: f32 = 1.1.; + │ ^ expected identifier "###, ); @@ -78,12 +78,12 @@ fn invalid_float() { #[test] fn invalid_texture_sample_type() { check( - "let x: texture_2d;", + "const x: texture_2d;", r###"error: texture sample type must be one of f32, i32 or u32, but found bool - ┌─ wgsl:1:19 + ┌─ wgsl:1:21 │ -1 │ let x: texture_2d; - │ ^^^^ must be one of f32, i32 or u32 +1 │ const x: texture_2d; + │ ^^^^ must be one of f32, i32 or u32 "###, ); @@ -211,10 +211,10 @@ fn unexpected_constructor_parameters() { } "#, r#"error: unexpected components - ┌─ wgsl:3:27 + ┌─ wgsl:3:28 │ 3 │ _ = i32(0, 1); - │ ^^ unexpected components + │ ^ unexpected components "#, ); @@ -365,13 +365,13 @@ fn unknown_ident() { fn unknown_scalar_type() { check( r#" - let a: vec2; + const a: vec2; "#, r#"error: unknown scalar type: 'something' - ┌─ wgsl:2:25 + ┌─ wgsl:2:27 │ -2 │ let a: vec2; - │ ^^^^^^^^^ unknown scalar type +2 │ const a: vec2; + │ ^^^^^^^^^ unknown scalar type │ = note: Valid scalar types are f32, f64, i32, u32, bool @@ -383,13 +383,13 @@ fn unknown_scalar_type() { fn unknown_type() { check( r#" - let a: Vec; + const a: Vec = 10; "#, r#"error: unknown type: 'Vec' - ┌─ wgsl:2:20 + ┌─ wgsl:2:22 │ -2 │ let a: Vec; - │ ^^^ unknown type +2 │ const a: Vec = 10; + │ ^^^ unknown type "#, ); @@ -399,13 +399,13 @@ fn unknown_type() { fn unknown_storage_format() { check( r#" - let storage1: texture_storage_1d; + const storage1: texture_storage_1d; "#, r#"error: unknown storage format: 'rgba' - ┌─ wgsl:2:46 + ┌─ wgsl:2:48 │ -2 │ let storage1: texture_storage_1d; - │ ^^^^ unknown storage format +2 │ const storage1: texture_storage_1d; + │ ^^^^ unknown storage format "#, ); @@ -505,11 +505,11 @@ fn unknown_local_function() { for (a();;) {} } "#, - r#"error: unknown local function `a` + r#"error: no definition in scope for identifier: 'a' ┌─ wgsl:3:22 │ 3 │ for (a();;) {} - │ ^ unknown local function + │ ^ unknown identifier "#, ); @@ -519,13 +519,13 @@ fn unknown_local_function() { fn let_type_mismatch() { check( r#" - let x: i32 = 1.0; + const x: i32 = 1.0; "#, - r#"error: the type of `x` is expected to be `f32` - ┌─ wgsl:2:17 + r#"error: the type of `x` is expected to be `i32`, but got `f32` + ┌─ wgsl:2:19 │ -2 │ let x: i32 = 1.0; - │ ^ definition of `x` +2 │ const x: i32 = 1.0; + │ ^ definition of `x` "#, ); @@ -536,7 +536,7 @@ fn let_type_mismatch() { let x: f32 = true; } "#, - r#"error: the type of `x` is expected to be `bool` + r#"error: the type of `x` is expected to be `f32`, but got `bool` ┌─ wgsl:3:21 │ 3 │ let x: f32 = true; @@ -548,29 +548,16 @@ fn let_type_mismatch() { #[test] fn var_type_mismatch() { - check( - r#" - let x: f32 = 1; - "#, - r#"error: the type of `x` is expected to be `i32` - ┌─ wgsl:2:17 - │ -2 │ let x: f32 = 1; - │ ^ definition of `x` - -"#, - ); - check( r#" fn foo() { - var x: f32 = 1u32; + var x: f32 = 1u; } "#, - r#"error: the type of `x` is expected to be `u32` + r#"error: the type of `x` is expected to be `f32`, but got `u32` ┌─ wgsl:3:21 │ -3 │ var x: f32 = 1u32; +3 │ var x: f32 = 1u; │ ^ definition of `x` "#, @@ -640,11 +627,11 @@ fn reserved_keyword() { r#" var bool: bool = true; "#, - r###"error: name `bool: bool = true;` is a reserved keyword + r###"error: name `bool` is a reserved keyword ┌─ wgsl:2:17 │ 2 │ var bool: bool = true; - │ ^^^^^^^^^^^^^^^^^^ definition of `bool: bool = true;` + │ ^^^^ definition of `bool` "###, ); @@ -652,16 +639,16 @@ fn reserved_keyword() { // global constant check( r#" - let break: bool = true; + const break: bool = true; fn foo() { var foo = break; } "#, r###"error: name `break` is a reserved keyword - ┌─ wgsl:2:17 + ┌─ wgsl:2:19 │ -2 │ let break: bool = true; - │ ^^^^^ definition of `break` +2 │ const break: bool = true; + │ ^^^^^ definition of `break` "###, ); @@ -743,19 +730,19 @@ fn reserved_keyword() { #[test] fn module_scope_identifier_redefinition() { - // let + // const check( r#" - let foo: bool = true; - let foo: bool = true; + const foo: bool = true; + const foo: bool = true; "#, r###"error: redefinition of `foo` - ┌─ wgsl:2:17 + ┌─ wgsl:2:19 │ -2 │ let foo: bool = true; - │ ^^^ previous definition of `foo` -3 │ let foo: bool = true; - │ ^^^ redefinition of `foo` +2 │ const foo: bool = true; + │ ^^^ previous definition of `foo` +3 │ const foo: bool = true; + │ ^^^ redefinition of `foo` "###, ); @@ -765,13 +752,13 @@ fn module_scope_identifier_redefinition() { var foo: bool = true; var foo: bool = true; "#, - r###"error: redefinition of `foo: bool = true;` + r###"error: redefinition of `foo` ┌─ wgsl:2:17 │ 2 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ previous definition of `foo: bool = true;` + │ ^^^ previous definition of `foo` 3 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ redefinition of `foo: bool = true;` + │ ^^^ redefinition of `foo` "###, ); @@ -780,15 +767,15 @@ fn module_scope_identifier_redefinition() { check( r#" var foo: bool = true; - let foo: bool = true; + const foo: bool = true; "#, r###"error: redefinition of `foo` ┌─ wgsl:2:17 │ 2 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ previous definition of `foo: bool = true;` -3 │ let foo: bool = true; - │ ^^^ redefinition of `foo` + │ ^^^ previous definition of `foo` +3 │ const foo: bool = true; + │ ^^^ redefinition of `foo` "###, ); @@ -813,14 +800,14 @@ fn module_scope_identifier_redefinition() { // let and function check( r#" - let foo: bool = true; + const foo: bool = true; fn foo() {} "#, r###"error: redefinition of `foo` - ┌─ wgsl:2:17 + ┌─ wgsl:2:19 │ -2 │ let foo: bool = true; - │ ^^^ previous definition of `foo` +2 │ const foo: bool = true; + │ ^^^ previous definition of `foo` 3 │ fn foo() {} │ ^^^ redefinition of `foo` @@ -937,7 +924,7 @@ fn invalid_arrays() { check_validation! { "type Bad = array;", r#" - let length: f32 = 2.718; + const length: f32 = 2.718; type Bad = array; "#: Err(naga::valid::ValidationError::Type { @@ -1606,11 +1593,11 @@ fn binary_statement() { 3 + 5; } ", - r###"error: expected assignment or increment/decrement, found '3 + 5' - ┌─ wgsl:3:13 + r###"error: expected assignment or increment/decrement, found ';' + ┌─ wgsl:3:18 │ 3 │ 3 + 5; - │ ^^^^^ expected assignment or increment/decrement + │ ^ expected assignment or increment/decrement "###, ); @@ -1655,3 +1642,116 @@ fn assign_to_let() { "###, ); } + +#[test] +fn recursive_function() { + check( + " + fn f() { + f(); + } + ", + r###"error: declaration of `f` is recursive + ┌─ wgsl:2:12 + │ +2 │ fn f() { + │ ^ +3 │ f(); + │ ^ uses itself here + +"###, + ); +} + +#[test] +fn cyclic_function() { + check( + " + fn f() { + g(); + } + fn g() { + f(); + } + ", + r###"error: declaration of `f` is cyclic + ┌─ wgsl:2:12 + │ +2 │ fn f() { + │ ^ +3 │ g(); + │ ^ uses `g` +4 │ } +5 │ fn g() { + │ ^ +6 │ f(); + │ ^ ending the cycle + +"###, + ); +} + +#[test] +fn switch_signed_unsigned_mismatch() { + check( + " + fn x(y: u32) { + switch y { + case 1: {} + } + } + ", + r###"error: invalid switch value + ┌─ wgsl:4:16 + │ +4 │ case 1: {} + │ ^ expected unsigned integer + │ + = note: suffix the integer with a `u`: '1u' + +"###, + ); + + check( + " + fn x(y: i32) { + switch y { + case 1u: {} + } + } + ", + r###"error: invalid switch value + ┌─ wgsl:4:16 + │ +4 │ case 1u: {} + │ ^^ expected signed integer + │ + = note: remove the `u` suffix: '1' + +"###, + ); +} + +#[test] +fn function_returns_void() { + check( + " + fn x() { + let a = vec2(1, 2u); + } + + fn b() { + let a = x(); + } + ", + r###"error: function does not return any value + ┌─ wgsl:7:18 + │ +7 │ let a = x(); + │ ^ + │ + = note: perhaps you meant to call the function in a separate statement? + +"###, + ) +}