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 `expr_handle` hasn't yet been calculated, call + /// [`grow`](Self::grow) to ensure it is covered. /// - /// If the type of the expression hasn't yet been calculated a - /// [`grow`](Self::grow) is performed instead + /// 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 super::{Error, ExpressionContext, Lexer, Parser, Rule, Span, Token}; - -/// 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, - }, +use crate::{Handle, Span}; + +use super::{ast, Error, ExpressionContext, Lowerer, OutputContext}; +use crate::proc::TypeResolution; + +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 }) - } - 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 }) +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::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 })) - } - (Token::Paren('<'), ConstructorType::PartialMatrix { columns, rows }) => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - match kind { - ScalarKind::Float => Ok(Some(ConstructorType::Matrix { - columns, - rows, - width, - })), - _ => Err(Error::BadMatrixScalarKind(span, kind, width)), - } - } - (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() - }; - - Ok(Some(ConstructorType::Array { base, size, stride })) +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), + }, } - (_, partial) => Ok(Some(partial)), } } -/// 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)); - } - None => return Ok(None), - } - } - }, - }; - - 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); - } - } +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, + }, +} - enum Components<'a> { - None, - One { - component: Handle, - span: Span, - ty: &'a TypeInner, - }, - Many { - components: Vec>, - spans: Vec, - first_component_ty: &'a TypeInner, - }, +impl Components<'_> { + fn into_components_vec(self) -> Vec> { + match self { + Self::None => vec![], + Self::One { component, .. } => vec![component], + Self::Many { components, .. } => components, + } } +} - impl<'a> Components<'a> { - fn into_components_vec(self) -> Vec> { - match self { - Components::None => vec![], - Components::One { component, .. } => vec![component], - Components::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(); - 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), + ctx.grow_types(component)?; + let ty = &ctx.typifier[component]; + + ComponentsHandle::Many { + components, + spans, + first_component_ty: ty, + } } - } - [component, ..] => { - ctx.resolve_type(component)?; - Components::Many { - components, - spans, - first_component_ty: ctx.typifier.get(component, ctx.types), + }; + + 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)), + }; } - } - }; - - 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, - .. - }, - .. + // 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), }, - 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, - .. + + // 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), }, - ConstructorType::Matrix { - columns: dst_columns, - rows: dst_rows, - width: 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, }, - ) 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, - .. + + // 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), }, - ConstructorType::PartialMatrix { - columns: dst_columns, - rows: dst_rows, + + // 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, }, - ) 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 { .. }, - .. + + // Vector constructor (splat) - infer type + ( + Components::One { + component, + ty_inner: &crate::TypeInner::Scalar { .. }, + .. + }, + ConcreteConstructor::PartialVector { size }, + ) => crate::Expression::Splat { + size, + value: component, }, - ConstructorType::PartialVector { size }, - ) => Expression::Splat { - size, - value: component, - }, - - // Vector constructor (splat) - ( - Components::One { - component, - ty: - &TypeInner::Scalar { - kind: src_kind, - width: src_width, - .. + + // 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, }, - .. - }, - ConstructorType::Vector { + ), + ) if dst_kind == src_kind || dst_width == src_width => crate::Expression::Splat { 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 { .. }, - .. + value: component, }, - 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, - }, + // Vector constructor (by elements) + ( + Components::Many { + components, + first_component_ty_inner: + &crate::TypeInner::Scalar { kind, width } + | &crate::TypeInner::Vector { kind, width, .. }, + .. }, - 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(); + 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 } + } - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Matrix { + // 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, }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } + ), + ) => { + 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, + }); + crate::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 { + // 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, }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } + ), + ) => { + let ty = ctx.ensure_type_exists(crate::TypeInner::Matrix { + columns, + rows, + width, + }); + crate::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() - }, - }; + // Array constructor - infer type + (components, ConcreteConstructor::PartialArray) => { + let components = components.into_components_vec(); - let ty = ctx - .types - .insert(Type { name: None, inner }, Default::default()); + let base = ctx.register_type(components[0])?; - Expression::Compose { ty, components } - } + 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); - // 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 } - } + crate::Expression::Compose { ty, components } + } - // Struct constructor - (components, ConstructorType::Struct(ty)) => Expression::Compose { - ty, - components: components.into_components_vec(), - }, + // Array constructor + (components, ConcreteConstructor::Type(ty, &crate::TypeInner::Array { .. })) => { + let components = components.into_components_vec(); + crate::Expression::Compose { ty, components } + } - // ERRORS + // Struct constructor + (components, ConcreteConstructor::Type(ty, &crate::TypeInner::Struct { .. })) => { + crate::Expression::Compose { + ty, + components: components.into_components_vec(), + } + } - // 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), - }); - } + // ERRORS - // 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, - })); - } + // 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()), + }); + } - // 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)); - } - }; + // 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)); + } - let span = NagaSpan::from(parser.pop_rule_span(lexer)); - Ok(Some(ctx.expressions.append(expr, 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) + } + + /// 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())?) + } + 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), + }; + + Ok(c) + } } 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,35 +234,42 @@ 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> { - let mut start_byte_offset = self.current_byte_offset(); - loop { - let (token, rest) = consume_token(self.input, false); - 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); - } - } - } + 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, true); + let (token, rest) = consume_token(self.input, generic); self.input = rest; match token { Token::Trivia => start_byte_offset = self.current_byte_offset(), - _ => return (token, start_byte_offset..self.current_byte_offset()), + _ => { + self.last_end_offset = self.current_byte_offset(); + return (token, self.span_from(start_byte_offset)); + } } } } @@ -265,10 +280,7 @@ impl<'a> Lexer<'a> { 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())], - 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())], + labels: vec![(bad_span, "invalid identifier".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::UnknownAddressSpace(bad_span) => ParseError { + message: format!("unknown address space: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown address space".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::UnknownAttribute(bad_span) => ParseError { + message: format!("unknown attribute: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown attribute".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::UnknownBuiltin(bad_span) => ParseError { + message: format!("unknown builtin: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown builtin".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::UnknownAccess(bad_span) => ParseError { + message: format!("unknown access: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown access".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::UnknownStorageFormat(bad_span) => ParseError { + message: format!("unknown storage format: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown storage format".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::UnknownConservativeDepth(bad_span) => ParseError { + message: format!("unknown conservative depth: '{}'", &source[bad_span]), + labels: vec![(bad_span, "unknown conservative depth".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())], + Error::UnknownType(bad_span) => ParseError { + message: format!("unknown type: '{}'", &source[bad_span]), + labels: vec![(bad_span, "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(), - )], - notes: vec![], - }, - Error::UnknownLocalFunction(ref span) => ParseError { - message: format!("unknown local function `{}`", &source[span.clone()]), - labels: vec![(span.clone(), "unknown local function".into())], + labels: vec![(span, "input/output binding is not consistent".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())], + Error::TypeNotConstructible(span) => ParseError { + message: format!("type `{}` is not constructible", &source[span]), + labels: vec![(span, "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())], - 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 - ), - labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), - )], + labels: vec![(span, "type can't be inferred".into())], notes: vec![], }, - Error::MissingType(ref name_span) => ParseError { - message: format!("variable `{}` needs a type", &source[name_span.clone()]), + 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::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> 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) + } +} + +/// 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<'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<'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) } } -struct StatementContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, +/// 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, } } -} -struct SamplingContext { - image: Handle, - arrayed: bool, + fn as_output(&mut self) -> OutputContext<'a, '_, '_> { + OutputContext { + ast_expressions: self.ast_expressions, + globals: self.globals, + types: self.types, + module: self.module, + } + } } -struct ExpressionContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, +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>, + 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( + fn as_output(&mut self) -> OutputContext<'a, '_, '_> { + OutputContext { + ast_expressions: self.ast_expressions, + globals: self.globals, + types: self.types, + module: self.module, + } + } + + /// 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<&crate::TypeInner, Error<'a>> { + ) -> 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.constants, - types: self.types, - global_vars: self.global_vars, + constants: &self.module.constants, + types: &self.module.types, + global_vars: &self.module.global_variables, local_vars: self.local_vars, - functions: self.functions, + functions: &self.module.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)), - } + self.typifier + .grow(handle, self.naga_expressions, &resolve_ctx) + .map_err(Error::InvalidResolve)?; + Ok(self) } - fn prepare_sampling( - &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)), - }, - }) + fn resolved_inner(&self, handle: Handle) -> &crate::TypeInner { + self.typifier[handle].inner_with(&self.module.types) } - fn parse_binary_op( + fn image_data( &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); + image: Handle, + span: 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)), } - Ok(accumulator) } - fn parse_binary_splat_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 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), - )); + 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) } /// 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))) + + Ok(arguments) } - fn parse_atomic_helper<'a>( + /// Expects [`Rule::PrimaryExpr`] or [`Rule::SingularExpr`] on top; does not pop it. + /// Expects `name` to be consumed (not in lexer). + fn function_call<'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 }, + name: &'a str, + name_span: Span, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + assert!(self.rules.last().is_some()); + + 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()?; + let expr = self.general_expression(lexer, ctx.reborrow())?; + lexer.close_arguments()?; + + ast::Expression::Bitcast { + expr, + to, + ty_span: 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, }, - NagaSpan::UNDEFINED, - ), - comparison: false, - }, - _ => return Err(Error::InvalidAtomicOperandType(value_span)), + arguments, + } + } }; - 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) + let span = self.peek_rule_span(lexer); + let expr = ctx.expressions.append(expr, span); + Ok(expr) } - /// 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>( + fn ident_expr<'a>( &mut self, - lexer: &mut Lexer<'a>, name: &'a str, - mut ctx: ExpressionContext<'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, + 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) } - } 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)), - }; + fn primary_expression<'a>( + &mut self, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + self.push_rule_span(Rule::PrimaryExpr, lexer); - 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), + let expr = match lexer.peek() { + (Token::Paren('('), _) => { + let _ = lexer.next(); + let expr = self.general_expression(lexer, ctx.reborrow())?; + lexer.expect(Token::Paren(')'))?; + self.pop_rule_span(lexer); + return Ok(expr); + } + (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) => { + let start = lexer.start_byte_offset(); + let _ = lexer.next(); + + 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) } - "textureSampleCompareLevel" => { + } + 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 postfix<'a>( + &mut self, + span_start: usize, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, '_>, + expr: Handle>, + ) -> Result>, Error<'a>> { + let mut expr = expr; + + loop { + let expression = match lexer.peek().0 { + Token::Separator('.') => { 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), - } + let field = lexer.next_ident()?; + + ast::Expression::Member { base: expr, field } } - "textureGather" => { + Token::Paren('[') => { 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, - )?; - - 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, - } - } - 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)); - } - 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) - } - - fn parse_const_expression<'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) - } - - fn parse_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 - 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())?; - lexer.expect(Token::Paren(')'))?; - self.pop_rule_span(lexer); - 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(word), span) => { - if let Some(definition) = ctx.symbol_table.lookup(word) { - let _ = lexer.next(); - self.pop_rule_span(lexer); - - *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)); - } - } - } - other => return Err(Error::Unexpected(other.1, ExpectedToken::PrimaryExpression)), - }; - Ok(expr) - } - - fn parse_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); - - 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()?; - - // 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 - } - 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(']'))?; - - // 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, - } - } + let index = self.general_expression(lexer, ctx.reborrow())?; + lexer.expect(Token::Paren(']'))?; + + 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>( - &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)) - } - - fn parse_general_expression<'a>( + fn general_expression<'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)) + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + self.general_expression_with_span(lexer, ctx.reborrow()) + .map(|(expr, _)| expr) } - fn parse_general_expression_for_reference<'a>( + fn general_expression_with_span<'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>( - &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>( + fn 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)? - } - "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, - )?, + 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)? + } "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, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result>, Error<'a>> { + self.push_rule_span(Rule::TypeDecl, lexer); + + let (name, span) = lexer.next_ident_with_span()?; + + let ty = match self.type_decl_impl(lexer, name, ctx.reborrow())? { + Some(ty) => ty, 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)), - } + ctx.unresolved.insert(ast::Dependency { + ident: name, + usage: span, + }); + ast::Type::User(ast::Ident { 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>> { - 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, 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: 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 context: StatementContext<'a, '_, 'out>, - block: &'out mut crate::Block, - is_uniform_control_flow: bool, + 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,760 +3096,2349 @@ 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, + }); + + let (block, span) = self.block(lexer, ctx.reborrow())?; + body.stmts.push(ast::Statement { + kind: ast::StatementKind::Block(block), + span, + }); + + ast::StatementKind::Loop { + body, + continuing: ast::Block::default(), + break_if: None, + } + } + "for" => { + let _ = lexer.next(); + lexer.expect(Token::Paren('('))?; + + ctx.local_table.push_scope(); + + if !lexer.skip(Token::Separator(';')) { + let num_statements = block.stmts.len(); + let (_, span) = lexer.capture_span(|lexer| { + self.statement(lexer, ctx.reborrow(), block) + })?; + + 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 = ast::Block::default(); + if !lexer.skip(Token::Separator(';')) { + let (condition, span) = lexer.capture_span(|lexer| { + let condition = self.general_expression(lexer, ctx.reborrow())?; + lexer.expect(Token::Separator(';'))?; + Ok(condition) + })?; + 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: ast::Block::default(), + reject, + }, + span, + }); + }; + + let mut continuing = ast::Block::default(); + if !lexer.skip(Token::Paren(')')) { + self.function_call_or_assignment_statement( + lexer, + ctx.reborrow(), + &mut continuing, + )?; + lexer.expect(Token::Paren(')'))?; + } + + let (block, span) = self.block(lexer, ctx.reborrow())?; + body.stmts.push(ast::Statement { + kind: ast::StatementKind::Block(block), + span, + }); + + ctx.local_table.pop_scope(); + + ast::StatementKind::Loop { + body, + continuing, + break_if: None, + } + } + "break" => { + 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 { + let span = span.until(&peeked_span); + return Err(Error::InvalidBreakIf(span)); + } + ast::StatementKind::Break + } + "continue" => { + let _ = lexer.next(); + ast::StatementKind::Continue + } + "discard" => { + let _ = lexer.next(); + ast::StatementKind::Kill + } + // assignment or a function call + _ => { + self.function_call_or_assignment_statement(lexer, ctx.reborrow(), block)?; + lexer.expect(Token::Separator(';'))?; + self.pop_rule_span(lexer); + return Ok(()); + } + }; + + let span = self.pop_rule_span(lexer); + block.stmts.push(ast::Statement { kind, span }); + } + _ => { + self.assignment_statement(lexer, ctx.reborrow(), block)?; + self.pop_rule_span(lexer); + } + } + Ok(()) + } + + fn r#loop<'a>( + &mut self, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result, Error<'a>> { + let _ = lexer.next(); + let mut body = ast::Block::default(); + let mut continuing = ast::Block::default(); + let mut break_if = None; + + lexer.expect(Token::Paren('{'))?; + + ctx.local_table.push_scope(); + + loop { + if lexer.skip(Token::Word("continuing")) { + // Branch for the `continuing` block, this must be + // the last thing in the loop body + + // Expect a opening brace to start the continuing block + lexer.expect(Token::Paren('{'))?; + loop { + if lexer.skip(Token::Word("break")) { + // Branch for the `break if` statement, this statement + // has the form `break if ;` and must be the last + // statement in a continuing block + + // The break must be followed by an `if` to form + // the break if + lexer.expect(Token::Word("if"))?; + + let condition = self.general_expression(lexer, ctx.reborrow())?; + // Set the condition of the break if to the newly parsed + // expression + break_if = Some(condition); + + // 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 + lexer.expect(Token::Paren('}'))?; + // Stop parsing the continuing block + break; + } else if lexer.skip(Token::Paren('}')) { + // If we encounter a closing brace it means we have reached + // the end of the continuing block and should stop processing + break; + } else { + // Otherwise try to parse a statement + self.statement(lexer, ctx.reborrow(), &mut continuing)?; + } + } + // Since the continuing block must be the last part of the loop body, + // we expect to see a closing brace to end the loop body + lexer.expect(Token::Paren('}'))?; + break; + } + if lexer.skip(Token::Paren('}')) { + // If we encounter a closing brace it means we have reached + // the end of the loop body and should stop processing + break; + } + // Otherwise try to parse a statement + self.statement(lexer, ctx.reborrow(), &mut body)?; + } + + ctx.local_table.pop_scope(); + + Ok(ast::StatementKind::Loop { + body, + continuing, + break_if, + }) + } + + /// compound_statement + fn block<'a>( + &mut self, + lexer: &mut Lexer<'a>, + mut ctx: ParseExpressionContext<'a, '_, '_>, + ) -> Result<(ast::Block<'a>, Span), Error<'a>> { + self.push_rule_span(Rule::Block, lexer); + + ctx.local_table.push_scope(); + + let _ = lexer.next(); + let mut statements = ast::Block::default(); + while !lexer.skip(Token::Paren('}')) { + self.statement(lexer, ctx.reborrow(), &mut statements)?; + } + + ctx.local_table.pop_scope(); + + let span = self.pop_rule_span(lexer); + Ok((statements, span)) + } + + fn varying_binding<'a>( + &mut self, + lexer: &mut Lexer<'a>, + ) -> Result, Error<'a>> { + let mut bind_parser = BindingParser::default(); + self.push_rule_span(Rule::Attribute, lexer); + + while lexer.skip(Token::Attribute) { + let (word, span) = lexer.next_ident_with_span()?; + bind_parser.parse(lexer, word, span)?; + } + + let span = self.pop_rule_span(lexer); + bind_parser.finish(span) + } + + fn function_decl<'a>( + &mut self, + lexer: &mut Lexer<'a>, + out: &mut ast::TranslationUnit<'a>, + dependencies: &mut FastHashSet>, + ) -> Result, Error<'a>> { + self.push_rule_span(Rule::FunctionDecl, lexer); + // read function name + 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('('))?; + let mut ready = true; + while !lexer.skip(Token::Paren(')')) { + if !ready { + return Err(Error::Unexpected( + lexer.next().1, + ExpectedToken::Token(Token::Separator(',')), + )); + } + 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 binding = self.varying_binding(lexer)?; + let ty = self.type_decl(lexer, ctx.reborrow())?; + Some(ast::FunctionResult { ty, binding }) + } else { + None + }; + + // read body + let body = self.block(lexer, ctx)?.0; + + let fun = ast::Function { + entry_point: None, + name: fun_name, + arguments, + result, + body, + locals, + }; + + // done + self.pop_rule_span(lexer); + + Ok(fun) + } + + fn global_decl<'a>( + &mut self, + lexer: &mut Lexer<'a>, + out: &mut ast::TranslationUnit<'a>, + ) -> Result<(), Error<'a>> { + // read attributes + let mut binding = None; + let mut stage = None; + let mut workgroup_size = [0u32; 3]; + let mut early_depth_test = None; + let (mut bind_index, mut bind_group) = (None, None); + + self.push_rule_span(Rule::Attribute, lexer); + while lexer.skip(Token::Attribute) { + match lexer.next_ident_with_span()? { + ("binding", _) => { + lexer.expect(Token::Paren('('))?; + bind_index = Some(Self::non_negative_i32_literal(lexer)?); + lexer.expect(Token::Paren(')'))?; + } + ("group", _) => { + lexer.expect(Token::Paren('('))?; + bind_group = Some(Self::non_negative_i32_literal(lexer)?); + lexer.expect(Token::Paren(')'))?; + } + ("vertex", _) => { + stage = Some(crate::ShaderStage::Vertex); + } + ("fragment", _) => { + stage = Some(crate::ShaderStage::Fragment); + } + ("compute", _) => { + stage = Some(crate::ShaderStage::Compute); + } + ("workgroup_size", _) => { + lexer.expect(Token::Paren('('))?; + workgroup_size = [1u32; 3]; + for (i, size) in workgroup_size.iter_mut().enumerate() { + *size = Self::generic_non_negative_int_literal(lexer)?; + match lexer.next() { + (Token::Paren(')'), _) => break, + (Token::Separator(','), _) if i != 2 => (), + other => { + return Err(Error::Unexpected( + other.1, + ExpectedToken::WorkgroupSizeSeparator, + )) + } + } + } + } + ("early_depth_test", _) => { + let conservative = if lexer.skip(Token::Paren('(')) { + let (ident, ident_span) = lexer.next_ident_with_span()?; + let value = conv::map_conservative_depth(ident, ident_span)?; + lexer.expect(Token::Paren(')'))?; + Some(value) + } else { + None + }; + early_depth_test = Some(crate::EarlyDepthTest { conservative }); + } + (_, word_span) => return Err(Error::UnknownAttribute(word_span)), + } + } + + let attrib_span = self.pop_rule_span(lexer); + match (bind_group, bind_index) { + (Some(group), Some(index)) => { + binding = Some(crate::ResourceBinding { + group, + binding: index, + }); + } + (Some(_), None) => return Err(Error::MissingAttribute("binding", attrib_span)), + (None, Some(_)) => return Err(Error::MissingAttribute("group", attrib_span)), + (None, None) => {} + } + + 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(); + let kind = match lexer.next() { + (Token::Separator(';'), _) => None, + (Token::Word("struct"), _) => { + 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.type_decl(lexer, ctx)?; + lexer.expect(Token::Separator(';'))?; + Some(ast::GlobalDeclKind::Type(ast::TypeAlias { name, ty })) + } + (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 init = self.general_expression(lexer, ctx)?; + lexer.expect(Token::Separator(';'))?; + + Some(ast::GlobalDeclKind::Const(ast::Const { name, ty, init })) + } + (Token::Word("var"), _) => { + let mut var = self.variable_decl(lexer, ctx)?; + var.binding = binding.take(); + Some(ast::GlobalDeclKind::Var(var)) + } + (Token::Word("fn"), _) => { + 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 + })) + } + (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(()), + // we had the attribute but no var? + Some(_) => Err(Error::Other), + } + } + + pub fn parse(&mut self, source: &str) -> Result { + self.reset(); + + let mut lexer = Lexer::new(source); + let mut tu = ast::TranslationUnit::default(); + loop { + match self.global_decl(&mut lexer, &mut tu) { + Err(error) => return Err(error.as_parse_error(lexer.source)), + 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); - body.extend_block(self.parse_block(lexer, context.reborrow(), false)?); + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; - Some(crate::Statement::Loop { - body, - continuing: crate::Block::new(), - break_if: None, - }) - } - "for" => { - let _ = lexer.next(); - lexer.expect(Token::Paren('('))?; - // Push a lexical scope for the for loop - context.symbol_table.push_scope(); + let compare = self.expression(args.next()?, ctx.reborrow())?; - if !lexer.skip(Token::Separator(';')) { - let num_statements = block.len(); - let (_, span) = lexer.capture_span(|lexer| { - self.parse_statement( - lexer, - context.reborrow(), - block, - is_uniform_control_flow, - ) - })?; + let value = args.next()?; + let value_span = ctx.ast_expressions.get_span(value); + let value = self.expression(value, ctx.reborrow())?; + ctx.grow_types(value)?; - if block.len() != num_statements { - match *block.last().unwrap() { - crate::Statement::Store { .. } - | crate::Statement::Call { .. } => {} - _ => return Err(Error::InvalidForInitializer(span)), + 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 mut body = crate::Block::new(); - 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), - )?; - 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 { - condition, - accept: crate::Block::new(), - reject, + let result = ctx.interrupt_emitter(expression, span); + ctx.block.push( + crate::Statement::Atomic { + pointer, + fun: crate::AtomicFunction::Exchange { + compare: Some(compare), + }, + value, + result, }, - NagaSpan::from(span), + span, ); - }; + return Ok(Some(result)); + } + "storageBarrier" => { + ctx.prepare_args(arguments, 0, span).finish()?; - let mut continuing = crate::Block::new(); - 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, - )?, - } - lexer.expect(Token::Paren(')'))?; + ctx.block + .push(crate::Statement::Barrier(crate::Barrier::STORAGE), span); + return Ok(None); } + "workgroupBarrier" => { + ctx.prepare_args(arguments, 0, span).finish()?; - body.extend_block(self.parse_block(lexer, context.reborrow(), false)?); + ctx.block + .push(crate::Statement::Barrier(crate::Barrier::WORK_GROUP), span); + return Ok(None); + } + "textureStore" => { + let mut args = ctx.prepare_args(arguments, 3, span); - // Pop the for loop lexical scope - context.symbol_table.pop_scope(); + let image = args.next()?; + let image_span = ctx.ast_expressions.get_span(image); + let image = self.expression(image, ctx.reborrow())?; - Some(crate::Statement::Loop { - body, - continuing, - break_if: None, - }) - } - "break" => { - let (_, mut 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; - return Err(Error::InvalidBreakIf(span)); + 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); } - Some(crate::Statement::Break) - } - "continue" => { - let _ = lexer.next(); - Some(crate::Statement::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, - }) - } - // 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), - )?, + "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, + } } - lexer.expect(Token::Separator(';'))?; - None + "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 span = NagaSpan::from(self.pop_rule_span(lexer)); - if let Some(statement) = statement { - block.push(statement, span); - } - } - _ => { - let mut emitter = super::Emitter::default(); - self.parse_assignment_statement(lexer, context, block, &mut emitter)?; - self.pop_rule_span(lexer); + + let expr = ctx.naga_expressions.append(expr, span); + Ok(Some(expr)) } } - Ok(()) } - fn parse_loop<'a>( + fn atomic_pointer( &mut self, - lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, '_>, - emitter: &mut super::Emitter, - ) -> Result> { - let _ = lexer.next(); - let mut body = crate::Block::new(); - let mut continuing = crate::Block::new(); - let mut break_if = None; - - // Push a lexical scope for the loop body - context.symbol_table.push_scope(); + 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)) + } + } + } - lexer.expect(Token::Paren('{'))?; + 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); - loop { - if lexer.skip(Token::Word("continuing")) { - // Branch for the `continuing` block, this must be - // the last thing in the loop body + let pointer = self.atomic_pointer(args.next()?, ctx.reborrow())?; - // Expect a opening brace to start the continuing block - lexer.expect(Token::Paren('{'))?; - loop { - if lexer.skip(Token::Word("break")) { - // Branch for the `break if` statement, this statement - // has the form `break if ;` and must be the last - // statement in a continuing block + let value = args.next()?; + let value = self.expression(value, ctx.reborrow())?; + let ty = ctx.register_type(value)?; - // The break must be followed by an `if` to form - // the break if - lexer.expect(Token::Word("if"))?; + args.finish()?; - // 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)); - // Set the condition of the break if to the newly parsed - // expression - break_if = Some(condition); + 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) + } - // Expext 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 - lexer.expect(Token::Paren('}'))?; - // Stop parsing the continuing block - break; - } else if lexer.skip(Token::Paren('}')) { - // If we encounter a closing brace it means we have reached - // the end of the continuing block and should stop processing - break; - } else { - // Otherwise try to parse a statement - self.parse_statement(lexer, context.reborrow(), &mut continuing, false)?; + 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)), } - // Since the continuing block must be the last part of the loop body, - // we expect to see a closing brace to end the loop body - lexer.expect(Token::Paren('}'))?; - break; } - if lexer.skip(Token::Paren('}')) { - // If we encounter a closing brace it means we have reached - // the end of the loop body and should stop processing - break; + Texture::GatherCompare => { + let image = args.next()?; + (image, Some(crate::SwizzleComponent::X)) } - // Otherwise try to parse a statement - self.parse_statement(lexer, context.reborrow(), &mut body, false)?; - } - - // Pop the loop body lexical scope - context.symbol_table.pop_scope(); - - Ok(crate::Statement::Loop { - body, - continuing, - break_if, - }) - } - /// compound_statement - fn parse_block<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, '_>, - is_uniform_control_flow: bool, - ) -> Result> { - self.push_rule_span(Rule::Block, lexer); - // Push a lexical scope for the block - context.symbol_table.push_scope(); + _ => { + let image = args.next()?; + (image, None) + } + }; - lexer.expect(Token::Paren('{'))?; - let mut block = crate::Block::new(); - while !lexer.skip(Token::Paren('}')) { - self.parse_statement( - lexer, - context.reborrow(), - &mut block, - is_uniform_control_flow, - )?; - } - // Pop the block lexical scope - context.symbol_table.pop_scope(); + let image_span = ctx.ast_expressions.get_span(image); + let image = self.expression(image, ctx.reborrow())?; - self.pop_rule_span(lexer); - Ok(block) - } + let sampler = self.expression(args.next()?, ctx.reborrow())?; - fn parse_varying_binding<'a>( - &mut self, - lexer: &mut Lexer<'a>, - ) -> Result, Error<'a>> { - let mut bind_parser = BindingParser::default(); - self.push_rule_span(Rule::Attribute, lexer); + let coordinate = self.expression(args.next()?, ctx.reborrow())?; - while lexer.skip(Token::Attribute) { - let (word, span) = lexer.next_ident_with_span()?; - bind_parser.parse(lexer, word, span)?; - } + let (_, arrayed) = ctx.image_data(image, image_span)?; + let array_index = arrayed + .then(|| self.expression(args.next()?, ctx.reborrow())) + .transpose()?; - let span = self.pop_rule_span(lexer); - bind_parser.finish(span) - } + 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)) + } - fn parse_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>> { - 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, - }, - ); - } - // read parameter list - let mut arguments = Vec::new(); - lexer.expect(Token::Paren('('))?; - let mut ready = true; - while !lexer.skip(Token::Paren(')')) { - if !ready { - return Err(Error::Unexpected( - lexer.next().1, - ExpectedToken::Token(Token::Separator(',')), - )); + Texture::Sample => (crate::SampleLevel::Auto, None), + Texture::SampleBias => { + let bias = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Bias(bias), None) } - 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)); + Texture::SampleCompare => { + let reference = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Auto, Some(reference)) } - 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); + Texture::SampleCompareLevel => { + let reference = self.expression(args.next()?, ctx.reborrow())?; + (crate::SampleLevel::Zero, Some(reference)) } - arguments.push(crate::FunctionArgument { - name: Some(param_name.to_string()), - ty: param_type, - binding, - }); - 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); + 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) } - Some(crate::FunctionResult { ty, binding }) - } else { - None }; - let mut fun = crate::Function { - name: Some(fun_name.to_string()), - arguments, - result, - local_variables: Arena::new(), - expressions, - named_expressions: crate::NamedExpressions::default(), - body: crate::Block::new(), - }; + let offset = args + .next() + .map(|arg| self.constant(arg, ctx.as_output())) + .ok() + .transpose()?; - // 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); + 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), + }; - // Set named expressions after block parsing ends - fun.named_expressions = named_expressions; + 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)); + } + }; - Ok((fun, fun_name)) + crate::SwizzleComponent::XYZW + .get(int as usize) + .copied() + .map(Some) + .ok_or(Error::InvalidGatherComponent(span)) } - fn parse_global_decl<'a>( + fn r#struct( &mut self, - lexer: &mut Lexer<'a>, - module: &mut crate::Module, - lookup_global_expression: &mut FastHashMap<&'a str, crate::Expression>, - ) -> Result> { - // read attributes - let mut binding = None; - let mut stage = None; - let mut workgroup_size = [0u32; 3]; - let mut early_depth_test = None; - let (mut bind_index, mut bind_group) = (None, None); + 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()); - self.push_rule_span(Rule::Attribute, lexer); - while lexer.skip(Token::Attribute) { - match lexer.next_ident_with_span()? { - ("binding", _) => { - lexer.expect(Token::Paren('('))?; - bind_index = Some(Self::parse_non_negative_i32_literal(lexer)?); - lexer.expect(Token::Paren(')'))?; - } - ("group", _) => { - lexer.expect(Token::Paren('('))?; - bind_group = Some(Self::parse_non_negative_i32_literal(lexer)?); - lexer.expect(Token::Paren(')'))?; - } - ("vertex", _) => { - stage = Some(crate::ShaderStage::Vertex); - } - ("fragment", _) => { - stage = Some(crate::ShaderStage::Fragment); - } - ("compute", _) => { - stage = Some(crate::ShaderStage::Compute); - } - ("workgroup_size", _) => { - 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)?; - match lexer.next() { - (Token::Paren(')'), _) => break, - (Token::Separator(','), _) if i != 2 => (), - other => { - return Err(Error::Unexpected( - other.1, - ExpectedToken::WorkgroupSizeSeparator, - )) - } - } - } + 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 } - ("early_depth_test", _) => { - let conservative = if lexer.skip(Token::Paren('(')) { - let (ident, ident_span) = lexer.next_ident_with_span()?; - let value = conv::map_conservative_depth(ident, ident_span)?; - lexer.expect(Token::Paren(')'))?; - Some(value) + } 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 { - None - }; - early_depth_test = Some(crate::EarlyDepthTest { conservative }); + alignment + } + } else { + return Err(Error::NonPowerOfTwoAlignAttribute(span)); } - (_, word_span) => return Err(Error::UnknownAttribute(word_span)), - } - } + } else { + member_min_alignment + }; - let attrib_span = self.pop_rule_span(lexer); - match (bind_group, bind_index) { - (Some(group), Some(index)) => { - binding = Some(crate::ResourceBinding { - group, - binding: index, - }); - } - (Some(_), None) => return Err(Error::MissingAttribute("binding", attrib_span)), - (None, Some(_)) => return Err(Error::MissingAttribute("group", attrib_span)), - (None, None) => {} + 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; } - // read items - let start = lexer.start_byte_offset(); - match lexer.next() { - (Token::Separator(';'), _) => {} - (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); - } - (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); - lexer.expect(Token::Separator(';'))?; - } - (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, - )?; - Some(ty) - } else { - None - }; + let size = struct_alignment.round_up(offset); + let inner = crate::TypeInner::Struct { + members, + span: size, + }; - 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, - )?; + let handle = ctx.module.types.insert( + crate::Type { + name: Some(s.name.name.to_string()), + inner, + }, + span, + ); + Ok(handle) + } - 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, - } + /// 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) } - 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, - )); - } + ast::ArraySize::Dynamic => crate::ArraySize::Dynamic, + }, + stride: self.layouter[base].to_stride(), } - - lexer.expect(Token::Separator(';'))?; - lookup_global_expression.insert(name, crate::Expression::Constant(const_handle)); } - (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, + 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, }, - NagaSpan::from(pvar.name_span), - ); - lookup_global_expression - .insert(pvar.name, crate::Expression::GlobalVariable(var_handle)); + } } - (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(), - stage, - early_depth_test, - workgroup_size, - function, - }), - None => { - module - .functions - .append(function, NagaSpan::from(lexer.span_from(start))); - } + 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)), } } - (Token::End, _) => return Ok(false), - other => return Err(Error::Unexpected(other.1, ExpectedToken::GlobalItem)), - } + }; - match binding { - None => Ok(true), - // we had the attribute but no var? - Some(_) => Err(Error::Other), - } + Ok(ctx.ensure_type_exists(inner)) } - pub fn parse(&mut self, source: &str) -> Result { - self.reset(); + /// 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 mut module = crate::Module::default(); - let mut lexer = Lexer::new(source); - let mut lookup_global_expression = FastHashMap::default(); - loop { - match self.parse_global_decl(&mut lexer, &mut module, &mut lookup_global_expression) { - 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); + 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: 1, + base: 6, index: 0, ), AccessIndex( - base: 2, + base: 1, 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 +%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 -%220 = OpFunction %2 None %221 -%219 = OpFunctionParameter %59 -%218 = OpLabel -OpBranch %222 -%222 = OpLabel -OpStore %219 %34 +%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 +%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 +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 -%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 +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 %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 +%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 -%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 +%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? + +"###, + ) +}