diff --git a/Cargo.toml b/Cargo.toml index b74e8ad52f..e0e364fb5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ serialize = ["serde", "indexmap/serde-1"] deserialize = ["serde", "indexmap/serde-1"] spv-in = ["petgraph", "spirv"] spv-out = ["spirv"] -wgsl-in = ["codespan-reporting", "hexf-parse", "termcolor", "unicode-xid"] +wgsl-in = ["clone", "codespan-reporting", "termcolor", "aho-corasick", "chumsky", "half", "hexf-parse", "lasso", "logos", "strum"] wgsl-out = [] hlsl-out = [] span = ["codespan-reporting", "termcolor"] @@ -58,10 +58,17 @@ num-traits = "0.2" spirv = { version = "0.2", optional = true } thiserror = "1.0.21" serde = { version = "1.0.103", features = ["derive"], optional = true } -petgraph = { version ="0.6", optional = true } +petgraph = { version = "0.6", optional = true } pp-rs = { version = "0.2.1", optional = true } + +# wgsl frontend dependencies +aho-corasick = { version = "0.7.19", optional = true } +chumsky = { version = "0.8.0", default-features = false, optional = true } +half = { version = "1.8.2", optional = true } hexf-parse = { version = "0.2.1", optional = true } -unicode-xid = { version = "0.2.3", optional = true } +lasso = { version = "0.6.0", optional = true } +logos = { version = "0.12.1", optional = true } +strum = { version = "0.24.1", features = ["derive"], optional = true } [dev-dependencies] bincode = "1" diff --git a/benches/criterion.rs b/benches/criterion.rs index ee8765b921..f111153043 100644 --- a/benches/criterion.rs +++ b/benches/criterion.rs @@ -42,12 +42,12 @@ fn frontends(c: &mut Criterion) { #[cfg(all(feature = "wgsl-in", feature = "serialize", feature = "deserialize"))] group.bench_function("bin", |b| { let inputs_wgsl = gather_inputs("tests/in", "wgsl"); - let mut parser = naga::front::wgsl::Parser::new(); + let mut context = naga::front::wgsl::WgslContext::new(); let inputs_bin = inputs_wgsl .iter() .map(|input| { let string = std::str::from_utf8(input).unwrap(); - let module = parser.parse(string).unwrap(); + let module = context.parse(string).unwrap(); bincode::serialize(&module).unwrap() }) .collect::>(); @@ -60,14 +60,14 @@ fn frontends(c: &mut Criterion) { #[cfg(feature = "wgsl-in")] group.bench_function("wgsl", |b| { let inputs_wgsl = gather_inputs("tests/in", "wgsl"); + let mut context = naga::front::wgsl::WgslContext::new(); let inputs = inputs_wgsl .iter() .map(|input| std::str::from_utf8(input).unwrap()) .collect::>(); - let mut parser = naga::front::wgsl::Parser::new(); b.iter(move || { for &input in inputs.iter() { - parser.parse(input).unwrap(); + context.parse(input).unwrap(); } }); }); @@ -99,12 +99,12 @@ fn frontends(c: &mut Criterion) { #[cfg(feature = "wgsl-in")] fn gather_modules() -> Vec { let inputs = gather_inputs("tests/in", "wgsl"); - let mut parser = naga::front::wgsl::Parser::new(); + let mut context = naga::front::wgsl::WgslContext::new(); inputs .iter() .map(|input| { let string = std::str::from_utf8(input).unwrap(); - parser.parse(string).unwrap() + context.parse(string).unwrap() }) .collect() } diff --git a/cli/src/main.rs b/cli/src/main.rs index f7a3f8312a..9ae00f9e66 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -287,8 +287,12 @@ fn run() -> Result<(), Box> { Ok(v) => (v, Some(input)), Err(ref e) => { let path = input_path.to_string_lossy(); - e.emit_to_stderr_with_path(&input, &path); - return Err(CliError("Could not parse WGSL").into()); + + for e in e { + e.emit_to_stderr_with_path(&input, &path); + } + + return Err(CliError("WGSL Error").into()); } } } diff --git a/src/back/wgsl/writer.rs b/src/back/wgsl/writer.rs index 0be7ef072a..cfa1f39960 100644 --- a/src/back/wgsl/writer.rs +++ b/src/back/wgsl/writer.rs @@ -1828,7 +1828,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) => { @@ -1852,7 +1852,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/wgsl/construction.rs b/src/front/wgsl/construction.rs deleted file mode 100644 index 43e719d0f3..0000000000 --- a/src/front/wgsl/construction.rs +++ /dev/null @@ -1,679 +0,0 @@ -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, - }, - PartialVector { - size: VectorSize, - }, - Vector { - size: VectorSize, - kind: ScalarKind, - width: Bytes, - }, - PartialMatrix { - columns: VectorSize, - rows: VectorSize, - }, - Matrix { - columns: VectorSize, - rows: VectorSize, - width: Bytes, - }, - PartialArray, - Array { - base: Handle, - size: ArraySize, - stride: u32, - }, - Struct(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 }) - } - ConstructorType::Struct(handle) => TypeResolution::Handle(handle), - _ => return None, - }) - } -} - -impl ConstructorType { - fn to_error_string(&self, types: &UniqueArena, constants: &Arena) -> String { - match *self { - ConstructorType::Scalar { kind, width } => kind.to_wgsl(width), - ConstructorType::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 } => { - 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()), - } - } -} - -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 })); - } - - 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 })) - } - (_, 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: &'a TypeInner, - }, - Many { - components: Vec>, - spans: Vec, - first_component_ty: &'a TypeInner, - }, - } - - impl<'a> Components<'a> { - fn into_components_vec(self) -> Vec> { - match self { - Components::None => vec![], - Components::One { component, .. } => vec![component], - Components::Many { components, .. } => components, - } - } - } - - let components = match *components.as_slice() { - [] => Components::None, - [component] => { - ctx.resolve_type(component)?; - Components::One { - component, - span: spans[0].clone(), - ty: ctx.typifier.get(component, ctx.types), - } - } - [component, ..] => { - ctx.resolve_type(component)?; - Components::Many { - components, - spans, - first_component_ty: ctx.typifier.get(component, ctx.types), - } - } - }; - - let expr = match (components, dst_ty) { - // Empty constructor - (Components::None, dst_ty) => { - let ty = match dst_ty.to_type_resolution() { - Some(TypeResolution::Handle(handle)) => handle, - Some(TypeResolution::Value(inner)) => ctx - .types - .insert(Type { name: None, inner }, Default::default()), - None => return Err(Error::TypeNotInferrable(type_span)), - }; - - return match ctx.create_zero_value_constant(ty) { - Some(constant) => { - let span = parser.pop_rule_span(lexer); - Ok(Some(ctx.interrupt_emitter( - Expression::Constant(constant), - span.into(), - ))) - } - None => Err(Error::TypeNotConstructible(type_span)), - }; - } - - // Scalar constructor & conversion (scalar -> scalar) - ( - Components::One { - component, - ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::Scalar { kind, width }, - ) => Expression::As { - expr: component, - kind, - convert: Some(width), - }, - - // Vector conversion (vector -> vector) - ( - Components::One { - component, - ty: &TypeInner::Vector { size: src_size, .. }, - .. - }, - ConstructorType::Vector { - size: dst_size, - kind: dst_kind, - width: dst_width, - }, - ) if dst_size == src_size => Expression::As { - expr: component, - kind: dst_kind, - convert: Some(dst_width), - }, - - // Vector conversion (vector -> vector) - partial - ( - Components::One { - component, - ty: - &TypeInner::Vector { - size: src_size, - kind: src_kind, - .. - }, - .. - }, - ConstructorType::PartialVector { size: dst_size }, - ) if dst_size == src_size => Expression::As { - expr: component, - kind: src_kind, - convert: None, - }, - - // Matrix conversion (matrix -> matrix) - ( - Components::One { - component, - ty: - &TypeInner::Matrix { - columns: src_columns, - rows: src_rows, - .. - }, - .. - }, - ConstructorType::Matrix { - columns: dst_columns, - rows: dst_rows, - width: dst_width, - }, - ) if dst_columns == src_columns && dst_rows == src_rows => Expression::As { - expr: component, - kind: ScalarKind::Float, - convert: Some(dst_width), - }, - - // Matrix conversion (matrix -> matrix) - partial - ( - Components::One { - component, - ty: - &TypeInner::Matrix { - columns: src_columns, - rows: src_rows, - .. - }, - .. - }, - ConstructorType::PartialMatrix { - columns: dst_columns, - rows: dst_rows, - }, - ) if dst_columns == src_columns && dst_rows == src_rows => Expression::As { - expr: component, - kind: ScalarKind::Float, - convert: None, - }, - - // Vector constructor (splat) - infer type - ( - Components::One { - component, - ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::PartialVector { size }, - ) => Expression::Splat { - size, - value: component, - }, - - // Vector constructor (splat) - ( - Components::One { - component, - ty: - &TypeInner::Scalar { - kind: src_kind, - width: src_width, - .. - }, - .. - }, - ConstructorType::Vector { - size, - kind: dst_kind, - width: dst_width, - }, - ) if dst_kind == src_kind || dst_width == src_width => Expression::Splat { - size, - value: component, - }, - - // Vector constructor (by elements) - ( - Components::Many { - components, - first_component_ty: - &TypeInner::Scalar { kind, width } | &TypeInner::Vector { kind, width, .. }, - .. - }, - ConstructorType::PartialVector { size }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { .. } | &TypeInner::Vector { .. }, - .. - }, - ConstructorType::Vector { size, width, kind }, - ) => { - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Vector { size, kind, width }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Matrix constructor (by elements) - ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { width, .. }, - .. - }, - ConstructorType::PartialMatrix { columns, rows }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Scalar { .. }, - .. - }, - ConstructorType::Matrix { - columns, - rows, - width, - }, - ) => { - let vec_ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Vector { - width, - kind: ScalarKind::Float, - size: rows, - }, - }, - Default::default(), - ); - - let components = components - .chunks(rows as usize) - .map(|vec_components| { - ctx.expressions.append( - Expression::Compose { - ty: vec_ty, - components: Vec::from(vec_components), - }, - Default::default(), - ) - }) - .collect(); - - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Matrix { - columns, - rows, - width, - }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Matrix constructor (by columns) - ( - Components::Many { - components, - first_component_ty: &TypeInner::Vector { width, .. }, - .. - }, - ConstructorType::PartialMatrix { columns, rows }, - ) - | ( - Components::Many { - components, - first_component_ty: &TypeInner::Vector { .. }, - .. - }, - ConstructorType::Matrix { - columns, - rows, - width, - }, - ) => { - let ty = ctx.types.insert( - Type { - name: None, - inner: TypeInner::Matrix { - columns, - rows, - width, - }, - }, - Default::default(), - ); - Expression::Compose { ty, components } - } - - // Array constructor - infer type - (components, ConstructorType::PartialArray) => { - let components = components.into_components_vec(); - - let base = match ctx.typifier[components[0]].clone() { - TypeResolution::Handle(ty) => ty, - TypeResolution::Value(inner) => ctx - .types - .insert(Type { name: None, inner }, Default::default()), - }; - - let size = Constant { - name: None, - specialization: None, - inner: ConstantInner::Scalar { - width: 4, - value: ScalarValue::Uint(components.len() as u64), - }, - }; - - let inner = TypeInner::Array { - base, - size: ArraySize::Constant(ctx.constants.append(size, Default::default())), - stride: { - parser.layouter.update(ctx.types, ctx.constants).unwrap(); - parser.layouter[base].to_stride() - }, - }; - - let ty = ctx - .types - .insert(Type { name: None, inner }, Default::default()); - - Expression::Compose { ty, components } - } - - // Array constructor - (components, ConstructorType::Array { base, size, stride }) => { - let components = components.into_components_vec(); - let inner = TypeInner::Array { base, size, stride }; - let ty = ctx - .types - .insert(Type { name: None, inner }, Default::default()); - Expression::Compose { ty, components } - } - - // Struct constructor - (components, ConstructorType::Struct(ty)) => Expression::Compose { - ty, - components: components.into_components_vec(), - }, - - // ERRORS - - // Bad conversion (type cast) - ( - Components::One { - span, ty: src_ty, .. - }, - dst_ty, - ) => { - return Err(Error::BadTypeCast { - span, - from_type: src_ty.to_wgsl(ctx.types, ctx.constants), - to_type: dst_ty.to_error_string(ctx.types, ctx.constants), - }); - } - - // Too many parameters for scalar constructor - (Components::Many { spans, .. }, ConstructorType::Scalar { .. }) => { - return Err(Error::UnexpectedComponents(Span { - start: spans[1].start, - end: spans.last().unwrap().end, - })); - } - - // Parameters are of the wrong type for vector or matrix constructor - ( - Components::Many { spans, .. }, - ConstructorType::Vector { .. } - | ConstructorType::Matrix { .. } - | ConstructorType::PartialVector { .. } - | ConstructorType::PartialMatrix { .. }, - ) => { - return Err(Error::InvalidConstructorComponentType(spans[0].clone(), 0)); - } - }; - - let span = NagaSpan::from(parser.pop_rule_span(lexer)); - Ok(Some(ctx.expressions.append(expr, span))) -} diff --git a/src/front/wgsl/conv.rs b/src/front/wgsl/conv.rs deleted file mode 100644 index ba41648757..0000000000 --- a/src/front/wgsl/conv.rs +++ /dev/null @@ -1,225 +0,0 @@ -use super::{Error, Span}; - -pub fn map_address_space(word: &str, span: Span) -> Result> { - match word { - "private" => Ok(crate::AddressSpace::Private), - "workgroup" => Ok(crate::AddressSpace::WorkGroup), - "uniform" => Ok(crate::AddressSpace::Uniform), - "storage" => Ok(crate::AddressSpace::Storage { - access: crate::StorageAccess::default(), - }), - "push_constant" => Ok(crate::AddressSpace::PushConstant), - "function" => Ok(crate::AddressSpace::Function), - _ => Err(Error::UnknownAddressSpace(span)), - } -} - -pub fn map_built_in(word: &str, span: Span) -> Result> { - Ok(match word { - "position" => crate::BuiltIn::Position { invariant: false }, - // vertex - "vertex_index" => crate::BuiltIn::VertexIndex, - "instance_index" => crate::BuiltIn::InstanceIndex, - "view_index" => crate::BuiltIn::ViewIndex, - // fragment - "front_facing" => crate::BuiltIn::FrontFacing, - "frag_depth" => crate::BuiltIn::FragDepth, - "primitive_index" => crate::BuiltIn::PrimitiveIndex, - "sample_index" => crate::BuiltIn::SampleIndex, - "sample_mask" => crate::BuiltIn::SampleMask, - // compute - "global_invocation_id" => crate::BuiltIn::GlobalInvocationId, - "local_invocation_id" => crate::BuiltIn::LocalInvocationId, - "local_invocation_index" => crate::BuiltIn::LocalInvocationIndex, - "workgroup_id" => crate::BuiltIn::WorkGroupId, - "workgroup_size" => crate::BuiltIn::WorkGroupSize, - "num_workgroups" => crate::BuiltIn::NumWorkGroups, - _ => return Err(Error::UnknownBuiltin(span)), - }) -} - -pub fn map_interpolation(word: &str, span: Span) -> Result> { - match word { - "linear" => Ok(crate::Interpolation::Linear), - "flat" => Ok(crate::Interpolation::Flat), - "perspective" => Ok(crate::Interpolation::Perspective), - _ => Err(Error::UnknownAttribute(span)), - } -} - -pub fn map_sampling(word: &str, span: Span) -> Result> { - match word { - "center" => Ok(crate::Sampling::Center), - "centroid" => Ok(crate::Sampling::Centroid), - "sample" => Ok(crate::Sampling::Sample), - _ => Err(Error::UnknownAttribute(span)), - } -} - -pub fn map_storage_format(word: &str, span: Span) -> Result> { - use crate::StorageFormat as Sf; - Ok(match word { - "r8unorm" => Sf::R8Unorm, - "r8snorm" => Sf::R8Snorm, - "r8uint" => Sf::R8Uint, - "r8sint" => Sf::R8Sint, - "r16uint" => Sf::R16Uint, - "r16sint" => Sf::R16Sint, - "r16float" => Sf::R16Float, - "rg8unorm" => Sf::Rg8Unorm, - "rg8snorm" => Sf::Rg8Snorm, - "rg8uint" => Sf::Rg8Uint, - "rg8sint" => Sf::Rg8Sint, - "r32uint" => Sf::R32Uint, - "r32sint" => Sf::R32Sint, - "r32float" => Sf::R32Float, - "rg16uint" => Sf::Rg16Uint, - "rg16sint" => Sf::Rg16Sint, - "rg16float" => Sf::Rg16Float, - "rgba8unorm" => Sf::Rgba8Unorm, - "rgba8snorm" => Sf::Rgba8Snorm, - "rgba8uint" => Sf::Rgba8Uint, - "rgba8sint" => Sf::Rgba8Sint, - "rgb10a2unorm" => Sf::Rgb10a2Unorm, - "rg11b10float" => Sf::Rg11b10Float, - "rg32uint" => Sf::Rg32Uint, - "rg32sint" => Sf::Rg32Sint, - "rg32float" => Sf::Rg32Float, - "rgba16uint" => Sf::Rgba16Uint, - "rgba16sint" => Sf::Rgba16Sint, - "rgba16float" => Sf::Rgba16Float, - "rgba32uint" => Sf::Rgba32Uint, - "rgba32sint" => Sf::Rgba32Sint, - "rgba32float" => Sf::Rgba32Float, - _ => return Err(Error::UnknownStorageFormat(span)), - }) -} - -pub fn get_scalar_type(word: &str) -> Option<(crate::ScalarKind, crate::Bytes)> { - match word { - "f16" => Some((crate::ScalarKind::Float, 2)), - "f32" => Some((crate::ScalarKind::Float, 4)), - "f64" => Some((crate::ScalarKind::Float, 8)), - "i8" => Some((crate::ScalarKind::Sint, 1)), - "i16" => Some((crate::ScalarKind::Sint, 2)), - "i32" => Some((crate::ScalarKind::Sint, 4)), - "i64" => Some((crate::ScalarKind::Sint, 8)), - "u8" => Some((crate::ScalarKind::Uint, 1)), - "u16" => Some((crate::ScalarKind::Uint, 2)), - "u32" => Some((crate::ScalarKind::Uint, 4)), - "u64" => Some((crate::ScalarKind::Uint, 8)), - "bool" => Some((crate::ScalarKind::Bool, crate::BOOL_WIDTH)), - _ => None, - } -} - -pub fn map_derivative_axis(word: &str) -> Option { - match word { - "dpdx" => Some(crate::DerivativeAxis::X), - "dpdy" => Some(crate::DerivativeAxis::Y), - "fwidth" => Some(crate::DerivativeAxis::Width), - _ => None, - } -} - -pub fn map_relational_fun(word: &str) -> Option { - match word { - "any" => Some(crate::RelationalFunction::Any), - "all" => Some(crate::RelationalFunction::All), - "isFinite" => Some(crate::RelationalFunction::IsFinite), - "isNormal" => Some(crate::RelationalFunction::IsNormal), - _ => None, - } -} - -pub fn map_standard_fun(word: &str) -> Option { - use crate::MathFunction as Mf; - Some(match word { - // comparison - "abs" => Mf::Abs, - "min" => Mf::Min, - "max" => Mf::Max, - "clamp" => Mf::Clamp, - "saturate" => Mf::Saturate, - // trigonometry - "cos" => Mf::Cos, - "cosh" => Mf::Cosh, - "sin" => Mf::Sin, - "sinh" => Mf::Sinh, - "tan" => Mf::Tan, - "tanh" => Mf::Tanh, - "acos" => Mf::Acos, - "asin" => Mf::Asin, - "atan" => Mf::Atan, - "atan2" => Mf::Atan2, - "radians" => Mf::Radians, - "degrees" => Mf::Degrees, - // decomposition - "ceil" => Mf::Ceil, - "floor" => Mf::Floor, - "round" => Mf::Round, - "fract" => Mf::Fract, - "trunc" => Mf::Trunc, - "modf" => Mf::Modf, - "frexp" => Mf::Frexp, - "ldexp" => Mf::Ldexp, - // exponent - "exp" => Mf::Exp, - "exp2" => Mf::Exp2, - "log" => Mf::Log, - "log2" => Mf::Log2, - "pow" => Mf::Pow, - // geometry - "dot" => Mf::Dot, - "outerProduct" => Mf::Outer, - "cross" => Mf::Cross, - "distance" => Mf::Distance, - "length" => Mf::Length, - "normalize" => Mf::Normalize, - "faceForward" => Mf::FaceForward, - "reflect" => Mf::Reflect, - // computational - "sign" => Mf::Sign, - "fma" => Mf::Fma, - "mix" => Mf::Mix, - "step" => Mf::Step, - "smoothstep" => Mf::SmoothStep, - "sqrt" => Mf::Sqrt, - "inverseSqrt" => Mf::InverseSqrt, - "transpose" => Mf::Transpose, - "determinant" => Mf::Determinant, - // bits - "countOneBits" => Mf::CountOneBits, - "reverseBits" => Mf::ReverseBits, - "extractBits" => Mf::ExtractBits, - "insertBits" => Mf::InsertBits, - "firstTrailingBit" => Mf::FindLsb, - "firstLeadingBit" => Mf::FindMsb, - // data packing - "pack4x8snorm" => Mf::Pack4x8snorm, - "pack4x8unorm" => Mf::Pack4x8unorm, - "pack2x16snorm" => Mf::Pack2x16snorm, - "pack2x16unorm" => Mf::Pack2x16unorm, - "pack2x16float" => Mf::Pack2x16float, - // data unpacking - "unpack4x8snorm" => Mf::Unpack4x8snorm, - "unpack4x8unorm" => Mf::Unpack4x8unorm, - "unpack2x16snorm" => Mf::Unpack2x16snorm, - "unpack2x16unorm" => Mf::Unpack2x16unorm, - "unpack2x16float" => Mf::Unpack2x16float, - _ => return None, - }) -} - -pub fn map_conservative_depth( - word: &str, - span: Span, -) -> Result> { - use crate::ConservativeDepth as Cd; - match word { - "greater_equal" => Ok(Cd::GreaterEqual), - "less_equal" => Ok(Cd::LessEqual), - "unchanged" => Ok(Cd::Unchanged), - _ => Err(Error::UnknownConservativeDepth(span)), - } -} diff --git a/src/front/wgsl/lexer.rs b/src/front/wgsl/lexer.rs deleted file mode 100644 index 35fe450892..0000000000 --- a/src/front/wgsl/lexer.rs +++ /dev/null @@ -1,671 +0,0 @@ -use super::{conv, number::consume_number, Error, ExpectedToken, Span, Token, TokenSpan}; - -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) -} - -fn consume_token(input: &str, generic: bool) -> (Token<'_>, &str) { - let mut chars = input.chars(); - let cur = match chars.next() { - Some(c) => c, - None => return (Token::End, ""), - }; - match cur { - ':' | ';' | ',' => (Token::Separator(cur), chars.as_str()), - '.' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('0'..='9') => consume_number(input), - _ => (Token::Separator(cur), og_chars), - } - } - '@' => (Token::Attribute, chars.as_str()), - '(' | ')' | '{' | '}' | '[' | ']' => (Token::Paren(cur), chars.as_str()), - '<' | '>' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('=') if !generic => (Token::LogicalOperation(cur), chars.as_str()), - Some(c) if c == cur && !generic => { - let og_chars = chars.as_str(); - match chars.next() { - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::ShiftOperation(cur), og_chars), - } - } - _ => (Token::Paren(cur), og_chars), - } - } - '0'..='9' => consume_number(input), - '/' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('/') => { - let _ = chars.position(is_comment_end); - (Token::Trivia, chars.as_str()) - } - Some('*') => { - let mut depth = 1; - let mut prev = None; - - for c in &mut chars { - match (prev, c) { - (Some('*'), '/') => { - prev = None; - depth -= 1; - if depth == 0 { - return (Token::Trivia, chars.as_str()); - } - } - (Some('/'), '*') => { - prev = None; - depth += 1; - } - _ => { - prev = Some(c); - } - } - } - - (Token::End, "") - } - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - '-' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('>') => (Token::Arrow, chars.as_str()), - Some('0'..='9' | '.') => consume_number(input), - Some('-') => (Token::DecrementOperation, chars.as_str()), - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - '+' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('+') => (Token::IncrementOperation, chars.as_str()), - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - '*' | '%' | '^' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - '~' => (Token::Operation(cur), chars.as_str()), - '=' | '!' => { - let og_chars = chars.as_str(); - match chars.next() { - Some('=') => (Token::LogicalOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - '&' | '|' => { - let og_chars = chars.as_str(); - match chars.next() { - Some(c) if c == cur => (Token::LogicalOperation(cur), chars.as_str()), - Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), - _ => (Token::Operation(cur), og_chars), - } - } - _ if is_blankspace(cur) => { - let (_, rest) = consume_any(input, is_blankspace); - (Token::Trivia, rest) - } - _ if is_word_start(cur) => { - let (word, rest) = consume_any(input, is_word_part); - (Token::Word(word), rest) - } - _ => (Token::Unknown(cur), chars.as_str()), - } -} - -/// Returns whether or not a char is a comment end -/// (Unicode Pattern_White_Space excluding U+0020, U+0009, U+200E and U+200F) -const fn is_comment_end(c: char) -> bool { - match c { - '\u{000a}'..='\u{000d}' | '\u{0085}' | '\u{2028}' | '\u{2029}' => true, - _ => false, - } -} - -/// Returns whether or not a char is a blankspace (Unicode Pattern_White_Space) -const fn is_blankspace(c: char) -> bool { - match c { - '\u{0020}' - | '\u{0009}'..='\u{000d}' - | '\u{0085}' - | '\u{200e}' - | '\u{200f}' - | '\u{2028}' - | '\u{2029}' => true, - _ => false, - } -} - -/// Returns whether or not a char is a word start (Unicode XID_Start + '_') -fn is_word_start(c: char) -> bool { - c == '_' || unicode_xid::UnicodeXID::is_xid_start(c) -} - -/// Returns whether or not a char is a word part (Unicode XID_Continue) -fn is_word_part(c: char) -> bool { - unicode_xid::UnicodeXID::is_xid_continue(c) -} - -#[derive(Clone)] -pub(super) struct Lexer<'a> { - input: &'a str, - pub(super) source: &'a str, - // The byte offset of the end of the last non-trivia token. - last_end_offset: usize, -} - -impl<'a> Lexer<'a> { - pub(super) const fn new(input: &'a str) -> Self { - Lexer { - input, - source: input, - last_end_offset: 0, - } - } - - 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 - /// ```ignore - /// let lexer = Lexer::new("5"); - /// let (value, span) = lexer.capture_span(Lexer::next_uint_literal); - /// assert_eq!(value, 5); - /// ``` - #[inline] - pub fn capture_span( - &mut self, - inner: impl FnOnce(&mut Self) -> Result, - ) -> Result<(T, Span), E> { - let start = self.current_byte_offset(); - let res = inner(self)?; - let end = self.current_byte_offset(); - Ok((res, start..end)) - } - - pub(super) fn start_byte_offset(&mut self) -> usize { - loop { - // Eat all trivia because `next` doesn't eat trailing trivia. - let (token, rest) = consume_token(self.input, false); - if let Token::Trivia = token { - self.input = rest; - } else { - return self.current_byte_offset(); - } - } - } - - 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(); - let rest = cloned.input; - (token, rest) - } - - const fn current_byte_offset(&self) -> usize { - self.source.len() - self.input.len() - } - - pub(super) const fn span_from(&self, offset: usize) -> Span { - offset..self.end_byte_offset() - } - - #[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); - } - } - } - } - - #[must_use] - pub(super) fn next_generic(&mut self) -> TokenSpan<'a> { - let mut start_byte_offset = self.current_byte_offset(); - loop { - let (token, rest) = consume_token(self.input, true); - self.input = rest; - match token { - Token::Trivia => start_byte_offset = self.current_byte_offset(), - _ => return (token, start_byte_offset..self.current_byte_offset()), - } - } - } - - #[must_use] - pub(super) fn peek(&mut self) -> TokenSpan<'a> { - let (token, _) = self.peek_token_and_rest(); - token - } - - pub(super) fn expect_span( - &mut self, - expected: Token<'a>, - ) -> Result, Error<'a>> { - let next = self.next(); - if next.0 == expected { - Ok(next.1) - } else { - Err(Error::Unexpected(next.1, ExpectedToken::Token(expected))) - } - } - - pub(super) fn expect(&mut self, expected: Token<'a>) -> Result<(), Error<'a>> { - self.expect_span(expected)?; - Ok(()) - } - - pub(super) fn expect_generic_paren(&mut self, expected: char) -> Result<(), Error<'a>> { - let next = self.next_generic(); - if next.0 == Token::Paren(expected) { - Ok(()) - } else { - Err(Error::Unexpected( - next.1, - ExpectedToken::Token(Token::Paren(expected)), - )) - } - } - - /// If the next token matches it is skipped and true is returned - pub(super) fn skip(&mut self, what: Token<'_>) -> bool { - let (peeked_token, rest) = self.peek_token_and_rest(); - if peeked_token.0 == what { - self.input = rest; - true - } else { - false - } - } - - pub(super) fn next_ident_with_span(&mut self) -> Result<(&'a str, Span), Error<'a>> { - match self.next() { - (Token::Word(word), span) if word == "_" => { - Err(Error::InvalidIdentifierUnderscore(span)) - } - (Token::Word(word), span) if word.starts_with("__") => { - Err(Error::ReservedIdentifierPrefix(span)) - } - (Token::Word(word), span) => Ok((word, span)), - other => Err(Error::Unexpected(other.1, ExpectedToken::Identifier)), - } - } - - pub(super) fn next_ident(&mut self) -> Result<&'a str, Error<'a>> { - self.next_ident_with_span().map(|(word, _)| word) - } - - /// Parses a generic scalar type, for example ``. - pub(super) fn next_scalar_generic( - &mut self, - ) -> Result<(crate::ScalarKind, crate::Bytes), Error<'a>> { - self.expect_generic_paren('<')?; - let pair = match self.next() { - (Token::Word(word), span) => { - conv::get_scalar_type(word).ok_or(Error::UnknownScalarType(span)) - } - (_, span) => Err(Error::UnknownScalarType(span)), - }?; - self.expect_generic_paren('>')?; - Ok(pair) - } - - /// Parses a generic scalar type, for example ``. - /// - /// Returns the span covering the inner type, excluding the brackets. - pub(super) fn next_scalar_generic_with_span( - &mut self, - ) -> Result<(crate::ScalarKind, crate::Bytes, Span), Error<'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())) - .ok_or(Error::UnknownScalarType(span)), - (_, span) => Err(Error::UnknownScalarType(span)), - }?; - self.expect_generic_paren('>')?; - Ok(pair) - } - - pub(super) fn next_storage_access(&mut self) -> Result> { - let (ident, span) = self.next_ident_with_span()?; - match ident { - "read" => Ok(crate::StorageAccess::LOAD), - "write" => Ok(crate::StorageAccess::STORE), - "read_write" => Ok(crate::StorageAccess::LOAD | crate::StorageAccess::STORE), - _ => Err(Error::UnknownAccess(span)), - } - } - - pub(super) fn next_format_generic( - &mut self, - ) -> Result<(crate::StorageFormat, crate::StorageAccess), Error<'a>> { - self.expect(Token::Paren('<'))?; - let (ident, ident_span) = self.next_ident_with_span()?; - let format = conv::map_storage_format(ident, ident_span)?; - self.expect(Token::Separator(','))?; - let access = self.next_storage_access()?; - self.expect(Token::Paren('>'))?; - Ok((format, access)) - } - - pub(super) fn open_arguments(&mut self) -> Result<(), Error<'a>> { - self.expect(Token::Paren('(')) - } - - pub(super) fn close_arguments(&mut self) -> Result<(), Error<'a>> { - let _ = self.skip(Token::Separator(',')); - self.expect(Token::Paren(')')) - } - - pub(super) fn next_argument(&mut self) -> Result> { - let paren = Token::Paren(')'); - if self.skip(Token::Separator(',')) { - Ok(!self.skip(paren)) - } else { - self.expect(paren).map(|()| false) - } - } -} - -#[cfg(test)] -use super::{number::Number, NumberError}; - -#[cfg(test)] -fn sub_test(source: &str, expected_tokens: &[Token]) { - let mut lex = Lexer::new(source); - for &token in expected_tokens { - assert_eq!(lex.next().0, token); - } - assert_eq!(lex.next().0, Token::End); -} - -#[test] -fn test_numbers() { - // WGSL spec examples // - - // decimal integer - sub_test( - "0x123 0X123u 1u 123 0 0i 0x3f", - &[ - Token::Number(Ok(Number::I32(291))), - Token::Number(Ok(Number::U32(291))), - Token::Number(Ok(Number::U32(1))), - Token::Number(Ok(Number::I32(123))), - Token::Number(Ok(Number::I32(0))), - Token::Number(Ok(Number::I32(0))), - Token::Number(Ok(Number::I32(63))), - ], - ); - // decimal floating point - sub_test( - "0.e+4f 01. .01 12.34 .0f 0h 1e-3 0xa.fp+2 0x1P+4f 0X.3 0x3p+2h 0X1.fp-4 0x3.2p+2h", - &[ - Token::Number(Ok(Number::F32(0.))), - Token::Number(Ok(Number::F32(1.))), - Token::Number(Ok(Number::F32(0.01))), - Token::Number(Ok(Number::F32(12.34))), - Token::Number(Ok(Number::F32(0.))), - Token::Number(Err(NumberError::UnimplementedF16)), - Token::Number(Ok(Number::F32(0.001))), - Token::Number(Ok(Number::F32(43.75))), - Token::Number(Ok(Number::F32(16.))), - Token::Number(Ok(Number::F32(0.1875))), - Token::Number(Err(NumberError::UnimplementedF16)), - Token::Number(Ok(Number::F32(0.12109375))), - Token::Number(Err(NumberError::UnimplementedF16)), - ], - ); - - // MIN / MAX // - - // min / max decimal signed integer - sub_test( - "-2147483648i 2147483647i -2147483649i 2147483648i", - &[ - Token::Number(Ok(Number::I32(i32::MIN))), - Token::Number(Ok(Number::I32(i32::MAX))), - Token::Number(Err(NumberError::NotRepresentable)), - Token::Number(Err(NumberError::NotRepresentable)), - ], - ); - // min / max decimal unsigned integer - sub_test( - "0u 4294967295u -1u 4294967296u", - &[ - Token::Number(Ok(Number::U32(u32::MIN))), - Token::Number(Ok(Number::U32(u32::MAX))), - Token::Number(Err(NumberError::NotRepresentable)), - Token::Number(Err(NumberError::NotRepresentable)), - ], - ); - - // min / max hexadecimal signed integer - sub_test( - "-0x80000000i 0x7FFFFFFFi -0x80000001i 0x80000000i", - &[ - Token::Number(Ok(Number::I32(i32::MIN))), - Token::Number(Ok(Number::I32(i32::MAX))), - Token::Number(Err(NumberError::NotRepresentable)), - Token::Number(Err(NumberError::NotRepresentable)), - ], - ); - // min / max hexadecimal unsigned integer - sub_test( - "0x0u 0xFFFFFFFFu -0x1u 0x100000000u", - &[ - Token::Number(Ok(Number::U32(u32::MIN))), - Token::Number(Ok(Number::U32(u32::MAX))), - Token::Number(Err(NumberError::NotRepresentable)), - Token::Number(Err(NumberError::NotRepresentable)), - ], - ); - - /// ≈ 2^-126 * 2^−23 (= 2^−149) - const SMALLEST_POSITIVE_SUBNORMAL_F32: f32 = 1e-45; - /// ≈ 2^-126 * (1 − 2^−23) - const LARGEST_SUBNORMAL_F32: f32 = 1.1754942e-38; - /// ≈ 2^-126 - const SMALLEST_POSITIVE_NORMAL_F32: f32 = f32::MIN_POSITIVE; - /// ≈ 1 − 2^−24 - const LARGEST_F32_LESS_THAN_ONE: f32 = 0.99999994; - /// ≈ 1 + 2^−23 - const SMALLEST_F32_LARGER_THAN_ONE: f32 = 1.0000001; - /// ≈ -(2^127 * (2 − 2^−23)) - const SMALLEST_NORMAL_F32: f32 = f32::MIN; - /// ≈ 2^127 * (2 − 2^−23) - const LARGEST_NORMAL_F32: f32 = f32::MAX; - - // decimal floating point - sub_test( - "1e-45f 1.1754942e-38f 1.17549435e-38f 0.99999994f 1.0000001f -3.40282347e+38f 3.40282347e+38f", - &[ - Token::Number(Ok(Number::F32( - SMALLEST_POSITIVE_SUBNORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_SUBNORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_POSITIVE_NORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_F32_LESS_THAN_ONE, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_F32_LARGER_THAN_ONE, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_NORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_NORMAL_F32, - ))), - ], - ); - sub_test( - "-3.40282367e+38f 3.40282367e+38f", - &[ - Token::Number(Err(NumberError::NotRepresentable)), // ≈ -2^128 - Token::Number(Err(NumberError::NotRepresentable)), // ≈ 2^128 - ], - ); - - // hexadecimal floating point - sub_test( - "0x1p-149f 0x7FFFFFp-149f 0x1p-126f 0xFFFFFFp-24f 0x800001p-23f -0xFFFFFFp+104f 0xFFFFFFp+104f", - &[ - Token::Number(Ok(Number::F32( - SMALLEST_POSITIVE_SUBNORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_SUBNORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_POSITIVE_NORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_F32_LESS_THAN_ONE, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_F32_LARGER_THAN_ONE, - ))), - Token::Number(Ok(Number::F32( - SMALLEST_NORMAL_F32, - ))), - Token::Number(Ok(Number::F32( - LARGEST_NORMAL_F32, - ))), - ], - ); - sub_test( - "-0x1p128f 0x1p128f 0x1.000001p0f", - &[ - Token::Number(Err(NumberError::NotRepresentable)), // = -2^128 - Token::Number(Err(NumberError::NotRepresentable)), // = 2^128 - Token::Number(Err(NumberError::NotRepresentable)), - ], - ); -} - -#[test] -fn test_tokens() { - sub_test("id123_OK", &[Token::Word("id123_OK")]); - sub_test( - "92No", - &[Token::Number(Ok(Number::I32(92))), Token::Word("No")], - ); - sub_test( - "2u3o", - &[ - Token::Number(Ok(Number::U32(2))), - Token::Number(Ok(Number::I32(3))), - Token::Word("o"), - ], - ); - sub_test( - "2.4f44po", - &[ - Token::Number(Ok(Number::F32(2.4))), - Token::Number(Ok(Number::I32(44))), - Token::Word("po"), - ], - ); - sub_test( - "Δέλτα réflexion Кызыл 𐰓𐰏𐰇 朝焼け سلام 검정 שָׁלוֹם गुलाबी փիրուզ", - &[ - Token::Word("Δέλτα"), - Token::Word("réflexion"), - Token::Word("Кызыл"), - Token::Word("𐰓𐰏𐰇"), - Token::Word("朝焼け"), - Token::Word("سلام"), - Token::Word("검정"), - Token::Word("שָׁלוֹם"), - Token::Word("गुलाबी"), - Token::Word("փիրուզ"), - ], - ); - sub_test("æNoø", &[Token::Word("æNoø")]); - sub_test("No¾", &[Token::Word("No"), Token::Unknown('¾')]); - sub_test("No好", &[Token::Word("No好")]); - sub_test("_No", &[Token::Word("_No")]); - sub_test( - "*/*/***/*//=/*****//", - &[ - Token::Operation('*'), - Token::AssignmentOperation('/'), - Token::Operation('/'), - ], - ); -} - -#[test] -fn test_variable_decl() { - sub_test( - "@group(0 ) var< uniform> texture: texture_multisampled_2d ;", - &[ - Token::Attribute, - Token::Word("group"), - Token::Paren('('), - Token::Number(Ok(Number::I32(0))), - Token::Paren(')'), - Token::Word("var"), - Token::Paren('<'), - Token::Word("uniform"), - Token::Paren('>'), - Token::Word("texture"), - Token::Separator(':'), - Token::Word("texture_multisampled_2d"), - Token::Paren('<'), - Token::Word("f32"), - Token::Paren('>'), - Token::Separator(';'), - ], - ); - sub_test( - "var buffer: array;", - &[ - Token::Word("var"), - Token::Paren('<'), - Token::Word("storage"), - Token::Separator(','), - Token::Word("read_write"), - Token::Paren('>'), - Token::Word("buffer"), - Token::Separator(':'), - Token::Word("array"), - Token::Paren('<'), - Token::Word("u32"), - Token::Paren('>'), - Token::Separator(';'), - ], - ); -} diff --git a/src/front/wgsl/lower/const_eval.rs b/src/front/wgsl/lower/const_eval.rs new file mode 100644 index 0000000000..32bb7b6570 --- /dev/null +++ b/src/front/wgsl/lower/const_eval.rs @@ -0,0 +1,409 @@ +use crate::front::wgsl::lower::{DeclData, EvaluationData}; +use crate::front::wgsl::parse::ast::Literal; +use crate::front::wgsl::resolve::ir::{CallExpr, CallTarget, Constructible, Expr, ExprKind}; +use crate::front::wgsl::WgslError; +use crate::{Handle, UnaryOperator}; +use std::convert::TryInto; +use std::fmt::Display; +use std::ops::{Neg, Not}; + +pub struct Evaluator { + errors: Vec, +} + +impl Evaluator { + pub const fn new() -> Self { + Self { errors: Vec::new() } + } + + pub(super) fn eval(&mut self, data: &EvaluationData, expr: &Expr) -> Option { + let unsupported = |this: &mut Self| { + this.errors.push( + WgslError::new("this operation is not supported in a const context yet") + .marker(expr.span), + ); + }; + + match expr.kind { + ExprKind::Error => None, + ExprKind::Literal(ref l) => Some(Value::Scalar(match *l { + Literal::Bool(b) => ScalarValue::Bool(b), + Literal::AbstractInt(i) => ScalarValue::AbstractInt(i), + Literal::AbstractFloat(f) => ScalarValue::AbstractFloat(f), + Literal::I32(i) => ScalarValue::I32(i), + Literal::U32(u) => ScalarValue::U32(u), + Literal::F32(f) => ScalarValue::F32(f), + Literal::F16(_) => { + unsupported(self); + return None; + } + })), + ExprKind::Unary(ref u) => { + let rhs = self.eval(data, &u.expr)?; + let ty = rhs.ty().to_string(); + + let ret = match u.op { + UnaryOperator::Not => rhs.map(|x| !x), + UnaryOperator::Negate => rhs.map(|x| -x), + }; + + if ret.is_none() { + self.errors.push( + WgslError::new("invalid type for operand") + .label(u.expr.span, format!("has type {}", ty)), + ) + } + + ret + } + ExprKind::Call(CallExpr { + target: CallTarget::Construction(ref ty), + ref args, + .. + }) => match *ty { + Constructible::Vector { size, .. } | Constructible::PartialVector { size } => { + if args.len() != size as usize && args.len() != 1 { + self.errors.push( + WgslError::new(format!( + "expected {} arguments, got {}", + size as usize, + args.len() + )) + .marker(expr.span), + ); + return None; + } + + let mut out = Vec::with_capacity(size as usize); + for expr in args { + let arg = self.eval(data, expr)?; + match arg { + Value::Scalar(scalar) => out.push(scalar), + _ => { + self.errors.push( + WgslError::new("expected scalar value") + .label(expr.span, format!("has type {}", arg.ty())), + ); + return None; + } + } + } + + // Splat. + if args.len() == 1 { + let arg = out[0]; + for _ in 1..size as usize { + out.push(arg); + } + } + + Some(Value::Vector(out)) + } + _ => { + unsupported(self); + None + } + }, + ExprKind::Call(CallExpr { + target: CallTarget::Decl(id), + ref args, + .. + }) => match data.decl_map[&id] { + DeclData::Type(ty) => { + let ty_val = &data.module.types[ty]; + let values = args + .iter() + .map(|x| self.eval(data, x)) + .collect::>>()?; + Some(Value::Struct { + ty: ty_val.name.clone().unwrap(), + handle: ty, + values, + }) + } + _ => { + unsupported(self); + None + } + }, + ExprKind::Binary(_) + | ExprKind::Call(_) + | ExprKind::Index(_, _) + | ExprKind::Member(_, _) + | ExprKind::Global(_) + | ExprKind::Local(_) + | ExprKind::AddrOf(_) + | ExprKind::Deref(_) => { + unsupported(self); + None + } + } + } + + pub(super) fn as_positive_int(&mut self, data: &EvaluationData, expr: &Expr) -> Option { + let value = self.eval(data, expr)?; + + match value { + Value::Scalar(ScalarValue::U32(u)) => Some(u), + Value::Scalar(ScalarValue::I32(i)) => { + let x: Result = i.try_into(); + match x { + Ok(x) => Some(x), + Err(_) => { + self.errors.push( + WgslError::new("integer value is too large") + .label(expr.span, format!("has value `{}`", i)), + ); + None + } + } + } + Value::Scalar(ScalarValue::AbstractInt(i)) => { + if i < 0 { + self.errors.push( + WgslError::new("expected a positive integer") + .label(expr.span, format!("has value `{}`", i)), + ); + return None; + } + + let x: Result = i.try_into(); + match x { + Ok(x) => Some(x), + Err(_) => { + self.errors.push( + WgslError::new("integer value is too large") + .label(expr.span, format!("has value {}", i)), + ); + None + } + } + } + _ => { + self.errors.push( + WgslError::new("expected a positive integer") + .label(expr.span, format!("has type {}", value.ty())), + ); + None + } + } + } + + pub(super) fn as_int(&mut self, data: &EvaluationData, expr: &Expr) -> Option { + let value = self.eval(data, expr)?; + + match value { + Value::Scalar(ScalarValue::U32(u)) => { + let x: Result = u.try_into(); + match x { + Ok(x) => Some(x), + Err(_) => { + self.errors.push( + WgslError::new("integer value is too large") + .label(expr.span, format!("has value {}", u)), + ); + None + } + } + } + Value::Scalar(ScalarValue::I32(i)) => Some(i), + Value::Scalar(ScalarValue::AbstractInt(i)) => { + let x: Result = i.try_into(); + match x { + Ok(x) => Some(x), + Err(_) => { + self.errors.push( + WgslError::new("integer value is too large") + .label(expr.span, format!("has value {}", i)), + ); + None + } + } + } + _ => { + self.errors.push( + WgslError::new("expected an integer") + .label(expr.span, format!("has type {}", value.ty())), + ); + None + } + } + } + + pub(super) fn as_bool(&mut self, data: &EvaluationData, expr: &Expr) -> Option { + let value = self.eval(data, expr)?; + + match value { + Value::Scalar(ScalarValue::Bool(b)) => Some(b), + _ => { + self.errors.push( + WgslError::new("expected a boolean") + .label(expr.span, format!("has type {}", value.ty())), + ); + None + } + } + } + + // `const` functions cannot evaluate destructors. + #[allow(clippy::missing_const_for_fn)] + pub fn finish(self) -> Vec { + self.errors + } +} + +#[derive(Clone)] +pub enum Value { + Scalar(ScalarValue), + Vector(Vec), + Struct { + ty: String, + handle: Handle, + values: Vec, + }, +} + +impl Value { + fn map(self, mut f: F) -> Option + where + F: FnMut(ScalarValue) -> Option + Copy, + { + match self { + Value::Scalar(s) => f(s).map(Value::Scalar), + Value::Vector(v) => v + .into_iter() + .map(f) + .collect::>>() + .map(Value::Vector), + Value::Struct { ty, handle, values } => values + .into_iter() + .map(move |x| x.map(f)) + .collect::>>() + .map(|values| Value::Struct { ty, handle, values }), + } + } + + pub const fn ty(&self) -> ValueType { + ValueType { src: self } + } +} + +impl Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Value::Scalar(s) => write!(f, "{}", s), + Value::Vector(ref v) => { + write!(f, "vec{}(", v.len())?; + for (i, s) in v.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{}", s)?; + } + write!(f, ")") + } + Value::Struct { + ref ty, ref values, .. + } => { + write!(f, "{}(", ty)?; + for (i, s) in values.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; + } + write!(f, "{}", s)?; + } + write!(f, ")") + } + } + } +} + +#[derive(Copy, Clone)] +pub enum ScalarValue { + Bool(bool), + AbstractInt(i64), + I32(i32), + U32(u32), + AbstractFloat(f64), + F32(f32), +} + +impl Display for ScalarValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + ScalarValue::Bool(b) => write!(f, "{}", b), + ScalarValue::AbstractInt(i) => write!(f, "{}", i), + ScalarValue::I32(i) => write!(f, "{}", i), + ScalarValue::U32(u) => write!(f, "{}", u), + ScalarValue::AbstractFloat(x) => write!(f, "{}", x), + ScalarValue::F32(x) => write!(f, "{}", x), + } + } +} + +impl Not for ScalarValue { + type Output = Option; + + fn not(self) -> Self::Output { + match self { + ScalarValue::Bool(b) => Some(ScalarValue::Bool(!b)), + ScalarValue::U32(u) => Some(ScalarValue::U32(!u)), + ScalarValue::I32(i) => Some(ScalarValue::I32(!i)), + ScalarValue::AbstractInt(i) => Some(ScalarValue::AbstractInt(!i)), + _ => None, + } + } +} + +impl Neg for ScalarValue { + type Output = Option; + + fn neg(self) -> Self::Output { + match self { + ScalarValue::AbstractInt(i) => Some(ScalarValue::AbstractInt(-i)), + ScalarValue::I32(i) => Some(ScalarValue::I32(-i)), + ScalarValue::AbstractFloat(f) => Some(ScalarValue::AbstractFloat(-f)), + ScalarValue::F32(f) => Some(ScalarValue::F32(-f)), + _ => None, + } + } +} + +impl ScalarValue { + const fn ty(&self) -> ScalarValueType { + ScalarValueType { src: self } + } +} + +pub struct ScalarValueType<'a> { + src: &'a ScalarValue, +} + +impl Display for ScalarValueType<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self.src { + ScalarValue::Bool(_) => write!(f, "bool"), + ScalarValue::AbstractInt(_) => write!(f, "{{integer}}"), + ScalarValue::I32(_) => write!(f, "i32"), + ScalarValue::U32(_) => write!(f, "u32"), + ScalarValue::AbstractFloat(_) => write!(f, "{{float}}"), + ScalarValue::F32(_) => write!(f, "f32"), + } + } +} + +pub struct ValueType<'a> { + src: &'a Value, +} + +impl Display for ValueType<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self.src { + Value::Scalar(s) => write!(f, "{}", s.ty()), + Value::Vector(ref v) => { + write!(f, "vec{}<{}>", v.len(), v[0].ty()) + } + Value::Struct { ref ty, .. } => write!(f, "{}", ty), + } + } +} diff --git a/src/front/wgsl/lower/construction.rs b/src/front/wgsl/lower/construction.rs new file mode 100644 index 0000000000..45439178fc --- /dev/null +++ b/src/front/wgsl/lower/construction.rs @@ -0,0 +1,581 @@ +use crate::front::wgsl::lower::Lowerer; +use crate::front::wgsl::resolve::ir::{Constructible, Expr}; +use crate::front::wgsl::WgslError; +use crate::{ + ArraySize, Bytes, ConstantInner, Handle, ScalarKind, ScalarValue, Type, TypeInner, VectorSize, +}; + +impl Lowerer<'_> { + pub fn array_size(&mut self, len: &Expr) -> Option { + let value = self.eval.as_positive_int(&self.data, len)?; + if value == 0 { + self.errors.push( + WgslError::new("expected a positive integer").label(len.span, "has value `0`"), + ); + return None; + } + + let size = self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + inner: ConstantInner::Scalar { + value: ScalarValue::Uint(value as _), + width: 4, + }, + specialization: None, + }, + crate::Span::UNDEFINED, + ); + Some(ArraySize::Constant(size)) + } + + pub fn construct( + &mut self, + ty: &Constructible, + args: &[Expr], + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let args = self.make_constructor_args(args, b, fun); + + match *ty { + Constructible::Scalar { kind, width } => { + let this_ty = self.make_ty(ty, span).unwrap(); + match args { + ConstructorArgs::None => self.make_zero_value(this_ty, span, b, fun), + ConstructorArgs::One { expr, ty, span } => { + match self.data.module.types[ty].inner { + TypeInner::Scalar { .. } => {} + _ => self.errors.push( + WgslError::new(format!( + "cannot cast to `{}`", + self.fmt_type(this_ty) + )) + .label(span, format!("has type `{}`", self.fmt_type(ty))), + ), + } + + let expr = crate::Expression::As { + expr, + kind, + convert: Some(width), + }; + Some(self.emit_expr(expr, span, b, fun)) + } + ConstructorArgs::Many { spans, .. } => { + self.check_arg_count(1, spans.iter().copied()); + None + } + } + } + Constructible::Vector { kind, width, size } => { + let this_ty = self.make_ty(ty, span).unwrap(); + match args { + ConstructorArgs::None => self.make_zero_value(this_ty, span, b, fun), + _ => self.construct_vector(args, span, this_ty, size, kind, width, b, fun), + } + } + Constructible::Matrix { + columns, + rows, + width, + } => { + let this_ty = self.make_ty(ty, span).unwrap(); + match args { + ConstructorArgs::None => self.make_zero_value(this_ty, span, b, fun), + _ => self.construct_matrix(args, span, this_ty, rows, columns, width, b, fun), + } + } + Constructible::Array { .. } => { + let this_ty = self.make_ty(ty, span)?; + + match args { + ConstructorArgs::None => self.make_zero_value(this_ty, span, b, fun), + ConstructorArgs::One { .. } | ConstructorArgs::Many { .. } => { + let components = args.into_vec(); + let expr = crate::Expression::Compose { + ty: this_ty, + components, + }; + Some(self.emit_expr(expr, span, b, fun)) + } + } + } + Constructible::PartialVector { size } => { + match args { + ConstructorArgs::None => { + self.make_ty(ty, span); // Errors with an inference error. + None + } + ConstructorArgs::One { ty: base, .. } + | ConstructorArgs::Many { ty: base, .. } => { + let (kind, width) = match self.data.module.types[base].inner { + TypeInner::Scalar { kind, width } + | TypeInner::Vector { kind, width, .. } => (kind, width), + _ => { + self.errors.push( + WgslError::new("expected scalar or vector to construct vector") + .label(span, format!("found `{}`", self.fmt_type(base))), + ); + return None; + } + }; + + let this_ty = self.register_type(TypeInner::Vector { kind, width, size }); + self.construct_vector(args, span, this_ty, size, kind, width, b, fun) + } + } + } + Constructible::PartialMatrix { columns, rows } => { + match args { + ConstructorArgs::None => { + self.make_ty(ty, span); // Errors with an inference error. + None + } + ConstructorArgs::One { ty: base, .. } + | ConstructorArgs::Many { ty: base, .. } => { + let width = match self.data.module.types[base].inner { + TypeInner::Scalar { + kind: ScalarKind::Float, + width, + } + | TypeInner::Vector { + kind: ScalarKind::Float, + width, + .. + } + | TypeInner::Matrix { width, .. } => width, + _ => { + self.errors.push( + WgslError::new("expected floating-point scalar, vector, or matrix to construct matrix") + .label(span, format!("found `{}`", self.fmt_type(base))), + ); + return None; + } + }; + + let this_ty = self.register_type(TypeInner::Matrix { + rows, + columns, + width, + }); + self.construct_matrix(args, span, this_ty, rows, columns, width, b, fun) + } + } + } + Constructible::PartialArray => { + match args { + ConstructorArgs::None => { + self.make_ty(ty, span); // Errors with an inference error. + None + } + ConstructorArgs::One { ty: base, .. } + | ConstructorArgs::Many { ty: base, .. } => { + let args = args.into_vec(); + let len = args.len() as u32; + + let size = crate::Constant { + name: None, + specialization: None, + inner: ConstantInner::Scalar { + value: ScalarValue::Uint(len as _), + width: 4, + }, + }; + let size = self + .data + .module + .constants + .fetch_or_append(size, crate::Span::UNDEFINED); + + self.layouter + .update(&self.data.module.types, &self.data.module.constants) + .unwrap(); + let ty = self.register_type(TypeInner::Array { + base, + size: ArraySize::Constant(size), + stride: self.layouter[base].to_stride(), + }); + + let expr = crate::Expression::Compose { + ty, + components: args, + }; + Some(self.emit_expr(expr, span, b, fun)) + } + } + } + Constructible::Type(ty) => match args { + ConstructorArgs::None => self.make_zero_value(ty, span, b, fun), + _ => { + let components = args.into_vec(); + let expr = crate::Expression::Compose { ty, components }; + Some(self.emit_expr(expr, span, b, fun)) + } + }, + } + } + + fn make_constructor_args( + &mut self, + args: &[Expr], + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> ConstructorArgs { + let mut out = ConstructorArgs::None; + for arg in args { + if let Some(expr) = self.expr(arg, b, fun) { + if let Some(ty) = self.type_handle_of(expr, fun) { + match out { + ConstructorArgs::None => { + out = ConstructorArgs::One { + expr, + ty, + span: arg.span, + }; + } + ConstructorArgs::One { + expr: old_expr, + ty, + span, + } => { + out = ConstructorArgs::Many { + exprs: vec![old_expr, expr], + spans: vec![span, arg.span], + ty, + }; + } + ConstructorArgs::Many { + ref mut exprs, + ref mut spans, + .. + } => { + exprs.push(expr); + spans.push(arg.span); + } + } + } + } + } + + out + } + + fn make_ty(&mut self, ty: &Constructible, span: crate::Span) -> Option> { + Some(match *ty { + Constructible::Scalar { kind, width } => { + self.register_type(TypeInner::Scalar { kind, width }) + } + Constructible::Vector { kind, size, width } => { + self.register_type(TypeInner::Vector { kind, size, width }) + } + Constructible::Matrix { + rows, + columns, + width, + } => self.register_type(TypeInner::Matrix { + rows, + columns, + width, + }), + Constructible::Array { ref base, ref len } => { + let base = self.ty(base)?; + self.layouter + .update(&self.data.module.types, &self.data.module.constants) + .unwrap(); + + let size = self.array_size(len)?; + self.register_type(TypeInner::Array { + base, + size, + stride: self.layouter[base].to_stride(), + }) + } + Constructible::Type(ty) => ty, + Constructible::PartialVector { .. } + | Constructible::PartialMatrix { .. } + | Constructible::PartialArray => { + self.errors.push( + WgslError::new("cannot infer generics") + .marker(span) + .note("consider annotating the generics with `<...>`"), + ); + return None; + } + }) + } + + fn make_zero_value( + &mut self, + ty: Handle, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let c = self.make_zero_value_of_type(ty, span)?; + Some(self.emit_expr(crate::Expression::Constant(c), span, b, fun)) + } + + fn make_zero_value_of_type( + &mut self, + ty: Handle, + span: crate::Span, + ) -> Option> { + let inner = match self.data.module.types[ty].inner { + TypeInner::Scalar { kind, width } => ConstantInner::Scalar { + width, + value: match kind { + ScalarKind::Float => ScalarValue::Float(0.0), + ScalarKind::Sint => ScalarValue::Sint(0), + ScalarKind::Uint => ScalarValue::Uint(0), + ScalarKind::Bool => ScalarValue::Bool(false), + }, + }, + TypeInner::Vector { size, kind, width } => { + let zero = self.register_type(TypeInner::Scalar { width, kind }); + ConstantInner::Composite { + ty, + components: std::iter::repeat( + self.make_zero_value_of_type(zero, span).unwrap(), + ) + .take(size as usize) + .collect(), + } + } + TypeInner::Matrix { + rows, + columns, + width, + } => { + let zero = self.register_type(TypeInner::Vector { + size: rows, + kind: ScalarKind::Float, + width, + }); + ConstantInner::Composite { + ty, + components: std::iter::repeat(self.make_zero_value_of_type(zero, span)?) + .take(columns as usize) + .collect(), + } + } + TypeInner::Array { base, size, .. } => { + let len = match size { + ArraySize::Constant(c) => c, + ArraySize::Dynamic => return None, + }; + let len = self.data.module.constants[len].to_array_length()? as usize; + self.layouter + .update(&self.data.module.types, &self.data.module.constants) + .unwrap(); + + ConstantInner::Composite { + ty, + components: std::iter::repeat(self.make_zero_value_of_type(base, span)?) + .take(len) + .collect(), + } + } + TypeInner::Struct { ref members, .. } => { + let tys: Vec<_> = members.iter().map(|x| x.ty).collect(); + ConstantInner::Composite { + ty, + components: tys + .iter() + .map(|&ty| self.make_zero_value_of_type(ty, span)) + .collect::>()?, + } + } + TypeInner::Atomic { .. } + | TypeInner::Pointer { .. } + | TypeInner::ValuePointer { .. } + | TypeInner::Image { .. } + | TypeInner::Sampler { .. } + | TypeInner::BindingArray { .. } => return None, + }; + + Some(self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + inner, + specialization: None, + }, + crate::Span::UNDEFINED, + )) + } + + #[allow(clippy::too_many_arguments)] + fn construct_vector( + &mut self, + args: ConstructorArgs, + span: crate::Span, + this_ty: Handle, + size: VectorSize, + kind: ScalarKind, + width: Bytes, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let expr = match args { + ConstructorArgs::None => unreachable!("should be handled by the caller"), + ConstructorArgs::One { + expr, + ty: arg_ty, + span: arg_span, + } => match self.data.module.types[arg_ty].inner { + TypeInner::Vector { + size: from_size, .. + } => { + if size != from_size { + self.errors.push( + WgslError::new("cannot cast between vectors of different sizes") + .label(span, format!("expected `{}`", self.fmt_type(this_ty))) + .label(arg_span, format!("found `{}`", self.fmt_type(arg_ty))), + ); + return None; + } + + crate::Expression::As { + expr, + kind, + convert: Some(width), + } + } + _ => crate::Expression::Splat { size, value: expr }, + }, + ConstructorArgs::Many { exprs, .. } => { + // self.check_arg_count(size as usize, &spans, this_ty)?; + + crate::Expression::Compose { + ty: this_ty, + components: exprs, + } + } + }; + + Some(self.emit_expr(expr, span, b, fun)) + } + + #[allow(clippy::too_many_arguments)] + fn construct_matrix( + &mut self, + args: ConstructorArgs, + span: crate::Span, + this_ty: Handle, + rows: VectorSize, + columns: VectorSize, + width: Bytes, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let expr = match args { + ConstructorArgs::None => unreachable!("should be handled by the caller"), + ConstructorArgs::One { + expr, + ty: arg_ty, + span: arg_span, + } => match self.data.module.types[arg_ty].inner { + TypeInner::Matrix { + rows: from_rows, + columns: from_columns, + width, + } => { + if rows != from_rows || columns != from_columns { + self.errors.push( + WgslError::new("cannot cast between matrices of different sizes") + .label(span, format!("expected `{}`", self.fmt_type(this_ty))) + .label(arg_span, format!("found `{}`", self.fmt_type(arg_ty))), + ); + return None; + } + + crate::Expression::As { + expr, + kind: ScalarKind::Float, + convert: Some(width), + } + } + _ => { + self.errors.push( + WgslError::new("expected matrix to cast") + .label(arg_span, format!("found `{}`", self.fmt_type(arg_ty))), + ); + return None; + } + }, + ConstructorArgs::Many { + exprs, + ty: arg_ty, + spans, + } => match self.data.module.types[arg_ty].inner { + TypeInner::Scalar { .. } => { + self.check_arg_count(columns as usize * rows as usize, spans.iter().copied())?; + + let column_ty = self.register_type(TypeInner::Vector { + kind: ScalarKind::Float, + width, + size: rows, + }); + let rows = rows as usize; + let columns = + exprs + .chunks(rows) + .zip(spans.chunks(rows)) + .map(|(components, spans)| { + let span = crate::Span::total_span(spans.iter().copied()); + let expr = crate::Expression::Compose { + ty: column_ty, + components: components.to_vec(), + }; + self.emit_expr(expr, span, b, fun) + }); + crate::Expression::Compose { + ty: this_ty, + components: columns.collect(), + } + } + TypeInner::Vector { .. } => { + self.check_arg_count(columns as usize, spans.iter().copied())?; + crate::Expression::Compose { + ty: this_ty, + components: exprs, + } + } + _ => { + self.errors.push( + WgslError::new("expected scalar or vector to construct matrix") + .label(spans[0], format!("found `{}`", self.fmt_type(arg_ty))), + ); + return None; + } + }, + }; + + Some(self.emit_expr(expr, span, b, fun)) + } +} + +enum ConstructorArgs { + None, + One { + expr: Handle, + ty: Handle, + span: crate::Span, + }, + Many { + exprs: Vec>, + spans: Vec, + ty: Handle, + }, +} + +impl ConstructorArgs { + fn into_vec(self) -> Vec> { + match self { + ConstructorArgs::None => Vec::new(), + ConstructorArgs::One { expr, .. } => vec![expr], + ConstructorArgs::Many { exprs, .. } => exprs, + } + } +} diff --git a/src/front/wgsl/lower/format.rs b/src/front/wgsl/lower/format.rs new file mode 100644 index 0000000000..75f037d4d1 --- /dev/null +++ b/src/front/wgsl/lower/format.rs @@ -0,0 +1,326 @@ +use crate::front::wgsl::lower::DeclData; +use crate::{ + Bytes, ImageClass, ImageDimension, ScalarKind, StorageFormat, Type, TypeInner, VectorSize, +}; +use std::fmt::{Display, Formatter}; + +pub struct Pluralizer { + inner: T, + count: isize, +} + +impl Display for Pluralizer { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}{}", + self.inner, + if self.count == 1 { "" } else { "s" } + ) + } +} + +pub trait Pluralize { + fn pluralize(self, count: isize) -> Pluralizer + where + Self: Sized; +} + +impl Pluralize for T { + fn pluralize(self, count: isize) -> Pluralizer + where + Self: Sized, + { + Pluralizer { inner: self, count } + } +} + +pub struct TypeInnerFormatter<'a> { + pub ty: &'a TypeInner, + pub types: &'a crate::UniqueArena, + pub constants: &'a crate::Arena, +} + +impl Display for TypeInnerFormatter<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match *self.ty { + TypeInner::Scalar { kind, width } => ScalarFormatter { kind, width }.fmt(f), + TypeInner::Vector { size, kind, width } => write!( + f, + "vec{}<{}>", + VectorSizeFormatter { size }, + ScalarFormatter { kind, width } + ), + TypeInner::Matrix { + columns, + rows, + width, + } => write!( + f, + "mat{}x{}<{}>", + columns as u8, + VectorSizeFormatter { size: rows }, + ScalarFormatter { + kind: ScalarKind::Float, + width + } + ), + TypeInner::Atomic { kind, width } => { + write!(f, "atomic<{}>", ScalarFormatter { kind, width }) + } + TypeInner::Pointer { base, space } => write!( + f, + "ptr<{}, {}>", + match space { + crate::AddressSpace::Function => "function", + crate::AddressSpace::Private => "private", + crate::AddressSpace::WorkGroup => "workgroup", + crate::AddressSpace::Uniform => "uniform", + crate::AddressSpace::Storage { .. } => "storage", + crate::AddressSpace::Handle => "handle", + crate::AddressSpace::PushConstant => "push_constant", + }, + self.types + .get_handle(base) + .unwrap() + .name + .as_ref() + .expect("created type without name"), + ), + TypeInner::ValuePointer { + size, + kind, + width, + space, + } => { + let space = match space { + crate::AddressSpace::Function => "function", + crate::AddressSpace::Private => "private", + crate::AddressSpace::WorkGroup => "workgroup", + crate::AddressSpace::Uniform => "uniform", + crate::AddressSpace::Storage { .. } => "storage", + crate::AddressSpace::Handle => "handle", + crate::AddressSpace::PushConstant => "push_constant", + }; + + if let Some(size) = size { + write!( + f, + "ptr<{}, vec{}<{}>>", + space, + VectorSizeFormatter { size }, + ScalarFormatter { kind, width } + ) + } else { + write!(f, "ptr<{}, {}>", space, ScalarFormatter { kind, width }) + } + } + TypeInner::Array { base, size, .. } => { + let base = self + .types + .get_handle(base) + .unwrap() + .name + .as_ref() + .expect("created type without name"); + match size { + crate::ArraySize::Constant(c) => write!( + f, + "array<{}, {}>", + base, + match self.constants[c].inner { + crate::ConstantInner::Scalar { value, .. } => + ScalarValueFormatter { value }, + _ => unreachable!("Array size should be a constant"), + } + ), + crate::ArraySize::Dynamic => write!(f, "array<{}>", base), + } + } + TypeInner::Struct { .. } => { + unreachable!("TypeInner::Struct should not be formatted by the frontend") + } + TypeInner::Image { + dim, + arrayed, + class, + } => { + let dim = match dim { + ImageDimension::D1 => "1d", + ImageDimension::D2 => "2d", + ImageDimension::D3 => "3d", + ImageDimension::Cube => "cube", + }; + let arrayed = if arrayed { "_array" } else { "" }; + match class { + ImageClass::Sampled { kind, multi } => { + let multi = if multi { "multisampled_" } else { "" }; + write!( + f, + "texture_{}{}{}<{}>", + multi, + dim, + arrayed, + match kind { + ScalarKind::Sint => "int", + ScalarKind::Uint => "uint", + ScalarKind::Float => "float", + ScalarKind::Bool => "bool", + } + ) + } + ImageClass::Depth { multi } => { + let multi = if multi { "multisampled_" } else { "" }; + write!(f, "texture_depth_{}{}{}", multi, dim, arrayed) + } + ImageClass::Storage { format, access } => { + write!( + f, + "texture_storage_{}{}<{}, {}>", + dim, + arrayed, + match format { + StorageFormat::R8Unorm => "r8unorm", + StorageFormat::R8Snorm => "r8snorm", + StorageFormat::R8Uint => "r8uint", + StorageFormat::R8Sint => "r8sint", + StorageFormat::R16Uint => "r16uint", + StorageFormat::R16Sint => "r16sint", + StorageFormat::R16Float => "r16float", + StorageFormat::Rg8Unorm => "rg8unorm", + StorageFormat::Rg8Snorm => "rg8snorm", + StorageFormat::Rg8Uint => "rg8uint", + StorageFormat::Rg8Sint => "rg8sint", + StorageFormat::R32Uint => "r32uint", + StorageFormat::R32Sint => "r32sint", + StorageFormat::R32Float => "r32float", + StorageFormat::Rg16Uint => "rg16uint", + StorageFormat::Rg16Sint => "rg16sint", + StorageFormat::Rg16Float => "rg16float", + StorageFormat::Rgba8Unorm => "rgba8unorm", + StorageFormat::Rgba8Snorm => "rgba8snorm", + StorageFormat::Rgba8Uint => "rgba8uint", + StorageFormat::Rgba8Sint => "rgba8sint", + StorageFormat::Rgb10a2Unorm => "rgb10a2unorm", + StorageFormat::Rg11b10Float => "rg11b10float", + StorageFormat::Rg32Uint => "rg32uint", + StorageFormat::Rg32Sint => "rg32sint", + StorageFormat::Rg32Float => "rg32float", + StorageFormat::Rgba16Uint => "rgba16uint", + StorageFormat::Rgba16Sint => "rgba16sint", + StorageFormat::Rgba16Float => "rgba16float", + StorageFormat::Rgba32Uint => "rgba32uint", + StorageFormat::Rgba32Sint => "rgba32sint", + StorageFormat::Rgba32Float => "rgba32float", + }, + if access + .contains(crate::StorageAccess::STORE | crate::StorageAccess::LOAD) + { + "read_write" + } else if access.contains(crate::StorageAccess::STORE) { + "write" + } else { + "read" + } + ) + } + } + } + TypeInner::Sampler { comparison } => write!( + f, + "{}", + if comparison { + "sampler_comparison" + } else { + "sampler" + } + ), + TypeInner::BindingArray { base, size } => { + let base = self + .types + .get_handle(base) + .unwrap() + .name + .as_ref() + .expect("created type without name"); + match size { + crate::ArraySize::Constant(c) => write!( + f, + "binding_array<{}, {}>", + base, + match self.constants[c].inner { + crate::ConstantInner::Scalar { value, .. } => + ScalarValueFormatter { value }, + _ => unreachable!("Array size should be a constant"), + } + ), + crate::ArraySize::Dynamic => write!(f, "binding_array<{}>", base), + } + } + } + } +} + +struct ScalarFormatter { + kind: ScalarKind, + width: Bytes, +} + +impl Display for ScalarFormatter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.kind { + ScalarKind::Sint => write!(f, "i{}", self.width * 8), + ScalarKind::Uint => write!(f, "u{}", self.width * 8), + ScalarKind::Float => write!(f, "f{}", self.width * 8), + ScalarKind::Bool => write!(f, "bool"), + } + } +} + +struct VectorSizeFormatter { + size: VectorSize, +} + +impl Display for VectorSizeFormatter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.size { + VectorSize::Bi => write!(f, "2"), + VectorSize::Tri => write!(f, "3"), + VectorSize::Quad => write!(f, "4"), + } + } +} + +impl Display for DeclData { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match *self { + DeclData::Function(_) => "function", + DeclData::Global(_) => "variable", + DeclData::Const(_) => "const", + DeclData::Type(_) => "type", + DeclData::Assert => "assert", + DeclData::Override => "override", + DeclData::EntryPoint => "entry point", + DeclData::Error => "error", + } + ) + } +} + +struct ScalarValueFormatter { + value: crate::ScalarValue, +} + +impl Display for ScalarValueFormatter { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self.value { + crate::ScalarValue::Sint(i) => write!(f, "{}", i), + crate::ScalarValue::Uint(u) => write!(f, "{}", u), + crate::ScalarValue::Float(v) => write!(f, "{}", v), + crate::ScalarValue::Bool(b) => write!(f, "{}", b), + } + } +} diff --git a/src/front/wgsl/lower/inbuilt_function.rs b/src/front/wgsl/lower/inbuilt_function.rs new file mode 100644 index 0000000000..0626ac663e --- /dev/null +++ b/src/front/wgsl/lower/inbuilt_function.rs @@ -0,0 +1,919 @@ +use crate::front::wgsl::lower::{CallError, Lowerer}; +use crate::front::wgsl::resolve::inbuilt_functions::InbuiltFunction; +use crate::front::wgsl::resolve::ir::{Expr, Type}; +use crate::front::wgsl::WgslError; +use crate::{Handle, ImageClass, TypeInner}; + +impl Lowerer<'_> { + pub(super) fn inbuilt_function( + &mut self, + f: InbuiltFunction, + generics: &[Type], + args: &[Expr], + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Result, CallError> { + let require_args = |this: &mut Self, n| { + let spans = args.iter().map(|x| x.span); + this.check_arg_count(n, spans).ok_or(CallError::Error) + }; + + let require_generics = |this: &mut Self, n| { + if generics.len() != n { + this.errors.push( + WgslError::new(format!( + "expected {} generic argument{}, found {}", + n, + if n == 1 { "" } else { "s" }, + generics.len() + )) + .marker(span), + ); + + if generics.len() < n { + return Err(CallError::Error); + } + } + Ok(()) + }; + + let math_function = |this: &mut Self, + fun: crate::MathFunction, + b: &mut crate::Block, + f: &mut crate::Function| { + require_args(this, fun.argument_count())?; + require_generics(this, 0)?; + + let mut args = args.iter().filter_map(|arg| this.expr(arg, b, f)); + Ok(crate::Expression::Math { + fun, + arg: args.next().ok_or(CallError::Error)?, + arg1: args.next(), + arg2: args.next(), + arg3: args.next(), + }) + }; + + let texture_query = |this: &mut Self, + query: crate::ImageQuery, + b: &mut crate::Block, + f: &mut crate::Function| { + require_args(this, 1)?; + require_generics(this, 0)?; + + Ok(crate::Expression::ImageQuery { + image: this.expr(&args[0], b, f).ok_or(CallError::Error)?, + query, + }) + }; + + let get_atomic_ptr = + |this: &mut Self, pointer: Handle, f: &crate::Function| { + let ptr_ty = this.type_handle_of(pointer, f).ok_or(CallError::Error)?; + let ty = match this.data.module.types[ptr_ty].inner { + TypeInner::Pointer { base, .. } => base, + _ => { + this.errors.push( + WgslError::new("expected pointer to atomic") + .marker(args[0].span) + .label(args[0].span, format!("found `{}`", this.fmt_type(ptr_ty))), + ); + return Err(CallError::Error); + } + }; + + match this.data.module.types[ty].inner { + TypeInner::Atomic { kind, width } => Ok((kind, width)), + _ => { + this.errors.push( + WgslError::new("expected pointer to atomic") + .marker(args[0].span) + .label( + args[0].span, + format!("found pointer to `{}`", this.fmt_type(ty)), + ), + ); + Err(CallError::Error) + } + } + }; + + let atomic_function = |this: &mut Self, + fun: crate::AtomicFunction, + b: &mut crate::Block, + f: &mut crate::Function| { + require_args(this, 2)?; + require_generics(this, 0)?; + + let pointer = this.expr(&args[0], b, f).ok_or(CallError::Error)?; + let value = this.expr(&args[1], b, f).ok_or(CallError::Error)?; + + let (kind, width) = get_atomic_ptr(this, pointer, f)?; + let result = crate::Expression::AtomicResult { + kind, + width, + comparison: false, + }; + let result = f.expressions.append(result, span); + + let stmt = crate::Statement::Atomic { + pointer, + fun, + value, + result, + }; + b.push(stmt, span); + Ok(result) + }; + + let expr = match f { + InbuiltFunction::Bitcast => { + require_args(self, 1)?; + require_generics(self, 1)?; + + let to = self.ty(&generics[0]).ok_or(CallError::Error)?; + let kind = match self.data.module.types[to].inner { + TypeInner::Scalar { kind, .. } => kind, + TypeInner::Vector { kind, .. } => kind, + _ => { + self.errors.push( + WgslError::new("invalid `bitcast` type") + .label(generics[0].span, "expected scalar or vector"), + ); + return Err(CallError::Error); + } + }; + + crate::Expression::As { + expr: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + kind, + convert: None, + } + } + InbuiltFunction::All => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::Relational { + fun: crate::RelationalFunction::All, + argument: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::Any => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::Relational { + fun: crate::RelationalFunction::Any, + argument: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::Select => { + require_args(self, 3)?; + require_generics(self, 0)?; + + crate::Expression::Select { + condition: self.expr(&args[2], b, fun).ok_or(CallError::Error)?, + accept: self.expr(&args[1], b, fun).ok_or(CallError::Error)?, + reject: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::ArrayLength => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::ArrayLength(self.expr(&args[0], b, fun).ok_or(CallError::Error)?) + } + InbuiltFunction::Abs => math_function(self, crate::MathFunction::Abs, b, fun)?, + InbuiltFunction::Acos => math_function(self, crate::MathFunction::Acos, b, fun)?, + InbuiltFunction::Acosh => math_function(self, crate::MathFunction::Acosh, b, fun)?, + InbuiltFunction::Asin => math_function(self, crate::MathFunction::Asin, b, fun)?, + InbuiltFunction::Asinh => math_function(self, crate::MathFunction::Asinh, b, fun)?, + InbuiltFunction::Atan => math_function(self, crate::MathFunction::Atan, b, fun)?, + InbuiltFunction::Atanh => math_function(self, crate::MathFunction::Atanh, b, fun)?, + InbuiltFunction::Atan2 => math_function(self, crate::MathFunction::Atan2, b, fun)?, + InbuiltFunction::Ceil => math_function(self, crate::MathFunction::Ceil, b, fun)?, + InbuiltFunction::Clamp => math_function(self, crate::MathFunction::Clamp, b, fun)?, + InbuiltFunction::Cos => math_function(self, crate::MathFunction::Cos, b, fun)?, + InbuiltFunction::Cosh => math_function(self, crate::MathFunction::Cosh, b, fun)?, + InbuiltFunction::CountOneBits => { + math_function(self, crate::MathFunction::CountOneBits, b, fun)? + } + InbuiltFunction::Cross => math_function(self, crate::MathFunction::Cross, b, fun)?, + InbuiltFunction::Degrees => math_function(self, crate::MathFunction::Degrees, b, fun)?, + InbuiltFunction::Determinant => { + math_function(self, crate::MathFunction::Determinant, b, fun)? + } + InbuiltFunction::Distance => { + math_function(self, crate::MathFunction::Distance, b, fun)? + } + InbuiltFunction::Dot => math_function(self, crate::MathFunction::Dot, b, fun)?, + InbuiltFunction::Exp => math_function(self, crate::MathFunction::Exp, b, fun)?, + InbuiltFunction::Exp2 => math_function(self, crate::MathFunction::Exp2, b, fun)?, + InbuiltFunction::ExtractBits => { + math_function(self, crate::MathFunction::ExtractBits, b, fun)? + } + InbuiltFunction::FaceForward => { + math_function(self, crate::MathFunction::FaceForward, b, fun)? + } + InbuiltFunction::FirstLeadingBit => { + math_function(self, crate::MathFunction::FindMsb, b, fun)? + } + InbuiltFunction::FirstTrailingBit => { + math_function(self, crate::MathFunction::FindLsb, b, fun)? + } + InbuiltFunction::Floor => math_function(self, crate::MathFunction::Floor, b, fun)?, + InbuiltFunction::Fma => math_function(self, crate::MathFunction::Fma, b, fun)?, + InbuiltFunction::Fract => math_function(self, crate::MathFunction::Fract, b, fun)?, + InbuiltFunction::Frexp => math_function(self, crate::MathFunction::Frexp, b, fun)?, + InbuiltFunction::InsertBits => { + math_function(self, crate::MathFunction::InsertBits, b, fun)? + } + InbuiltFunction::InverseSqrt => { + math_function(self, crate::MathFunction::InverseSqrt, b, fun)? + } + InbuiltFunction::Ldexp => math_function(self, crate::MathFunction::Ldexp, b, fun)?, + InbuiltFunction::Length => math_function(self, crate::MathFunction::Length, b, fun)?, + InbuiltFunction::Log => math_function(self, crate::MathFunction::Log, b, fun)?, + InbuiltFunction::Log2 => math_function(self, crate::MathFunction::Log2, b, fun)?, + InbuiltFunction::Max => math_function(self, crate::MathFunction::Max, b, fun)?, + InbuiltFunction::Min => math_function(self, crate::MathFunction::Min, b, fun)?, + InbuiltFunction::Mix => math_function(self, crate::MathFunction::Mix, b, fun)?, + InbuiltFunction::Modf => math_function(self, crate::MathFunction::Modf, b, fun)?, + InbuiltFunction::Normalize => { + math_function(self, crate::MathFunction::Normalize, b, fun)? + } + InbuiltFunction::Pow => math_function(self, crate::MathFunction::Pow, b, fun)?, + InbuiltFunction::Radians => math_function(self, crate::MathFunction::Radians, b, fun)?, + InbuiltFunction::Reflect => math_function(self, crate::MathFunction::Reflect, b, fun)?, + InbuiltFunction::Refract => math_function(self, crate::MathFunction::Refract, b, fun)?, + InbuiltFunction::ReverseBits => { + math_function(self, crate::MathFunction::ReverseBits, b, fun)? + } + InbuiltFunction::Round => math_function(self, crate::MathFunction::Round, b, fun)?, + InbuiltFunction::Saturate => { + math_function(self, crate::MathFunction::Saturate, b, fun)? + } + InbuiltFunction::Sign => math_function(self, crate::MathFunction::Sign, b, fun)?, + InbuiltFunction::Sin => math_function(self, crate::MathFunction::Sin, b, fun)?, + InbuiltFunction::Sinh => math_function(self, crate::MathFunction::Sinh, b, fun)?, + InbuiltFunction::Smoothstep => { + math_function(self, crate::MathFunction::SmoothStep, b, fun)? + } + InbuiltFunction::Sqrt => math_function(self, crate::MathFunction::Sqrt, b, fun)?, + InbuiltFunction::Step => math_function(self, crate::MathFunction::Step, b, fun)?, + InbuiltFunction::Tan => math_function(self, crate::MathFunction::Tan, b, fun)?, + InbuiltFunction::Tanh => math_function(self, crate::MathFunction::Tanh, b, fun)?, + InbuiltFunction::Transpose => { + math_function(self, crate::MathFunction::Transpose, b, fun)? + } + InbuiltFunction::Trunc => math_function(self, crate::MathFunction::Trunc, b, fun)?, + InbuiltFunction::Dpdx | InbuiltFunction::DpdxCoarse | InbuiltFunction::DpdxFine => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::Derivative { + axis: crate::DerivativeAxis::X, + expr: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::Dpdy | InbuiltFunction::DpdyCoarse | InbuiltFunction::DpdyFine => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::Derivative { + axis: crate::DerivativeAxis::Y, + expr: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::Fwidth + | InbuiltFunction::FwidthCoarse + | InbuiltFunction::FwidthFine => { + require_args(self, 1)?; + require_generics(self, 0)?; + + crate::Expression::Derivative { + axis: crate::DerivativeAxis::Width, + expr: self.expr(&args[0], b, fun).ok_or(CallError::Error)?, + } + } + InbuiltFunction::TextureDimensions => { + require_generics(self, 0)?; + if args.is_empty() || args.len() > 2 { + self.errors.push( + WgslError::new(format!("expected 1 or 2 arguments, found {}", args.len())) + .marker(span), + ); + return Err(CallError::Error); + } + + let image = self.expr(&args[0], b, fun).ok_or(CallError::Error)?; + let level = args.get(1).and_then(|e| self.expr(e, b, fun)); + crate::Expression::ImageQuery { + image, + query: crate::ImageQuery::Size { level }, + } + } + InbuiltFunction::TextureNumLayers => { + texture_query(self, crate::ImageQuery::NumLayers, b, fun)? + } + InbuiltFunction::TextureNumLevels => { + texture_query(self, crate::ImageQuery::NumLevels, b, fun)? + } + InbuiltFunction::TextureNumSamples => { + texture_query(self, crate::ImageQuery::NumSamples, b, fun)? + } + InbuiltFunction::TextureLoad => { + if args.len() < 2 { + self.errors.push( + WgslError::new(format!( + "expected at least 2 arguments, found {}", + args.len() + )) + .marker(span), + ); + return Err(CallError::Error); + } + + // Argument order: image, coordinate, array_index?, level? sample?. + + let mut args = args.iter(); + + let image_expr = args.next().unwrap(); + let image = self.expr(image_expr, b, fun).ok_or(CallError::Error)?; + let coordinate = self + .expr(args.next().unwrap(), b, fun) + .ok_or(CallError::Error)?; + + let (class, arrayed) = self + .get_texture_data(image, image_expr.span, fun) + .ok_or(CallError::Error)?; + + let array_index = arrayed.then(|| self.expr(args.next()?, b, fun)).flatten(); + let level = class + .is_mipmapped() + .then(|| self.expr(args.next()?, b, fun)) + .flatten(); + let sample = class + .is_multisampled() + .then(|| self.expr(args.next()?, b, fun)) + .flatten(); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageLoad { + image, + coordinate, + array_index, + sample, + level, + } + } + InbuiltFunction::TextureSample => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Auto, + depth_ref: None, + } + } + InbuiltFunction::TextureSampleBias => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let bias = self + .require_arg(span, "bias", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Bias(bias), + depth_ref: None, + } + } + InbuiltFunction::TextureSampleCompare => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let depth_ref = self + .require_arg(span, "depth_ref", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Auto, + depth_ref: Some(depth_ref), + } + } + InbuiltFunction::TextureSampleCompareLevel => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let depth_ref = self + .require_arg(span, "depth_ref", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Zero, + depth_ref: Some(depth_ref), + } + } + InbuiltFunction::TextureSampleGrad => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let x = self + .require_arg(span, "ddx", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let y = self + .require_arg(span, "ddy", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Gradient { x, y }, + depth_ref: None, + } + } + InbuiltFunction::TextureSampleLevel => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_sample_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let level = self + .require_arg(span, "level", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: None, + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Exact(level), + depth_ref: None, + } + } + InbuiltFunction::TextureGather => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_gather_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: Some(sample.component), + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Zero, + depth_ref: None, + } + } + InbuiltFunction::TextureGatherCompare => { + require_generics(self, 0)?; + let mut args = args.iter(); + let sample = self + .texture_gather_base(span, &mut args, b, fun) + .ok_or(CallError::Error)?; + let depth_ref = self + .require_arg(span, "depth_ref", &mut args, |this, x| this.expr(x, b, fun)) + .ok_or(CallError::Error)?; + let offset = self.texture_sample_offset(&mut args); + + if args.next().is_some() { + self.errors + .push(WgslError::new("too many arguments").marker(span)); + } + + crate::Expression::ImageSample { + image: sample.image, + sampler: sample.sampler, + gather: Some(sample.component), + coordinate: sample.coordinate, + array_index: sample.array_index, + offset, + level: crate::SampleLevel::Zero, + depth_ref: Some(depth_ref), + } + } + InbuiltFunction::TextureStore => { + if args.len() != 3 && args.len() != 4 { + self.errors.push( + WgslError::new(format!("expected 3 or 4 arguments, found {}", args.len())) + .marker(span), + ); + return Err(CallError::Error); + } + require_generics(self, 0)?; + + let image = self.expr(&args[0], b, fun).ok_or(CallError::Error)?; + let coordinate = self.expr(&args[1], b, fun).ok_or(CallError::Error)?; + let array_index = if args.len() == 4 { + Some(self.expr(&args[2], b, fun).ok_or(CallError::Error)?) + } else { + None + }; + let value = self + .expr(args.last().unwrap(), b, fun) + .ok_or(CallError::Error)?; + + let stmt = crate::Statement::ImageStore { + image, + coordinate, + array_index, + value, + }; + b.push(stmt, span); + return Err(CallError::Error); + } + InbuiltFunction::AtomicLoad => { + require_args(self, 1)?; + require_generics(self, 0)?; + + let pointer = self.expr(&args[0], b, fun).ok_or(CallError::Error)?; + get_atomic_ptr(self, pointer, fun)?; + + crate::Expression::Load { pointer } + } + InbuiltFunction::AtomicStore => { + require_args(self, 2)?; + require_generics(self, 0)?; + + let pointer = self.expr(&args[0], b, fun).ok_or(CallError::Error)?; + let value = self.expr(&args[1], b, fun).ok_or(CallError::Error)?; + get_atomic_ptr(self, pointer, fun)?; + + let stmt = crate::Statement::Store { pointer, value }; + b.push(stmt, span); + return Err(CallError::NoReturn); + } + InbuiltFunction::AtomicAdd => { + return atomic_function(self, crate::AtomicFunction::Add, b, fun); + } + InbuiltFunction::AtomicSub => { + return atomic_function(self, crate::AtomicFunction::Subtract, b, fun); + } + InbuiltFunction::AtomicMax => { + return atomic_function(self, crate::AtomicFunction::Max, b, fun); + } + InbuiltFunction::AtomicMin => { + return atomic_function(self, crate::AtomicFunction::Min, b, fun); + } + InbuiltFunction::AtomicAnd => { + return atomic_function(self, crate::AtomicFunction::And, b, fun); + } + InbuiltFunction::AtomicOr => { + return atomic_function(self, crate::AtomicFunction::InclusiveOr, b, fun); + } + InbuiltFunction::AtomicXor => { + return atomic_function(self, crate::AtomicFunction::ExclusiveOr, b, fun); + } + InbuiltFunction::AtomicExchange => { + return atomic_function( + self, + crate::AtomicFunction::Exchange { compare: None }, + b, + fun, + ); + } + InbuiltFunction::AtomicCompareExchangeWeak => { + require_args(self, 3)?; + require_generics(self, 0)?; + + let pointer = self.expr(&args[0], b, fun).ok_or(CallError::Error)?; + let compare = self.expr(&args[1], b, fun); + let value = self.expr(&args[2], b, fun).ok_or(CallError::Error)?; + + let (kind, width) = get_atomic_ptr(self, pointer, fun)?; + let result = crate::Expression::AtomicResult { + kind, + width, + comparison: true, + }; + let result = fun.expressions.append(result, span); + + let stmt = crate::Statement::Atomic { + pointer, + fun: crate::AtomicFunction::Exchange { compare }, + value, + result, + }; + b.push(stmt, span); + return Ok(result); + } + InbuiltFunction::Pack4x8Snorm => { + math_function(self, crate::MathFunction::Pack4x8snorm, b, fun)? + } + InbuiltFunction::Pack4x8Unorm => { + math_function(self, crate::MathFunction::Pack4x8unorm, b, fun)? + } + InbuiltFunction::Pack2x16Snorm => { + math_function(self, crate::MathFunction::Pack2x16snorm, b, fun)? + } + InbuiltFunction::Pack2x16Unorm => { + math_function(self, crate::MathFunction::Pack2x16unorm, b, fun)? + } + InbuiltFunction::Pack2x16Float => { + math_function(self, crate::MathFunction::Pack2x16float, b, fun)? + } + InbuiltFunction::Unpack4x8Snorm => { + math_function(self, crate::MathFunction::Unpack4x8snorm, b, fun)? + } + InbuiltFunction::Unpack4x8Unorm => { + math_function(self, crate::MathFunction::Unpack4x8unorm, b, fun)? + } + InbuiltFunction::Unpack2x16Snorm => { + math_function(self, crate::MathFunction::Unpack2x16snorm, b, fun)? + } + InbuiltFunction::Unpack2x16Unorm => { + math_function(self, crate::MathFunction::Unpack2x16unorm, b, fun)? + } + InbuiltFunction::Unpack2x16Float => { + math_function(self, crate::MathFunction::Unpack2x16float, b, fun)? + } + InbuiltFunction::StorageBarrier => { + let stmt = crate::Statement::Barrier(crate::Barrier::STORAGE); + b.push(stmt, span); + return Err(CallError::NoReturn); + } + InbuiltFunction::WorkgroupBarrier => { + let stmt = crate::Statement::Barrier(crate::Barrier::WORK_GROUP); + b.push(stmt, span); + return Err(CallError::NoReturn); + } + InbuiltFunction::OuterProduct => { + math_function(self, crate::MathFunction::Outer, b, fun)? + } + _ => { + self.errors + .push(WgslError::new("unimplemented inbuilt function").marker(span)); + return Err(CallError::NoReturn); + } + }; + + Ok(self.emit_expr(expr, span, b, fun)) + } + + fn get_texture_data( + &mut self, + image: Handle, + span: crate::Span, + fun: &crate::Function, + ) -> Option<(ImageClass, bool)> { + let ty = self.type_handle_of(image, fun)?; + match self.data.module.types[ty].inner { + TypeInner::Image { class, arrayed, .. } => Some((class, arrayed)), + _ => { + self.errors.push( + WgslError::new("expected a texture") + .label(span, format!("found `{}`", self.fmt_type(ty))), + ); + None + } + } + } + + fn texture_sample_base<'a>( + &mut self, + span: crate::Span, + args: &mut impl ExactSizeIterator, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option { + if args.len() < 3 { + self.errors.push( + WgslError::new(format!( + "expected at least 3 arguments, found {}", + args.len() + )) + .marker(span), + ); + return None; + } + + // Argument order: image, sampler, coordinate, array_index?. + + let img = args.next().unwrap(); + let image = self.expr(img, b, fun)?; + let sampler = self.expr(args.next().unwrap(), b, fun)?; + let coordinate = self.expr(args.next().unwrap(), b, fun)?; + + let (_, arrayed) = self.get_texture_data(image, img.span, fun)?; + let array_index = if arrayed { + args.next().and_then(|x| self.expr(x, b, fun)) + } else { + None + }; + + Some(ImageSampleBase { + image, + sampler, + coordinate, + array_index, + }) + } + + fn texture_gather_base<'a>( + &mut self, + span: crate::Span, + args: &mut impl ExactSizeIterator, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option { + if args.len() < 3 { + self.errors.push( + WgslError::new(format!( + "expected at least 3 arguments, found {}", + args.len() + )) + .marker(span), + ); + return None; + } + + // Argument order: component?, image, sampler, coordinate, array_index?. + + let component_or_img = args.next().unwrap(); + let img_or_sampler = args.next().unwrap(); + + let img_or_sampler_span = img_or_sampler.span; + let img_or_sampler = self.expr(img_or_sampler, b, fun)?; + + let (component, (image, image_span), sampler) = match *self.type_of(img_or_sampler, fun)? { + TypeInner::Sampler { .. } => { + // component not is present. + let image = self.expr(component_or_img, b, fun)?; + let sampler = img_or_sampler; + (0, (image, component_or_img.span), sampler) + } + _ => { + // component not present. + let component = self.eval.as_positive_int(&self.data, component_or_img)?; + let image = (img_or_sampler, img_or_sampler_span); + let sampler = self.expr(args.next().unwrap(), b, fun)?; + (component, image, sampler) + } + }; + let coordinate = self.expr(args.next().unwrap(), b, fun)?; + + let (_, arrayed) = self.get_texture_data(image, image_span, fun)?; + let array_index = if arrayed { + args.next().and_then(|x| self.expr(x, b, fun)) + } else { + None + }; + + let component = match component { + 0 => crate::SwizzleComponent::X, + 1 => crate::SwizzleComponent::Y, + 2 => crate::SwizzleComponent::Z, + 3 => crate::SwizzleComponent::W, + _ => { + self.errors.push( + WgslError::new(format!("invalid component {}", component)) + .label(component_or_img.span, "expected 0, 1, 2, or 3"), + ); + return None; + } + }; + + Some(ImageGatherBase { + component, + image, + sampler, + coordinate, + array_index, + }) + } + + fn texture_sample_offset<'a>( + &mut self, + args: &mut impl ExactSizeIterator, + ) -> Option> { + args.next().and_then(|x| self.constant(x)) + } + + fn require_arg<'a, T>( + &mut self, + span: crate::Span, + name: &str, + args: &mut impl ExactSizeIterator, + f: impl FnOnce(&mut Self, &'a Expr) -> Option, + ) -> Option { + match args.next() { + Some(arg) => f(self, arg), + None => { + self.errors.push( + WgslError::new("missing an argument") + .label(span, format!("missing `{}`", name)), + ); + None + } + } + } +} + +struct ImageSampleBase { + image: Handle, + sampler: Handle, + coordinate: Handle, + array_index: Option>, +} + +struct ImageGatherBase { + component: crate::SwizzleComponent, + image: Handle, + sampler: Handle, + coordinate: Handle, + array_index: Option>, +} diff --git a/src/front/wgsl/lower/mod.rs b/src/front/wgsl/lower/mod.rs new file mode 100644 index 0000000000..90e6367a3a --- /dev/null +++ b/src/front/wgsl/lower/mod.rs @@ -0,0 +1,1793 @@ +use crate::front::wgsl::lower::const_eval::{Evaluator, ScalarValue, Value}; +use crate::front::wgsl::lower::format::{Pluralize, TypeInnerFormatter}; +use crate::front::wgsl::parse::ast::Literal; +use crate::front::wgsl::resolve::ir::{ + Arg, AssignTarget, Binding, Block, CallExpr, CallTarget, CaseSelector, Constructible, Decl, + DeclId, DeclKind, Expr, ExprKind, ExprStatementKind, Fn, InbuiltType, Let, LocalId, + ShaderStage, Stmt, StmtKind, Struct, TranslationUnit, Type, TypeKind, Var, VarDeclKind, +}; +use crate::front::wgsl::text::Interner; +use crate::front::wgsl::WgslError; +use crate::front::Typifier; +use crate::proc::{Alignment, Layouter, ResolveContext, TypeResolution}; +use crate::{proc, FastHashMap, Handle, TypeInner}; +use std::convert::TryInto; +use std::fmt::Display; + +mod const_eval; +mod construction; +mod format; +mod inbuilt_function; + +struct EvaluationData<'a> { + tu: &'a TranslationUnit, + decl_map: FastHashMap, + module: crate::Module, +} + +pub struct Lowerer<'a> { + eval: Evaluator, + intern: &'a Interner, + errors: Vec, + layouter: Layouter, + typifier: Typifier, + locals: FastHashMap, + data: EvaluationData<'a>, +} + +enum DeclData { + Function(Handle), + Global(Handle), + Const(Handle), + Type(Handle), + Assert, + Override, + EntryPoint, + Error, +} + +enum LocalData { + Variable(Handle), + Let(Handle), + FunctionArg(u32), +} + +struct RefExpression { + handle: InferenceExpression, + is_ref: bool, +} + +#[derive(Copy, Clone)] +enum InferenceExpression { + Concrete(Handle), + AbstractInt(i64), + AbstractFloat(f64), +} + +enum CallError { + NoReturn, + Error, +} + +impl<'a> Lowerer<'a> { + pub fn new(module: &'a TranslationUnit, intern: &'a Interner) -> Self { + Self { + eval: Evaluator::new(), + intern, + errors: Vec::new(), + layouter: Layouter::default(), + typifier: Typifier::default(), + locals: FastHashMap::default(), + data: EvaluationData { + tu: module, + decl_map: FastHashMap::default(), + module: crate::Module::default(), + }, + } + } + + pub fn lower(mut self) -> Result> { + for (id, decl) in self.data.tu.decls_ordered() { + let data = self.decl(decl); + self.data.decl_map.insert(id, data); + } + + let eval_errors = self.eval.finish(); + if self.errors.is_empty() && eval_errors.is_empty() { + Ok(self.data.module) + } else { + self.errors.extend(eval_errors); + Err(self.errors) + } + } + + fn decl(&mut self, decl: &Decl) -> DeclData { + match decl.kind { + DeclKind::Fn(ref f) => { + let handle = self.fn_(f, decl.span); + handle + .map(DeclData::Function) + .unwrap_or(DeclData::EntryPoint) + } + DeclKind::Override(_) => { + self.errors + .push(WgslError::new("overrides are not supported yet").marker(decl.span)); + DeclData::Override + } + DeclKind::Var(ref v) => { + let handle = self.var(v, decl.span); + handle.map(DeclData::Global).unwrap_or(DeclData::Error) + } + DeclKind::Const(ref c) => { + let handle = self.const_(c, decl.span); + handle.map(DeclData::Const).unwrap_or(DeclData::Error) + } + DeclKind::StaticAssert(ref expr) => { + let value = self.eval.as_bool(&self.data, expr).unwrap_or(true); + if !value { + self.errors + .push(WgslError::new("static assertion failed").marker(decl.span)); + } + DeclData::Assert + } + DeclKind::Struct(ref s) => { + let handle = self.struct_(s, decl.span); + handle.map(DeclData::Type).unwrap_or(DeclData::Error) + } + DeclKind::Type(ref ty) => { + let handle = self.ty(&ty.ty); + handle.map(DeclData::Type).unwrap_or(DeclData::Error) + } + } + } + + fn fn_(&mut self, f: &Fn, span: crate::Span) -> Option> { + let name = self.intern.resolve(f.name.name).to_string(); + + self.locals.clear(); + self.typifier.reset(); + let mut fun = crate::Function { + name: Some(name.clone()), + arguments: f + .args + .iter() + .enumerate() + .filter_map(|(i, arg)| { + self.locals.insert(arg.id, LocalData::FunctionArg(i as u32)); + self.arg(arg) + }) + .collect(), + result: f.ret.as_ref().and_then(|x| { + let ty = self.ty(x)?; + Some(crate::FunctionResult { + ty, + binding: f + .ret_binding + .as_ref() + .and_then(|b| self.binding(b, x.span, ty)), + }) + }), + local_variables: Default::default(), + expressions: Default::default(), + named_expressions: Default::default(), + body: Default::default(), + }; + + let mut body = self.block(&f.block, &mut fun); + proc::ensure_block_returns(&mut body); + fun.body = body; + + let entry = match f.stage { + ShaderStage::None => { + return Some(self.data.module.functions.append(fun, span)); + } + ShaderStage::Vertex => crate::EntryPoint { + name, + stage: crate::ShaderStage::Vertex, + early_depth_test: None, + workgroup_size: [0, 0, 0], + function: fun, + }, + ShaderStage::Fragment(early_depth_test) => crate::EntryPoint { + name, + stage: crate::ShaderStage::Fragment, + early_depth_test, + workgroup_size: [0, 0, 0], + function: fun, + }, + ShaderStage::Compute(ref x, ref y, ref z) => crate::EntryPoint { + name, + stage: crate::ShaderStage::Compute, + early_depth_test: None, + workgroup_size: [ + x.as_ref() + .and_then(|x| self.eval.as_positive_int(&self.data, x)) + .unwrap_or(1), + y.as_ref() + .and_then(|y| self.eval.as_positive_int(&self.data, y)) + .unwrap_or(1), + z.as_ref() + .and_then(|z| self.eval.as_positive_int(&self.data, z)) + .unwrap_or(1), + ], + function: fun, + }, + }; + + self.data.module.entry_points.push(entry); + None + } + + fn var(&mut self, v: &Var, span: crate::Span) -> Option> { + let name = self.intern.resolve(v.inner.name.name).to_string(); + let init = v + .inner + .val + .as_ref() + .and_then(|x| self.eval.eval(&self.data, x).map(move |v| (v, x.span))); + + let ty = self + .ty(&v.inner.ty) + .or_else(|| init.as_ref().map(|&(ref init, _)| self.val_to_ty(init))); + + let ty = if let Some(ty) = ty { + ty + } else { + self.errors.push( + WgslError::new("global variable must have a type or an initializer").marker(span), + ); + return None; + }; + + let binding = if let Some(ref binding) = v.attribs.binding { + if let Some(ref group) = v.attribs.group { + let binding = self.eval.as_positive_int(&self.data, binding).unwrap_or(0); + let group = self.eval.as_positive_int(&self.data, group).unwrap_or(0); + Some(crate::ResourceBinding { binding, group }) + } else { + self.errors.push( + WgslError::new("resource variable must have both binding and group") + .marker(span), + ); + None + } + } else { + None + }; + + let var = crate::GlobalVariable { + name: Some(name), + space: v.inner.address_space, + binding, + ty, + init: init.map(|(v, span)| self.val_to_const(v, span)), + }; + + Some(self.data.module.global_variables.append(var, span)) + } + + fn struct_(&mut self, s: &Struct, span: crate::Span) -> Option> { + let name = self.intern.resolve(s.name.name).to_string(); + + let mut members = Vec::with_capacity(s.fields.len()); + let mut offset = 0; + let mut alignment = Alignment::ONE; + + for field in s.fields.iter() { + let name = self.intern.resolve(field.name.name).to_string(); + let ty = self.ty(&field.ty)?; + let binding = field + .attribs + .binding + .as_ref() + .and_then(|x| self.binding(x, field.name.span, ty)); + + self.layouter + .update(&self.data.module.types, &self.data.module.constants) + .unwrap(); + + let min_align = self.layouter[ty].alignment; + let min_size = self.layouter[ty].size; + + let align = field + .attribs + .align + .as_ref() + .and_then(|x| self.eval.as_positive_int(&self.data, x)); + let size = field + .attribs + .size + .as_ref() + .and_then(|x| self.eval.as_positive_int(&self.data, x)) + .unwrap_or(min_size); + + if size < min_size { + self.errors.push( + WgslError::new("size attribute is too small") + .label(field.name.span, format!("set size is `{}`", size)) + .label(field.ty.span, format!("type size is `{}`", min_size)), + ); + } + + let align = if let Some(align) = align { + if let Some(align) = Alignment::new(align) { + if align >= min_align { + align + } else { + self.errors.push( + WgslError::new("alignment attribute is too small") + .label(field.name.span, format!("set alignment is `{}`", align)) + .label(field.ty.span, format!("type alignment is `{}`", min_align)), + ); + min_align + } + } else { + self.errors.push( + WgslError::new("alignment must be a power of two") + .label(field.name.span, format!("set to `{}`", align)), + ); + min_align + } + } else { + min_align + }; + + offset = align.round_up(offset); + alignment = alignment.max(align); + + members.push(crate::StructMember { + name: Some(name), + binding, + ty, + offset, + }); + + offset += size; + } + + let ty = crate::Type { + name: Some(name), + inner: TypeInner::Struct { + members, + span: alignment.round_up(offset), + }, + }; + + Some(self.data.module.types.insert(ty, span)) + } + + fn const_(&mut self, c: &Let, span: crate::Span) -> Option> { + let ident = self.intern.resolve(c.name.name).to_string(); + let value = self.eval.eval(&self.data, &c.val)?; + let ty = self.ty(&c.ty); + + if let Some(ty) = ty { + let inferred = self.val_to_ty(&value); + if !self.data.module.types[ty].inner.equivalent( + &self.data.module.types[inferred].inner, + &self.data.module.types, + ) { + self.errors.push( + WgslError::new("mismatched types") + .label(c.ty.span, format!("expected {}", self.fmt_type(ty))) + .label(c.val.span, format!("found {}", self.fmt_type(inferred))), + ); + } + } + + let constant = crate::Constant { + name: Some(ident), + specialization: None, + inner: self.val_to_const_inner(value, span), + }; + Some(self.data.module.constants.append(constant, span)) + } + + fn arg(&mut self, arg: &Arg) -> Option { + let ty = self.ty(&arg.ty)?; + Some(crate::FunctionArgument { + name: Some(self.intern.resolve(arg.name.name).to_string()), + ty, + binding: arg + .binding + .as_ref() + .and_then(|x| self.binding(x, arg.span, ty)), + }) + } + + fn block(&mut self, b: &Block, fun: &mut crate::Function) -> crate::Block { + let mut block = crate::Block::with_capacity(b.stmts.len()); + + for stmt in b.stmts.iter() { + self.stmt(stmt, &mut block, fun); + } + + block + } + + fn stmt(&mut self, s: &Stmt, b: &mut crate::Block, fun: &mut crate::Function) { + let stmt = match s.kind { + StmtKind::Expr(ref k) => return self.expr_stmt(k, s.span, b, fun), + StmtKind::Block(ref b) => crate::Statement::Block(self.block(b, fun)), + StmtKind::Break => crate::Statement::Break, + StmtKind::Continue => crate::Statement::Continue, + StmtKind::Discard => crate::Statement::Kill, + StmtKind::For(ref f) => { + let mut block = crate::Block::with_capacity(2); + if let Some(ref x) = f.init { + self.expr_stmt(&x.kind, x.span, &mut block, fun); + } + + let mut body = crate::Block::with_capacity(2); + if let Some(ref x) = f.cond { + if let Some(condition) = self.expr(x, &mut body, fun) { + body.push( + crate::Statement::If { + condition, + accept: crate::Block::new(), + reject: { + let mut b = crate::Block::new(); + b.push(crate::Statement::Break, x.span); + b + }, + }, + x.span, + ); + } + } + body.push( + crate::Statement::Block(self.block(&f.block, fun)), + f.block.span, + ); + + let mut continuing = crate::Block::new(); + if let Some(ref x) = f.update { + self.expr_stmt(&x.kind, x.span, &mut continuing, fun) + } + + block.push( + crate::Statement::Loop { + body, + continuing, + break_if: None, + }, + s.span, + ); + + crate::Statement::Block(block) + } + StmtKind::If(ref i) => { + let condition = if let Some(condition) = self.expr(&i.cond, b, fun) { + condition + } else { + return; + }; + let accept = self.block(&i.block, fun); + let reject = i + .else_ + .as_ref() + .map(|stmt| { + let mut b = crate::Block::with_capacity(1); + self.stmt(stmt, &mut b, fun); + b + }) + .unwrap_or_default(); + + crate::Statement::If { + condition, + accept, + reject, + } + } + StmtKind::Loop(ref l) => { + let body = self.block(&l.body, fun); + let continuing = l + .continuing + .as_ref() + .map(|x| self.block(x, fun)) + .unwrap_or_default(); + let break_if = l.break_if.as_ref().and_then(|x| self.expr(x, b, fun)); + + crate::Statement::Loop { + body, + continuing, + break_if, + } + } + StmtKind::Return(ref e) => crate::Statement::Return { + value: e.as_ref().and_then(|x| self.expr(x, b, fun)), + }, + StmtKind::StaticAssert(ref expr) => { + if let Some(value) = self.eval.as_bool(&self.data, expr) { + if !value { + self.errors + .push(WgslError::new("static assertion failed").marker(expr.span)); + } + } + + return; + } + StmtKind::Switch(ref s) => { + let selector = if let Some(selector) = self.expr(&s.expr, b, fun) { + selector + } else { + return; + }; + let cases = s + .cases + .iter() + .flat_map(|x| { + x.selectors + .iter() + .filter_map(|sel| { + let value = match *sel { + CaseSelector::Expr(ref e) => { + let value = self.eval.as_int(&self.data, e)?; + crate::SwitchValue::Integer(value) + } + CaseSelector::Default => crate::SwitchValue::Default, + }; + Some(crate::SwitchCase { + value, + body: self.block(&x.block, fun), + fall_through: false, + }) + }) + .collect::>() + }) + .collect(); + crate::Statement::Switch { selector, cases } + } + StmtKind::While(ref w) => { + let mut body = crate::Block::with_capacity(3); + if let Some(condition) = self.expr(&w.cond, &mut body, fun) { + body.push( + crate::Statement::If { + condition, + accept: crate::Block::new(), + reject: { + let mut b = crate::Block::new(); + b.push(crate::Statement::Break, w.cond.span); + b + }, + }, + w.cond.span, + ); + } + + let b = self.block(&w.block, fun); + body.push(crate::Statement::Block(b), w.block.span); + + crate::Statement::Loop { + body, + continuing: crate::Block::new(), + break_if: None, + } + } + }; + b.push(stmt, s.span); + } + + fn expr_stmt( + &mut self, + s: &ExprStatementKind, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) { + match *s { + ExprStatementKind::VarDecl(ref decl) => match decl.kind { + VarDeclKind::Var(ref v) => { + let name = self.intern.resolve(v.name.name).to_string(); + let expr = v.val.as_ref().and_then(|x| self.expr(x, b, fun)); + let ty = self.ty(&v.ty); + let inferred = expr.and_then(|x| self.type_handle_of(x, fun)); + + if let Some(ty) = ty { + if let Some(inferred) = inferred { + if !self.data.module.types[ty].inner.equivalent( + &self.data.module.types[inferred].inner, + &self.data.module.types, + ) { + self.errors.push( + WgslError::new("mismatched types") + .label(v.ty.span, format!("expected {}", self.fmt_type(ty))) + .label( + v.val.as_ref().unwrap().span, + format!("found {}", self.fmt_type(inferred)), + ), + ); + } + } + } + + if let Some(ty) = ty.or(inferred) { + let var = fun.local_variables.append( + crate::LocalVariable { + name: Some(name.clone()), + ty, + init: None, + }, + span, + ); + if let Some(expr) = expr { + fun.named_expressions.insert(expr, name); + b.push( + crate::Statement::Store { + pointer: fun + .expressions + .append(crate::Expression::LocalVariable(var), span), + value: expr, + }, + span, + ); + } + + self.locals.insert(decl.id, LocalData::Variable(var)); + } else { + self.errors.push( + WgslError::new( + "variable declaration must have either initializer or type", + ) + .marker(span), + ); + } + } + VarDeclKind::Const(_) => { + self.errors.push( + WgslError::new("const declarations are not supported here yet") + .marker(span), + ); + } + VarDeclKind::Let(ref l) => { + let name = self.intern.resolve(l.name.name).to_string(); + let expr = self.expr(&l.val, b, fun); + let ty = self.ty(&l.ty); + + if let Some(ty) = ty { + let inferred = expr.and_then(|x| self.type_handle_of(x, fun)); + if let Some(inferred) = inferred { + if !self.data.module.types[ty].inner.equivalent( + &self.data.module.types[inferred].inner, + &self.data.module.types, + ) { + self.errors.push( + WgslError::new("mismatched types") + .label(l.ty.span, format!("expected {}", self.fmt_type(ty))) + .label( + l.val.span, + format!("found {}", self.fmt_type(inferred)), + ), + ); + } + } + } + + if let Some(expr) = expr { + fun.named_expressions.insert(expr, name); + self.locals.insert(decl.id, LocalData::Let(expr)); + } + } + }, + ExprStatementKind::Call(ref call) => { + let _ = self.call(call, span, b, fun); + } + ExprStatementKind::Assign(ref assign) => { + let rhs = if let Some(rhs) = self.expr_load(&assign.value, b, fun) { + rhs + } else { + return; + }; + let lhs = if let AssignTarget::Expr(ref lhs) = assign.target { + lhs + } else { + return; + }; + + if let Some(l) = self.expr_base(lhs, b, fun) { + let lc = self.concretize(l.handle, lhs.span, b, fun); + if !l.is_ref { + let mut error = WgslError::new("cannot assign to value").marker(lhs.span); + + if let crate::Expression::Swizzle { .. } = fun.expressions[lc] { + error.notes.push("cannot assign to a swizzle".to_string()); + error.notes.push( + "consider assigning to each component separately".to_string(), + ); + } + if fun.named_expressions.contains_key(&lc) { + error + .notes + .push("cannot assign to a `let` binding".to_string()); + error.notes.push("consider using `var` instead".to_string()); + } + + self.errors.push(error); + } + + let value = if let Some(op) = assign.op { + let left = + self.emit_expr(crate::Expression::Load { pointer: lc }, span, b, fun); + let mut right = if let Some(rhs) = + self.unify_exprs(left, rhs, assign.value.span, b, fun) + { + rhs + } else { + return; + }; + + // Insert splats if required (only on the right side). + if op != crate::BinaryOperator::Multiply { + let left_size = match self.type_of(left, fun) { + Some(&TypeInner::Vector { size, .. }) => Some(size), + _ => None, + }; + if let (Some(size), Some(&TypeInner::Scalar { .. })) = + (left_size, self.type_of(right, fun)) + { + right = self.emit_expr( + crate::Expression::Splat { size, value: right }, + assign.value.span, + b, + fun, + ); + } + } + + self.emit_expr(crate::Expression::Binary { left, op, right }, span, b, fun) + } else { + self.concretize(rhs, assign.value.span, b, fun) + }; + + b.push(crate::Statement::Store { pointer: lc, value }, span); + } + } + } + } + + fn expr( + &mut self, + e: &Expr, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let expr = self.expr_load(e, b, fun)?; + Some(self.concretize(expr, e.span, b, fun)) + } + + fn expr_load( + &mut self, + e: &Expr, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option { + let expr = self.expr_base(e, b, fun)?; + Some(if expr.is_ref { + let expr = self.emit_expr( + crate::Expression::Load { + pointer: match expr.handle { + InferenceExpression::Concrete(h) => h, + _ => unreachable!("abstract values are not references"), + }, + }, + e.span, + b, + fun, + ); + InferenceExpression::Concrete(expr) + } else { + expr.handle + }) + } + + fn expr_base( + &mut self, + e: &Expr, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option { + let (expr, is_ref) = match e.kind { + ExprKind::Error => return None, + ExprKind::Literal(ref l) => { + let inner = match *l { + Literal::Bool(b) => crate::ConstantInner::Scalar { + width: 1, + value: crate::ScalarValue::Bool(b), + }, + Literal::AbstractInt(i) => { + return Some(RefExpression { + handle: InferenceExpression::AbstractInt(i), + is_ref: false, + }) + } + Literal::AbstractFloat(f) => { + return Some(RefExpression { + handle: InferenceExpression::AbstractFloat(f), + is_ref: false, + }) + } + Literal::I32(i) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Sint(i as _), + }, + Literal::U32(i) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Uint(i as _), + }, + Literal::F32(f) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Float(f as _), + }, + Literal::F16(f) => crate::ConstantInner::Scalar { + width: 2, + value: crate::ScalarValue::Float(f.to_f64()), + }, + }; + + ( + crate::Expression::Constant(self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + inner, + specialization: None, + }, + crate::Span::UNDEFINED, + )), + false, + ) + } + ExprKind::Local(local) => match *self.locals.get(&local)? { + LocalData::Variable(var) => (crate::Expression::LocalVariable(var), true), + LocalData::Let(l) => { + return Some(RefExpression { + handle: InferenceExpression::Concrete(l), + is_ref: false, + }) + } + LocalData::FunctionArg(arg) => (crate::Expression::FunctionArgument(arg), false), + }, + ExprKind::Global(global) => match *self.data.decl_map.get(&global)? { + DeclData::Function(_) | DeclData::EntryPoint => { + self.errors.push( + WgslError::new("function cannot be used as an expression") + .marker(e.span) + .note("all function calls must be resolved statically"), + ); + return None; + } + DeclData::Global(var) => { + let space = self.data.module.global_variables[var].space; + ( + crate::Expression::GlobalVariable(var), + !matches!(space, crate::AddressSpace::Handle), + ) + } + DeclData::Const(constant) => (crate::Expression::Constant(constant), false), + DeclData::Type(_) => { + self.errors + .push(WgslError::new("expected value, found type").marker(e.span)); + return None; + } + DeclData::Assert | DeclData::Override | DeclData::Error => return None, + }, + ExprKind::Unary(ref un) => { + let expr = self.expr(&un.expr, b, fun)?; + (crate::Expression::Unary { op: un.op, expr }, false) + } + ExprKind::Binary(ref bin) => { + let mut left = self.expr(&bin.lhs, b, fun)?; + let right = self.expr_load(&bin.rhs, b, fun)?; + let mut right = self.unify_exprs(left, right, bin.rhs.span, b, fun)?; + + // Insert splats if required. + if bin.op != crate::BinaryOperator::Multiply { + let left_size = match *self.type_of(left, fun)? { + TypeInner::Vector { size, .. } => Some(size), + _ => None, + }; + match (left_size, self.type_of(right, fun)?) { + (Some(size), &TypeInner::Scalar { .. }) => { + right = self.emit_expr( + crate::Expression::Splat { size, value: right }, + bin.rhs.span, + b, + fun, + ); + } + (None, &TypeInner::Vector { size, .. }) => { + left = self.emit_expr( + crate::Expression::Splat { size, value: left }, + bin.lhs.span, + b, + fun, + ); + } + _ => {} + } + } + + ( + crate::Expression::Binary { + left, + right, + op: bin.op, + }, + false, + ) + } + ExprKind::Call(ref call) => { + return match self.call(call, e.span, b, fun) { + Ok(expr) => Some(RefExpression { + handle: InferenceExpression::Concrete(expr), + is_ref: false, + }), + Err(CallError::NoReturn) => { + self.errors.push( + WgslError::new("function does not return any value").marker(e.span), + ); + None + } + Err(CallError::Error) => None, + } + } + ExprKind::Index(ref base, ref index) => { + let base_ref = self.expr_base(base, b, fun)?; + let base_c = self.concretize(base_ref.handle, base.span, b, fun); + let index = self.expr(index, b, fun)?; + + let ty = self.type_handle_of(base_c, fun)?; + if self.data.module.types[ty].inner.pointer_space().is_some() && !base_ref.is_ref { + self.errors.push( + WgslError::new("cannot index a pointer") + .label(base.span, format!("found type `{}`", self.fmt_type(ty))) + .note("consider dereferencing first"), + ); + return None; + } + + // Use `AccessIndex` if possible (`index` is an `Expression::Constant`). + // TODO: Remove this when the SPIR-V backend can see through constant expressions. + let expr = if let crate::Expression::Constant(c) = fun.expressions[index] { + match self.data.module.constants[c].inner { + crate::ConstantInner::Scalar { value, .. } => match value { + crate::ScalarValue::Uint(u) => { + if let Ok(index) = u.try_into() { + crate::Expression::AccessIndex { + base: base_c, + index, + } + } else { + crate::Expression::Access { + base: base_c, + index, + } + } + } + crate::ScalarValue::Sint(i) => { + if let Ok(index) = i.try_into() { + crate::Expression::AccessIndex { + base: base_c, + index, + } + } else { + crate::Expression::Access { + base: base_c, + index, + } + } + } + _ => crate::Expression::Access { + base: base_c, + index, + }, + }, + _ => crate::Expression::Access { + base: base_c, + index, + }, + } + } else { + crate::Expression::Access { + base: base_c, + index, + } + }; + (expr, base_ref.is_ref) + } + ExprKind::AddrOf(ref e) => { + let expr = self.expr_base(e, b, fun)?; + if !expr.is_ref { + let mut error = + WgslError::new("cannot take the address of this expression").marker(e.span); + + if matches!(e.kind, ExprKind::Local(l) if matches!(self.locals[&l], LocalData::Let(_))) + { + error + .notes + .push("`let` bindings resolve to values, not references".to_string()); + } + + error.notes.push( + "consider assigning to a `var` and then taking the address".to_string(), + ); + + self.errors.push(error); + return None; + } + + return Some(RefExpression { + handle: expr.handle, + is_ref: false, + }); + } + ExprKind::Deref(ref e) => { + let expr = self.expr(e, b, fun)?; + let ty = self.type_handle_of(expr, fun)?; + if self.data.module.types[ty].inner.pointer_space().is_none() { + self.errors.push( + WgslError::new("cannot dereference this expression") + .label(e.span, format!("has type `{}`", self.fmt_type(ty))), + ); + return None; + } + + return Some(RefExpression { + handle: InferenceExpression::Concrete(expr), + is_ref: true, + }); + } + ExprKind::Member(ref e, m) => { + let expr = self.expr_base(e, b, fun)?; + let e_c = self.concretize(expr.handle, e.span, b, fun); + + let ty = self.type_handle_of(e_c, fun)?; + let (ty, is_ref) = if expr.is_ref { + match self.data.module.types[ty].inner { + TypeInner::Pointer { base, .. } => (base, true), + TypeInner::ValuePointer { + size: Some(size), + kind, + width, + .. + } => ( + self.register_type(TypeInner::Vector { size, kind, width }), + true, + ), + _ => unreachable!("got reference without pointer type"), + } + } else { + (ty, false) + }; + + let error = |this: &mut Self| { + this.errors.push( + WgslError::new(format!("unknown field of type `{}`", this.fmt_type(ty))) + .marker(m.span), + ); + }; + + match self.data.module.types[ty].inner { + TypeInner::Vector { .. } => { + let mem = self.intern.resolve(m.name); + return if mem.len() == 1 { + let index = match mem.chars().next().unwrap() { + 'x' => 0, + 'y' => 1, + 'z' => 2, + 'w' => 3, + 'r' => 0, + 'g' => 1, + 'b' => 2, + 'a' => 3, + _ => { + error(self); + return None; + } + }; + let out = self.emit_expr( + crate::Expression::AccessIndex { base: e_c, index }, + e.span, + b, + fun, + ); + Some(RefExpression { + handle: InferenceExpression::Concrete(out), + is_ref: expr.is_ref, + }) + } else if mem.len() > 4 { + self.errors.push( + WgslError::new("vector swizzle must be between 1 and 4 elements") + .marker(m.span), + ); + None + } else { + let size = match mem.len() { + 2 => crate::VectorSize::Bi, + 3 => crate::VectorSize::Tri, + 4 => crate::VectorSize::Quad, + _ => unreachable!(), + }; + let mut pattern = [crate::SwizzleComponent::X; 4]; + + let mut is_pattern_xyzw = None; + + for (i, char) in mem.chars().enumerate() { + let (comp, used_xyzw) = match char { + 'x' => (crate::SwizzleComponent::X, true), + 'y' => (crate::SwizzleComponent::Y, true), + 'z' => (crate::SwizzleComponent::Z, true), + 'w' => (crate::SwizzleComponent::W, true), + 'r' => (crate::SwizzleComponent::X, false), + 'g' => (crate::SwizzleComponent::Y, false), + 'b' => (crate::SwizzleComponent::Z, false), + 'a' => (crate::SwizzleComponent::W, false), + _ => { + error(self); + return None; + } + }; + pattern[i] = comp; + + match is_pattern_xyzw { + Some(true) if !used_xyzw => { + self.errors.push( + WgslError::new( + "cannot mix xyzw and rgba swizzle components", + ) + .marker(m.span), + ); + return None; + } + Some(false) if used_xyzw => { + self.errors.push( + WgslError::new( + "cannot mix xyzw and rgba swizzle components", + ) + .marker(m.span), + ); + return None; + } + None => { + is_pattern_xyzw = Some(used_xyzw); + } + _ => {} + } + } + + let concrete = self.concretize(expr.handle, e.span, b, fun); + // Load the vector for the swizzle. + let expr = if is_ref { + self.emit_expr( + crate::Expression::Load { pointer: concrete }, + e.span, + b, + fun, + ) + } else { + concrete + }; + + let swizzle = self.emit_expr( + crate::Expression::Swizzle { + size, + vector: expr, + pattern, + }, + e.span, + b, + fun, + ); + return Some(RefExpression { + handle: InferenceExpression::Concrete(swizzle), + is_ref: false, + }); + }; + } + TypeInner::Matrix { .. } => { + let mem = self.intern.resolve(m.name); + return if mem.len() == 1 { + let index = match mem.chars().next().unwrap() { + 'x' => 0, + 'y' => 1, + 'z' => 2, + 'w' => 3, + 'r' => 0, + 'g' => 1, + 'b' => 2, + 'a' => 3, + _ => { + error(self); + return None; + } + }; + let base = self.concretize(expr.handle, e.span, b, fun); + let concrete = self.emit_expr( + crate::Expression::AccessIndex { base, index }, + e.span, + b, + fun, + ); + Some(RefExpression { + handle: InferenceExpression::Concrete(concrete), + is_ref: expr.is_ref, + }) + } else { + self.errors.push( + WgslError::new("vector swizzle must be between 1 and 4 elements") + .marker(m.span), + ); + None + }; + } + TypeInner::Struct { ref members, .. } => { + for (i, member) in members.iter().enumerate() { + if self.intern.resolve(m.name) == member.name.as_ref().unwrap().as_str() + { + let base = self.concretize(expr.handle, e.span, b, fun); + let concrete = self.emit_expr( + crate::Expression::AccessIndex { + base, + index: i as _, + }, + e.span, + b, + fun, + ); + return Some(RefExpression { + handle: InferenceExpression::Concrete(concrete), + is_ref: expr.is_ref, + }); + } + } + + error(self); + } + _ => { + let mut error = WgslError::new(format!( + "unknown field of type `{}`", + self.fmt_type(ty) + )) + .marker(m.span); + + if self.data.module.types[ty].inner.pointer_space().is_some() { + error.notes.push("consider dereferencing first".to_string()); + } + + self.errors.push(error); + } + } + + return None; + } + }; + let handle = self.emit_expr(expr, e.span, b, fun); + + Some(RefExpression { + handle: InferenceExpression::Concrete(handle), + is_ref, + }) + } + + fn emit_expr( + &mut self, + expr: crate::Expression, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Handle { + let needs_emit = !expr.needs_pre_emit(); + let start = fun.expressions.len(); + let handle = fun.expressions.append(expr, span); + + if needs_emit { + b.push( + crate::Statement::Emit(fun.expressions.range_from(start)), + span, + ); + } + + handle + } + + fn call( + &mut self, + call: &CallExpr, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Result, CallError> { + match call.target { + CallTarget::Construction(ref ty) => self + .construct(ty, &call.args, call.target_span, b, fun) + .ok_or(CallError::Error), + CallTarget::Decl(id) => match self.data.decl_map[&id] { + DeclData::Function(function) => { + let result = if self.data.module.functions[function].result.is_some() { + let expr = fun + .expressions + .append(crate::Expression::CallResult(function), span); + Some(expr) + } else { + None + }; + let target_args: Vec<_> = self.data.module.functions[function] + .arguments + .iter() + .map(|x| x.ty) + .collect(); + + let spans = call.args.iter().map(|x| x.span); + self.check_arg_count(target_args.len(), spans) + .ok_or(CallError::Error)?; + + let stmt = crate::Statement::Call { + function, + arguments: call + .args + .iter() + .zip(target_args) + .filter_map(|(arg, ty)| { + let expr = self.expr_load(arg, b, fun)?; + self.unify_with_type(ty, expr, arg.span, b, fun) + }) + .collect(), + result, + }; + b.push(stmt, span); + + result.ok_or(CallError::NoReturn) + } + DeclData::Const(_) | DeclData::Global(_) => { + self.errors.push( + WgslError::new("cannot call a value").label(span, "expected function"), + ); + Err(CallError::Error) + } + DeclData::Type(ty) => self + .construct(&Constructible::Type(ty), &call.args, span, b, fun) + .ok_or(CallError::Error), + DeclData::EntryPoint => { + self.errors + .push(WgslError::new("cannot call entry point").marker(span)); + Err(CallError::Error) + } + DeclData::Assert | DeclData::Override | DeclData::Error => Err(CallError::Error), + }, + CallTarget::InbuiltFunction(inbuilt, ref generics) => { + self.inbuilt_function(inbuilt, generics, &call.args, span, b, fun) + } + CallTarget::Error => Err(CallError::Error), + } + } + + fn binding( + &mut self, + binding: &Binding, + span: crate::Span, + ty: Handle, + ) -> Option { + match *binding { + Binding::Builtin(b) => Some(crate::Binding::BuiltIn(b)), + Binding::Location { + ref location, + interpolation, + sampling, + } => { + if let Some(ref loc) = *location { + let mut binding = crate::Binding::Location { + location: self.eval.as_positive_int(&self.data, loc)?, + interpolation, + sampling, + }; + binding.apply_default_interpolation(&self.data.module.types[ty].inner); + + Some(binding) + } else { + self.errors.push( + WgslError::new("location must be specified for all bindings").marker(span), + ); + None + } + } + } + } + + fn type_of( + &mut self, + expr: Handle, + fun: &crate::Function, + ) -> Option<&TypeInner> { + match self.typifier.grow( + expr, + &fun.expressions, + &ResolveContext { + constants: &self.data.module.constants, + types: &self.data.module.types, + global_vars: &self.data.module.global_variables, + local_vars: &fun.local_variables, + functions: &self.data.module.functions, + arguments: &fun.arguments, + }, + ) { + Ok(_) => {} + Err(e) => { + self.errors + .push(WgslError::new(format!("type error: {:?}", e))); + return None; + } + } + + Some(self.typifier.get(expr, &self.data.module.types)) + } + + fn type_handle_of( + &mut self, + expr: Handle, + fun: &crate::Function, + ) -> Option> { + let _ = self.type_of(expr, fun); + match self.typifier.resolutions.get(expr.index()) { + Some(&TypeResolution::Handle(h)) => Some(h), + Some(&TypeResolution::Value(ref inner)) => Some(self.register_type(inner.clone())), + None => None, + } + } + + fn fmt_type(&self, ty: Handle) -> impl Display + '_ { + self.data.module.types[ty] + .name + .as_ref() + .expect("type without name") + } + + fn ty(&mut self, ty: &Type) -> Option> { + match ty.kind { + TypeKind::Inbuilt(ref inbuilt) => { + let inner = match *inbuilt { + InbuiltType::Scalar { kind, width } => TypeInner::Scalar { kind, width }, + InbuiltType::Vector { size, kind, width } => { + TypeInner::Vector { size, kind, width } + } + InbuiltType::Matrix { + columns, + rows, + width, + } => TypeInner::Matrix { + columns, + rows, + width, + }, + InbuiltType::Image { + dim, + arrayed, + class, + } => TypeInner::Image { + dim, + arrayed, + class, + }, + InbuiltType::Sampler { comparison } => TypeInner::Sampler { comparison }, + InbuiltType::Array { ref of, ref len } => { + let base = self.ty(of)?; + self.layouter + .update(&self.data.module.types, &self.data.module.constants) + .unwrap(); + TypeInner::Array { + base, + size: len + .as_ref() + .and_then(|x| self.array_size(x)) + .unwrap_or(crate::ArraySize::Dynamic), + stride: self.layouter[base].to_stride(), + } + } + InbuiltType::BindingArray { ref of, ref len } => { + let base = self.ty(of)?; + TypeInner::BindingArray { + base, + size: len + .as_ref() + .and_then(|x| self.array_size(x)) + .unwrap_or(crate::ArraySize::Dynamic), + } + } + InbuiltType::Pointer { ref to, space } => TypeInner::Pointer { + base: self.ty(to)?, + space, + }, + InbuiltType::Atomic { kind, width } => TypeInner::Atomic { kind, width }, + InbuiltType::Infer => return None, + }; + + Some(self.register_type(inner)) + } + TypeKind::User(ref id) => match self.data.decl_map[id] { + DeclData::Type(handle) => Some(handle), + ref x => { + self.errors.push( + WgslError::new("expected type").label(ty.span, format!("found `{}`", x)), + ); + None + } + }, + } + } + + fn register_type(&mut self, inner: TypeInner) -> Handle { + self.data.module.types.insert( + crate::Type { + name: Some( + TypeInnerFormatter { + ty: &inner, + types: &self.data.module.types, + constants: &self.data.module.constants, + } + .to_string(), + ), + inner, + }, + crate::Span::UNDEFINED, + ) + } + + fn constant(&mut self, expr: &Expr) -> Option> { + let value = self.eval.eval(&self.data, expr)?; + Some(self.val_to_const(value, expr.span)) + } + + fn val_to_const(&mut self, value: Value, span: crate::Span) -> Handle { + let inner = self.val_to_const_inner(value, span); + self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner, + }, + crate::Span::UNDEFINED, + ) + } + + fn val_to_const_inner(&mut self, value: Value, span: crate::Span) -> crate::ConstantInner { + let scalar_to_const = |this: &mut Self, scalar: ScalarValue| { + let (width, value) = this.val_to_scalar(scalar); + + crate::ConstantInner::Scalar { width, value } + }; + + let ty = self.val_to_ty(&value); + match value { + Value::Scalar(scalar) => scalar_to_const(self, scalar), + Value::Vector(vector) => crate::ConstantInner::Composite { + ty, + components: vector + .into_iter() + .map(|scalar| { + let inner = scalar_to_const(self, scalar); + self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner, + }, + crate::Span::UNDEFINED, + ) + }) + .collect(), + }, + Value::Struct { handle, values, .. } => crate::ConstantInner::Composite { + ty: handle, + components: values + .into_iter() + .map(|value| self.val_to_const(value, span)) + .collect(), + }, + } + } + + fn val_to_ty(&mut self, value: &Value) -> Handle { + match *value { + Value::Scalar(scalar) => { + let (width, value) = self.val_to_scalar(scalar); + + self.register_type(TypeInner::Scalar { + kind: value.scalar_kind(), + width, + }) + } + Value::Vector(ref vector) => { + let (width, value) = self.val_to_scalar(vector[0]); + + self.register_type(TypeInner::Vector { + size: match vector.len() { + 2 => crate::VectorSize::Bi, + 3 => crate::VectorSize::Tri, + 4 => crate::VectorSize::Quad, + _ => unreachable!(), + }, + kind: value.scalar_kind(), + width, + }) + } + Value::Struct { handle, .. } => handle, + } + } + + fn val_to_scalar(&mut self, value: ScalarValue) -> (crate::Bytes, crate::ScalarValue) { + match value { + ScalarValue::Bool(b) => (1, crate::ScalarValue::Bool(b)), + ScalarValue::AbstractInt(i) => (4, crate::ScalarValue::Sint(i)), // Concretize to `i32`. + ScalarValue::I32(i) => (4, crate::ScalarValue::Sint(i as _)), + ScalarValue::U32(u) => (4, crate::ScalarValue::Uint(u as _)), + ScalarValue::AbstractFloat(f) => (4, crate::ScalarValue::Float(f)), // Concretize to `f32`. + ScalarValue::F32(f) => (4, crate::ScalarValue::Float(f as _)), + } + } + + fn concretize( + &mut self, + expr: InferenceExpression, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Handle { + let inner = match expr { + InferenceExpression::Concrete(handle) => return handle, + InferenceExpression::AbstractInt(i) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Sint(i), + }, + InferenceExpression::AbstractFloat(f) => crate::ConstantInner::Scalar { + width: 4, + value: crate::ScalarValue::Float(f), + }, + }; + + let c = self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner, + }, + crate::Span::UNDEFINED, + ); + self.emit_expr(crate::Expression::Constant(c), span, b, fun) + } + + fn unify_exprs( + &mut self, + with: Handle, + to: InferenceExpression, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + let ty = self.type_handle_of(with, fun)?; + self.unify_with_type(ty, to, span, b, fun) + } + + fn unify_with_type( + &mut self, + ty: Handle, + to: InferenceExpression, + span: crate::Span, + b: &mut crate::Block, + fun: &mut crate::Function, + ) -> Option> { + match self.data.module.types[ty].inner { + TypeInner::Scalar { kind, width } => match kind { + crate::ScalarKind::Float => match to { + InferenceExpression::Concrete(handle) => Some(handle), + InferenceExpression::AbstractInt(i) => { + let c = self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + width, + value: crate::ScalarValue::Float(i as _), + }, + }, + crate::Span::UNDEFINED, + ); + Some(self.emit_expr(crate::Expression::Constant(c), span, b, fun)) + } + InferenceExpression::AbstractFloat(f) => { + let c = self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + width, + value: crate::ScalarValue::Float(f), + }, + }, + crate::Span::UNDEFINED, + ); + Some(self.emit_expr(crate::Expression::Constant(c), span, b, fun)) + } + }, + crate::ScalarKind::Uint => match to { + InferenceExpression::Concrete(handle) => Some(handle), + InferenceExpression::AbstractInt(i) => { + let value = match i.try_into() { + Ok(value) => value, + Err(_) => { + self.errors.push( + WgslError::new("expected a positive integer").marker(span), + ); + return None; + } + }; + let c = self.data.module.constants.fetch_or_append( + crate::Constant { + name: None, + specialization: None, + inner: crate::ConstantInner::Scalar { + width, + value: crate::ScalarValue::Uint(value), + }, + }, + crate::Span::UNDEFINED, + ); + Some(self.emit_expr(crate::Expression::Constant(c), span, b, fun)) + } + InferenceExpression::AbstractFloat(_) => { + Some(self.concretize(to, span, b, fun)) + } + }, + crate::ScalarKind::Sint | crate::ScalarKind::Bool => { + Some(self.concretize(to, span, b, fun)) + } + }, + _ => Some(self.concretize(to, span, b, fun)), + } + } + + fn check_arg_count( + &mut self, + expected: usize, + spans: impl ExactSizeIterator, + ) -> Option<()> { + if spans.len() != expected { + let extra = spans.len() as isize - expected as isize; + let span = if spans.len() < expected { + crate::Span::total_span(spans) + } else { + crate::Span::total_span(spans.skip(expected)) + }; + let expected = expected as isize; + + self.errors.push( + WgslError::new(format!( + "expected {} {}", + expected, + "argument".pluralize(expected), + )) + .label( + span, + if extra < 0 { + format!("missing {}", "argument".pluralize(-extra)) + } else { + format!("extra {}", "argument".pluralize(extra)) + }, + ) + .note(if extra < 0 { + format!( + "consider adding {} more {}", + -extra, + "argument".pluralize(-extra) + ) + } else { + format!( + "consider removing the {} extra {}", + extra, + "argument".pluralize(extra) + ) + }), + ); + return None; + } + + Some(()) + } +} diff --git a/src/front/wgsl/mod.rs b/src/front/wgsl/mod.rs index 2873e6c73c..4a5178ac17 100644 --- a/src/front/wgsl/mod.rs +++ b/src/front/wgsl/mod.rs @@ -4,1403 +4,56 @@ Frontend for [WGSL][wgsl] (WebGPU Shading Language). [wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html */ -mod construction; -mod conv; -mod lexer; -mod number; -#[cfg(test)] -mod tests; - -use crate::{ - arena::{Arena, Handle, UniqueArena}, - proc::{ - ensure_block_returns, Alignment, Layouter, ResolveContext, ResolveError, TypeResolution, - }, - span::SourceLocation, - span::Span as NagaSpan, - ConstantInner, FastHashMap, ScalarValue, -}; - -use self::{lexer::Lexer, number::Number}; -use codespan_reporting::{ - diagnostic::{Diagnostic, Label}, - files::SimpleFile, - term::{ - self, - termcolor::{ColorChoice, NoColor, StandardStream}, - }, -}; -use std::{borrow::Cow, convert::TryFrom, ops}; -use thiserror::Error; - -type Span = ops::Range; -type TokenSpan<'a> = (Token<'a>, Span); - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum Token<'a> { - Separator(char), - Paren(char), - Attribute, - Number(Result), - Word(&'a str), - Operation(char), - LogicalOperation(char), - ShiftOperation(char), - AssignmentOperation(char), - IncrementOperation, - DecrementOperation, - Arrow, - Unknown(char), - Trivia, - End, -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum NumberType { - I32, - U32, - F32, -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum ExpectedToken<'a> { - Token(Token<'a>), - Identifier, - Number(NumberType), - Integer, - Constant, - /// Expected: constant, parenthesized expression, identifier - PrimaryExpression, - /// Expected: assignment, increment/decrement expression - 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, -} - -#[derive(Clone, Copy, Debug, Error, PartialEq)] -pub enum NumberError { - #[error("invalid numeric literal format")] - Invalid, - #[error("numeric literal not representable by target type")] - NotRepresentable, - #[error("unimplemented f16 type")] - UnimplementedF16, -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum InvalidAssignmentType { - Other, - Swizzle, - ImmutableBinding, -} +use crate::front::wgsl::lower::Lowerer; +use crate::front::wgsl::parse::parse; +use crate::front::wgsl::resolve::ResolveContext; +use crate::front::wgsl::text::Interner; +use crate::{SourceLocation, Span}; +use codespan_reporting::diagnostic::{Diagnostic, Label}; +use codespan_reporting::files::SimpleFile; +use codespan_reporting::term; +use termcolor::{ColorChoice, NoColor, StandardStream}; + +mod lower; +mod parse; +mod resolve; +mod text; #[derive(Clone, Debug)] -pub enum Error<'a> { - Unexpected(Span, ExpectedToken<'a>), - UnexpectedComponents(Span), - BadNumber(Span, NumberError), - /// A negative signed integer literal where both signed and unsigned, - /// but only non-negative literals are allowed. - NegativeInt(Span), - BadU32Constant(Span), - BadMatrixScalarKind(Span, crate::ScalarKind, u8), - BadAccessor(Span), - BadTexture(Span), - BadTypeCast { - span: Span, - from_type: String, - to_type: String, - }, - BadTextureSampleType { - span: Span, - kind: crate::ScalarKind, - width: u8, - }, - BadIncrDecrReferenceType(Span), - InvalidResolve(ResolveError), - InvalidForInitializer(Span), - /// A break if appeared outside of a continuing block - InvalidBreakIf(Span), - InvalidGatherComponent(Span, u32), - InvalidConstructorComponentType(Span, i32), - InvalidIdentifierUnderscore(Span), - ReservedIdentifierPrefix(Span), - UnknownAddressSpace(Span), - UnknownAttribute(Span), - UnknownBuiltin(Span), - UnknownAccess(Span), - UnknownShaderStage(Span), - UnknownIdent(Span, &'a str), - UnknownScalarType(Span), - UnknownType(Span), - UnknownStorageFormat(Span), - UnknownConservativeDepth(Span), - SizeAttributeTooLow(Span, u32), - AlignAttributeTooLow(Span, Alignment), - NonPowerOfTwoAlignAttribute(Span), - InconsistentBinding(Span), - UnknownLocalFunction(Span), - TypeNotConstructible(Span), - TypeNotInferrable(Span), - InitializationTypeMismatch(Span, String), - MissingType(Span), - MissingAttribute(&'static str, Span), - InvalidAtomicPointer(Span), - InvalidAtomicOperandType(Span), - Pointer(&'static str, Span), - NotPointer(Span), - NotReference(&'static str, Span), - InvalidAssignment { - span: Span, - ty: InvalidAssignmentType, - }, - ReservedKeyword(Span), - Redefinition { - previous: Span, - current: Span, - }, - Other, -} - -impl<'a> Error<'a> { - fn as_parse_error(&self, source: &'a str) -> ParseError { - match *self { - Error::Unexpected(ref unexpected_span, expected) => { - let expected_str = match expected { - ExpectedToken::Token(token) => { - match token { - Token::Separator(c) => format!("'{}'", c), - Token::Paren(c) => format!("'{}'", c), - Token::Attribute => "@".to_string(), - Token::Number(_) => "number".to_string(), - Token::Word(s) => s.to_string(), - Token::Operation(c) => format!("operation ('{}')", c), - Token::LogicalOperation(c) => format!("logical operation ('{}')", c), - Token::ShiftOperation(c) => format!("bitshift ('{}{}')", c, c), - Token::AssignmentOperation(c) if c=='<' || c=='>' => format!("bitshift ('{}{}=')", c, c), - Token::AssignmentOperation(c) => format!("operation ('{}=')", c), - Token::IncrementOperation => "increment operation".to_string(), - Token::DecrementOperation => "decrement operation".to_string(), - Token::Arrow => "->".to_string(), - Token::Unknown(c) => format!("unknown ('{}')", c), - Token::Trivia => "trivia".to_string(), - Token::End => "end".to_string(), - } - } - ExpectedToken::Identifier => "identifier".to_string(), - ExpectedToken::Number(ty) => { - match ty { - NumberType::I32 => "32-bit signed integer literal", - NumberType::U32 => "32-bit unsigned integer literal", - NumberType::F32 => "32-bit floating-point literal", - }.to_string() - }, - ExpectedToken::Integer => "unsigned/signed integer literal".to_string(), - ExpectedToken::Constant => "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(), - }; - ParseError { - message: format!( - "expected {}, found '{}'", - expected_str, - &source[unexpected_span.clone()], - ), - labels: vec![( - unexpected_span.clone(), - format!("expected {}", expected_str).into(), - )], - notes: vec![], - } - } - Error::UnexpectedComponents(ref bad_span) => ParseError { - message: "unexpected components".to_string(), - labels: vec![(bad_span.clone(), "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())], - notes: vec![], - }, - Error::NegativeInt(ref bad_span) => ParseError { - message: format!( - "expected non-negative integer literal, found `{}`", - &source[bad_span.clone()], - ), - labels: vec![(bad_span.clone(), "expected non-negative integer".into())], - notes: vec![], - }, - Error::BadU32Constant(ref bad_span) => ParseError { - message: format!( - "expected unsigned integer constant expression, found `{}`", - &source[bad_span.clone()], - ), - labels: vec![(bad_span.clone(), "expected unsigned integer".into())], - notes: vec![], - }, - Error::BadMatrixScalarKind(ref 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())], - 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())], - notes: vec![], - }, - Error::UnknownIdent(ref ident_span, ident) => ParseError { - message: format!("no definition in scope for identifier: '{}'", ident), - labels: vec![(ident_span.clone(), "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())], - notes: vec!["Valid scalar types are f16, f32, f64, \ - i8, i16, i32, i64, \ - u8, u16, u32, u64, bool" - .into()], - }, - Error::BadTextureSampleType { - ref 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())], - notes: vec![], - }, - Error::BadIncrDecrReferenceType(ref 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(), - )], - notes: vec![], - }, - Error::BadTexture(ref bad_span) => ParseError { - message: format!( - "expected an image, but found '{}' which is not an image", - &source[bad_span.clone()] - ), - labels: vec![(bad_span.clone(), "not an image".into())], - notes: vec![], - }, - Error::BadTypeCast { - ref 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())], - notes: vec![], - } - } - Error::InvalidResolve(ref resolve_error) => ParseError { - message: resolve_error.to_string(), - labels: vec![], - notes: vec![], - }, - Error::InvalidForInitializer(ref bad_span) => ParseError { - message: format!( - "for(;;) initializer is not an assignment or a function call: '{}'", - &source[bad_span.clone()] - ), - labels: vec![( - bad_span.clone(), - "not an assignment or function call".into(), - )], - notes: vec![], - }, - Error::InvalidBreakIf(ref 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())], - notes: vec![], - }, - Error::InvalidGatherComponent(ref bad_span, component) => ParseError { - message: format!( - "textureGather component {} doesn't exist, must be 0, 1, 2, or 3", - component - ), - labels: vec![(bad_span.clone(), "invalid component".into())], - notes: vec![], - }, - Error::InvalidConstructorComponentType(ref bad_span, component) => ParseError { - message: format!( - "invalid type for constructor component at index [{}]", - component - ), - labels: vec![(bad_span.clone(), "invalid component type".into())], - notes: vec![], - }, - Error::InvalidIdentifierUnderscore(ref bad_span) => ParseError { - message: "Identifier can't be '_'".to_string(), - labels: vec![(bad_span.clone(), "invalid identifier".into())], - notes: vec![ - "Use phony assignment instead ('_ =' notice the absence of 'let' or 'var')" - .to_string(), - ], - }, - Error::ReservedIdentifierPrefix(ref bad_span) => ParseError { - message: format!( - "Identifier starts with a reserved prefix: '{}'", - &source[bad_span.clone()] - ), - 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())], - notes: vec![], - }, - Error::UnknownAttribute(ref bad_span) => ParseError { - message: format!("unknown attribute: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown attribute".into())], - notes: vec![], - }, - Error::UnknownBuiltin(ref bad_span) => ParseError { - message: format!("unknown builtin: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown builtin".into())], - notes: vec![], - }, - Error::UnknownAccess(ref bad_span) => ParseError { - message: format!("unknown access: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown access".into())], - notes: vec![], - }, - Error::UnknownShaderStage(ref bad_span) => ParseError { - message: format!("unknown shader stage: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown shader stage".into())], - 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())], - 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())], - notes: vec![], - }, - Error::UnknownType(ref bad_span) => ParseError { - message: format!("unknown type: '{}'", &source[bad_span.clone()]), - labels: vec![(bad_span.clone(), "unknown type".into())], - notes: vec![], - }, - Error::SizeAttributeTooLow(ref bad_span, min_size) => ParseError { - message: format!("struct member size must be at least {}", min_size), - labels: vec![( - bad_span.clone(), - format!("must be at least {}", min_size).into(), - )], - notes: vec![], - }, - Error::AlignAttributeTooLow(ref 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(), - )], - notes: vec![], - }, - Error::NonPowerOfTwoAlignAttribute(ref 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())], - notes: vec![], - }, - Error::InconsistentBinding(ref 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())], - notes: vec![], - }, - Error::TypeNotConstructible(ref span) => ParseError { - message: format!("type `{}` is not constructible", &source[span.clone()]), - labels: vec![(span.clone(), "type is not constructible".into())], - notes: vec![], - }, - Error::TypeNotInferrable(ref span) => ParseError { - 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(), - )], - notes: vec![], - }, - Error::MissingType(ref name_span) => ParseError { - message: format!("variable `{}` needs a type", &source[name_span.clone()]), - labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), - )], - notes: vec![], - }, - Error::MissingAttribute(name, ref name_span) => ParseError { - message: format!( - "variable `{}` needs a '{}' attribute", - &source[name_span.clone()], - name - ), - labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), - )], - notes: vec![], - }, - Error::InvalidAtomicPointer(ref 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())], - notes: vec![], - }, - Error::InvalidAtomicOperandType(ref span) => ParseError { - message: "atomic operand type is inconsistent with the operation".to_string(), - labels: vec![(span.clone(), "atomic operand type is invalid".into())], - notes: vec![], - }, - Error::NotPointer(ref span) => ParseError { - message: "the operand of the `*` operator must be a pointer".to_string(), - labels: vec![(span.clone(), "expression is not a pointer".into())], - notes: vec![], - }, - Error::NotReference(what, ref span) => ParseError { - message: format!("{} must be a reference", what), - labels: vec![(span.clone(), "expression is not a reference".into())], - notes: vec![], - }, - Error::InvalidAssignment { ref span, ty } => ParseError { - message: "invalid left-hand side of assignment".into(), - labels: vec![(span.clone(), "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()]), - "consider declaring it with `var` instead of `let`".into(), - ], - InvalidAssignmentType::Other => vec![], - }, - }, - Error::Pointer(what, ref span) => ParseError { - message: format!("{} must not be a pointer", what), - labels: vec![(span.clone(), "expression is a pointer".into())], - notes: vec![], - }, - Error::ReservedKeyword(ref name_span) => ParseError { - message: format!( - "name `{}` is a reserved keyword", - &source[name_span.clone()] - ), - labels: vec![( - name_span.clone(), - format!("definition of `{}`", &source[name_span.clone()]).into(), - )], - notes: vec![], - }, - Error::Redefinition { - ref previous, - ref current, - } => ParseError { - message: format!("redefinition of `{}`", &source[current.clone()]), - labels: vec![ - ( - current.clone(), - format!("redefinition of `{}`", &source[current.clone()]).into(), - ), - ( - previous.clone(), - format!("previous definition of `{}`", &source[previous.clone()]).into(), - ), - ], - notes: vec![], - }, - Error::Other => ParseError { - message: "other error".to_string(), - labels: vec![], - notes: vec![], - }, - } - } -} - -impl crate::StorageFormat { - const fn to_wgsl(self) -> &'static str { - use crate::StorageFormat as Sf; - match self { - Sf::R8Unorm => "r8unorm", - Sf::R8Snorm => "r8snorm", - Sf::R8Uint => "r8uint", - Sf::R8Sint => "r8sint", - Sf::R16Uint => "r16uint", - Sf::R16Sint => "r16sint", - Sf::R16Float => "r16float", - Sf::Rg8Unorm => "rg8unorm", - Sf::Rg8Snorm => "rg8snorm", - Sf::Rg8Uint => "rg8uint", - Sf::Rg8Sint => "rg8sint", - Sf::R32Uint => "r32uint", - Sf::R32Sint => "r32sint", - Sf::R32Float => "r32float", - Sf::Rg16Uint => "rg16uint", - Sf::Rg16Sint => "rg16sint", - Sf::Rg16Float => "rg16float", - Sf::Rgba8Unorm => "rgba8unorm", - Sf::Rgba8Snorm => "rgba8snorm", - Sf::Rgba8Uint => "rgba8uint", - Sf::Rgba8Sint => "rgba8sint", - Sf::Rgb10a2Unorm => "rgb10a2unorm", - Sf::Rg11b10Float => "rg11b10float", - Sf::Rg32Uint => "rg32uint", - Sf::Rg32Sint => "rg32sint", - Sf::Rg32Float => "rg32float", - Sf::Rgba16Uint => "rgba16uint", - Sf::Rgba16Sint => "rgba16sint", - Sf::Rgba16Float => "rgba16float", - Sf::Rgba32Uint => "rgba32uint", - Sf::Rgba32Sint => "rgba32sint", - Sf::Rgba32Float => "rgba32float", - } - } -} - -impl crate::TypeInner { - /// Formats the type as it is written in wgsl. - /// - /// For example `vec3`. - /// - /// Note: The names of a `TypeInner::Struct` is not known. Therefore this method will simply return "struct" for them. - fn to_wgsl( - &self, - types: &UniqueArena, - constants: &Arena, - ) -> String { - use crate::TypeInner as Ti; - - match *self { - Ti::Scalar { kind, width } => kind.to_wgsl(width), - Ti::Vector { size, kind, width } => { - format!("vec{}<{}>", size as u32, kind.to_wgsl(width)) - } - Ti::Matrix { - columns, - rows, - width, - } => { - format!( - "mat{}x{}<{}>", - columns as u32, - rows as u32, - crate::ScalarKind::Float.to_wgsl(width), - ) - } - Ti::Atomic { kind, width } => { - format!("atomic<{}>", kind.to_wgsl(width)) - } - Ti::Pointer { base, .. } => { - let base = &types[base]; - let name = base.name.as_deref().unwrap_or("unknown"); - format!("ptr<{}>", name) - } - Ti::ValuePointer { kind, width, .. } => { - format!("ptr<{}>", kind.to_wgsl(width)) - } - Ti::Array { base, size, .. } => { - let member_type = &types[base]; - 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"); - format!("array<{}, {}>", base, size) - } - crate::ArraySize::Dynamic => format!("array<{}>", base), - } - } - Ti::Struct { .. } => { - // TODO: Actually output the struct? - "struct".to_string() - } - Ti::Image { - dim, - arrayed, - class, - } => { - let dim_suffix = match dim { - crate::ImageDimension::D1 => "_1d", - crate::ImageDimension::D2 => "_2d", - crate::ImageDimension::D3 => "_3d", - crate::ImageDimension::Cube => "_cube", - }; - let array_suffix = if arrayed { "_array" } else { "" }; - - let class_suffix = match class { - crate::ImageClass::Sampled { multi: true, .. } => "_multisampled", - crate::ImageClass::Depth { multi: false } => "_depth", - crate::ImageClass::Depth { multi: true } => "_depth_multisampled", - crate::ImageClass::Sampled { multi: false, .. } - | crate::ImageClass::Storage { .. } => "", - }; - - let type_in_brackets = match class { - crate::ImageClass::Sampled { kind, .. } => { - // Note: The only valid widths are 4 bytes wide. - // The lexer has already verified this, so we can safely assume it here. - // https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type - let element_type = kind.to_wgsl(4); - format!("<{}>", element_type) - } - crate::ImageClass::Depth { multi: _ } => String::new(), - crate::ImageClass::Storage { format, access } => { - if access.contains(crate::StorageAccess::STORE) { - format!("<{},write>", format.to_wgsl()) - } else { - format!("<{}>", format.to_wgsl()) - } - } - }; - - format!( - "texture{}{}{}{}", - class_suffix, dim_suffix, array_suffix, type_in_brackets - ) - } - Ti::Sampler { .. } => "sampler".to_string(), - Ti::BindingArray { base, size, .. } => { - let member_type = &types[base]; - 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"); - format!("binding_array<{}, {}>", base, size) - } - crate::ArraySize::Dynamic => format!("binding_array<{}>", base), - } - } - } - } -} - -mod type_inner_tests { - #[test] - fn to_wgsl() { - let mut types = crate::UniqueArena::new(); - let mut constants = crate::Arena::new(); - let c = constants.append( - crate::Constant { - name: Some("C".to_string()), - specialization: None, - inner: crate::ConstantInner::Scalar { - width: 4, - value: crate::ScalarValue::Uint(32), - }, - }, - Default::default(), - ); - - let mytype1 = types.insert( - crate::Type { - name: Some("MyType1".to_string()), - inner: crate::TypeInner::Struct { - members: vec![], - span: 0, - }, - }, - Default::default(), - ); - let mytype2 = types.insert( - crate::Type { - name: Some("MyType2".to_string()), - inner: crate::TypeInner::Struct { - members: vec![], - span: 0, - }, - }, - Default::default(), - ); - - let array = crate::TypeInner::Array { - base: mytype1, - stride: 4, - size: crate::ArraySize::Constant(c), - }; - assert_eq!(array.to_wgsl(&types, &constants), "array"); - - let mat = crate::TypeInner::Matrix { - rows: crate::VectorSize::Quad, - columns: crate::VectorSize::Bi, - width: 8, - }; - assert_eq!(mat.to_wgsl(&types, &constants), "mat2x4"); - - let ptr = crate::TypeInner::Pointer { - base: mytype2, - space: crate::AddressSpace::Storage { - access: crate::StorageAccess::default(), - }, - }; - assert_eq!(ptr.to_wgsl(&types, &constants), "ptr"); - - let img1 = crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Sampled { - kind: crate::ScalarKind::Float, - multi: true, - }, - }; - assert_eq!( - img1.to_wgsl(&types, &constants), - "texture_multisampled_2d" - ); - - let img2 = crate::TypeInner::Image { - dim: crate::ImageDimension::Cube, - arrayed: true, - class: crate::ImageClass::Depth { multi: false }, - }; - assert_eq!(img2.to_wgsl(&types, &constants), "texture_depth_cube_array"); - - let img3 = crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Depth { multi: true }, - }; - assert_eq!( - img3.to_wgsl(&types, &constants), - "texture_depth_multisampled_2d" - ); - - let array = crate::TypeInner::BindingArray { - base: mytype1, - size: crate::ArraySize::Constant(c), - }; - assert_eq!( - array.to_wgsl(&types, &constants), - "binding_array" - ); - } -} - -impl crate::ScalarKind { - /// Format a scalar kind+width as a type is written in wgsl. - /// - /// Examples: `f32`, `u64`, `bool`. - fn to_wgsl(self, width: u8) -> String { - let prefix = match self { - crate::ScalarKind::Sint => "i", - crate::ScalarKind::Uint => "u", - crate::ScalarKind::Float => "f", - crate::ScalarKind::Bool => return "bool".to_string(), - }; - format!("{}{}", prefix, width * 8) - } -} - -trait StringValueLookup<'a> { - type Value; - fn lookup(&self, key: &'a str, span: Span) -> Result>; -} -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)) - } -} - -struct StatementContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, - typifier: &'temp mut super::Typifier, - variables: &'out mut Arena, - 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], -} - -impl<'a, 'temp> StatementContext<'a, 'temp, '_> { - fn reborrow(&mut self) -> StatementContext<'a, '_, '_> { - StatementContext { - symbol_table: self.symbol_table, - typifier: self.typifier, - variables: self.variables, - expressions: self.expressions, - named_expressions: self.named_expressions, - types: self.types, - constants: self.constants, - global_vars: self.global_vars, - functions: self.functions, - arguments: self.arguments, - } - } - - fn as_expression<'t>( - &'t mut self, - block: &'t mut crate::Block, - emitter: &'t mut super::Emitter, - ) -> ExpressionContext<'a, 't, '_> - where - 'temp: 't, - { - ExpressionContext { - symbol_table: self.symbol_table, - typifier: self.typifier, - expressions: self.expressions, - types: self.types, - constants: self.constants, - global_vars: self.global_vars, - local_vars: self.variables, - functions: self.functions, - arguments: self.arguments, - block, - emitter, - } - } -} - -struct SamplingContext { - image: Handle, - arrayed: bool, -} - -struct ExpressionContext<'input, 'temp, 'out> { - symbol_table: &'temp mut super::SymbolTable<&'input str, TypedExpression>, - typifier: &'temp mut super::Typifier, - expressions: &'out mut Arena, - types: &'out mut UniqueArena, - constants: &'out mut Arena, - global_vars: &'out Arena, - local_vars: &'out Arena, - arguments: &'out [crate::FunctionArgument], - functions: &'out Arena, - block: &'temp mut crate::Block, - emitter: &'temp mut super::Emitter, -} - -impl<'a> ExpressionContext<'a, '_, '_> { - fn reborrow(&mut self) -> ExpressionContext<'a, '_, '_> { - ExpressionContext { - symbol_table: self.symbol_table, - typifier: self.typifier, - expressions: self.expressions, - types: self.types, - constants: self.constants, - global_vars: self.global_vars, - local_vars: self.local_vars, - functions: self.functions, - arguments: self.arguments, - block: self.block, - emitter: self.emitter, - } - } - - fn resolve_type( - &mut self, - handle: Handle, - ) -> Result<&crate::TypeInner, Error<'a>> { - let resolve_ctx = ResolveContext { - constants: self.constants, - types: self.types, - global_vars: self.global_vars, - local_vars: self.local_vars, - functions: self.functions, - arguments: self.arguments, - }; - match self.typifier.grow(handle, self.expressions, &resolve_ctx) { - Err(e) => Err(Error::InvalidResolve(e)), - Ok(()) => Ok(self.typifier.get(handle, self.types)), - } - } - - 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 parse_binary_op( - &mut self, - lexer: &mut Lexer<'a>, - classifier: impl Fn(Token<'a>) -> Option, - mut parser: impl FnMut( - &mut Lexer<'a>, - ExpressionContext<'a, '_, '_>, - ) -> Result>, - ) -> Result> { - let start = lexer.start_byte_offset() as u32; - let mut accumulator = parser(lexer, self.reborrow())?; - while let Some(op) = classifier(lexer.peek().0) { - let _ = lexer.next(); - // Binary expressions always apply the load rule to their operands. - let mut left = self.apply_load_rule(accumulator); - let unloaded_right = parser(lexer, self.reborrow())?; - let 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); - } - Ok(accumulator) - } - - fn parse_binary_splat_op( - &mut self, - lexer: &mut Lexer<'a>, - classifier: impl Fn(Token<'a>) -> Option, - mut parser: impl FnMut( - &mut Lexer<'a>, - ExpressionContext<'a, '_, '_>, - ) -> Result>, - ) -> Result> { - let start = lexer.start_byte_offset() as u32; - let mut accumulator = parser(lexer, self.reborrow())?; - while let Some(op) = classifier(lexer.peek().0) { - let _ = lexer.next(); - // Binary expressions always apply the load rule to their operands. - let mut left = self.apply_load_rule(accumulator); - let unloaded_right = parser(lexer, self.reborrow())?; - let mut right = self.apply_load_rule(unloaded_right); - let end = lexer.end_byte_offset() as u32; - - self.binary_op_splat(op, &mut left, &mut right)?; - - accumulator = TypedExpression::non_reference(self.expressions.append( - crate::Expression::Binary { op, left, right }, - NagaSpan::new(start, end), - )); - } - Ok(accumulator) - } - - /// Insert splats, if needed by the non-'*' operations. - fn binary_op_splat( - &mut self, - op: crate::BinaryOperator, - left: &mut Handle, - right: &mut Handle, - ) -> Result<(), Error<'a>> { - if op != crate::BinaryOperator::Multiply { - let left_size = match *self.resolve_type(*left)? { - crate::TypeInner::Vector { size, .. } => Some(size), - _ => None, - }; - match (left_size, self.resolve_type(*right)?) { - (Some(size), &crate::TypeInner::Scalar { .. }) => { - *right = self.expressions.append( - crate::Expression::Splat { - size, - value: *right, - }, - self.expressions.get_span(*right), - ); - } - (None, &crate::TypeInner::Vector { size, .. }) => { - *left = self.expressions.append( - crate::Expression::Splat { size, value: *left }, - self.expressions.get_span(*left), - ); - } - _ => {} - } - } - - Ok(()) - } - - /// Add a single expression to the expression table that is not covered by `self.emitter`. - /// - /// This is useful for `CallResult` and `AtomicResult` expressions, which should not be covered by - /// `Emit` statements. - fn interrupt_emitter( - &mut self, - expression: crate::Expression, - span: NagaSpan, - ) -> Handle { - self.block.extend(self.emitter.finish(self.expressions)); - let result = self.expressions.append(expression, span); - self.emitter.start(self.expressions); - result - } - - /// Apply the WGSL Load Rule to `expr`. - /// - /// If `expr` is has type `ref`, perform a load to produce a value of type - /// `T`. Otherwise, return `expr` unchanged. - fn apply_load_rule(&mut self, expr: TypedExpression) -> Handle { - if expr.is_reference { - let load = crate::Expression::Load { - pointer: expr.handle, - }; - let span = self.expressions.get_span(expr.handle); - self.expressions.append(load, span) - } else { - expr.handle - } - } - - /// Creates a zero value constant of type `ty` - /// - /// Returns `None` if the given `ty` is not a constructible type - fn create_zero_value_constant( - &mut self, - ty: Handle, - ) -> Option> { - let inner = match self.types[ty].inner { - crate::TypeInner::Scalar { kind, width } => { - let value = match kind { - crate::ScalarKind::Sint => crate::ScalarValue::Sint(0), - crate::ScalarKind::Uint => crate::ScalarValue::Uint(0), - crate::ScalarKind::Float => crate::ScalarValue::Float(0.), - crate::ScalarKind::Bool => crate::ScalarValue::Bool(false), - }; - 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 component = self.create_zero_value_constant(scalar_ty); - crate::ConstantInner::Composite { - ty, - components: (0..size as u8).map(|_| component).collect::>()?, - } - } - crate::TypeInner::Matrix { - columns, - 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 component = self.create_zero_value_constant(vec_ty); - crate::ConstantInner::Composite { - ty, - components: (0..columns as u8) - .map(|_| component) - .collect::>()?, - } - } - crate::TypeInner::Array { - base, - size: crate::ArraySize::Constant(size), - .. - } => { - let component = self.create_zero_value_constant(base); - crate::ConstantInner::Composite { - ty, - components: (0..self.constants[size].to_array_length().unwrap()) - .map(|_| component) - .collect::>()?, - } - } - crate::TypeInner::Struct { ref members, .. } => { - let members = members.clone(); - crate::ConstantInner::Composite { - ty, - components: members - .iter() - .map(|member| self.create_zero_value_constant(member.ty)) - .collect::>()?, - } - } - _ => return None, - }; - - let constant = self.constants.fetch_or_append( - crate::Constant { - name: None, - specialization: None, - inner, - }, - crate::Span::default(), - ); - Some(constant) - } -} - -/// A Naga [`Expression`] handle, with WGSL type information. -/// -/// Naga and WGSL types are very close, but Naga lacks WGSL's 'reference' types, -/// which we need to know to apply the Load Rule. This struct carries a Naga -/// `Handle` along with enough information to determine its WGSL type. -/// -/// [`Expression`]: crate::Expression -#[derive(Debug, Copy, Clone)] -struct TypedExpression { - /// The handle of the Naga expression. - handle: Handle, - - /// True if this expression's WGSL type is a reference. - /// - /// When this is true, `handle` must be a pointer. - is_reference: bool, -} - -impl TypedExpression { - const fn non_reference(handle: Handle) -> TypedExpression { - TypedExpression { - handle, - is_reference: false, - } - } -} - -enum Composition { - Single(u32), - Multi(crate::VectorSize, [crate::SwizzleComponent; 4]), +pub struct WgslError { + message: String, + labels: Vec<(Span, String)>, + notes: Vec, } -impl Composition { - const fn letter_component(letter: char) -> Option { - use crate::SwizzleComponent as Sc; - match letter { - 'x' | 'r' => Some(Sc::X), - 'y' | 'g' => Some(Sc::Y), - 'z' | 'b' => Some(Sc::Z), - 'w' | 'a' => Some(Sc::W), - _ => None, +impl WgslError { + fn new(message: impl Into) -> Self { + Self { + message: message.into(), + labels: Vec::new(), + notes: Vec::new(), } } - fn extract_impl(name: &str, name_span: Span) -> Result { - let ch = name - .chars() - .next() - .ok_or_else(|| Error::BadAccessor(name_span.clone()))?; - match Self::letter_component(ch) { - Some(sc) => Ok(sc as u32), - None => Err(Error::BadAccessor(name_span)), - } + fn label(mut self, span: Span, message: impl Into) -> Self { + self.labels.push((span, message.into())); + self } - fn make(name: &str, name_span: Span) -> Result { - 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()))?; - } - - let size = match name.len() { - 2 => crate::VectorSize::Bi, - 3 => crate::VectorSize::Tri, - 4 => crate::VectorSize::Quad, - _ => return Err(Error::BadAccessor(name_span)), - }; - Ok(Composition::Multi(size, components)) - } else { - Self::extract_impl(name, name_span).map(Composition::Single) - } - } -} - -#[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 -/// these and (occasionally) checks that it is being pushed and popped -/// as expected. -#[derive(Clone, Debug, PartialEq)] -enum Rule { - Attribute, - VariableDecl, - TypeDecl, - FunctionDecl, - Block, - Statement, - ConstantExpr, - PrimaryExpr, - SingularExpr, - UnaryExpr, - GeneralExpr, -} - -type LocalFunctionCall = (Handle, Vec>); - -#[derive(Default)] -struct BindingParser { - location: Option, - built_in: Option, - interpolation: Option, - sampling: Option, - invariant: bool, -} - -impl BindingParser { - fn parse<'a>( - &mut self, - lexer: &mut Lexer<'a>, - name: &'a str, - name_span: Span, - ) -> Result<(), Error<'a>> { - match name { - "location" => { - lexer.expect(Token::Paren('('))?; - self.location = Some(Parser::parse_non_negative_i32_literal(lexer)?); - lexer.expect(Token::Paren(')'))?; - } - "builtin" => { - lexer.expect(Token::Paren('('))?; - let (raw, span) = lexer.next_ident_with_span()?; - self.built_in = Some(conv::map_built_in(raw, span)?); - lexer.expect(Token::Paren(')'))?; - } - "interpolate" => { - lexer.expect(Token::Paren('('))?; - let (raw, span) = lexer.next_ident_with_span()?; - self.interpolation = Some(conv::map_interpolation(raw, span)?); - if lexer.skip(Token::Separator(',')) { - let (raw, span) = lexer.next_ident_with_span()?; - self.sampling = Some(conv::map_sampling(raw, span)?); - } - lexer.expect(Token::Paren(')'))?; - } - "invariant" => self.invariant = true, - _ => return Err(Error::UnknownAttribute(name_span)), - } - Ok(()) + fn marker(mut self, span: Span) -> Self { + self.labels.push((span, String::new())); + self } - const fn finish<'a>(self, span: Span) -> Result, Error<'a>> { - match ( - self.location, - self.built_in, - self.interpolation, - self.sampling, - self.invariant, - ) { - (None, None, None, None, false) => Ok(None), - (Some(location), None, interpolation, sampling, false) => { - // Before handing over the completed `Module`, we call - // `apply_default_interpolation` to ensure that the interpolation and - // sampling have been explicitly specified on all vertex shader output and fragment - // shader input user bindings, so leaving them potentially `None` here is fine. - Ok(Some(crate::Binding::Location { - location, - interpolation, - sampling, - })) - } - (None, Some(crate::BuiltIn::Position { .. }), None, None, invariant) => { - Ok(Some(crate::Binding::BuiltIn(crate::BuiltIn::Position { - invariant, - }))) - } - (None, Some(built_in), None, None, false) => { - Ok(Some(crate::Binding::BuiltIn(built_in))) - } - (_, _, _, _, _) => Err(Error::InconsistentBinding(span)), - } + fn note(mut self, message: impl Into) -> Self { + self.notes.push(message.into()); + self } -} - -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, - labels: Vec<(Span, Cow<'static, str>)>, - notes: Vec, -} -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 { @@ -1414,7 +67,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(), ) @@ -1457,3294 +111,51 @@ 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)) } } -impl std::fmt::Display for ParseError { +impl std::fmt::Display for WgslError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.message) } } -impl std::error::Error for ParseError { +impl std::error::Error for WgslError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } -pub struct Parser { - rules: Vec<(Rule, usize)>, - module_scope_identifiers: FastHashMap, - lookup_type: FastHashMap>, - layouter: Layouter, +pub struct WgslContext { + interner: Interner, + resolve: ResolveContext, } -impl Parser { +impl WgslContext { pub fn new() -> Self { - Parser { - rules: Vec::new(), - module_scope_identifiers: FastHashMap::default(), - lookup_type: FastHashMap::default(), - layouter: Default::default(), - } - } - - fn reset(&mut self) { - self.rules.clear(); - self.module_scope_identifiers.clear(); - self.lookup_type.clear(); - self.layouter.clear(); - } + let mut intern = Interner::new(); - fn push_rule_span(&mut self, rule: Rule, lexer: &mut Lexer<'_>) { - self.rules.push((rule, lexer.start_byte_offset())); - } - - fn pop_rule_span(&mut self, lexer: &Lexer<'_>) -> Span { - let (_, initial) = self.rules.pop().unwrap(); - lexer.span_from(initial) - } - - fn peek_rule_span(&mut self, lexer: &Lexer<'_>) -> Span { - let &(_, initial) = self.rules.last().unwrap(); - lexer.span_from(initial) - } - - fn parse_switch_value<'a>(lexer: &mut Lexer<'a>, uint: bool) -> Result> { - let token_span = lexer.next(); - match token_span.0 { - Token::Number(Ok(Number::U32(num))) if uint => Ok(num as i32), - Token::Number(Ok(Number::I32(num))) if !uint => Ok(num), - 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> { - match lexer.next() { - (Token::Number(Ok(Number::I32(num))), span) => { - u32::try_from(num).map_err(|_| Error::NegativeInt(span)) - } - (Token::Number(Err(e)), span) => Err(Error::BadNumber(span, e)), - other => Err(Error::Unexpected( - other.1, - ExpectedToken::Number(NumberType::I32), - )), - } - } - - /// 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> { - match lexer.next() { - (Token::Number(Ok(Number::I32(num))), span) => { - u32::try_from(num).map_err(|_| Error::NegativeInt(span)) - } - (Token::Number(Ok(Number::U32(num))), _) => Ok(num), - (Token::Number(Err(e)), span) => Err(Error::BadNumber(span, e)), - other => Err(Error::Unexpected( - other.1, - ExpectedToken::Number(NumberType::I32), - )), + Self { + resolve: ResolveContext::new(&mut intern), + interner: intern, } } - fn parse_atomic_pointer<'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)) - } - }, - ref other => { - log::error!("Type {:?} passed to atomic op", other); - Err(Error::InvalidAtomicPointer(pointer_span)) - } - } - } + pub fn parse(&mut self, source: &str) -> Result> { + let mut diags = Vec::new(); - /// Expects name to be peeked from lexer, does not consume if returns None. - fn parse_local_function_call<'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 ast = parse(source, &mut self.interner, &mut diags); + let module = self.resolve.resolve(ast, &mut self.interner, &mut diags); - let count = ctx.functions[fun_handle].arguments.len(); - let mut arguments = Vec::with_capacity(count); - let _ = lexer.next(); - lexer.open_arguments()?; - while arguments.len() != count { - if !arguments.is_empty() { - lexer.expect(Token::Separator(','))?; - } - let arg = self.parse_general_expression(lexer, ctx.reborrow())?; - arguments.push(arg); + if !diags.is_empty() { + return Err(diags); } - lexer.close_arguments()?; - Ok(Some((fun_handle, arguments))) - } - - fn parse_atomic_helper<'a>( - &mut self, - lexer: &mut Lexer<'a>, - fun: crate::AtomicFunction, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - lexer.open_arguments()?; - let pointer = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let ctx_span = ctx.reborrow(); - let (value, value_span) = - lexer.capture_span(|lexer| self.parse_general_expression(lexer, ctx_span))?; - lexer.close_arguments()?; - - let expression = match *ctx.resolve_type(value)? { - crate::TypeInner::Scalar { kind, width } => crate::Expression::AtomicResult { - kind, - width, - comparison: false, - }, - _ => return Err(Error::InvalidAtomicOperandType(value_span)), - }; - - let span = NagaSpan::from(value_span); - let result = ctx.interrupt_emitter(expression, span); - ctx.block.push( - crate::Statement::Atomic { - pointer, - fun, - value, - result, - }, - span, - ); - Ok(result) - } - - /// 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>( - &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, - } - } 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 } => { - crate::Expression::AtomicResult { - kind, - width, - comparison: true, - } - } - _ => return Err(Error::InvalidAtomicOperandType(value_span)), - }; - - let span = NagaSpan::from(self.peek_rule_span(lexer)); - let result = ctx.interrupt_emitter(expression, span); - ctx.block.push( - crate::Statement::Atomic { - pointer, - fun: crate::AtomicFunction::Exchange { compare: Some(cmp) }, - value, - result, - }, - span, - ); - return Ok(Some(CalledFunction { - result: Some(result), - })); - } - // texture sampling - "textureSample" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Auto, - depth_ref: None, - } - } - "textureSampleLevel" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let level = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Exact(level), - depth_ref: None, - } - } - "textureSampleBias" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let bias = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Bias(bias), - depth_ref: None, - } - } - "textureSampleGrad" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let x = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let y = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Gradient { x, y }, - depth_ref: None, - } - } - "textureSampleCompare" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Auto, - depth_ref: Some(reference), - } - } - "textureSampleCompareLevel" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: None, - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: Some(reference), - } - } - "textureGather" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let component = if let (Token::Number(..), span) = lexer.peek() { - let index = Self::parse_non_negative_i32_literal(lexer)?; - lexer.expect(Token::Separator(','))?; - *crate::SwizzleComponent::XYZW - .get(index as usize) - .ok_or(Error::InvalidGatherComponent(span, index))? - } else { - crate::SwizzleComponent::X - }; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: Some(component), - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: None, - } - } - "textureGatherCompare" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let sampler_expr = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let sc = ctx.prepare_sampling(image, image_span)?; - let array_index = if sc.arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.expect(Token::Separator(','))?; - let reference = self.parse_general_expression(lexer, ctx.reborrow())?; - let offset = if lexer.skip(Token::Separator(',')) { - Some(self.parse_const_expression(lexer, ctx.types, ctx.constants)?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageSample { - image: sc.image, - sampler: sampler_expr, - gather: Some(crate::SwizzleComponent::X), - coordinate, - array_index, - offset, - level: crate::SampleLevel::Zero, - depth_ref: Some(reference), - } - } - "textureLoad" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let (image, image_span) = - self.parse_general_expression_with_span(lexer, ctx.reborrow())?; - lexer.expect(Token::Separator(','))?; - let coordinate = self.parse_general_expression(lexer, ctx.reborrow())?; - let (class, arrayed) = match *ctx.resolve_type(image)? { - crate::TypeInner::Image { class, arrayed, .. } => (class, arrayed), - _ => return Err(Error::BadTexture(image_span)), - }; - let array_index = if arrayed { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let level = if class.is_mipmapped() { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - let sample = if class.is_multisampled() { - lexer.expect(Token::Separator(','))?; - Some(self.parse_general_expression(lexer, ctx.reborrow())?) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageLoad { - image, - coordinate, - array_index, - sample, - level, - } - } - "textureDimensions" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - let level = if lexer.skip(Token::Separator(',')) { - let expr = self.parse_general_expression(lexer, ctx.reborrow())?; - Some(expr) - } else { - None - }; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::Size { level }, - } - } - "textureNumLevels" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumLevels, - } - } - "textureNumLayers" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumLayers, - } - } - "textureNumSamples" => { - let _ = lexer.next(); - lexer.open_arguments()?; - let image = self.parse_general_expression(lexer, ctx.reborrow())?; - lexer.close_arguments()?; - crate::Expression::ImageQuery { - image, - query: crate::ImageQuery::NumSamples, - } - } - // other - _ => { - let result = - match self.parse_local_function_call(lexer, name, ctx.reborrow())? { - Some((function, arguments)) => { - let span = NagaSpan::from(self.peek_rule_span(lexer)); - ctx.block.extend(ctx.emitter.finish(ctx.expressions)); - let result = ctx.functions[function].result.as_ref().map(|_| { - ctx.expressions - .append(crate::Expression::CallResult(function), span) - }); - ctx.emitter.start(ctx.expressions); - ctx.block.push( - crate::Statement::Call { - function, - arguments, - result, - }, - span, - ); - result - } - None => return Ok(None), - }; - return Ok(Some(CalledFunction { result })); - } - } - }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - let handle = ctx.expressions.append(expr, span); - Ok(Some(CalledFunction { - result: Some(handle), - })) - } - - fn parse_const_expression_impl<'a>( - &mut self, - first_token_span: TokenSpan<'a>, - lexer: &mut Lexer<'a>, - register_name: Option<&'a str>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - self.push_rule_span(Rule::ConstantExpr, lexer); - let inner = match first_token_span { - (Token::Word("true"), _) => crate::ConstantInner::boolean(true), - (Token::Word("false"), _) => crate::ConstantInner::boolean(false), - (Token::Number(num), _) => match num { - Ok(Number::I32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Sint(num as i64), - width: 4, - }, - Ok(Number::U32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Uint(num as u64), - width: 4, - }, - Ok(Number::F32(num)) => crate::ConstantInner::Scalar { - value: crate::ScalarValue::Float(num as f64), - width: 4, - }, - Ok(Number::AbstractInt(_) | Number::AbstractFloat(_)) => unreachable!(), - Err(e) => return Err(Error::BadNumber(first_token_span.1, e)), - }, - (Token::Word(name), name_span) => { - // look for an existing constant first - for (handle, var) in const_arena.iter() { - match var.name { - Some(ref string) if string == name => { - self.pop_rule_span(lexer); - return Ok(handle); - } - _ => {} - } - } - let composite_ty = self.parse_type_decl_name( - lexer, - name, - name_span, - None, - TypeAttributes::default(), - type_arena, - const_arena, - )?; - - 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, - } - } - } - _ => break, - }; - - prefix_span = lexer.span_from(span_start); - handle = ctx - .expressions - .append(expression, NagaSpan::from(prefix_span.clone())); - } - - Ok(TypedExpression { - handle, - is_reference, - }) - } - - /// Parse a `unary_expression`. - fn parse_unary_expression<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result> { - 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 { - op: crate::UnaryOperator::Negate, - expr, - }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - TypedExpression::non_reference(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 { - op: crate::UnaryOperator::Not, - expr, - }; - let span = NagaSpan::from(self.peek_rule_span(lexer)); - TypedExpression::non_reference(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, - } - } - 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 - } - } - _ => self.parse_singular_expression(lexer, ctx.reborrow())?, - }; - - self.pop_rule_span(lexer); - Ok(expr) - } - - /// Parse a `singular_expression`. - fn parse_singular_expression<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result> { - 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)?; - self.pop_rule_span(lexer); - - Ok(singular_expr) - } - - fn parse_equality_expression<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: ExpressionContext<'a, '_, '_>, - ) -> Result> { - // equality_expression - context.parse_binary_op( - lexer, - |token| match token { - Token::LogicalOperation('=') => Some(crate::BinaryOperator::Equal), - Token::LogicalOperation('!') => Some(crate::BinaryOperator::NotEqual), - _ => None, - }, - // relational_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::Paren('<') => Some(crate::BinaryOperator::Less), - Token::Paren('>') => Some(crate::BinaryOperator::Greater), - Token::LogicalOperation('<') => Some(crate::BinaryOperator::LessEqual), - Token::LogicalOperation('>') => Some(crate::BinaryOperator::GreaterEqual), - _ => None, - }, - // shift_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::ShiftOperation('<') => { - Some(crate::BinaryOperator::ShiftLeft) - } - Token::ShiftOperation('>') => { - Some(crate::BinaryOperator::ShiftRight) - } - _ => None, - }, - // additive_expression - |lexer, mut context| { - context.parse_binary_splat_op( - lexer, - |token| match token { - Token::Operation('+') => Some(crate::BinaryOperator::Add), - Token::Operation('-') => { - Some(crate::BinaryOperator::Subtract) - } - _ => None, - }, - // multiplicative_expression - |lexer, mut context| { - context.parse_binary_splat_op( - lexer, - |token| match token { - Token::Operation('*') => { - Some(crate::BinaryOperator::Multiply) - } - Token::Operation('/') => { - Some(crate::BinaryOperator::Divide) - } - Token::Operation('%') => { - Some(crate::BinaryOperator::Modulo) - } - _ => None, - }, - |lexer, context| { - self.parse_unary_expression(lexer, context) - }, - ) - }, - ) - }, - ) - }, - ) - }, - ) - } - - 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>( - &mut self, - lexer: &mut Lexer<'a>, - mut ctx: ExpressionContext<'a, '_, '_>, - ) -> Result, Error<'a>> { - let (expr, _span) = self.parse_general_expression_for_reference(lexer, ctx.reborrow())?; - Ok(ctx.apply_load_rule(expr)) - } - - fn parse_general_expression_for_reference<'a>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: ExpressionContext<'a, '_, '_>, - ) -> Result<(TypedExpression, Span), Error<'a>> { - self.push_rule_span(Rule::GeneralExpr, lexer); - // logical_or_expression - let handle = context.parse_binary_op( - lexer, - |token| match token { - Token::LogicalOperation('|') => Some(crate::BinaryOperator::LogicalOr), - _ => None, - }, - // logical_and_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::LogicalOperation('&') => Some(crate::BinaryOperator::LogicalAnd), - _ => None, - }, - // inclusive_or_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::Operation('|') => Some(crate::BinaryOperator::InclusiveOr), - _ => None, - }, - // exclusive_or_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::Operation('^') => { - Some(crate::BinaryOperator::ExclusiveOr) - } - _ => None, - }, - // and_expression - |lexer, mut context| { - context.parse_binary_op( - lexer, - |token| match token { - Token::Operation('&') => { - Some(crate::BinaryOperator::And) - } - _ => None, - }, - |lexer, context| { - self.parse_equality_expression(lexer, context) - }, - ) - }, - ) - }, - ) - }, - ) - }, - )?; - 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>( - &mut self, - lexer: &mut Lexer<'a>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - self.push_rule_span(Rule::VariableDecl, lexer); - let mut space = None; - - if lexer.skip(Token::Paren('<')) { - let (class_str, span) = lexer.next_ident_with_span()?; - space = Some(match class_str { - "storage" => { - let access = if lexer.skip(Token::Separator(',')) { - lexer.next_storage_access()? - } else { - // defaulting to `read` - crate::StorageAccess::LOAD - }; - 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 init = if lexer.skip(Token::Operation('=')) { - let handle = self.parse_const_expression(lexer, type_arena, const_arena)?; - Some(handle) - } else { - None - }; - lexer.expect(Token::Separator(';'))?; - let name_span = self.pop_rule_span(lexer); - Ok(ParsedVariable { - name, - name_span, - space, - ty, - init, - }) - } - - fn parse_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; - let mut members = 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 (mut size_attr, mut align_attr) = (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)?; - lexer.expect(Token::Paren(')'))?; - size_attr = Some((value, span)); - } - ("align", _) => { - lexer.expect(Token::Paren('('))?; - let (value, span) = - lexer.capture_span(Self::parse_non_negative_i32_literal)?; - lexer.expect(Token::Paren(')'))?; - align_attr = 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 (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)); - } - lexer.expect(Token::Separator(':'))?; - let ty = self.parse_type_decl(lexer, None, type_arena, const_arena)?; - 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()), - ty, - binding, - offset, - }); - - offset += member_size; - } - - let struct_size = struct_alignment.round_up(offset); - Ok((members, struct_size)) - } - - fn parse_matrix_scalar_type<'a>( - &mut self, - lexer: &mut Lexer<'a>, - columns: crate::VectorSize, - rows: crate::VectorSize, - ) -> Result> { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - match kind { - crate::ScalarKind::Float => Ok(crate::TypeInner::Matrix { - columns, - rows, - width, - }), - _ => Err(Error::BadMatrixScalarKind(span, kind, width)), - } - } - - fn parse_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>> { - if let Some((kind, width)) = conv::get_scalar_type(word) { - return Ok(Some(crate::TypeInner::Scalar { kind, width })); - } - - Ok(Some(match word { - "vec2" => { - let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { - size: crate::VectorSize::Bi, - kind, - width, - } - } - "vec3" => { - let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { - size: crate::VectorSize::Tri, - kind, - width, - } - } - "vec4" => { - let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::Vector { - size: crate::VectorSize::Quad, - kind, - width, - } - } - "mat2x2" => { - self.parse_matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Bi)? - } - "mat2x3" => { - self.parse_matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Tri)? - } - "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, - )?, - "atomic" => { - let (kind, width) = lexer.next_scalar_generic()?; - crate::TypeInner::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)?; - if let crate::AddressSpace::Storage { ref mut access } = space { - *access = if lexer.skip(Token::Separator(',')) { - lexer.next_storage_access()? - } else { - crate::StorageAccess::LOAD - }; - } - lexer.expect_generic_paren('>')?; - crate::TypeInner::Pointer { base, space } - } - "array" => { - lexer.expect_generic_paren('<')?; - let base = self.parse_type_decl(lexer, None, type_arena, const_arena)?; - let size = if lexer.skip(Token::Separator(',')) { - let const_handle = - self.parse_const_expression(lexer, type_arena, const_arena)?; - crate::ArraySize::Constant(const_handle) - } else { - crate::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 } - } - "binding_array" => { - lexer.expect_generic_paren('<')?; - let base = self.parse_type_decl(lexer, None, type_arena, const_arena)?; - let size = if lexer.skip(Token::Separator(',')) { - let const_handle = - self.parse_const_expression(lexer, type_arena, const_arena)?; - crate::ArraySize::Constant(const_handle) - } else { - crate::ArraySize::Dynamic - }; - lexer.expect_generic_paren('>')?; - - crate::TypeInner::BindingArray { base, size } - } - "sampler" => crate::TypeInner::Sampler { comparison: false }, - "sampler_comparison" => crate::TypeInner::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 { - dim: crate::ImageDimension::D1, - arrayed: false, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_1d_array" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D1, - arrayed: true, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_2d" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_2d_array" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: true, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_3d" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D3, - arrayed: false, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_cube" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::Cube, - arrayed: false, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_cube_array" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::Cube, - arrayed: true, - class: crate::ImageClass::Sampled { kind, multi: false }, - } - } - "texture_multisampled_2d" => { - let (kind, width, span) = lexer.next_scalar_generic_with_span()?; - Self::check_texture_sample_type(kind, width, span)?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Sampled { kind, multi: true }, - } - } - "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 { - dim: crate::ImageDimension::D2, - arrayed: true, - class: crate::ImageClass::Sampled { kind, multi: true }, - } - } - "texture_depth_2d" => crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Depth { multi: false }, - }, - "texture_depth_2d_array" => crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: true, - class: crate::ImageClass::Depth { multi: false }, - }, - "texture_depth_cube" => crate::TypeInner::Image { - dim: crate::ImageDimension::Cube, - arrayed: false, - class: crate::ImageClass::Depth { multi: false }, - }, - "texture_depth_cube_array" => crate::TypeInner::Image { - dim: crate::ImageDimension::Cube, - arrayed: true, - class: crate::ImageClass::Depth { multi: false }, - }, - "texture_depth_multisampled_2d" => crate::TypeInner::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 { - dim: crate::ImageDimension::D1, - arrayed: false, - class: crate::ImageClass::Storage { format, access }, - } - } - "texture_storage_1d_array" => { - let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D1, - arrayed: true, - class: crate::ImageClass::Storage { format, access }, - } - } - "texture_storage_2d" => { - let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: false, - class: crate::ImageClass::Storage { format, access }, - } - } - "texture_storage_2d_array" => { - let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D2, - arrayed: true, - class: crate::ImageClass::Storage { format, access }, - } - } - "texture_storage_3d" => { - let (format, access) = lexer.next_format_generic()?; - crate::TypeInner::Image { - dim: crate::ImageDimension::D3, - arrayed: false, - class: crate::ImageClass::Storage { format, access }, - } - } - _ => return Ok(None), - })) - } - - const fn check_texture_sample_type( - kind: crate::ScalarKind, - width: u8, - span: Span, - ) -> Result<(), Error<'static>> { - use crate::ScalarKind::*; - // Validate according to https://gpuweb.github.io/gpuweb/wgsl/#sampled-texture-type - match (kind, width) { - (Float | Sint | Uint, 4) => Ok(()), - _ => Err(Error::BadTextureSampleType { span, kind, width }), - } - } - - /// Parse type declaration of a given name and attribute. - #[allow(clippy::too_many_arguments)] - fn parse_type_decl_name<'a>( - &mut self, - lexer: &mut Lexer<'a>, - name: &'a str, - name_span: Span, - debug_name: Option<&'a str>, - attribute: TypeAttributes, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - Ok(match self.lookup_type.get(name) { - Some(&handle) => handle, - None => { - match self.parse_type_decl_impl(lexer, attribute, name, type_arena, const_arena)? { - Some(inner) => { - let span = name_span.start..lexer.end_byte_offset(); - type_arena.insert( - crate::Type { - name: debug_name.map(|s| s.to_string()), - inner, - }, - NagaSpan::from(span), - ) - } - None => return Err(Error::UnknownType(name_span)), - } - } - }) - } - - fn parse_type_decl<'a>( - &mut self, - lexer: &mut Lexer<'a>, - debug_name: Option<&'a str>, - type_arena: &mut UniqueArena, - const_arena: &mut Arena, - ) -> Result, Error<'a>> { - 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 - Ok(handle) - } - - /// Parse an assignment statement (will also parse increment and decrement statements) - fn parse_assignment_statement<'a, 'out>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, 'out>, - block: &mut crate::Block, - emitter: &mut super::Emitter, - ) -> 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 { - (Token::Operation('='), _) => { - self.parse_general_expression(lexer, context.reborrow())? - } - (Token::AssignmentOperation(c), span) => { - let op = match c { - '<' => Bo::ShiftLeft, - '>' => Bo::ShiftRight, - '+' => Bo::Add, - '-' => Bo::Subtract, - '*' => Bo::Multiply, - '/' => Bo::Divide, - '%' => Bo::Modulo, - '&' => Bo::And, - '|' => Bo::InclusiveOr, - '^' => Bo::ExclusiveOr, - //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()) - } - token @ (Token::IncrementOperation | Token::DecrementOperation, _) => { - let op = match token.0 { - Token::IncrementOperation => Bo::Add, - Token::DecrementOperation => Bo::Subtract, - _ => 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(), - ) - } - other => return Err(Error::Unexpected(other.1, ExpectedToken::SwitchItem)), - }; - - 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), - ); - Ok(()) - } - - /// Parse a function call statement. - fn parse_function_statement<'a, 'out>( - &mut self, - lexer: &mut Lexer<'a>, - ident: &'a str, - mut context: ExpressionContext<'a, '_, 'out>, - ) -> 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)); - self.pop_rule_span(lexer); - - Ok(()) - } - - fn parse_switch_case_body<'a, 'out>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, 'out>, - ) -> Result<(bool, crate::Block), Error<'a>> { - let mut body = crate::Block::new(); - // Push a new lexical scope for the switch case body - context.symbol_table.push_scope(); - - lexer.expect(Token::Paren('{'))?; - let fall_through = loop { - // default statements - if lexer.skip(Token::Word("fallthrough")) { - lexer.expect(Token::Separator(';'))?; - lexer.expect(Token::Paren('}'))?; - break true; - } - if lexer.skip(Token::Paren('}')) { - break false; - } - self.parse_statement(lexer, context.reborrow(), &mut body, false)?; - }; - // Pop the switch case body lexical scope - context.symbol_table.pop_scope(); - - Ok((fall_through, body)) - } - - fn parse_statement<'a, 'out>( - &mut self, - lexer: &mut Lexer<'a>, - mut context: StatementContext<'a, '_, 'out>, - block: &'out mut crate::Block, - is_uniform_control_flow: bool, - ) -> Result<(), Error<'a>> { - self.push_rule_span(Rule::Statement, lexer); - match lexer.peek() { - (Token::Separator(';'), _) => { - let _ = lexer.next(); - self.pop_rule_span(lexer); - return Ok(()); - } - (Token::Paren('{'), _) => { - self.push_rule_span(Rule::Block, lexer); - // Push a new lexical scope for the block statement - context.symbol_table.push_scope(); - - let _ = lexer.next(); - let mut statements = crate::Block::new(); - while !lexer.skip(Token::Paren('}')) { - self.parse_statement( - lexer, - context.reborrow(), - &mut statements, - is_uniform_control_flow, - )?; - } - // Pop the block statement lexical scope - context.symbol_table.pop_scope(); - - self.pop_rule_span(lexer); - let span = NagaSpan::from(self.pop_rule_span(lexer)); - block.push(crate::Statement::Block(statements), span); - return Ok(()); - } - (Token::Word(word), _) => { - let mut emitter = super::Emitter::default(); - let statement = match word { - "_" => { - let _ = lexer.next(); - emitter.start(context.expressions); - lexer.expect(Token::Operation('='))?; - self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - lexer.expect(Token::Separator(';'))?; - block.extend(emitter.finish(context.expressions)); - None - } - "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 given_ty = if lexer.skip(Token::Separator(':')) { - let ty = self.parse_type_decl( - lexer, - None, - context.types, - context.constants, - )?; - Some(ty) - } else { - None - }; - lexer.expect(Token::Operation('='))?; - let expr_id = self.parse_general_expression( - lexer, - context.as_expression(block, &mut emitter), - )?; - 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), - )); - } - } - block.extend(emitter.finish(context.expressions)); - context.symbol_table.add( - name, - TypedExpression { - handle: expr_id, - is_reference: false, - }, - ); - context - .named_expressions - .insert(expr_id, String::from(name)); - None - } - "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, - )?; - 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) - } 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)); - } - } - }; - - 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 - } - } - "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)); - Some(handle) - } else { - None - }; - lexer.expect(Token::Separator(';'))?; - Some(crate::Statement::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 accept = self.parse_block(lexer, context.reborrow(), false)?; - - 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(); - } - - if !lexer.skip(Token::Word("if")) { - // ... else { ... } - break self.parse_block(lexer, context.reborrow(), false)?; - } - - // ... 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, - )); - 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 - elsif_stack.into_iter().rev() - { - let sub_stmt = crate::Statement::If { - condition: other_cond, - accept: other_block, - reject, - }; - reject = crate::Block::new(); - reject.extend(other_emit); - reject.push(sub_stmt, NagaSpan::from(other_span_start..span_end)) - } - - Some(crate::Statement::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)); - lexer.expect(Token::Paren('{'))?; - let mut cases = Vec::new(); - - loop { - // cases + default - match lexer.next() { - (Token::Word("case"), _) => { - // parse a list of values - let value = loop { - let value = Self::parse_switch_value(lexer, uint)?; - if lexer.skip(Token::Separator(',')) { - if lexer.skip(Token::Separator(':')) { - break value; - } - } else { - lexer.skip(Token::Separator(':')); - break value; - } - cases.push(crate::SwitchCase { - value: crate::SwitchValue::Integer(value), - body: crate::Block::new(), - fall_through: true, - }); - }; - - let (fall_through, body) = - self.parse_switch_case_body(lexer, context.reborrow())?; - - cases.push(crate::SwitchCase { - value: crate::SwitchValue::Integer(value), - body, - fall_through, - }); - } - (Token::Word("default"), _) => { - lexer.skip(Token::Separator(':')); - let (fall_through, body) = - self.parse_switch_case_body(lexer, context.reborrow())?; - cases.push(crate::SwitchCase { - value: crate::SwitchValue::Default, - body, - fall_through, - }); - } - (Token::Paren('}'), _) => break, - other => { - return Err(Error::Unexpected( - other.1, - ExpectedToken::SwitchItem, - )) - } - } - } - - Some(crate::Statement::Switch { selector, cases }) - } - "loop" => Some(self.parse_loop(lexer, context.reborrow(), &mut emitter)?), - "while" => { - let _ = lexer.next(); - let mut body = crate::Block::new(); - - 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::Paren('{'))?; - 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, - }, - NagaSpan::from(span), - ); - // Push a lexical scope for the while loop body - context.symbol_table.push_scope(); - - while !lexer.skip(Token::Paren('}')) { - self.parse_statement(lexer, context.reborrow(), &mut body, false)?; - } - // Pop the while loop body lexical scope - context.symbol_table.pop_scope(); - - 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(); - - 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, - ) - })?; - - if block.len() != num_statements { - match *block.last().unwrap() { - crate::Statement::Store { .. } - | crate::Statement::Call { .. } => {} - _ => return Err(Error::InvalidForInitializer(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, - }, - NagaSpan::from(span), - ); - }; - - 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(')'))?; - } - lexer.expect(Token::Paren('{'))?; - - while !lexer.skip(Token::Paren('}')) { - self.parse_statement(lexer, context.reborrow(), &mut body, false)?; - } - // Pop the for loop lexical scope - context.symbol_table.pop_scope(); - - 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)); - } - 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), - )?, - } - lexer.expect(Token::Separator(';'))?; - None - } - }; - 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); - } - } - Ok(()) - } - - fn parse_loop<'a>( - &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(); - - lexer.expect(Token::Paren('{'))?; - - 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"))?; - - // 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); - - // 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)?; - } - } - // 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.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, - }) - } - - 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(); - - 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(); - - self.pop_rule_span(lexer); - Ok(block) - } - - 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); - - 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 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(',')), - )); - } - let mut binding = self.parse_varying_binding(lexer)?; - let (param_name, param_name_span, param_type) = - self.parse_variable_ident_decl(lexer, &mut module.types, &mut module.constants)?; - if crate::keywords::wgsl::RESERVED.contains(¶m_name) { - return Err(Error::ReservedKeyword(param_name_span)); - } - let param_index = arguments.len() as u32; - let expression = expressions.append( - crate::Expression::FunctionArgument(param_index), - NagaSpan::from(param_name_span), - ); - symbol_table.add( - param_name, - TypedExpression { - handle: expression, - is_reference: false, - }, - ); - if let Some(ref mut binding) = binding { - binding.apply_default_interpolation(&module.types[param_type].inner); - } - arguments.push(crate::FunctionArgument { - name: Some(param_name.to_string()), - 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); - } - 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(), - }; - - // read body - let mut typifier = super::Typifier::new(); - let mut named_expressions = crate::FastHashMap::default(); - fun.body = self.parse_block( - lexer, - StatementContext { - symbol_table: &mut symbol_table, - typifier: &mut typifier, - variables: &mut fun.local_variables, - expressions: &mut fun.expressions, - named_expressions: &mut named_expressions, - types: &mut module.types, - constants: &mut module.constants, - global_vars: &module.global_variables, - functions: &module.functions, - arguments: &fun.arguments, - }, - true, - )?; - // fixup the IR - ensure_block_returns(&mut fun.body); - // done - self.pop_rule_span(lexer); - - // Set named expressions after block parsing ends - fun.named_expressions = named_expressions; - - Ok((fun, fun_name)) - } - - fn parse_global_decl<'a>( - &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); - - 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, - )) - } - } - } - } - ("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) => {} - } - - // 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 - }; - - lexer.expect(Token::Operation('='))?; - let first_token_span = lexer.next(); - let const_handle = self.parse_const_expression_impl( - first_token_span, - lexer, - Some(name), - &mut module.types, - &mut module.constants, - )?; - - if let Some(explicit_ty) = given_ty { - let con = &module.constants[const_handle]; - let type_match = match con.inner { - crate::ConstantInner::Scalar { width, value } => { - module.types[explicit_ty].inner - == crate::TypeInner::Scalar { - kind: value.scalar_kind(), - width, - } - } - crate::ConstantInner::Composite { ty, components: _ } => ty == explicit_ty, - }; - if !type_match { - let expected_inner_str = match con.inner { - crate::ConstantInner::Scalar { width, value } => { - crate::TypeInner::Scalar { - kind: value.scalar_kind(), - width, - } - .to_wgsl(&module.types, &module.constants) - } - crate::ConstantInner::Composite { .. } => module.types[explicit_ty] - .inner - .to_wgsl(&module.types, &module.constants), - }; - return Err(Error::InitializationTypeMismatch( - name_span, - expected_inner_str, - )); - } - } - - 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, - }, - 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))); - } - } - } - (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), - } - } - - pub fn parse(&mut self, source: &str) -> Result { - self.reset(); - - let mut module = crate::Module::default(); - let mut lexer = Lexer::new(source); - let mut lookup_global_expression = FastHashMap::default(); - 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); - } - } - } + Lowerer::new(&module, &self.interner).lower() } } -pub fn parse_str(source: &str) -> Result { - Parser::new().parse(source) +pub fn parse_str(source: &str) -> Result> { + WgslContext::new().parse(source) } diff --git a/src/front/wgsl/number.rs b/src/front/wgsl/number.rs deleted file mode 100644 index d7e8801b09..0000000000 --- a/src/front/wgsl/number.rs +++ /dev/null @@ -1,445 +0,0 @@ -use std::borrow::Cow; - -use super::{NumberError, Token}; - -/// When using this type assume no Abstract Int/Float for now -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum Number { - /// Abstract Int (-2^63 ≤ i < 2^63) - AbstractInt(i64), - /// Abstract Float (IEEE-754 binary64) - AbstractFloat(f64), - /// Concrete i32 - I32(i32), - /// Concrete u32 - U32(u32), - /// Concrete f32 - F32(f32), -} - -impl Number { - /// Convert abstract numbers to a plausible concrete counterpart. - /// - /// Return concrete numbers unchanged. If the conversion would be - /// lossy, return an error. - fn abstract_to_concrete(self) -> Result { - match self { - Number::AbstractInt(num) => { - use std::convert::TryFrom; - i32::try_from(num) - .map(Number::I32) - .map_err(|_| NumberError::NotRepresentable) - } - Number::AbstractFloat(num) => { - let num = num as f32; - if num.is_finite() { - Ok(Number::F32(num)) - } else { - Err(NumberError::NotRepresentable) - } - } - num => Ok(num), - } - } -} - -// TODO: when implementing Creation-Time Expressions, remove the ability to match the minus sign - -pub(super) fn consume_number(input: &str) -> (Token<'_>, &str) { - let (result, rest) = parse(input); - ( - Token::Number(result.and_then(Number::abstract_to_concrete)), - rest, - ) -} - -enum Kind { - Int(IntKind), - Float(FloatKind), -} - -enum IntKind { - I32, - U32, -} - -enum FloatKind { - F32, - F16, -} - -// The following regexes (from the WGSL spec) will be matched: - -// int_literal: -// | / 0 [iu]? / -// | / [1-9][0-9]* [iu]? / -// | / 0[xX][0-9a-fA-F]+ [iu]? / - -// decimal_float_literal: -// | / 0 [fh] / -// | / [1-9][0-9]* [fh] / -// | / [0-9]* \.[0-9]+ ([eE][+-]?[0-9]+)? [fh]? / -// | / [0-9]+ \.[0-9]* ([eE][+-]?[0-9]+)? [fh]? / -// | / [0-9]+ [eE][+-]?[0-9]+ [fh]? / - -// hex_float_literal: -// | / 0[xX][0-9a-fA-F]* \.[0-9a-fA-F]+ ([pP][+-]?[0-9]+ [fh]?)? / -// | / 0[xX][0-9a-fA-F]+ \.[0-9a-fA-F]* ([pP][+-]?[0-9]+ [fh]?)? / -// | / 0[xX][0-9a-fA-F]+ [pP][+-]?[0-9]+ [fh]? / - -// You could visualize the regex below via https://debuggex.com to get a rough idea what `parse` is doing -// -?(?:0[xX](?:([0-9a-fA-F]+\.[0-9a-fA-F]*|[0-9a-fA-F]*\.[0-9a-fA-F]+)(?:([pP][+-]?[0-9]+)([fh]?))?|([0-9a-fA-F]+)([pP][+-]?[0-9]+)([fh]?)|([0-9a-fA-F]+)([iu]?))|((?:[0-9]+[eE][+-]?[0-9]+|(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?))([fh]?)|((?:[0-9]|[1-9][0-9]+))([iufh]?)) - -fn parse(input: &str) -> (Result, &str) { - /// returns `true` and consumes `X` bytes from the given byte buffer - /// if the given `X` nr of patterns are found at the start of the buffer - macro_rules! consume { - ($bytes:ident, $($($pattern:pat)|*),*) => { - match $bytes { - &[$($($pattern)|*),*, ref rest @ ..] => { $bytes = rest; true }, - _ => false, - } - }; - } - - /// consumes one byte from the given byte buffer - /// if one of the given patterns are found at the start of the buffer - /// returning the corresponding expr for the matched pattern - macro_rules! consume_map { - ($bytes:ident, [$($($pattern:pat)|* => $to:expr),*]) => { - match $bytes { - $( &[$($pattern)|*, ref rest @ ..] => { $bytes = rest; Some($to) }, )* - _ => None, - } - }; - } - - /// consumes all consecutive bytes matched by the `0-9` pattern from the given byte buffer - /// returning the number of consumed bytes - macro_rules! consume_dec_digits { - ($bytes:ident) => {{ - let start_len = $bytes.len(); - while let &[b'0'..=b'9', ref rest @ ..] = $bytes { - $bytes = rest; - } - start_len - $bytes.len() - }}; - } - - /// consumes all consecutive bytes matched by the `0-9 | a-f | A-F` pattern from the given byte buffer - /// returning the number of consumed bytes - macro_rules! consume_hex_digits { - ($bytes:ident) => {{ - let start_len = $bytes.len(); - while let &[b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F', ref rest @ ..] = $bytes { - $bytes = rest; - } - start_len - $bytes.len() - }}; - } - - /// maps the given `&[u8]` (tail of the initial `input: &str`) to a `&str` - macro_rules! rest_to_str { - ($bytes:ident) => { - &input[input.len() - $bytes.len()..] - }; - } - - struct ExtractSubStr<'a>(&'a str); - - impl<'a> ExtractSubStr<'a> { - /// given an `input` and a `start` (tail of the `input`) - /// creates a new [ExtractSubStr] - fn start(input: &'a str, start: &'a [u8]) -> Self { - let start = input.len() - start.len(); - Self(&input[start..]) - } - /// given an `end` (tail of the initial `input`) - /// returns a substring of `input` - fn end(&self, end: &'a [u8]) -> &'a str { - let end = self.0.len() - end.len(); - &self.0[..end] - } - } - - let mut bytes = input.as_bytes(); - - let general_extract = ExtractSubStr::start(input, bytes); - - let is_negative = consume!(bytes, b'-'); - - if consume!(bytes, b'0', b'x' | b'X') { - let digits_extract = ExtractSubStr::start(input, bytes); - - let consumed = consume_hex_digits!(bytes); - - if consume!(bytes, b'.') { - let consumed_after_period = consume_hex_digits!(bytes); - - if consumed + consumed_after_period == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let significand = general_extract.end(bytes); - - if consume!(bytes, b'p' | b'P') { - consume!(bytes, b'+' | b'-'); - let consumed = consume_dec_digits!(bytes); - - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let number = general_extract.end(bytes); - - let kind = consume_map!(bytes, [b'f' => FloatKind::F32, b'h' => FloatKind::F16]); - - (parse_hex_float(number, kind), rest_to_str!(bytes)) - } else { - ( - parse_hex_float_missing_exponent(significand, None), - rest_to_str!(bytes), - ) - } - } else { - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let significand = general_extract.end(bytes); - let digits = digits_extract.end(bytes); - - let exp_extract = ExtractSubStr::start(input, bytes); - - if consume!(bytes, b'p' | b'P') { - consume!(bytes, b'+' | b'-'); - let consumed = consume_dec_digits!(bytes); - - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let exponent = exp_extract.end(bytes); - - let kind = consume_map!(bytes, [b'f' => FloatKind::F32, b'h' => FloatKind::F16]); - - ( - parse_hex_float_missing_period(significand, exponent, kind), - rest_to_str!(bytes), - ) - } else { - let kind = consume_map!(bytes, [b'i' => IntKind::I32, b'u' => IntKind::U32]); - - ( - parse_hex_int(is_negative, digits, kind), - rest_to_str!(bytes), - ) - } - } - } else { - let is_first_zero = bytes.first() == Some(&b'0'); - - let consumed = consume_dec_digits!(bytes); - - if consume!(bytes, b'.') { - let consumed_after_period = consume_dec_digits!(bytes); - - if consumed + consumed_after_period == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - if consume!(bytes, b'e' | b'E') { - consume!(bytes, b'+' | b'-'); - let consumed = consume_dec_digits!(bytes); - - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - } - - let number = general_extract.end(bytes); - - let kind = consume_map!(bytes, [b'f' => FloatKind::F32, b'h' => FloatKind::F16]); - - (parse_dec_float(number, kind), rest_to_str!(bytes)) - } else { - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - if consume!(bytes, b'e' | b'E') { - consume!(bytes, b'+' | b'-'); - let consumed = consume_dec_digits!(bytes); - - if consumed == 0 { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let number = general_extract.end(bytes); - - let kind = consume_map!(bytes, [b'f' => FloatKind::F32, b'h' => FloatKind::F16]); - - (parse_dec_float(number, kind), rest_to_str!(bytes)) - } else { - // make sure the multi-digit numbers don't start with zero - if consumed > 1 && is_first_zero { - return (Err(NumberError::Invalid), rest_to_str!(bytes)); - } - - let digits_with_sign = general_extract.end(bytes); - - let kind = consume_map!(bytes, [ - b'i' => Kind::Int(IntKind::I32), - b'u' => Kind::Int(IntKind::U32), - b'f' => Kind::Float(FloatKind::F32), - b'h' => Kind::Float(FloatKind::F16) - ]); - - ( - parse_dec(is_negative, digits_with_sign, kind), - rest_to_str!(bytes), - ) - } - } - } -} - -fn parse_hex_float_missing_exponent( - // format: -?0[xX] ( [0-9a-fA-F]+\.[0-9a-fA-F]* | [0-9a-fA-F]*\.[0-9a-fA-F]+ ) - significand: &str, - kind: Option, -) -> Result { - let hexf_input = format!("{}{}", significand, "p0"); - parse_hex_float(&hexf_input, kind) -} - -fn parse_hex_float_missing_period( - // format: -?0[xX] [0-9a-fA-F]+ - significand: &str, - // format: [pP][+-]?[0-9]+ - exponent: &str, - kind: Option, -) -> Result { - let hexf_input = format!("{}.{}", significand, exponent); - parse_hex_float(&hexf_input, kind) -} - -fn parse_hex_int( - is_negative: bool, - // format: [0-9a-fA-F]+ - digits: &str, - kind: Option, -) -> Result { - let digits_with_sign = if is_negative { - Cow::Owned(format!("-{}", digits)) - } else { - Cow::Borrowed(digits) - }; - parse_int(&digits_with_sign, kind, 16, is_negative) -} - -fn parse_dec( - is_negative: bool, - // format: -? ( [0-9] | [1-9][0-9]+ ) - digits_with_sign: &str, - kind: Option, -) -> Result { - match kind { - None => parse_int(digits_with_sign, None, 10, is_negative), - Some(Kind::Int(kind)) => parse_int(digits_with_sign, Some(kind), 10, is_negative), - Some(Kind::Float(kind)) => parse_dec_float(digits_with_sign, Some(kind)), - } -} - -// Float parsing notes - -// The following chapters of IEEE 754-2019 are relevant: -// -// 7.4 Overflow (largest finite number is exceeded by what would have been -// the rounded floating-point result were the exponent range unbounded) -// -// 7.5 Underflow (tiny non-zero result is detected; -// for decimal formats tininess is detected before rounding when a non-zero result -// computed as though both the exponent range and the precision were unbounded -// would lie strictly between 2^−126) -// -// 7.6 Inexact (rounded result differs from what would have been computed -// were both exponent range and precision unbounded) - -// The WGSL spec requires us to error: -// on overflow for decimal floating point literals -// on overflow and inexact for hexadecimal floating point literals -// (underflow is not mentioned) - -// hexf_parse errors on overflow, underflow, inexact -// rust std lib float from str handles overflow, underflow, inexact transparently (rounds and will not error) - -// Therefore we only check for overflow manually for decimal floating point literals - -// input format: -?0[xX] ( [0-9a-fA-F]+\.[0-9a-fA-F]* | [0-9a-fA-F]*\.[0-9a-fA-F]+ ) [pP][+-]?[0-9]+ -fn parse_hex_float(input: &str, kind: Option) -> Result { - match kind { - None => match hexf_parse::parse_hexf64(input, false) { - Ok(num) => Ok(Number::AbstractFloat(num)), - // can only be ParseHexfErrorKind::Inexact but we can't check since it's private - _ => Err(NumberError::NotRepresentable), - }, - Some(FloatKind::F32) => match hexf_parse::parse_hexf32(input, false) { - Ok(num) => Ok(Number::F32(num)), - // can only be ParseHexfErrorKind::Inexact but we can't check since it's private - _ => Err(NumberError::NotRepresentable), - }, - Some(FloatKind::F16) => Err(NumberError::UnimplementedF16), - } -} - -// input format: -? ( [0-9]+\.[0-9]* | [0-9]*\.[0-9]+ ) ([eE][+-]?[0-9]+)? -// | -? [0-9]+ [eE][+-]?[0-9]+ -fn parse_dec_float(input: &str, kind: Option) -> Result { - match kind { - None => { - let num = input.parse::().unwrap(); // will never fail - num.is_finite() - .then(|| Number::AbstractFloat(num)) - .ok_or(NumberError::NotRepresentable) - } - Some(FloatKind::F32) => { - let num = input.parse::().unwrap(); // will never fail - num.is_finite() - .then(|| Number::F32(num)) - .ok_or(NumberError::NotRepresentable) - } - Some(FloatKind::F16) => Err(NumberError::UnimplementedF16), - } -} - -fn parse_int( - input: &str, - kind: Option, - radix: u32, - is_negative: bool, -) -> Result { - fn map_err(e: core::num::ParseIntError) -> NumberError { - match *e.kind() { - core::num::IntErrorKind::PosOverflow | core::num::IntErrorKind::NegOverflow => { - NumberError::NotRepresentable - } - _ => unreachable!(), - } - } - match kind { - None => match i64::from_str_radix(input, radix) { - Ok(num) => Ok(Number::AbstractInt(num)), - Err(e) => Err(map_err(e)), - }, - Some(IntKind::I32) => match i32::from_str_radix(input, radix) { - Ok(num) => Ok(Number::I32(num)), - Err(e) => Err(map_err(e)), - }, - Some(IntKind::U32) if is_negative => Err(NumberError::NotRepresentable), - Some(IntKind::U32) => match u32::from_str_radix(input, radix) { - Ok(num) => Ok(Number::U32(num)), - Err(e) => Err(map_err(e)), - }, - } -} diff --git a/src/front/wgsl/parse/ast.rs b/src/front/wgsl/parse/ast.rs new file mode 100644 index 0000000000..2a0f19811f --- /dev/null +++ b/src/front/wgsl/parse/ast.rs @@ -0,0 +1,284 @@ +use crate::{front::wgsl::text::Text, Span}; + +#[derive(Clone, Debug, Default)] +pub struct TranslationUnit { + pub enables: Vec, + pub decls: Vec, +} + +#[derive(Clone, Debug)] +pub struct Enable { + pub name: Ident, + pub span: Span, +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct Ident { + pub name: Text, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub struct Attribute { + pub name: Ident, + pub exprs: Vec, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub struct GlobalDecl { + pub kind: GlobalDeclKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum GlobalDeclKind { + Fn(Fn), + Override(Override), + Var(Var), + Let(Let), + Const(Let), + StaticAssert(StaticAssert), + Struct(Struct), + Type(TypeDecl), +} + +#[derive(Clone, Debug)] +pub struct Fn { + pub attribs: Vec, + pub name: Ident, + pub args: Vec, + pub ret_attribs: Vec, + pub ret: Option, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub struct Override { + pub attribs: Vec, + pub name: Ident, + pub ty: Option, + pub val: Option, +} + +#[derive(Clone, Debug)] +pub struct Var { + pub attribs: Vec, + pub inner: VarNoAttribs, +} + +#[derive(Clone, Debug)] +pub struct VarNoAttribs { + pub address_space: Option, + pub access_mode: Option, + pub name: Ident, + pub ty: Option, + pub val: Option, +} + +#[derive(Clone, Debug)] +pub struct StaticAssert { + pub expr: Expr, +} + +#[derive(Clone, Debug)] +pub struct Struct { + pub name: Ident, + pub fields: Vec, +} + +#[derive(Clone, Debug)] +pub struct TypeDecl { + pub name: Ident, + pub ty: Type, +} + +#[derive(Clone, Debug)] +pub struct Arg { + pub attribs: Vec, + pub name: Ident, + pub ty: Type, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub struct Type { + pub kind: TypeKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum TypeKind { + Ident(Ident, Vec), + Array(Ident, Box, Option), +} + +#[derive(Clone, Debug)] +pub struct Block { + pub stmts: Vec, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub struct Stmt { + pub kind: StmtKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum StmtKind { + Block(Block), + Expr(Expr), + Break, + Continue, + Discard, + For(For), + If(If), + Loop(Block), + Return(Option), + StaticAssert(StaticAssert), + Switch(Switch), + While(While), + Continuing(Block), + BreakIf(Expr), + Empty, +} + +#[derive(Clone, Debug)] +pub struct For { + pub init: Option, + pub cond: Option, + pub update: Option, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub struct If { + pub cond: Expr, + pub block: Block, + pub else_: Option>, +} + +#[derive(Clone, Debug)] +pub struct While { + pub cond: Expr, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub struct Switch { + pub expr: Expr, + pub cases: Vec, +} + +#[derive(Clone, Debug)] +pub struct Case { + pub selectors: Vec, + pub block: Block, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum CaseSelector { + Expr(Expr), + Default, +} + +#[derive(Clone, Debug)] +pub struct Expr { + pub kind: ExprKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum ExprKind { + Underscore, + VarDecl(Box), + Literal(Literal), + Ident(IdentExpr), + Unary(UnaryExpr), + Binary(BinaryExpr), + Assign(AssignExpr), + Call(CallExpr), + Index(Box, Box), + Member(Box, Ident), + Postfix(PostfixExpr), +} + +#[derive(Clone, Debug)] +pub struct IdentExpr { + pub name: Ident, + pub generics: Vec, + pub array_len: Option>, +} + +#[derive(Clone, Debug)] +pub enum Literal { + Bool(bool), + AbstractInt(i64), + AbstractFloat(f64), + I32(i32), + U32(u32), + F32(f32), + F16(half::f16), +} + +#[derive(Clone, Debug)] +pub struct UnaryExpr { + pub op: UnaryOp, + pub expr: Box, +} + +#[derive(Copy, Clone, Debug)] +pub enum UnaryOp { + Ref, + Deref, + Not, + Minus, +} + +#[derive(Clone, Debug)] +pub struct AssignExpr { + pub lhs: Box, + pub op: Option, + pub rhs: Box, +} + +#[derive(Clone, Debug)] +pub struct CallExpr { + pub target: Box, + pub args: Vec, +} + +#[derive(Clone, Debug)] +pub struct BinaryExpr { + pub lhs: Box, + pub op: crate::BinaryOperator, + pub rhs: Box, +} + +#[derive(Clone, Debug)] +pub struct PostfixExpr { + pub expr: Box, + pub op: PostfixOp, +} + +#[derive(Copy, Clone, Debug)] +pub enum PostfixOp { + Increment, + Decrement, +} + +#[derive(Clone, Debug)] +pub enum VarDecl { + Var(VarNoAttribs), + Const(Let), + Let(Let), +} + +#[derive(Clone, Debug)] +pub struct Let { + pub name: Ident, + pub ty: Option, + pub val: Expr, +} diff --git a/src/front/wgsl/parse/lexer.rs b/src/front/wgsl/parse/lexer.rs new file mode 100644 index 0000000000..6a710e7840 --- /dev/null +++ b/src/front/wgsl/parse/lexer.rs @@ -0,0 +1,222 @@ +use std::fmt::{Debug, Display}; + +use crate::Span; +use logos::Logos; + +#[derive(Clone)] +pub struct Lexer<'a> { + inner: logos::Lexer<'a, TokenKind>, +} + +impl<'a> Lexer<'a> { + pub fn new(source: &'a str) -> Self { + Self { + inner: logos::Lexer::new(source), + } + } + + pub fn eof_span(&self) -> Span { + Span::new( + self.inner.source().len() as _, + self.inner.source().len() as u32 + 1, + ) + } +} + +impl Iterator for Lexer<'_> { + type Item = Token; + + fn next(&mut self) -> Option { + let next = self.inner.next(); + let span = self.inner.span(); + next.map(|kind| Token { + kind, + span: Span::new(span.start as _, span.end as _), + }) + } +} + +#[derive(Copy, Clone)] +pub struct Token { + pub kind: TokenKind, + pub span: Span, +} + +#[derive(Copy, Clone, Hash, Eq, PartialEq, Logos)] +pub enum TokenKind { + #[regex(r#"(0[iu]?)|([1-9][0-9]*[iu]?)|(0[xX][0-9a-fA-F]+[iu]?)"#)] + IntLit, + #[regex( + r#"(0[fh])|([0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[fh]?)|([0-9]+[eE][+-]?[0-9]+[fh]?)|([0-9]+\.[0-9]*([eE][+-]?[0-9]+)?[fh]?)|([1-9][0-9]*[fh])|(0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+([pP][+-]?[0-9]+[fh]?)?)|(0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?)|(0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*([pP][+-]?[0-9]+[fh]?)?)"# + )] + FloatLit, + #[regex(r"[\p{XID_Start}_]\p{XID_Continue}*")] + Word, + #[token("&")] + And, + #[token("&&")] + AndAnd, + #[token("->")] + Arrow, + #[token("@")] + Attr, + #[token("/")] + ForwardSlash, + #[token("!")] + Bang, + #[token("[")] + LBracket, + #[token("]")] + RBracket, + #[token("{")] + LBrace, + #[token("}")] + RBrace, + #[token(":")] + Colon, + #[token(",")] + Comma, + #[token("=")] + Equal, + #[token("==")] + EqualEqual, + #[token("!=")] + NotEqual, + #[token(">")] + Greater, + #[token(">=")] + GreaterEqual, + #[token("<")] + Less, + #[token("<=")] + LessEqual, + #[token("<<")] + ShiftLeft, + #[token("%")] + Modulo, + #[token("-")] + Minus, + #[token("--")] + MinusMinus, + #[token(".")] + Period, + #[token("+")] + Plus, + #[token("++")] + PlusPlus, + #[token("|")] + Or, + #[token("||")] + OrOr, + #[token("(")] + LParen, + #[token(")")] + RParen, + #[token(";")] + Semicolon, + #[token("*")] + Star, + #[token("~")] + Tilde, + #[token("_")] + Underscore, + #[token("^")] + Xor, + #[token("+=")] + PlusEqual, + #[token("-=")] + MinusEqual, + #[token("*=")] + TimesEqual, + #[token("/=")] + DivideEqual, + #[token("%=")] + ModuloEqual, + #[token("&=")] + AndEqual, + #[token("|=")] + OrEqual, + #[token("^=")] + XorEqual, + #[token(">>=")] + ShiftRightEqual, + #[token("<<=")] + ShiftLeftEqual, + #[error] + #[regex(r"[ \t\n\r\f]+|//.*|", logos::skip)] + #[token("/*", |lex| { + let len = lex.remainder().find("*/").unwrap_or(lex.remainder().len() - 2); + lex.bump(len + 2); // include len of `*/` + + logos::Skip + })] + Error, +} + +impl Display for TokenKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl Debug for TokenKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use TokenKind::*; + + write!( + f, + "{}", + match *self { + IntLit => "{integer}", + FloatLit => "{float}", + Word => "", + And => "&", + AndAnd => "&&", + Arrow => "->", + Attr => "@", + ForwardSlash => "/", + Bang => "!", + LBracket => "[", + RBracket => "]", + LBrace => "{", + RBrace => "}", + Colon => ":", + Comma => ",", + Equal => "=", + EqualEqual => "==", + NotEqual => "!=", + Greater => ">", + GreaterEqual => ">=", + Less => "<", + LessEqual => "<=", + ShiftLeft => "<<", + Modulo => "%", + Minus => "-", + MinusMinus => "--", + Period => ".", + Plus => "+", + PlusPlus => "++", + Or => "|", + OrOr => "||", + LParen => "(", + RParen => ")", + Semicolon => ";", + Star => "*", + Tilde => "~", + Underscore => "_", + Xor => "^", + PlusEqual => "+=", + MinusEqual => "-=", + TimesEqual => "*=", + DivideEqual => "/=", + ModuloEqual => "%=", + AndEqual => "&=", + OrEqual => "|=", + XorEqual => "^=", + ShiftRightEqual => ">>=", + ShiftLeftEqual => "<<=", + Error => "", + } + ) + } +} diff --git a/src/front/wgsl/parse/mod.rs b/src/front/wgsl/parse/mod.rs new file mode 100644 index 0000000000..9871c927f1 --- /dev/null +++ b/src/front/wgsl/parse/mod.rs @@ -0,0 +1,776 @@ +use std::convert::TryInto; +use std::ops::Range; +use std::{cell::RefCell, fmt::Write, str::FromStr}; + +use ast::*; +use chumsky::{error::SimpleReason, prelude::*, Parser as CParser, Stream}; +use half::f16; +use lexer::{Lexer, Token, TokenKind}; + +use crate::front::wgsl::{text::Interner, WgslError}; +use crate::{BinaryOperator, Span}; + +pub mod ast; +mod lexer; + +impl chumsky::Span for Span { + type Context = (); + type Offset = usize; + + fn new(_: Self::Context, range: Range) -> Self { + range.into() + } + + fn context(&self) -> Self::Context {} + + fn start(&self) -> Self::Offset { + self.to_range().unwrap().start + } + + fn end(&self) -> Self::Offset { + self.to_range().unwrap().end + } +} + +struct Parser<'a> { + intern: &'a mut Interner, + diagnostics: &'a mut Vec, + lexer: Lexer<'a>, +} + +pub fn parse( + source: &str, + intern: &mut Interner, + diagnostics: &mut Vec, +) -> TranslationUnit { + let (tu, errors) = Parser { + lexer: Lexer::new(source), + intern, + diagnostics, + } + .parse(source); + + for x in errors.into_iter().map(error_to_diagnostic) { + diagnostics.push(x); + } + + tu.unwrap_or_default() +} + +impl Parser<'_> { + fn parse(self, source: &str) -> (Option, Vec>) { + fn get_text(source: &str, span: Span) -> &str { + &source[span.to_range().unwrap()] + } + + let intern = RefCell::new(self.intern); + let diagnostics = RefCell::new(self.diagnostics); + + let kw = |kw: &'static str| { + filter_map(move |span: Span, kind: TokenKind| { + if matches!(kind, TokenKind::Word) && get_text(source, span) == kw { + Ok(span) + } else { + Err(Simple::custom(span, format!("expected keyword `{}`", kw))) + } + }) + }; + let text = just(TokenKind::Word) + .map_with_span(|_, span: Span| intern.borrow_mut().get(get_text(source, span))); + let ident = text.map_with_span(|name, span| Ident { name, span }); + + let mut expr = Recursive::declare(); + + let static_assert = kw("static_assert") + .ignore_then(expr.clone()) + .map(|expr| StaticAssert { expr }); + + let mut block = Recursive::declare(); + + let stmt = recursive(|stmt| { + let break_ = kw("break") + .ignore_then(kw("if").ignore_then(expr.clone()).or_not()) + .map(|expr| match expr { + Some(expr) => StmtKind::BreakIf(expr), + None => StmtKind::Break, + }); + + let for_ = kw("for") + .ignore_then(just(TokenKind::LParen)) + .ignore_then(expr.clone().or_not()) + .then_ignore(just(TokenKind::Semicolon)) + .then(expr.clone().or_not()) + .then_ignore(just(TokenKind::Semicolon)) + .then(expr.clone().or_not()) + .then_ignore(just(TokenKind::RParen)) + .then(block.clone()) + .map(|(((init, cond), update), block)| For { + init, + cond, + update, + block, + }) + .boxed(); + + let if_ = kw("if") + .ignore_then(expr.clone()) + .then(block.clone()) + .then(kw("else").ignore_then(stmt.clone()).or_not()) + .map(|((cond, block), else_)| If { + cond, + block, + else_: else_.map(Box::new), + }) + .boxed(); + + let case_selector = kw("default") + .to(CaseSelector::Default) + .or(kw("case").ignore_then( + kw("default") + .to(CaseSelector::Default) + .or(expr.clone().map(CaseSelector::Expr)), + )); + let case = case_selector + .separated_by(just(TokenKind::Comma)) + .allow_trailing() + .then_ignore(just(TokenKind::Colon).or_not()) + .then(block.clone()) + .map_with_span(|(selectors, block), span| Case { + selectors, + block, + span, + }) + .boxed(); + let switch_ = kw("switch") + .ignore_then(expr.clone()) + .then( + case.repeated() + .delimited_by(just(TokenKind::LBrace), just(TokenKind::RBrace)), + ) + .map(|(expr, cases)| Switch { expr, cases }) + .boxed(); + + let while_ = kw("while") + .ignore_then(expr.clone()) + .then(block.clone()) + .map(|(cond, block)| While { cond, block }); + + let with_semi = choice(( + break_, + kw("continue").to(StmtKind::Continue), + kw("discard").to(StmtKind::Discard), + kw("return") + .ignore_then(expr.clone().or_not()) + .map(StmtKind::Return), + static_assert.clone().map(StmtKind::StaticAssert), + expr.clone().map(StmtKind::Expr), + )) + .then_ignore(just(TokenKind::Semicolon)) + .boxed(); + + choice(( + block.clone().map(StmtKind::Block), + for_.map(StmtKind::For), + if_.map(StmtKind::If), + kw("loop").ignore_then(block.clone()).map(StmtKind::Loop), + switch_.map(StmtKind::Switch), + while_.map(StmtKind::While), + kw("continuing") + .ignore_then(block.clone()) + .map(StmtKind::Continuing), + just(TokenKind::Semicolon).to(StmtKind::Empty), + )) + .or(with_semi) + .map_with_span(|kind, span| Stmt { kind, span }) + .boxed() + }); + + block.define( + stmt.repeated() + .delimited_by(just(TokenKind::LBrace), just(TokenKind::RBrace)) + .map_with_span(|stmts, span| Block { stmts, span }), + ); + + let mut shift = Recursive::declare(); + + let ty = recursive(|ty: Recursive<_, Type, _>| { + choice(( + kw("array") + .or(kw("binding_array")) + .then_ignore(just(TokenKind::Less)) + .then(ty.clone()) + .then(just(TokenKind::Comma).ignore_then(shift.clone()).or_not()) + .then_ignore(just(TokenKind::Greater)) + .map(|((span, ty), len)| { + TypeKind::Array( + Ident { + name: intern.borrow_mut().get(get_text(source, span)), + span, + }, + Box::new(ty), + len, + ) + }), + ident + .then( + ty.separated_by(just(TokenKind::Comma)) + .delimited_by(just(TokenKind::Less), just(TokenKind::Greater)) + .or_not(), + ) + .map(|(ident, generics)| TypeKind::Ident(ident, generics.unwrap_or_default())), + )) + .map_with_span(|kind, span| Type { kind, span }) + }); + + let let_ = |k: &'static str| { + kw(k) + .ignore_then(ident) + .then(just(TokenKind::Colon).ignore_then(ty.clone()).or_not()) + .then(just(TokenKind::Equal).ignore_then(expr.clone())) + .map(|((name, ty), val)| Let { name, ty, val }) + .boxed() + }; + let const_ = let_("const"); + let let_ = let_("let"); + + let var_no_attribs = kw("var") + .ignore_then( + just(TokenKind::Less) + .ignore_then(ident.or_not()) + .then(just(TokenKind::Comma).ignore_then(ident).or_not()) + .then_ignore(just(TokenKind::Greater)) + .or_not(), + ) + .then(ident) + .then(just(TokenKind::Colon).ignore_then(ty.clone()).or_not()) + .then(just(TokenKind::Equal).ignore_then(expr.clone()).or_not()) + .map(|(((access, name), ty), val)| { + let (address_space, access_mode) = match access { + Some((address_space, access_mode)) => (address_space, access_mode), + None => (None, None), + }; + VarNoAttribs { + address_space, + access_mode, + name, + ty, + val, + } + }) + .boxed(); + + let var_decl = choice(( + var_no_attribs.clone().map(VarDecl::Var), + const_.clone().map(VarDecl::Const), + let_.clone().map(VarDecl::Let), + )) + .map(Box::new); + + let lit = choice(( + kw("true").to(Literal::Bool(true)), + kw("false").to(Literal::Bool(false)), + just(TokenKind::IntLit).map_with_span(|_, span| { + parse_int(get_text(source, span), span, &mut diagnostics.borrow_mut()) + }), + just(TokenKind::FloatLit).map_with_span(|_, span| { + parse_float(get_text(source, span), span, &mut diagnostics.borrow_mut()) + }), + )); + + let array = intern.borrow_mut().get_static("array"); + let ident_expr = kw("array") + .then( + just(TokenKind::Less) + .ignore_then(ty.clone()) + .then(just(TokenKind::Comma).ignore_then(shift.clone()).or_not()) + .then_ignore(just(TokenKind::Greater)) + .or_not(), + ) + .map(move |(span, ty)| { + let (generics, array_len) = match ty { + Some((generics, len)) => (vec![generics], len.map(Box::new)), + None => (Vec::new(), None), + }; + IdentExpr { + name: Ident { name: array, span }, + generics, + array_len, + } + }) + .or(ident + .then( + ty.clone() + .separated_by(just(TokenKind::Comma)) + .allow_trailing() + .delimited_by(just(TokenKind::Less), just(TokenKind::Greater)) + .or_not(), + ) + .map(|(name, generics)| IdentExpr { + name, + generics: generics.unwrap_or_default(), + array_len: None, + })); + + let atom = choice(( + just(TokenKind::Underscore).to(ExprKind::Underscore), + lit.map(ExprKind::Literal), + var_decl.map(ExprKind::VarDecl), + ident_expr.map(ExprKind::Ident), + )) + .map_with_span(|kind, span| Expr { kind, span }) + .or(expr + .clone() + .delimited_by(just(TokenKind::LParen), just(TokenKind::RParen))) + .boxed(); + + enum CallIndexAccess { + Call(Vec), + Index(Expr), + Access(Ident), + Postfix(PostfixOp), + } + let postfix = atom + .then( + choice(( + expr.clone() + .separated_by(just(TokenKind::Comma)) + .allow_trailing() + .delimited_by(just(TokenKind::LParen), just(TokenKind::RParen)) + .map_with_span(|args, span| (CallIndexAccess::Call(args), span)), + expr.clone() + .delimited_by(just(TokenKind::LBracket), just(TokenKind::RBracket)) + .map_with_span(|index, span| (CallIndexAccess::Index(index), span)), + just(TokenKind::Period) + .ignore_then(ident) + .map_with_span(|ident, span| (CallIndexAccess::Access(ident), span)), + just(TokenKind::PlusPlus) + .to(PostfixOp::Increment) + .or(just(TokenKind::MinusMinus).to(PostfixOp::Decrement)) + .map_with_span(|op, span| (CallIndexAccess::Postfix(op), span)), + )) + .repeated(), + ) + .foldl(|f, access| { + let span = Span::total_span([f.span, access.1]); + Expr { + kind: match access.0 { + CallIndexAccess::Call(args) => ExprKind::Call(CallExpr { + target: Box::new(f), + args, + }), + CallIndexAccess::Index(index) => { + ExprKind::Index(Box::new(f), Box::new(index)) + } + CallIndexAccess::Access(field) => ExprKind::Member(Box::new(f), field), + CallIndexAccess::Postfix(op) => ExprKind::Postfix(PostfixExpr { + expr: Box::new(f), + op, + }), + }, + span, + } + }) + .boxed(); + + let unary = select! { + TokenKind::And => UnaryOp::Ref, + TokenKind::Star => UnaryOp::Deref, + TokenKind::Bang => UnaryOp::Not, + TokenKind::Minus => UnaryOp::Minus, + TokenKind::Tilde => UnaryOp::Not, + } + .map_with_span(|op, span| (op, span)) + .repeated() + .then(postfix) + .foldr(|op, expr| { + let span = Span::total_span([op.1, expr.span]); + Expr { + kind: ExprKind::Unary(UnaryExpr { + op: op.0, + expr: Box::new(expr), + }), + span, + } + }) + .boxed(); + + fn binary<'a>( + side: impl CParser> + Clone + 'a, + op: impl CParser> + Clone + 'a, + ) -> impl CParser> + Clone + 'a { + side.clone() + .then(op.then(side).repeated()) + .foldl(|lhs, (op, rhs)| { + let span = Span::total_span([lhs.span, rhs.span]); + Expr { + kind: ExprKind::Binary(BinaryExpr { + lhs: Box::new(lhs), + op, + rhs: Box::new(rhs), + }), + span, + } + }) + .boxed() + } + + let product = binary( + unary, + select! { + TokenKind::Star => BinaryOperator::Multiply, + TokenKind::ForwardSlash => BinaryOperator::Divide, + TokenKind::Modulo => BinaryOperator::Modulo, + }, + ); + let sum = binary( + product, + select! { + TokenKind::Plus => BinaryOperator::Add, + TokenKind::Minus => BinaryOperator::Subtract, + }, + ); + shift.define(binary( + sum, + select! { + TokenKind::ShiftLeft => BinaryOperator::ShiftLeft, + } + .or(just(TokenKind::Greater) + .map_with_span(|_, span| span) + .then(just(TokenKind::Greater).map_with_span(|_, span: Span| span)) + .try_map(|(l, r): (Span, Span), span| { + if l.end() == r.start() { + Ok(BinaryOperator::ShiftRight) + } else { + Err(Simple::custom(span, "you should not be seeing this")) + } + })), + )); + + let comparison = binary( + shift, + select! { + TokenKind::Greater => BinaryOperator::Greater, + TokenKind::GreaterEqual => BinaryOperator::GreaterEqual, + TokenKind::Less => BinaryOperator::Less, + TokenKind::LessEqual => BinaryOperator::LessEqual, + }, + ); + let equality = binary( + comparison, + select! { + TokenKind::EqualEqual => BinaryOperator::Equal, + TokenKind::NotEqual => BinaryOperator::NotEqual, + }, + ); + let bitand = binary(equality, just(TokenKind::And).to(BinaryOperator::And)); + let bitxor = binary(bitand, just(TokenKind::Xor).to(BinaryOperator::ExclusiveOr)); + let bitor = binary(bitxor, just(TokenKind::Or).to(BinaryOperator::InclusiveOr)); + let and = binary(bitor, just(TokenKind::AndAnd).to(BinaryOperator::And)); + let or = binary(and, just(TokenKind::OrOr).to(BinaryOperator::InclusiveOr)); + + let assign = select! { + TokenKind::Equal => None, + TokenKind::PlusEqual => Some(BinaryOperator::Add), + TokenKind::MinusEqual => Some(BinaryOperator::Subtract), + TokenKind::TimesEqual => Some(BinaryOperator::Multiply), + TokenKind::DivideEqual => Some(BinaryOperator::Divide), + TokenKind::ModuloEqual => Some(BinaryOperator::Modulo), + TokenKind::ShiftLeftEqual => Some(BinaryOperator::ShiftLeft), + TokenKind::ShiftRightEqual => Some(BinaryOperator::ShiftRight), + TokenKind::AndEqual => Some(BinaryOperator::And), + TokenKind::XorEqual => Some(BinaryOperator::ExclusiveOr), + TokenKind::OrEqual => Some(BinaryOperator::InclusiveOr), + }; + let assign = or + .clone() + .then(assign.then(or).repeated()) + .foldl(|lhs, (op, rhs)| { + let span = Span::total_span([lhs.span, rhs.span]); + Expr { + kind: ExprKind::Assign(AssignExpr { + lhs: Box::new(lhs), + op, + rhs: Box::new(rhs), + }), + span, + } + }) + .boxed(); + + expr.define(assign); + + let attrib = just(TokenKind::Attr) + .ignore_then(ident) + .then( + expr.clone() + .separated_by(just(TokenKind::Comma)) + .allow_trailing() + .delimited_by(just(TokenKind::LParen), just(TokenKind::RParen)) + .or_not(), + ) + .map_with_span(|(name, exprs), span| Attribute { + name, + exprs: exprs.unwrap_or_default(), + span, + }) + .boxed(); + let attribs = attrib.repeated(); + + let arg = attribs + .clone() + .then(ident) + .then(just(TokenKind::Colon).ignore_then(ty.clone())) + .map_with_span(|((attribs, name), ty), span| Arg { + attribs, + name, + ty, + span, + }) + .boxed(); + + let fn_ = attribs + .clone() + .then_ignore(kw("fn")) + .then(ident) + .then( + arg.clone() + .separated_by(just(TokenKind::Comma)) + .allow_trailing() + .delimited_by(just(TokenKind::LParen), just(TokenKind::RParen)), + ) + .then( + just(TokenKind::Arrow) + .ignore_then(attribs.clone()) + .then(ty.clone()) + .or_not(), + ) + .then(block.clone()) + .map(|((((attribs, name), args), ret), block)| { + let (ret_attribs, ret) = match ret { + Some((ret_attribs, ret)) => (ret_attribs, Some(ret)), + None => (Vec::new(), None), + }; + + Fn { + attribs, + name, + args, + ret_attribs, + ret, + block, + } + }) + .boxed(); + + let over = attribs + .clone() + .then_ignore(kw("override")) + .then(ident) + .then(just(TokenKind::Colon).ignore_then(ty.clone()).or_not()) + .then(just(TokenKind::Equal).ignore_then(expr.clone()).or_not()) + .then_ignore(just(TokenKind::Semicolon)) + .map(|(((attribs, name), ty), val)| Override { + attribs, + name, + ty, + val, + }) + .boxed(); + + let var = attribs + .then(var_no_attribs.clone()) + .map(|(attribs, inner)| Var { attribs, inner }) + .then_ignore(just(TokenKind::Semicolon)) + .boxed(); + + let struct_ = kw("struct") + .ignore_then(ident) + .then( + arg.separated_by(just(TokenKind::Comma)) + .allow_trailing() + .delimited_by(just(TokenKind::LBrace), just(TokenKind::RBrace)), + ) + .map(|(name, fields)| Struct { name, fields }) + .boxed(); + + let type_ = kw("type") + .ignore_then(ident) + .then(just(TokenKind::Equal).ignore_then(ty.clone())) + .then_ignore(just(TokenKind::Semicolon)) + .map(|(name, ty)| TypeDecl { name, ty }) + .boxed(); + + let global_decl = choice(( + fn_.map(GlobalDeclKind::Fn), + over.map(GlobalDeclKind::Override), + var.map(GlobalDeclKind::Var), + const_ + .map(GlobalDeclKind::Const) + .then_ignore(just(TokenKind::Semicolon)), + let_.map(GlobalDeclKind::Let) + .then_ignore(just(TokenKind::Semicolon)), + static_assert + .map(GlobalDeclKind::StaticAssert) + .then_ignore(just(TokenKind::Semicolon)), + struct_.map(GlobalDeclKind::Struct), + type_.map(GlobalDeclKind::Type), + )) + .map_with_span(|kind, span| GlobalDecl { kind, span }) + .boxed(); + + let enable = kw("enable") + .ignore_then(ident) + .then_ignore(just(TokenKind::Semicolon)) + .map_with_span(|name, span| Enable { name, span }) + .boxed(); + + let tu = enable + .repeated() + .then(global_decl.repeated()) + .then_ignore(end()) + .map(|(enables, decls)| TranslationUnit { enables, decls }); + + let mut lexer = self.lexer; + tu.parse_recovery(Stream::from_iter( + lexer.eof_span(), + std::iter::from_fn(|| lexer.next().map(|Token { kind, span }| (kind, span))), + )) + } +} + +fn parse_int(text: &str, span: Span, diagnostics: &mut Vec) -> Literal { + let signedness = text.bytes().last().unwrap(); + let ty = if text.len() > 2 { &text[..2] } else { "" }; + let value = if signedness == b'i' || signedness == b'u' { + &text[..text.len() - 1] + } else { + text + }; + + let value = if ty == "0x" { + let value = &value[2..]; + i64::from_str_radix(value, 16) + } else { + i64::from_str(value) + }; + + match value { + Ok(value) => { + if signedness == b'i' { + let i32: Result = value.try_into(); + match i32 { + Ok(value) => Literal::I32(value), + Err(_) => { + diagnostics.push( + WgslError::new("integer literal is too large for i32").marker(span), + ); + Literal::I32(0) + } + } + } else if signedness == b'u' { + let u32: Result = value.try_into(); + match u32 { + Ok(value) => Literal::U32(value), + Err(_) => { + diagnostics.push( + WgslError::new("integer literal is too large for u32").marker(span), + ); + Literal::U32(0) + } + } + } else { + Literal::AbstractInt(value) + } + } + Err(_) => { + diagnostics.push(WgslError::new("integer literal is too large").marker(span)); + Literal::AbstractInt(0) + } + } +} + +fn parse_float(text: &str, span: Span, diagnostics: &mut Vec) -> Literal { + let width = text.bytes().last().unwrap(); + let ty = if text.len() > 2 { &text[..2] } else { "" }; + let value = if width == b'f' || width == b'h' { + &text[..text.len() - 1] + } else { + text + }; + + let (value, ty) = if ty == "0x" { + let value = &value[2..]; + if width == b'f' { + ( + hexf_parse::parse_hexf32(value, false) + .ok() + .map(Literal::F32), + "f32", + ) + } else if width == b'h' { + diagnostics.push( + WgslError::new("hexadecimal `f16` literals are not supported yet").marker(span), + ); + return Literal::F16(f16::from_f64(0.0)); + } else { + ( + hexf_parse::parse_hexf64(value, false) + .ok() + .map(Literal::AbstractFloat), + "f64", + ) + } + } else if width == b'f' { + let num = f32::from_str(value).unwrap(); + (num.is_finite().then(|| Literal::F32(num)), "f32") + } else if width == b'h' { + let num = f16::from_f32(f32::from_str(value).unwrap()); + (num.is_finite().then(|| Literal::F16(num)), "f16") + } else { + let num = f64::from_str(value).unwrap(); + (num.is_finite().then(|| Literal::AbstractFloat(num)), "f64") + }; + + value.unwrap_or_else(|| { + diagnostics.push( + WgslError::new(format!("float literal is not representable by `{}`", ty)).marker(span), + ); + Literal::AbstractFloat(0.0) + }) +} + +fn error_to_diagnostic(error: Simple) -> WgslError { + let span = error.span(); + + match *error.reason() { + SimpleReason::Unexpected => { + let expected = error.expected(); + match error.found() { + Some(tok) => WgslError::new(format!("unexpected `{}`", tok)).label(span, { + let mut s = "expected one of ".to_string(); + comma_sep(&mut s, expected); + s + }), + None => WgslError::new("unexpected end of file").label(span, { + let mut s = "expected one of ".to_string(); + comma_sep(&mut s, expected); + s + }), + } + } + SimpleReason::Unclosed { span, delimiter } => { + WgslError::new(format!("unclosed `{}`", delimiter)).marker(span) + } + SimpleReason::Custom(ref message) => WgslError::new(message).marker(span), + } +} + +fn comma_sep<'a>(to: &mut String, toks: impl ExactSizeIterator>) { + let mut toks = toks.filter_map(|x| x.as_ref().copied()); + if let Some(tok) = toks.next() { + write!(to, "`{}`", tok).unwrap(); + for tok in toks { + write!(to, ", `{}`", tok).unwrap(); + } + } +} diff --git a/src/front/wgsl/resolve/dependency.rs b/src/front/wgsl/resolve/dependency.rs new file mode 100644 index 0000000000..53acd1a8ae --- /dev/null +++ b/src/front/wgsl/resolve/dependency.rs @@ -0,0 +1,138 @@ +use crate::front::wgsl::resolve::ir::{Decl, DeclDependency, DeclId, DeclKind, TranslationUnit}; +use crate::front::wgsl::WgslError; +use crate::Span; + +pub struct DependencyContext { + visited: Vec, + temp_visited: Vec, + path: Vec, + out: Vec, +} + +impl DependencyContext { + pub const fn new() -> Self { + Self { + visited: Vec::new(), + temp_visited: Vec::new(), + path: Vec::new(), + out: Vec::new(), + } + } + + pub fn resolve(&mut self, module: &mut TranslationUnit, diagnostics: &mut Vec) { + self.reset_for(module); + let solver = DependencySolver { + module, + diagnostics, + ctx: self, + }; + solver.solve(); + module.dependency_order = std::mem::take(&mut self.out); + } + + pub fn reset_for(&mut self, module: &TranslationUnit) { + self.visited.clear(); + self.visited.resize(module.decls.len(), false); + self.temp_visited.clear(); + self.temp_visited.resize(module.decls.len(), false); + self.path.clear(); + self.path.reserve(module.decls.len()); + self.out.reserve(module.decls.len()); + } +} + +struct DependencySolver<'a> { + module: &'a TranslationUnit, + diagnostics: &'a mut Vec, + ctx: &'a mut DependencyContext, +} + +impl<'a> DependencySolver<'a> { + fn solve(mut self) { + for id in 0..self.module.decls.len() { + if self.ctx.visited[id] { + continue; + } + self.dfs(id); + } + } + + fn dfs(&mut self, id: usize) { + let decl = &self.module.decls[id]; + if self.ctx.visited[id] { + return; + } + + self.ctx.temp_visited[id] = true; + for dep in decl.dependencies.iter() { + let dep_id = dep.id.0 as usize; + self.ctx.path.push(*dep); + + if self.ctx.temp_visited[dep_id] { + // found a cycle. + if dep_id == id { + self.diagnostics.push( + WgslError::new("recursive declarations are not allowed") + .marker(decl_ident_span(decl)) + .label(dep.usage, "uses itself here"), + ) + } else { + let mut error = WgslError::new("cyclic declarations are not allowed").label( + decl_ident_span(&self.module.decls[dep_id]), + "this declaration", + ); + + let start_at = self + .ctx + .path + .iter() + .rev() + .enumerate() + .find(|&(_, dep)| dep.id.0 as usize == dep_id) + .map(|x| x.0) + .unwrap_or(0); + + let last = self.ctx.path.len() - start_at - 1; + for (i, curr_dep) in self.ctx.path[start_at..].iter().enumerate() { + let curr_id = curr_dep.id.0 as usize; + let curr_decl = &self.module.decls[curr_id]; + + error.labels.push(( + curr_dep.usage, + if i == last { + "ending the cycle".to_string() + } else { + "uses".to_string() + }, + )); + error + .labels + .push((decl_ident_span(curr_decl), "".to_string())); + } + + self.diagnostics.push(error); + } + } else if !self.ctx.visited[dep_id] { + self.dfs(dep_id); + } + + self.ctx.path.pop(); + } + + self.ctx.temp_visited[id] = false; + self.ctx.visited[id] = true; + self.ctx.out.push(DeclId(id as _)); + } +} + +fn decl_ident_span(decl: &Decl) -> Span { + match decl.kind { + DeclKind::Fn(ref f) => f.name.span, + DeclKind::Struct(ref s) => s.name.span, + DeclKind::Type(ref t) => t.name.span, + DeclKind::Const(ref c) => c.name.span, + DeclKind::Override(ref o) => o.name.span, + DeclKind::Var(ref v) => v.inner.name.span, + DeclKind::StaticAssert(_) => unreachable!(), + } +} diff --git a/src/front/wgsl/resolve/features.rs b/src/front/wgsl/resolve/features.rs new file mode 100644 index 0000000000..658a735b47 --- /dev/null +++ b/src/front/wgsl/resolve/features.rs @@ -0,0 +1,88 @@ +use std::fmt::{Debug, Display}; + +use rustc_hash::FxHashSet; +use strum::EnumIter; + +use crate::front::wgsl::parse::ast::Enable; +use crate::front::wgsl::{ + resolve::inbuilt::{Matcher, ToStaticString}, + text::Interner, + WgslError, +}; +use crate::Span; + +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, EnumIter)] +pub enum Feature { + Float16, + Float64, + PrimitiveIndex, + BindingArray, + PushConstant, + StorageImageRead, + Multiview, + ConservativeDepth, +} + +impl ToStaticString for Feature { + fn to_static_str(&self) -> &'static str { + match *self { + Feature::Float16 => "f16", + Feature::Float64 => "f64", + Feature::PrimitiveIndex => "primitive_index", + Feature::BindingArray => "binding_array", + Feature::PushConstant => "push_constant", + Feature::StorageImageRead => "storage_image_read", + Feature::Multiview => "multiview", + Feature::ConservativeDepth => "conservative_depth", + } + } +} + +impl Display for Feature { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +#[derive(Clone)] +pub struct EnabledFeatures { + features: FxHashSet, + matcher: Matcher, +} + +impl Debug for EnabledFeatures { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_set().entries(self.features.iter()).finish() + } +} + +impl EnabledFeatures { + pub fn new(intern: &mut Interner) -> Self { + Self { + features: FxHashSet::default(), + matcher: Matcher::new(intern), + } + } + + pub fn enable(&mut self, enable: Enable, intern: &Interner, diagnostics: &mut Vec) { + if let Some(feature) = self.matcher.get(enable.name.name) { + self.features.insert(feature); + } else { + diagnostics.push( + WgslError::new(format!( + "unknown feature `{}`", + intern.resolve(enable.name.name) + )) + .marker(enable.name.span), + ); + } + } + + pub fn require(&mut self, _: Feature, _: Span, _: &mut Vec) { + // if !self.features.contains(&feature) { + // diagnostics + // .push(WgslError::new(format!("feature `{}` is not enabled", feature)).marker(span)); + // self.features.insert(feature); // Only error once. + // } + } +} diff --git a/src/front/wgsl/resolve/inbuilt.rs b/src/front/wgsl/resolve/inbuilt.rs new file mode 100644 index 0000000000..f06bb03e32 --- /dev/null +++ b/src/front/wgsl/resolve/inbuilt.rs @@ -0,0 +1,693 @@ +use std::fmt::Display; + +use aho_corasick::{AhoCorasick, AhoCorasickBuilder, MatchKind}; +use rustc_hash::FxHashMap; +use strum::{EnumIter, IntoEnumIterator}; + +use crate::front::wgsl::parse::ast::Expr; +use crate::{ + front::wgsl::text::{Interner, Text}, + BuiltIn, Bytes, ImageDimension, Interpolation, Sampling, ScalarKind, Span, StorageFormat, + VectorSize, +}; + +pub trait ToStaticString { + fn to_static_str(&self) -> &'static str; +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum AccessMode { + Read, + Write, + ReadWrite, +} + +impl ToStaticString for AccessMode { + fn to_static_str(&self) -> &'static str { + match *self { + AccessMode::Read => "read", + AccessMode::Write => "write", + AccessMode::ReadWrite => "read_write", + } + } +} + +impl Display for AccessMode { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for crate::StorageAccess { + fn from(access: AccessMode) -> Self { + match access { + AccessMode::Read => Self::LOAD, + AccessMode::Write => Self::STORE, + AccessMode::ReadWrite => Self::LOAD | Self::STORE, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum AddressSpace { + Function, + Private, + Storage, + Uniform, + Workgroup, + Handle, + PushConstant, +} + +impl ToStaticString for AddressSpace { + fn to_static_str(&self) -> &'static str { + match *self { + AddressSpace::Function => "function", + AddressSpace::Private => "private", + AddressSpace::Storage => "storage", + AddressSpace::Uniform => "uniform", + AddressSpace::Workgroup => "workgroup", + AddressSpace::Handle => "handle", + AddressSpace::PushConstant => "push_constant", + } + } +} + +impl Display for AddressSpace { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for crate::AddressSpace { + fn from(space: AddressSpace) -> Self { + match space { + AddressSpace::Function => Self::Function, + AddressSpace::Private => Self::Private, + AddressSpace::Storage => Self::Storage { + access: crate::StorageAccess::LOAD, + }, + AddressSpace::Uniform => Self::Uniform, + AddressSpace::Workgroup => Self::WorkGroup, + AddressSpace::Handle => Self::Handle, + AddressSpace::PushConstant => Self::PushConstant, + } + } +} + +#[derive(Clone, Debug)] +pub struct Attribute { + pub ty: AttributeType, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum AttributeType { + Align(Expr), + Binding(Expr), + Builtin(Builtin), + Compute, + Const, + Fragment, + Group(Expr), + Id(Expr), + Interpolate(InterpolationType, Option), + Invariant, + Location(Expr), + Size(Expr), + Vertex, + WorkgroupSize(Expr, Option, Option), + ConservativeDepth(Option), +} + +impl Display for AttributeType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + AttributeType::Align(_) => write!(f, "align"), + AttributeType::Binding(_) => write!(f, "binding"), + AttributeType::Builtin(_) => write!(f, "builtin"), + AttributeType::Compute => write!(f, "compute"), + AttributeType::Const => write!(f, "const"), + AttributeType::Fragment => write!(f, "fragment"), + AttributeType::Group(_) => write!(f, "group"), + AttributeType::Id(_) => write!(f, "id"), + AttributeType::Interpolate(..) => write!(f, "interpolate"), + AttributeType::Invariant => write!(f, "invariant"), + AttributeType::Location(_) => write!(f, "location"), + AttributeType::Size(_) => write!(f, "size"), + AttributeType::Vertex => write!(f, "vertex"), + AttributeType::WorkgroupSize(..) => write!(f, "workgroup_size"), + AttributeType::ConservativeDepth(_) => write!(f, "early_depth_test"), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum Builtin { + FragDepth, + FrontFacing, + GlobalInvocationId, + InstanceIndex, + LocalInvocationId, + LocalInvocationIndex, + NumWorkgroups, + Position, + SampleIndex, + SampleMask, + VertexIndex, + WorkgroupId, + PrimitiveIndex, + ViewIndex, +} + +impl ToStaticString for Builtin { + fn to_static_str(&self) -> &'static str { + match *self { + Builtin::FragDepth => "frag_depth", + Builtin::FrontFacing => "front_facing", + Builtin::GlobalInvocationId => "global_invocation_id", + Builtin::InstanceIndex => "instance_index", + Builtin::LocalInvocationId => "local_invocation_id", + Builtin::LocalInvocationIndex => "local_invocation_index", + Builtin::NumWorkgroups => "num_workgroups", + Builtin::Position => "position", + Builtin::SampleIndex => "sample_index", + Builtin::SampleMask => "sample_mask", + Builtin::VertexIndex => "vertex_index", + Builtin::WorkgroupId => "workgroup_id", + Builtin::PrimitiveIndex => "primitive_index", + Builtin::ViewIndex => "view_index", + } + } +} + +impl Display for Builtin { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for BuiltIn { + fn from(bt: Builtin) -> Self { + match bt { + Builtin::FragDepth => Self::FragDepth, + Builtin::FrontFacing => Self::FrontFacing, + Builtin::GlobalInvocationId => Self::GlobalInvocationId, + Builtin::InstanceIndex => Self::InstanceIndex, + Builtin::LocalInvocationId => Self::LocalInvocationId, + Builtin::LocalInvocationIndex => Self::LocalInvocationIndex, + Builtin::NumWorkgroups => Self::NumWorkGroups, + Builtin::Position => Self::Position { invariant: false }, + Builtin::SampleIndex => Self::SampleIndex, + Builtin::SampleMask => Self::SampleMask, + Builtin::VertexIndex => Self::VertexIndex, + Builtin::WorkgroupId => Self::WorkGroupId, + Builtin::PrimitiveIndex => Self::PrimitiveIndex, + Builtin::ViewIndex => Self::ViewIndex, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum InterpolationSample { + Center, + Centroid, + Sample, +} + +impl ToStaticString for InterpolationSample { + fn to_static_str(&self) -> &'static str { + match *self { + InterpolationSample::Center => "center", + InterpolationSample::Centroid => "centroid", + InterpolationSample::Sample => "sample", + } + } +} + +impl Display for InterpolationSample { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for Sampling { + fn from(sample: InterpolationSample) -> Self { + match sample { + InterpolationSample::Center => Self::Center, + InterpolationSample::Centroid => Self::Centroid, + InterpolationSample::Sample => Self::Sample, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum InterpolationType { + Flat, + Linear, + Perspective, +} + +impl ToStaticString for InterpolationType { + fn to_static_str(&self) -> &'static str { + match *self { + InterpolationType::Flat => "flat", + InterpolationType::Linear => "linear", + InterpolationType::Perspective => "perspective", + } + } +} + +impl Display for InterpolationType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for Interpolation { + fn from(it: InterpolationType) -> Self { + match it { + InterpolationType::Flat => Self::Flat, + InterpolationType::Linear => Self::Linear, + InterpolationType::Perspective => Self::Perspective, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum ScalarType { + I32, + U32, + F64, + F32, + F16, + Bool, +} + +impl ToStaticString for ScalarType { + fn to_static_str(&self) -> &'static str { + match *self { + ScalarType::I32 => "i32", + ScalarType::U32 => "u32", + ScalarType::F64 => "f64", + ScalarType::F32 => "f32", + ScalarType::F16 => "f16", + ScalarType::Bool => "bool", + } + } +} + +impl Display for ScalarType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for (ScalarKind, Bytes) { + fn from(ty: ScalarType) -> (ScalarKind, Bytes) { + match ty { + ScalarType::I32 => (ScalarKind::Sint, 4), + ScalarType::U32 => (ScalarKind::Uint, 4), + ScalarType::F64 => (ScalarKind::Float, 8), + ScalarType::F32 => (ScalarKind::Float, 4), + ScalarType::F16 => (ScalarKind::Float, 2), + ScalarType::Bool => (ScalarKind::Bool, 1), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum VecType { + Vec2, + Vec3, + Vec4, +} + +impl ToStaticString for VecType { + fn to_static_str(&self) -> &'static str { + match *self { + VecType::Vec2 => "vec2", + VecType::Vec3 => "vec3", + VecType::Vec4 => "vec4", + } + } +} + +impl Display for VecType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for VectorSize { + fn from(ty: VecType) -> Self { + match ty { + VecType::Vec2 => Self::Bi, + VecType::Vec3 => Self::Tri, + VecType::Vec4 => Self::Quad, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum MatType { + Mat2x2, + Mat2x3, + Mat2x4, + Mat3x2, + Mat3x3, + Mat3x4, + Mat4x2, + Mat4x3, + Mat4x4, +} + +impl ToStaticString for MatType { + fn to_static_str(&self) -> &'static str { + match *self { + MatType::Mat2x2 => "mat2x2", + MatType::Mat2x3 => "mat2x3", + MatType::Mat2x4 => "mat2x4", + MatType::Mat3x2 => "mat3x2", + MatType::Mat3x3 => "mat3x3", + MatType::Mat3x4 => "mat3x4", + MatType::Mat4x2 => "mat4x2", + MatType::Mat4x3 => "mat4x3", + MatType::Mat4x4 => "mat4x4", + } + } +} + +impl Display for MatType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for (VectorSize, VectorSize) { + fn from(ty: MatType) -> (VectorSize, VectorSize) { + match ty { + MatType::Mat2x2 => (VectorSize::Bi, VectorSize::Bi), + MatType::Mat2x3 => (VectorSize::Bi, VectorSize::Tri), + MatType::Mat2x4 => (VectorSize::Bi, VectorSize::Quad), + MatType::Mat3x2 => (VectorSize::Tri, VectorSize::Bi), + MatType::Mat3x3 => (VectorSize::Tri, VectorSize::Tri), + MatType::Mat3x4 => (VectorSize::Tri, VectorSize::Quad), + MatType::Mat4x2 => (VectorSize::Quad, VectorSize::Bi), + MatType::Mat4x3 => (VectorSize::Quad, VectorSize::Tri), + MatType::Mat4x4 => (VectorSize::Quad, VectorSize::Quad), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum SampledTextureType { + Texture1d, + Texture1dArray, + Texture2d, + TextureMultisampled2d, + Texture2dArray, + TextureMultisampled2dArray, + Texture3d, + TextureCube, + TextureCubeArray, +} + +impl ToStaticString for SampledTextureType { + fn to_static_str(&self) -> &'static str { + match *self { + SampledTextureType::Texture1d => "texture_1d", + SampledTextureType::Texture1dArray => "texture_1d_array", + SampledTextureType::Texture2d => "texture_2d", + SampledTextureType::TextureMultisampled2d => "texture_multisampled_2d", + SampledTextureType::Texture2dArray => "texture_2d_array", + SampledTextureType::TextureMultisampled2dArray => "texture_multisampled_2d_array", + SampledTextureType::Texture3d => "texture_3d", + SampledTextureType::TextureCube => "texture_cube", + SampledTextureType::TextureCubeArray => "texture_cube_array", + } + } +} + +impl Display for SampledTextureType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for (ImageDimension, bool, bool) { + fn from(ty: SampledTextureType) -> (ImageDimension, bool, bool) { + match ty { + SampledTextureType::Texture1d => (ImageDimension::D1, false, false), + SampledTextureType::Texture1dArray => (ImageDimension::D1, true, false), + SampledTextureType::Texture2d => (ImageDimension::D2, false, false), + SampledTextureType::TextureMultisampled2d => (ImageDimension::D2, false, true), + SampledTextureType::Texture2dArray => (ImageDimension::D2, true, false), + SampledTextureType::TextureMultisampled2dArray => (ImageDimension::D2, true, true), + SampledTextureType::Texture3d => (ImageDimension::D3, false, false), + SampledTextureType::TextureCube => (ImageDimension::Cube, false, false), + SampledTextureType::TextureCubeArray => (ImageDimension::Cube, true, false), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum DepthTextureType { + Depth2d, + Depth2dArray, + DepthCube, + DepthCubeArray, + DepthMultisampled2d, +} + +impl ToStaticString for DepthTextureType { + fn to_static_str(&self) -> &'static str { + match *self { + DepthTextureType::Depth2d => "texture_depth_2d", + DepthTextureType::Depth2dArray => "texture_depth_2d_array", + DepthTextureType::DepthCube => "texture_depth_cube", + DepthTextureType::DepthCubeArray => "texture_depth_cube_array", + DepthTextureType::DepthMultisampled2d => "texture_depth_multisampled_2d", + } + } +} + +impl Display for DepthTextureType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for (ImageDimension, bool, bool) { + fn from(ty: DepthTextureType) -> (ImageDimension, bool, bool) { + match ty { + DepthTextureType::Depth2d => (ImageDimension::D2, false, false), + DepthTextureType::Depth2dArray => (ImageDimension::D2, true, false), + DepthTextureType::DepthCube => (ImageDimension::Cube, false, false), + DepthTextureType::DepthCubeArray => (ImageDimension::Cube, true, false), + DepthTextureType::DepthMultisampled2d => (ImageDimension::D2, false, true), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum SamplerType { + Sampler, + SamplerComparison, +} + +impl ToStaticString for SamplerType { + fn to_static_str(&self) -> &'static str { + match *self { + SamplerType::Sampler => "sampler", + SamplerType::SamplerComparison => "sampler_comparison", + } + } +} + +impl Display for SamplerType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for bool { + fn from(ty: SamplerType) -> bool { + match ty { + SamplerType::Sampler => false, + SamplerType::SamplerComparison => true, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum StorageTextureType { + Storage1d, + Storage1dArray, + Storage2d, + Storage2dArray, + Storage3d, +} + +impl ToStaticString for StorageTextureType { + fn to_static_str(&self) -> &'static str { + match *self { + StorageTextureType::Storage1d => "texture_storage_1d", + StorageTextureType::Storage1dArray => "texture_storage_1d_array", + StorageTextureType::Storage2d => "texture_storage_2d", + StorageTextureType::Storage2dArray => "texture_storage_2d_array", + StorageTextureType::Storage3d => "texture_storage_3d", + } + } +} + +impl Display for StorageTextureType { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for (ImageDimension, bool) { + fn from(ty: StorageTextureType) -> (ImageDimension, bool) { + match ty { + StorageTextureType::Storage1d => (ImageDimension::D1, false), + StorageTextureType::Storage1dArray => (ImageDimension::D1, true), + StorageTextureType::Storage2d => (ImageDimension::D2, false), + StorageTextureType::Storage2dArray => (ImageDimension::D2, true), + StorageTextureType::Storage3d => (ImageDimension::D3, false), + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum TexelFormat { + R32Float, + R32Sint, + R32Uint, + Rg32Float, + Rg32Sint, + Rg32Uint, + Rgba16Float, + Rgba16Sint, + Rgba16Uint, + Rgba32Float, + Rgba32Sint, + Rgba32Uint, + Rgba8Sint, + Rgba8Uint, + Rgba8Unorm, + Rgba8Snorm, +} + +impl ToStaticString for TexelFormat { + fn to_static_str(&self) -> &'static str { + match *self { + TexelFormat::R32Float => "r32float", + TexelFormat::R32Sint => "r32sint", + TexelFormat::R32Uint => "r32uint", + TexelFormat::Rg32Float => "rg32float", + TexelFormat::Rg32Sint => "rg32sint", + TexelFormat::Rg32Uint => "rg32uint", + TexelFormat::Rgba16Float => "rgba16float", + TexelFormat::Rgba16Sint => "rgba16sint", + TexelFormat::Rgba16Uint => "rgba16uint", + TexelFormat::Rgba32Float => "rgba32float", + TexelFormat::Rgba32Sint => "rgba32sint", + TexelFormat::Rgba32Uint => "rgba32uint", + TexelFormat::Rgba8Sint => "rgba8sint", + TexelFormat::Rgba8Uint => "rgba8uint", + TexelFormat::Rgba8Unorm => "rgba8unorm", + TexelFormat::Rgba8Snorm => "rgba8snorm", + } + } +} + +impl Display for TexelFormat { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for StorageFormat { + fn from(fmt: TexelFormat) -> Self { + match fmt { + TexelFormat::R32Float => Self::R32Float, + TexelFormat::R32Sint => Self::R32Sint, + TexelFormat::R32Uint => Self::R32Uint, + TexelFormat::Rg32Float => Self::Rg32Float, + TexelFormat::Rg32Sint => Self::Rg32Sint, + TexelFormat::Rg32Uint => Self::Rg32Uint, + TexelFormat::Rgba16Float => Self::Rgba16Float, + TexelFormat::Rgba16Sint => Self::Rgba16Sint, + TexelFormat::Rgba16Uint => Self::Rgba16Uint, + TexelFormat::Rgba32Float => Self::Rgba32Float, + TexelFormat::Rgba32Sint => Self::Rgba32Sint, + TexelFormat::Rgba32Uint => Self::Rgba32Uint, + TexelFormat::Rgba8Sint => Self::Rgba8Sint, + TexelFormat::Rgba8Uint => Self::Rgba8Uint, + TexelFormat::Rgba8Unorm => Self::Rgba8Unorm, + TexelFormat::Rgba8Snorm => Self::Rgba8Snorm, + } + } +} + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum ConservativeDepth { + GreaterEqual, + LessEqual, + Unchanged, +} + +impl ToStaticString for ConservativeDepth { + fn to_static_str(&self) -> &'static str { + match *self { + ConservativeDepth::GreaterEqual => "greater_equal", + ConservativeDepth::LessEqual => "less_equal", + ConservativeDepth::Unchanged => "unchanged", + } + } +} + +impl Display for ConservativeDepth { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl From for crate::ConservativeDepth { + fn from(depth: ConservativeDepth) -> Self { + match depth { + ConservativeDepth::GreaterEqual => Self::GreaterEqual, + ConservativeDepth::LessEqual => Self::LessEqual, + ConservativeDepth::Unchanged => Self::Unchanged, + } + } +} + +#[derive(Clone)] +pub struct Matcher { + map: FxHashMap, +} + +impl Matcher { + pub fn new(intern: &mut Interner) -> Self { + let mut map = FxHashMap::default(); + + for variant in T::iter() { + map.insert(intern.get_static(variant.to_static_str()), variant); + } + + Self { map } + } + + pub fn get(&self, text: Text) -> Option { + self.map.get(&text).copied() + } +} + +pub fn reserved_matcher() -> AhoCorasick { + AhoCorasickBuilder::new() + .anchored(true) + .match_kind(MatchKind::LeftmostLongest) + .build(crate::keywords::wgsl::RESERVED) +} diff --git a/src/front/wgsl/resolve/inbuilt_functions.rs b/src/front/wgsl/resolve/inbuilt_functions.rs new file mode 100644 index 0000000000..7a41b7dd6e --- /dev/null +++ b/src/front/wgsl/resolve/inbuilt_functions.rs @@ -0,0 +1,246 @@ +use std::fmt::Display; + +use strum::EnumIter; + +use crate::front::wgsl::resolve::inbuilt::ToStaticString; + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, EnumIter)] +pub enum InbuiltFunction { + Bitcast, + All, + Any, + Select, + ArrayLength, + Abs, + Acos, + Acosh, + Asin, + Asinh, + Atan, + Atanh, + Atan2, + Ceil, + Clamp, + Cos, + Cosh, + CountLeadingZeros, + CountOneBits, + CountTrailingZeros, + Cross, + Degrees, + Determinant, + Distance, + Dot, + Exp, + Exp2, + ExtractBits, + FaceForward, + FirstLeadingBit, + FirstTrailingBit, + Floor, + Fma, + Fract, + Frexp, + InsertBits, + InverseSqrt, + Ldexp, + Length, + Log, + Log2, + Max, + Min, + Mix, + Modf, + Normalize, + Pow, + QuantizeToF16, + Radians, + Reflect, + Refract, + ReverseBits, + Round, + Saturate, + Sign, + Sin, + Sinh, + Smoothstep, + Sqrt, + Step, + Tan, + Tanh, + Transpose, + Trunc, + Dpdx, + DpdxCoarse, + DpdxFine, + Dpdy, + DpdyCoarse, + DpdyFine, + Fwidth, + FwidthCoarse, + FwidthFine, + TextureDimensions, + TextureGather, + TextureGatherCompare, + TextureLoad, + TextureNumLayers, + TextureNumLevels, + TextureNumSamples, + TextureSample, + TextureSampleBias, + TextureSampleCompare, + TextureSampleCompareLevel, + TextureSampleGrad, + TextureSampleLevel, + TextureSampleBaseClampToEdge, + TextureStore, + AtomicLoad, + AtomicStore, + AtomicAdd, + AtomicSub, + AtomicMax, + AtomicMin, + AtomicAnd, + AtomicOr, + AtomicXor, + AtomicExchange, + AtomicCompareExchangeWeak, + Pack4x8Snorm, + Pack4x8Unorm, + Pack2x16Snorm, + Pack2x16Unorm, + Pack2x16Float, + Unpack4x8Snorm, + Unpack4x8Unorm, + Unpack2x16Snorm, + Unpack2x16Unorm, + Unpack2x16Float, + StorageBarrier, + WorkgroupBarrier, + OuterProduct, +} + +impl Display for InbuiltFunction { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.to_static_str()) + } +} + +impl ToStaticString for InbuiltFunction { + fn to_static_str(&self) -> &'static str { + match *self { + InbuiltFunction::Abs => "abs", + InbuiltFunction::Acos => "acos", + InbuiltFunction::All => "all", + InbuiltFunction::Any => "any", + InbuiltFunction::Asin => "asin", + InbuiltFunction::Atan => "atan", + InbuiltFunction::Atan2 => "atan2", + InbuiltFunction::Ceil => "ceil", + InbuiltFunction::Clamp => "clamp", + InbuiltFunction::Cos => "cos", + InbuiltFunction::Cosh => "cosh", + InbuiltFunction::Cross => "cross", + InbuiltFunction::Determinant => "determinant", + InbuiltFunction::Distance => "distance", + InbuiltFunction::Dot => "dot", + InbuiltFunction::Exp => "exp", + InbuiltFunction::Exp2 => "exp2", + InbuiltFunction::FaceForward => "faceForward", + InbuiltFunction::Floor => "floor", + InbuiltFunction::Fma => "fma", + InbuiltFunction::Fract => "fract", + InbuiltFunction::Frexp => "frexp", + InbuiltFunction::InverseSqrt => "inverseSqrt", + InbuiltFunction::Length => "length", + InbuiltFunction::Log => "log", + InbuiltFunction::Log2 => "log2", + InbuiltFunction::Max => "max", + InbuiltFunction::Min => "min", + InbuiltFunction::Mix => "mix", + InbuiltFunction::Modf => "modf", + InbuiltFunction::Normalize => "normalize", + InbuiltFunction::Pow => "pow", + InbuiltFunction::QuantizeToF16 => "quantizeToF16", + InbuiltFunction::Radians => "radians", + InbuiltFunction::Reflect => "reflect", + InbuiltFunction::Refract => "refract", + InbuiltFunction::ReverseBits => "reverseBits", + InbuiltFunction::Round => "round", + InbuiltFunction::Saturate => "saturate", + InbuiltFunction::Sign => "sign", + InbuiltFunction::Sin => "sin", + InbuiltFunction::Sinh => "sinh", + InbuiltFunction::Smoothstep => "smoothstep", + InbuiltFunction::Sqrt => "sqrt", + InbuiltFunction::Step => "step", + InbuiltFunction::Tan => "tan", + InbuiltFunction::Tanh => "tanh", + InbuiltFunction::Trunc => "trunc", + InbuiltFunction::Transpose => "transpose", + InbuiltFunction::TextureLoad => "textureLoad", + InbuiltFunction::TextureSample => "textureSample", + InbuiltFunction::TextureSampleBias => "textureSampleBias", + InbuiltFunction::TextureSampleCompare => "textureSampleCompare", + InbuiltFunction::TextureSampleGrad => "textureSampleGrad", + InbuiltFunction::TextureSampleLevel => "textureSampleLevel", + InbuiltFunction::TextureStore => "textureStore", + InbuiltFunction::AtomicLoad => "atomicLoad", + InbuiltFunction::AtomicStore => "atomicStore", + InbuiltFunction::AtomicAdd => "atomicAdd", + InbuiltFunction::AtomicSub => "atomicSub", + InbuiltFunction::AtomicMax => "atomicMax", + InbuiltFunction::AtomicMin => "atomicMin", + InbuiltFunction::AtomicAnd => "atomicAnd", + InbuiltFunction::AtomicOr => "atomicOr", + InbuiltFunction::AtomicXor => "atomicXor", + InbuiltFunction::AtomicExchange => "atomicExchange", + InbuiltFunction::AtomicCompareExchangeWeak => "atomicCompareExchangeWeak", + InbuiltFunction::Pack4x8Snorm => "pack4x8snorm", + InbuiltFunction::Pack4x8Unorm => "pack4x8unorm", + InbuiltFunction::Pack2x16Snorm => "pack2x16snorm", + InbuiltFunction::Pack2x16Unorm => "pack2x16unorm", + InbuiltFunction::Pack2x16Float => "pack2x16float", + InbuiltFunction::Unpack4x8Snorm => "unpack4x8snorm", + InbuiltFunction::Unpack4x8Unorm => "unpack4x8unorm", + InbuiltFunction::Unpack2x16Snorm => "unpack2x16snorm", + InbuiltFunction::Unpack2x16Unorm => "unpack2x16unorm", + InbuiltFunction::Unpack2x16Float => "unpack2x16float", + InbuiltFunction::StorageBarrier => "storageBarrier", + InbuiltFunction::WorkgroupBarrier => "workgroupBarrier", + InbuiltFunction::Bitcast => "bitcast", + InbuiltFunction::Select => "select", + InbuiltFunction::ArrayLength => "arrayLength", + InbuiltFunction::Acosh => "acosh", + InbuiltFunction::Asinh => "asinh", + InbuiltFunction::Atanh => "atanh", + InbuiltFunction::CountLeadingZeros => "countLeadingZeros", + InbuiltFunction::CountOneBits => "countOneBits", + InbuiltFunction::CountTrailingZeros => "countTrailingZeros", + InbuiltFunction::Degrees => "degrees", + InbuiltFunction::ExtractBits => "extractBits", + InbuiltFunction::FirstLeadingBit => "firstLeadingBit", + InbuiltFunction::FirstTrailingBit => "firstTrailingBit", + InbuiltFunction::InsertBits => "insertBits", + InbuiltFunction::Ldexp => "ldexp", + InbuiltFunction::Dpdx => "dpdx", + InbuiltFunction::DpdxCoarse => "dpdxCoarse", + InbuiltFunction::DpdxFine => "dpdxFine", + InbuiltFunction::Dpdy => "dpdy", + InbuiltFunction::DpdyCoarse => "dpdyCoarse", + InbuiltFunction::DpdyFine => "dpdyFine", + InbuiltFunction::Fwidth => "fwidth", + InbuiltFunction::FwidthCoarse => "fwidthCoarse", + InbuiltFunction::FwidthFine => "fwidthFine", + InbuiltFunction::TextureDimensions => "textureDimensions", + InbuiltFunction::TextureGather => "textureGather", + InbuiltFunction::TextureGatherCompare => "textureGatherCompare", + InbuiltFunction::TextureNumLayers => "textureNumLayers", + InbuiltFunction::TextureNumLevels => "textureNumLevels", + InbuiltFunction::TextureNumSamples => "textureNumSamples", + InbuiltFunction::TextureSampleCompareLevel => "textureSampleCompareLevel", + InbuiltFunction::TextureSampleBaseClampToEdge => "textureSampleBaseClampToEdge", + InbuiltFunction::OuterProduct => "outerProduct", + } + } +} diff --git a/src/front/wgsl/resolve/index.rs b/src/front/wgsl/resolve/index.rs new file mode 100644 index 0000000000..92aad82eb7 --- /dev/null +++ b/src/front/wgsl/resolve/index.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; + +use crate::front::wgsl::parse::ast::*; +use crate::front::wgsl::{resolve::ir::DeclId, text::Text, WgslError}; +use crate::Span; + +pub struct Index { + decls: HashMap, + spans: Vec, +} + +impl Index { + pub fn new() -> Self { + Self { + decls: HashMap::new(), + spans: Vec::new(), + } + } + + fn insert(&mut self, ident: Ident) -> Option { + let id = self.spans.len() as u32; + let old = self.decls.insert(ident.name, DeclId(id)); + self.spans.push(ident.span); + old.map(|id| self.spans[id.0 as usize]) + } + + pub fn get(&self, ident: Text) -> Option { + self.decls.get(&ident).copied() + } + + pub fn reset(&mut self) { + self.decls.clear(); + self.spans.clear(); + } + + pub fn generate(&mut self, tu: &TranslationUnit, diagnostics: &mut Vec) { + self.reset(); + + for decl in tu.decls.iter() { + let prev = match decl.kind { + GlobalDeclKind::Fn(ref f) => self.insert(f.name), + GlobalDeclKind::Override(ref o) => self.insert(o.name), + GlobalDeclKind::Var(ref v) => self.insert(v.inner.name), + GlobalDeclKind::Const(ref c) => self.insert(c.name), + GlobalDeclKind::Struct(ref s) => self.insert(s.name), + GlobalDeclKind::Type(ref ty) => self.insert(ty.name), + GlobalDeclKind::StaticAssert(_) => None, + GlobalDeclKind::Let(ref l) => { + diagnostics.push( + WgslError::new("global `let`s are deprecated") + .marker(decl.span) + .note("consider making it a `const`"), + ); + self.insert(l.name) + } + }; + + if let Some(prev) = prev { + diagnostics.push( + WgslError::new("duplicate declaration") + .label(prev, "previously declared here") + .label(decl_ident_span(decl), "redeclared here"), + ); + } + } + } +} + +fn decl_ident_span(decl: &GlobalDecl) -> Span { + match decl.kind { + GlobalDeclKind::Fn(ref f) => f.name.span, + GlobalDeclKind::Struct(ref s) => s.name.span, + GlobalDeclKind::Type(ref t) => t.name.span, + GlobalDeclKind::Const(ref c) => c.name.span, + GlobalDeclKind::Override(ref o) => o.name.span, + GlobalDeclKind::Var(ref v) => v.inner.name.span, + GlobalDeclKind::Let(ref l) => l.name.span, + GlobalDeclKind::StaticAssert(_) => unreachable!(), + } +} diff --git a/src/front/wgsl/resolve/ir.rs b/src/front/wgsl/resolve/ir.rs new file mode 100644 index 0000000000..ca2c79a955 --- /dev/null +++ b/src/front/wgsl/resolve/ir.rs @@ -0,0 +1,431 @@ +use std::hash::Hash; + +use crate::{FastHashSet, Span}; + +use crate::front::wgsl::parse::ast::{Ident, Literal}; +use crate::front::wgsl::resolve::{features::EnabledFeatures, inbuilt_functions::InbuiltFunction}; + +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct DeclId(pub u32); +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct LocalId(pub u32); + +#[derive(Clone, Debug)] +pub struct TranslationUnit { + pub features: EnabledFeatures, + pub decls: Vec, + pub roots: Vec, + pub dependency_order: Vec, +} + +impl TranslationUnit { + pub fn decls_ordered(&self) -> impl Iterator { + self.dependency_order + .iter() + .map(move |id| (*id, &self.decls[id.0 as usize])) + } +} + +impl TranslationUnit { + pub const fn new(features: EnabledFeatures) -> Self { + Self { + features, + decls: Vec::new(), + roots: Vec::new(), + dependency_order: Vec::new(), + } + } +} + +#[derive(Copy, Clone, Debug)] +pub struct DeclDependency { + pub id: DeclId, + pub usage: Span, +} + +impl Hash for DeclDependency { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + +impl PartialEq for DeclDependency { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for DeclDependency {} + +#[derive(Clone, Debug)] +pub struct Decl { + pub kind: DeclKind, + /// The direct dependencies of this declaration. + pub dependencies: FastHashSet, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum DeclKind { + Fn(Fn), + Override(Override), + Var(Var), + Const(Let), + StaticAssert(Expr), + Struct(Struct), + Type(TypeDecl), +} + +#[derive(Clone, Debug)] +pub struct Fn { + pub stage: ShaderStage, + pub name: Ident, + pub args: Vec, + pub ret_binding: Option, + pub ret: Option, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub enum ShaderStage { + None, + Vertex, + Fragment(Option), + Compute(Option, Option>, Option>), +} + +#[derive(Clone, Debug)] +pub struct Arg { + pub binding: Option, + pub name: Ident, + pub ty: Type, + pub span: Span, + pub id: LocalId, +} + +#[derive(Clone, Debug)] +pub enum Binding { + Builtin(crate::BuiltIn), + Location { + location: Option, + interpolation: Option, + sampling: Option, + }, +} + +#[derive(Clone, Debug)] +pub struct Override { + pub id: Option, + pub name: Ident, + pub ty: Type, + pub val: Option, +} + +#[derive(Clone, Debug)] +pub struct Var { + pub attribs: VarAttribs, + pub inner: VarNoAttribs, +} + +#[derive(Clone, Debug)] +pub struct VarAttribs { + pub group: Option, + pub binding: Option, +} + +#[derive(Clone, Debug)] +pub struct VarNoAttribs { + pub address_space: crate::AddressSpace, + pub name: Ident, + pub ty: Type, + pub val: Option, +} + +#[derive(Clone, Debug)] +pub struct Struct { + pub name: Ident, + pub fields: Vec, +} + +#[derive(Clone, Debug)] +pub struct Field { + pub attribs: FieldAttribs, + pub name: Ident, + pub ty: Type, +} + +#[derive(Clone, Debug)] +pub struct FieldAttribs { + pub align: Option, + pub size: Option, + pub binding: Option, +} + +#[derive(Clone, Debug)] +pub struct TypeDecl { + pub name: Ident, + pub ty: Type, +} + +#[derive(Clone, Debug)] +pub struct Type { + pub kind: TypeKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum TypeKind { + Inbuilt(InbuiltType), + User(DeclId), +} + +#[derive(Clone, Debug)] +pub enum InbuiltType { + 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, + }, + Image { + dim: crate::ImageDimension, + arrayed: bool, + class: crate::ImageClass, + }, + Sampler { + comparison: bool, + }, + Array { + of: Box, + len: Option, + }, + BindingArray { + of: Box, + len: Option, + }, + Pointer { + to: Box, + space: crate::AddressSpace, + }, + Atomic { + kind: crate::ScalarKind, + width: crate::Bytes, + }, + Infer, +} + +#[derive(Clone, Debug)] +pub struct Block { + pub stmts: Vec, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub struct Stmt { + pub kind: StmtKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum StmtKind { + Expr(Box), + Block(Block), + Break, + Continue, + Discard, + For(Box), + If(If), + Loop(Loop), + Return(Option), + StaticAssert(Expr), + Switch(Switch), + While(While), +} + +#[derive(Clone, Debug)] +pub struct ExprStatement { + pub kind: ExprStatementKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum ExprStatementKind { + VarDecl(VarDecl), + Call(CallExpr), + Assign(AssignExpr), +} + +#[derive(Clone, Debug)] +pub struct CallStmt { + pub name: Ident, + pub args: Vec, +} + +#[derive(Clone, Debug)] +pub struct For { + pub init: Option, + pub cond: Option, + /// Var decls are not going to be here. + pub update: Option, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub struct If { + pub cond: Expr, + pub block: Block, + pub else_: Option>, +} + +#[derive(Clone, Debug)] +pub struct Loop { + pub body: Block, + pub continuing: Option, + pub break_if: Option, +} + +#[derive(Clone, Debug)] +pub struct While { + pub cond: Expr, + pub block: Block, +} + +#[derive(Clone, Debug)] +pub struct Switch { + pub expr: Expr, + pub cases: Vec, +} + +#[derive(Clone, Debug)] +pub struct Case { + pub selectors: Vec, + pub block: Block, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum CaseSelector { + Expr(Expr), + Default, +} + +#[derive(Clone, Debug)] +pub struct Expr { + pub kind: ExprKind, + pub span: Span, +} + +#[derive(Clone, Debug)] +pub enum ExprKind { + Error, + Literal(Literal), + Local(LocalId), + Global(DeclId), + Unary(UnaryExpr), + AddrOf(Box), + Deref(Box), + Binary(BinaryExpr), + Call(CallExpr), + Index(Box, Box), + Member(Box, Ident), +} + +#[derive(Clone, Debug)] +pub struct UnaryExpr { + pub op: crate::UnaryOperator, + pub expr: Box, +} + +#[derive(Clone, Debug)] +pub struct AssignExpr { + pub target: AssignTarget, + pub op: Option, + pub value: Box, +} + +#[derive(Clone, Debug)] +pub enum AssignTarget { + Phony, + Expr(Box), +} + +#[derive(Clone, Debug)] +pub struct CallExpr { + pub target: CallTarget, + pub target_span: Span, + pub args: Vec, +} + +#[derive(Clone, Debug)] +pub enum CallTarget { + Decl(DeclId), + InbuiltFunction(InbuiltFunction, Vec), + Construction(Constructible), + Error, +} + +#[derive(Clone, Debug)] +pub enum Constructible { + Scalar { + kind: crate::ScalarKind, + width: crate::Bytes, + }, + PartialVector { + size: crate::VectorSize, + }, + Vector { + size: crate::VectorSize, + kind: crate::ScalarKind, + width: crate::Bytes, + }, + PartialMatrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + }, + Matrix { + columns: crate::VectorSize, + rows: crate::VectorSize, + width: crate::Bytes, + }, + PartialArray, + Array { + base: Box, + len: Box, + }, + Type(crate::Handle), +} + +#[derive(Clone, Debug)] +pub struct BinaryExpr { + pub lhs: Box, + pub op: crate::BinaryOperator, + pub rhs: Box, +} + +#[derive(Clone, Debug)] +pub struct VarDecl { + pub kind: VarDeclKind, + pub id: LocalId, +} + +#[derive(Clone, Debug)] +pub enum VarDeclKind { + Var(VarNoAttribs), + Const(Let), + Let(Let), +} + +#[derive(Clone, Debug)] +pub struct Let { + pub name: Ident, + pub ty: Type, + pub val: Expr, +} diff --git a/src/front/wgsl/resolve/mod.rs b/src/front/wgsl/resolve/mod.rs new file mode 100644 index 0000000000..63e027ad4c --- /dev/null +++ b/src/front/wgsl/resolve/mod.rs @@ -0,0 +1,1852 @@ +use aho_corasick::AhoCorasick; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::ops::{Deref, DerefMut}; + +use crate::front::wgsl::parse::ast; +use crate::front::wgsl::parse::ast::UnaryOp; +use crate::front::wgsl::parse::ast::{ExprKind, GlobalDeclKind, Ident, StmtKind, VarDecl}; +use crate::front::wgsl::resolve::dependency::DependencyContext; +use crate::front::wgsl::resolve::inbuilt::Attribute; +use crate::front::wgsl::WgslError; +use crate::{ + front::wgsl::resolve::{ + features::{EnabledFeatures, Feature}, + inbuilt::{ + reserved_matcher, AccessMode, AddressSpace, AttributeType, Builtin, ConservativeDepth, + DepthTextureType, InterpolationSample, InterpolationType, MatType, Matcher, + SampledTextureType, SamplerType, ScalarType, StorageTextureType, TexelFormat, + ToStaticString, VecType, + }, + inbuilt_functions::InbuiltFunction, + index::Index, + ir::{CallTarget, DeclDependency, DeclId, InbuiltType, LocalId}, + }, + front::wgsl::text::{Interner, Text}, + BinaryOperator, ImageClass, ScalarKind, Span, StorageAccess, UnaryOperator, +}; + +mod dependency; +pub mod features; +pub mod inbuilt; +pub mod inbuilt_functions; +mod index; +pub mod ir; + +pub struct ResolveContext { + dependency_context: DependencyContext, + index: Index, + reserved_matcher: AhoCorasick, + access_mode: Matcher, + address_space: Matcher, + builtin: Matcher, + interpolation_sample: Matcher, + interpolation_type: Matcher, + scalar: Matcher, + vec: Matcher, + mat: Matcher, + sampled_texture: Matcher, + depth_texture: Matcher, + sampler: Matcher, + storage_texture: Matcher, + texel_format: Matcher, + conservative_depth: Matcher, + inbuilt_function: Matcher, + kws: Box, + locals: u32, + in_function: bool, + scopes: Vec>, + dependencies: FxHashSet, +} + +impl ResolveContext { + pub fn new(intern: &mut Interner) -> Self { + Self { + dependency_context: DependencyContext::new(), + index: Index::new(), + kws: Box::new(Kws::init(intern)), + access_mode: Matcher::new(intern), + address_space: Matcher::new(intern), + builtin: Matcher::new(intern), + interpolation_sample: Matcher::new(intern), + interpolation_type: Matcher::new(intern), + scalar: Matcher::new(intern), + vec: Matcher::new(intern), + mat: Matcher::new(intern), + sampled_texture: Matcher::new(intern), + depth_texture: Matcher::new(intern), + sampler: Matcher::new(intern), + storage_texture: Matcher::new(intern), + texel_format: Matcher::new(intern), + conservative_depth: Matcher::new(intern), + inbuilt_function: Matcher::new(intern), + reserved_matcher: reserved_matcher(), + locals: 0, + in_function: false, + scopes: Vec::new(), + dependencies: FxHashSet::default(), + } + } + + pub fn reset(&mut self) { + self.locals = 0; + self.in_function = false; + self.scopes.clear(); + self.dependencies.clear(); + } + + pub fn resolve( + &mut self, + tu: ast::TranslationUnit, + intern: &mut Interner, + diagnostics: &mut Vec, + ) -> ir::TranslationUnit { + self.reset(); + + self.index.generate(&tu, diagnostics); + + let mut out = ir::TranslationUnit::new(EnabledFeatures::new(intern)); + + for enable in tu.enables { + out.features.enable(enable, intern, diagnostics); + } + + let mut resolver = Resolver { + tu: &mut out, + intern, + diagnostics, + ctx: self, + }; + + for decl in tu.decls { + resolver.decl(decl); + } + + self.dependency_context.resolve(&mut out, diagnostics); + + out + } +} + +struct Resolver<'a> { + tu: &'a mut ir::TranslationUnit, + diagnostics: &'a mut Vec, + intern: &'a mut Interner, + ctx: &'a mut ResolveContext, +} + +impl Deref for Resolver<'_> { + type Target = ResolveContext; + + fn deref(&self) -> &Self::Target { + self.ctx + } +} + +impl DerefMut for Resolver<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.ctx + } +} + +impl<'a> Resolver<'a> { + fn decl(&mut self, decl: ast::GlobalDecl) { + self.locals = 0; + + let kind = match decl.kind { + GlobalDeclKind::Fn(f) => { + let f = self.fn_(f); + + if !matches!(f.stage, ir::ShaderStage::None) { + self.tu.roots.push(DeclId(self.tu.decls.len() as _)); + } + + ir::DeclKind::Fn(f) + } + GlobalDeclKind::Override(ov) => ir::DeclKind::Override(self.ov(ov)), + GlobalDeclKind::Var(v) => ir::DeclKind::Var(ir::Var { + attribs: self.var_attribs(v.attribs), + inner: self.var(v.inner), + }), + GlobalDeclKind::Let(l) => ir::DeclKind::Const(self.let_(l)), + GlobalDeclKind::Const(c) => ir::DeclKind::Const(self.let_(c)), + GlobalDeclKind::StaticAssert(s) => ir::DeclKind::StaticAssert(self.expr(s.expr)), + GlobalDeclKind::Struct(s) => { + self.verify_ident(s.name); + ir::DeclKind::Struct(ir::Struct { + name: s.name, + fields: s.fields.into_iter().map(|f| self.field(f)).collect(), + }) + } + GlobalDeclKind::Type(ty) => { + self.verify_ident(ty.name); + ir::DeclKind::Type(ir::TypeDecl { + name: ty.name, + ty: self.ty(ty.ty), + }) + } + }; + + let decl = ir::Decl { + kind, + span: decl.span, + dependencies: std::mem::take(&mut self.dependencies), + }; + + self.tu.decls.push(decl); + } + + fn fn_(&mut self, fn_: ast::Fn) -> ir::Fn { + self.verify_ident(fn_.name); + + self.in_function = true; + + self.scopes.push(FxHashMap::default()); + let args = fn_.args.into_iter().map(|x| self.arg(x)).collect(); + let block = self.block_inner(fn_.block); + self.pop_scope(); + + self.in_function = false; + + ir::Fn { + stage: self.fn_attribs(fn_.attribs), + name: fn_.name, + args, + ret_binding: self.binding(fn_.ret_attribs), + ret: fn_.ret.map(|x| self.ty(x)), + block, + } + } + + fn ov(&mut self, o: ast::Override) -> ir::Override { + self.verify_ident(o.name); + + let mut id = None; + let a: Vec<_> = o + .attribs + .into_iter() + .filter_map(|x| self.attrib(x)) + .collect(); + for attrib in a { + match attrib.ty { + AttributeType::Id(expr) => { + if id.is_some() { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } else { + id = Some(self.expr(expr)); + } + } + _ => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + } + } + + ir::Override { + id, + name: o.name, + ty: o.ty.map(|x| self.ty(x)).unwrap_or(ir::Type { + kind: ir::TypeKind::Inbuilt(InbuiltType::Infer), + span: Span::UNDEFINED, + }), + val: o.val.map(|x| self.expr(x)), + } + } + + fn arg(&mut self, arg: ast::Arg) -> ir::Arg { + self.verify_ident(arg.name); + + let id = LocalId(self.locals); + let args = self.scopes.last_mut().expect("no scope"); + let old = args.insert(arg.name.name, (id, arg.span, false)); + self.locals += 1; + if let Some((_, span, _)) = old { + self.diagnostics.push( + WgslError::new("duplicate argument name") + .label(arg.name.span, "redefined here") + .label(span, "previous definition"), + ); + } + + ir::Arg { + binding: self.binding(arg.attribs), + name: arg.name, + ty: self.ty(arg.ty), + span: arg.span, + id, + } + } + + fn let_(&mut self, l: ast::Let) -> ir::Let { + self.verify_ident(l.name); + ir::Let { + name: l.name, + ty: l.ty.map(|x| self.ty(x)).unwrap_or(ir::Type { + kind: ir::TypeKind::Inbuilt(InbuiltType::Infer), + span: Span::UNDEFINED, + }), + val: self.expr(l.val), + } + } + + fn var_attribs(&mut self, attribs: Vec) -> ir::VarAttribs { + let mut out = ir::VarAttribs { + group: None, + binding: None, + }; + + let a: Vec<_> = attribs.into_iter().filter_map(|x| self.attrib(x)).collect(); + for attrib in a { + match attrib.ty { + AttributeType::Group(g) => { + if out.group.is_some() { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } else { + out.group = Some(self.expr(g)); + } + } + AttributeType::Binding(b) => { + if out.binding.is_some() { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } else { + out.binding = Some(self.expr(b)); + } + } + _ => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + } + } + + out + } + + fn binding(&mut self, attribs: Vec) -> Option { + let mut out = None; + + let a: Vec<_> = attribs.into_iter().filter_map(|x| self.attrib(x)).collect(); + + let mut inv = None; + let mut builtin = None; + + for attrib in a { + self.binding_inner(attrib, &mut out, &mut inv, &mut builtin); + } + + if let Some(invariant) = inv { + if builtin.is_none() { + self.diagnostics.push( + WgslError::new("invariant requires a `@builtin(position)` attribute") + .marker(invariant), + ); + } + } + + out + } + + fn binding_inner( + &mut self, + attrib: Attribute, + out: &mut Option, + inv: &mut Option, + builtin: &mut Option, + ) { + match attrib.ty { + AttributeType::Builtin(b) => match *out { + Some(ir::Binding::Builtin(_)) if inv.is_none() => { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + Some(ir::Binding::Location { .. }) => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + _ => { + *out = Some(ir::Binding::Builtin(b.into())); + *builtin = Some(attrib.span); + } + }, + AttributeType::Location(l) => match *out { + Some(ir::Binding::Builtin(_)) => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + Some(ir::Binding::Location { ref location, .. }) if location.is_some() => { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + Some(ir::Binding::Location { + ref mut location, .. + }) => { + *location = Some(self.expr(l)); + } + None => { + *out = Some(ir::Binding::Location { + location: Some(self.expr(l)), + interpolation: None, + sampling: None, + }); + } + }, + AttributeType::Interpolate(i, s) => match *out { + Some(ir::Binding::Builtin(_)) => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + Some(ir::Binding::Location { interpolation, .. }) if interpolation.is_some() => { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + Some(ir::Binding::Location { + ref mut interpolation, + ref mut sampling, + .. + }) => { + *interpolation = Some(i.into()); + *sampling = s.map(|x| x.into()); + } + None => { + *out = Some(ir::Binding::Location { + location: None, + interpolation: Some(i.into()), + sampling: s.map(|x| x.into()), + }); + } + }, + AttributeType::Invariant => match *out { + Some(ir::Binding::Builtin(_)) if builtin.is_none() => { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + Some(ir::Binding::Builtin(ref mut b)) => match *b { + crate::BuiltIn::Position { ref mut invariant } => { + *invariant = true; + *inv = Some(attrib.span); + } + _ => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here") + .marker(attrib.span), + ); + } + }, + Some(ir::Binding::Location { .. }) => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + None => { + *out = Some(ir::Binding::Builtin(crate::BuiltIn::Position { + invariant: true, + })); + *inv = Some(attrib.span); + } + }, + _ => { + self.diagnostics + .push(WgslError::new("this attribute is not allowed here").marker(attrib.span)); + } + } + } + + fn fn_attribs(&mut self, attribs: Vec) -> ir::ShaderStage { + let mut out = ir::ShaderStage::None; + let mut expect_compute = None; + + let a: Vec<_> = attribs.into_iter().filter_map(|x| self.attrib(x)).collect(); + for attrib in a { + match attrib.ty { + AttributeType::Const => self.diagnostics.push( + WgslError::new("user defined `const` functions are not allowed") + .marker(attrib.span), + ), + AttributeType::Vertex => { + if let ir::ShaderStage::None = out { + out = ir::ShaderStage::Vertex; + } else { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + } + AttributeType::Fragment => { + if let ir::ShaderStage::None = out { + out = ir::ShaderStage::Fragment(None); + } else { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + } + AttributeType::Compute => { + if let ir::ShaderStage::None = out { + expect_compute = Some(attrib.span); + } else if expect_compute.is_some() { + expect_compute = None; + } else { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + + out = ir::ShaderStage::Compute(None, None, None); + } + AttributeType::WorkgroupSize(x, y, z) => { + if let ir::ShaderStage::None = out { + expect_compute = Some(attrib.span); + } else if expect_compute.is_some() { + expect_compute = None; + } else { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } + + out = ir::ShaderStage::Compute( + Some(self.expr(x)), + y.map(|x| Box::new(self.expr(x))), + z.map(|x| Box::new(self.expr(x))), + ); + } + AttributeType::ConservativeDepth(depth) => { + if let ir::ShaderStage::Fragment(_) = out { + out = ir::ShaderStage::Fragment(Some(crate::EarlyDepthTest { + conservative: depth.map(|x| x.into()), + })); + } else { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here") + .marker(attrib.span), + ); + } + } + _ => { + self.diagnostics.push( + WgslError::new("this attribute is not allowed here").marker(attrib.span), + ); + } + } + } + + if let Some(span) = expect_compute { + self.diagnostics.push( + WgslError::new(if matches!(out, ir::ShaderStage::Compute(None, _, _)) { + "`@compute` without `@workgroup_size` attribute" + } else { + "`@workgroup_size` without `@compute` attribute" + }) + .marker(span), + ); + } + + out + } + + fn field(&mut self, field: ast::Arg) -> ir::Field { + let mut attribs = ir::FieldAttribs { + align: None, + binding: None, + size: None, + }; + + let a: Vec<_> = field + .attribs + .into_iter() + .filter_map(|x| self.attrib(x)) + .collect(); + + let mut inv = None; + let mut builtin = None; + + for attrib in a { + match attrib.ty { + AttributeType::Align(expr) => { + if attribs.align.is_some() { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } else { + attribs.align = Some(self.expr(expr)); + } + } + AttributeType::Size(expr) => { + if attribs.size.is_some() { + self.diagnostics + .push(WgslError::new("duplicate attribute").marker(attrib.span)); + } else { + attribs.size = Some(self.expr(expr)); + } + } + _ => { + self.binding_inner(attrib, &mut attribs.binding, &mut inv, &mut builtin); + } + } + } + + self.verify_ident(field.name); + + ir::Field { + attribs, + name: field.name, + ty: self.ty(field.ty), + } + } + + fn var(&mut self, v: ast::VarNoAttribs) -> ir::VarNoAttribs { + self.verify_ident(v.name); + + let ty = v.ty.map(|x| self.ty(x)).unwrap_or(ir::Type { + kind: ir::TypeKind::Inbuilt(InbuiltType::Infer), + span: Span::UNDEFINED, + }); + + let as_ = v + .address_space + .map(|x| (self.address_space(x), x.span)) + .and_then(|(a, s)| a.map(|a| (a, s))); + let am = v + .access_mode + .map(|x| (self.access_mode(x), x.span)) + .and_then(|(a, s)| a.map(|a| (a, s))); + + let address_space = as_.map(|x| x.0).unwrap_or_else(|| { + if self.in_function { + AddressSpace::Function + } else if let ir::TypeKind::Inbuilt( + InbuiltType::BindingArray { .. } + | InbuiltType::Sampler { .. } + | InbuiltType::Image { .. }, + ) = ty.kind + { + // Infer handle if its a resource type. + AddressSpace::Handle + } else { + AddressSpace::Private + } + }); + + if self.in_function && address_space != AddressSpace::Function { + let span = as_.unwrap().1; + self.diagnostics.push( + WgslError::new(format!( + "cannot declare variable with address space `{}` in a function", + address_space + )) + .marker(span), + ); + } else if !self.in_function && address_space == AddressSpace::Function { + let span = as_.unwrap().1; + self.diagnostics.push( + WgslError::new( + "cannot declare variable with address space `function` outside of a function", + ) + .marker(span), + ); + } + + let address_space = if let Some((mode, span)) = am { + let mut x = address_space.into(); + match x { + crate::AddressSpace::Storage { ref mut access } => *access = mode.into(), + _ => { + self.diagnostics.push( + WgslError::new(format!( + "cannot declare variable with access mode `{}` in address space `{}`", + mode, address_space + )) + .marker(span), + ); + } + } + + x + } else { + address_space.into() + }; + + ir::VarNoAttribs { + address_space, + name: v.name, + ty, + val: v.val.map(|x| self.expr(x)), + } + } + + fn ty(&mut self, ty: ast::Type) -> ir::Type { + let span = ty.span; + let t = match ty.kind { + ast::TypeKind::Ident(ident, ref generics) => Some((ident, generics.is_empty())), + _ => None, + }; + let kind = if let Some(inbuilt) = self.inbuilt(ty) { + ir::TypeKind::Inbuilt(inbuilt) + } else { + let (ident, no_generics) = t.unwrap(); + if !no_generics { + self.diagnostics + .push(WgslError::new("unexpected generics on type").marker(ident.span)); + } + + if let Some(user) = self.index.get(ident.name) { + self.dependencies.insert(DeclDependency { + id: user, + usage: ident.span, + }); + ir::TypeKind::User(user) + } else { + self.diagnostics + .push(WgslError::new("undefined type").marker(ident.span)); + ir::TypeKind::Inbuilt(InbuiltType::Scalar { + kind: ScalarKind::Sint, + width: 4, + }) + } + }; + + ir::Type { kind, span } + } + + fn block(&mut self, block: ast::Block) -> ir::Block { + self.scopes.push(FxHashMap::default()); + let ret = self.block_inner(block); + self.pop_scope(); + ret + } + + fn block_inner(&mut self, block: ast::Block) -> ir::Block { + let mut stmts = Vec::with_capacity(block.stmts.len()); + for stmt in block.stmts { + if let Some(stmt) = self.stmt(stmt) { + stmts.push(stmt); + } + } + + ir::Block { + stmts, + span: block.span, + } + } + + fn stmt(&mut self, stmt: ast::Stmt) -> Option { + let kind = match stmt.kind { + StmtKind::Block(block) => ir::StmtKind::Block(self.block(block)), + StmtKind::Expr(expr) => ir::StmtKind::Expr(Box::new(self.expr_statement(expr)?.kind)), + StmtKind::Break => ir::StmtKind::Break, + StmtKind::Continue => ir::StmtKind::Continue, + StmtKind::Discard => ir::StmtKind::Discard, + StmtKind::For(for_) => { + self.scopes.push(FxHashMap::default()); + let init = for_.init.and_then(|x| self.expr_statement(x)); + let cond = for_.cond.map(|x| self.expr(x)); + let update = for_ + .update + .and_then(|x| self.expr_statement(x)) + .and_then(|x| { + if matches!(x.kind, ir::ExprStatementKind::VarDecl(_)) { + self.diagnostics.push( + WgslError::new("variable declaration not allowed here") + .marker(x.span), + ); + None + } else { + Some(x) + } + }); + let block = self.block_inner(for_.block); + self.pop_scope(); + + ir::StmtKind::For(Box::new(ir::For { + init, + cond, + update, + block, + })) + } + StmtKind::If(if_) => { + let cond = self.expr(if_.cond); + let block = self.block(if_.block); + let mut else_ = if_.else_.and_then(|x| self.stmt(*x)).map(Box::new); + + if !matches!( + else_.as_ref().map(|x| &x.kind), + Some(&ir::StmtKind::If(_) | &ir::StmtKind::Block(_)) | None + ) { + self.diagnostics.push( + WgslError::new("`else` must be followed by `if` or block") + .marker(stmt.span), + ); + else_ = None; + } + + ir::StmtKind::If(ir::If { cond, block, else_ }) + } + StmtKind::Loop(mut block) => { + let (continuing, break_if) = if let Some(continuing) = block.stmts.pop() { + match continuing.kind { + StmtKind::Continuing(mut c) => { + let break_if = if let Some(break_if) = c.stmts.pop() { + match break_if.kind { + StmtKind::BreakIf(b) => Some(b), + _ => { + c.stmts.push(break_if); + None + } + } + } else { + None + }; + + (Some(c), break_if) + } + _ => { + block.stmts.push(continuing); + (None, None) + } + } + } else { + (None, None) + }; + + self.scopes.push(FxHashMap::default()); + let body = self.block_inner(block); + self.scopes.push(FxHashMap::default()); + let continuing = continuing.map(|x| self.block_inner(x)); + let break_if = break_if.map(|x| self.expr(x)); + self.scopes.pop(); + self.scopes.pop(); + + ir::StmtKind::Loop(ir::Loop { + body, + continuing, + break_if, + }) + } + StmtKind::Return(expr) => ir::StmtKind::Return(expr.map(|x| self.expr(x))), + StmtKind::StaticAssert(assert) => ir::StmtKind::StaticAssert(self.expr(assert.expr)), + StmtKind::Switch(switch) => ir::StmtKind::Switch(ir::Switch { + expr: self.expr(switch.expr), + cases: switch + .cases + .into_iter() + .map(|case| ir::Case { + selectors: case + .selectors + .into_iter() + .map(|sel| match sel { + ast::CaseSelector::Expr(expr) => { + ir::CaseSelector::Expr(self.expr(expr)) + } + ast::CaseSelector::Default => ir::CaseSelector::Default, + }) + .collect(), + block: self.block(case.block), + span: case.span, + }) + .collect(), + }), + StmtKind::While(while_) => ir::StmtKind::While(ir::While { + cond: self.expr(while_.cond), + block: self.block(while_.block), + }), + StmtKind::Continuing(c) => { + let _ = self.block(c); + self.diagnostics.push( + WgslError::new("`continuing` must be the last statement in `loop`") + .marker(stmt.span), + ); + return None; + } + StmtKind::BreakIf(x) => { + let _ = self.expr(x); + self.diagnostics.push( + WgslError::new("`break if` must be the last statement in `continuing`") + .marker(stmt.span), + ); + return None; + } + StmtKind::Empty => return None, + }; + + Some(ir::Stmt { + kind, + span: stmt.span, + }) + } + + fn expr(&mut self, expr: ast::Expr) -> ir::Expr { + let kind = match expr.kind { + ExprKind::Underscore => { + self.diagnostics + .push(WgslError::new("cannot use `_` as an expression").marker(expr.span)); + ir::ExprKind::Error + } + ExprKind::VarDecl(_) => { + self.diagnostics.push( + WgslError::new("cannot use variable declaration as an expression") + .marker(expr.span), + ); + ir::ExprKind::Error + } + ExprKind::Literal(l) => { + if let ast::Literal::F16(_) = l { + self.tu + .features + .require(Feature::Float16, expr.span, self.diagnostics) + } + ir::ExprKind::Literal(l) + } + ExprKind::Ident(ident) => { + self.verify_ident(ident.name); + if !ident.generics.is_empty() { + self.diagnostics + .push(WgslError::new("generics not allowed here").marker(expr.span)); + } + self.resolve_access(ident.name) + } + ExprKind::Unary(u) => match u.op { + UnaryOp::Ref => ir::ExprKind::AddrOf(Box::new(self.expr(*u.expr))), + UnaryOp::Deref => ir::ExprKind::Deref(Box::new(self.expr(*u.expr))), + op => { + let op = match op { + UnaryOp::Not => UnaryOperator::Not, + UnaryOp::Minus => UnaryOperator::Negate, + _ => unreachable!(), + }; + ir::ExprKind::Unary(ir::UnaryExpr { + op, + expr: Box::new(self.expr(*u.expr)), + }) + } + }, + ExprKind::Binary(b) => ir::ExprKind::Binary(ir::BinaryExpr { + op: b.op, + lhs: Box::new(self.expr(*b.lhs)), + rhs: Box::new(self.expr(*b.rhs)), + }), + ExprKind::Assign(_) => { + self.diagnostics.push( + WgslError::new("cannot use assignment as an expression").marker(expr.span), + ); + ir::ExprKind::Error + } + ExprKind::Call(call) => { + let target_span = call.target.span; + let target = self.call_target(*call.target); + let args = call.args.into_iter().map(|x| self.expr(x)).collect(); + ir::ExprKind::Call(ir::CallExpr { + target, + target_span, + args, + }) + } + ExprKind::Index(on, with) => { + ir::ExprKind::Index(Box::new(self.expr(*on)), Box::new(self.expr(*with))) + } + ExprKind::Member(on, member) => ir::ExprKind::Member(Box::new(self.expr(*on)), member), + ExprKind::Postfix(_) => { + self.diagnostics.push( + WgslError::new("cannot use postfix statement as an expression") + .marker(expr.span), + ); + ir::ExprKind::Error + } + }; + + ir::Expr { + kind, + span: expr.span, + } + } + + fn expr_statement(&mut self, expr: ast::Expr) -> Option { + let kind = match expr.kind { + ExprKind::VarDecl(decl) => { + let (name, kind) = match *decl { + VarDecl::Var(v) => (v.name, ir::VarDeclKind::Var(self.var(v))), + VarDecl::Const(c) => (c.name, ir::VarDeclKind::Const(self.let_(c))), + VarDecl::Let(l) => (l.name, ir::VarDeclKind::Let(self.let_(l))), + }; + + ir::ExprStatementKind::VarDecl(ir::VarDecl { + kind, + id: { + let id = LocalId(self.locals); + self.locals += 1; + let old = self + .scopes + .last_mut() + .expect("no scopes") + .insert(name.name, (id, name.span, false)); + + if let Some((_, span, _)) = old { + self.diagnostics.push( + WgslError::new("shadowing is not allowed in the same scope") + .label(span, "previously declared here") + .label(name.span, "redeclared here"), + ); + } + + id + }, + }) + } + ExprKind::Call(call) => { + let target_span = call.target.span; + let target = self.call_target(*call.target); + let args = call.args.into_iter().map(|x| self.expr(x)).collect(); + ir::ExprStatementKind::Call(ir::CallExpr { + target, + target_span, + args, + }) + } + ExprKind::Assign(assign) => { + if let ExprKind::Underscore = assign.lhs.kind { + if assign.op.is_none() { + ir::ExprStatementKind::Assign(ir::AssignExpr { + target: ir::AssignTarget::Phony, + op: None, + value: Box::new(self.expr(*assign.rhs)), + }) + } else { + self.diagnostics.push( + WgslError::new("`_` is not allowed here").marker(assign.lhs.span), + ); + return None; + } + } else { + let lhs = Box::new(self.expr(*assign.lhs)); + let rhs = Box::new(self.expr(*assign.rhs)); + + ir::ExprStatementKind::Assign(ir::AssignExpr { + target: ir::AssignTarget::Expr(lhs), + op: assign.op, + value: rhs, + }) + } + } + ExprKind::Postfix(postfix) => { + let span = postfix.expr.span; + let expr = Box::new(self.expr(*postfix.expr)); + + let target = ir::AssignTarget::Expr(expr); + let value = Box::new(ir::Expr { + kind: ir::ExprKind::Literal(ast::Literal::AbstractInt(1)), + span, + }); + + ir::ExprStatementKind::Assign(ir::AssignExpr { + target, + op: Some(match postfix.op { + ast::PostfixOp::Increment => BinaryOperator::Add, + ast::PostfixOp::Decrement => BinaryOperator::Subtract, + }), + value, + }) + } + _ => { + self.diagnostics + .push(WgslError::new("this expression is not allowed here").marker(expr.span)); + return None; + } + }; + + Some(ir::ExprStatement { + kind, + span: expr.span, + }) + } + + fn call_target(&mut self, target: ast::Expr) -> CallTarget { + match target.kind { + ExprKind::Ident(ident) => { + let name = ident.name; + + if let Some(decl) = self.index.get(name.name) { + self.dependencies.insert(DeclDependency { + id: decl, + usage: name.span, + }); + if !ident.generics.is_empty() { + self.diagnostics + .push(WgslError::new("unexpected generics").marker(target.span)); + } + CallTarget::Decl(decl) + } else if let Some(inbuilt) = self.inbuilt_function.get(name.name) { + CallTarget::InbuiltFunction( + inbuilt, + ident.generics.into_iter().map(|x| self.ty(x)).collect(), + ) + } else if let Some(ty) = self.constructible_inbuilt(ident, target.span) { + CallTarget::Construction(ty) + } else { + self.diagnostics + .push(WgslError::new("undefined function").marker(name.span)); + CallTarget::Error + } + } + _ => { + self.diagnostics + .push(WgslError::new("invalid function call target").marker(target.span)); + CallTarget::Error + } + } + } + + fn constructible_inbuilt( + &mut self, + ident: ast::IdentExpr, + span: Span, + ) -> Option { + let name = ident.name.name; + let name_span = ident.name.span; + Some(if name == self.kws.array { + if ident.generics.len() > 1 { + self.diagnostics + .push(WgslError::new("too many generics for `array`").marker(span)); + } + let base = ident.generics.into_iter().next().map(|x| self.ty(x)); + + if let Some(base) = base { + let len = ident + .array_len + .map(|x| Box::new(self.expr(*x))) + .unwrap_or_else(|| { + self.diagnostics + .push(WgslError::new("expected array length").marker(name_span)); + Box::new(ir::Expr { + kind: ir::ExprKind::Error, + span, + }) + }); + ir::Constructible::Array { + base: Box::new(base), + len, + } + } else { + ir::Constructible::PartialArray + } + } else if let Some(scalar) = self.scalar.get(name) { + if !ident.generics.is_empty() { + self.diagnostics.push( + WgslError::new(format!( + "`{}` cannot have generic parameters", + scalar.to_static_str() + )) + .marker(span), + ); + } + + match scalar { + ScalarType::F64 => { + self.tu + .features + .require(Feature::Float64, span, self.diagnostics) + } + ScalarType::F16 => { + self.tu + .features + .require(Feature::Float16, span, self.diagnostics) + } + _ => {} + } + + let (kind, width) = scalar.into(); + ir::Constructible::Scalar { kind, width } + } else if let Some(comp) = self.vec.get(name) { + let name = comp.to_static_str(); + if ident.generics.len() > 1 { + self.diagnostics + .push(WgslError::new(format!("too many generics for `{}`", name)).marker(span)); + } + + let ty = ident.generics.into_iter().next(); + let size = comp.into(); + match ty { + Some(ty) => { + if let Some(InbuiltType::Scalar { kind, width }) = self.inbuilt(ty) { + ir::Constructible::Vector { kind, width, size } + } else { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have a scalar type as its generic parameter", + name + )) + .marker(span), + ); + ir::Constructible::PartialVector { size } + } + } + None => ir::Constructible::PartialVector { size }, + } + } else if let Some(comp) = self.mat.get(name) { + let name = comp.to_static_str(); + if ident.generics.len() > 1 { + self.diagnostics + .push(WgslError::new(format!("too many generics for `{}`", name)).marker(span)); + } + + let ty = ident.generics.into_iter().next(); + let (columns, rows) = comp.into(); + match ty { + Some(ty) => { + if let Some(InbuiltType::Scalar { + kind: ScalarKind::Float, + width, + }) = self.inbuilt(ty) + { + ir::Constructible::Matrix { + columns, + rows, + width, + } + } else { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have a floating-point type as its generic parameter", + name + )) + .label(span, "eg. `f32`"), + ); + + let (columns, rows) = comp.into(); + ir::Constructible::PartialMatrix { columns, rows } + } + } + None => ir::Constructible::PartialMatrix { columns, rows }, + } + } else if name == self.kws.atomic + || name == self.kws.ptr + || self.sampled_texture.get(name).is_some() + || self.storage_texture.get(name).is_some() + || self.depth_texture.get(name).is_some() + || self.sampler.get(name).is_some() + { + self.diagnostics + .push(WgslError::new("cannot construct this type").marker(span)); + return None; + } else { + return None; + }) + } + + fn inbuilt(&mut self, ty: ast::Type) -> Option { + let span = ty.span; + let no_generics = |this: &mut Self, generics: Vec, name: &str| { + if !generics.is_empty() { + this.diagnostics.push( + WgslError::new(format!("`{}` cannot have generic parameters", name)) + .marker(span), + ); + } + }; + + let ty = match ty.kind { + ast::TypeKind::Ident(ident, generics) => { + if let Some(scalar) = self.scalar.get(ident.name) { + no_generics(self, generics, scalar.to_static_str()); + + match scalar { + ScalarType::F64 => { + self.tu + .features + .require(Feature::Float64, ident.span, self.diagnostics) + } + ScalarType::F16 => { + self.tu + .features + .require(Feature::Float16, ident.span, self.diagnostics) + } + _ => {} + } + + let (kind, width) = scalar.into(); + InbuiltType::Scalar { kind, width } + } else if let Some(comp) = self.vec.get(ident.name) { + let name = comp.to_static_str(); + + if generics.len() != 1 { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have exactly 1 generic parameter", + name + )) + .marker(span), + ); + } + + if let Some(InbuiltType::Scalar { kind, width }) = + generics.into_iter().next().and_then(|x| self.inbuilt(x)) + { + InbuiltType::Vector { + kind, + width, + size: comp.into(), + } + } else { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have a scalar type as its generic parameter", + name + )) + .marker(span), + ); + InbuiltType::Vector { + kind: ScalarKind::Sint, + width: 4, + size: comp.into(), + } + } + } else if let Some(comp) = self.mat.get(ident.name) { + let name = comp.to_static_str(); + + if generics.len() != 1 { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have exactly 1 generic parameter", + name + )) + .marker(span), + ); + } + + let (columns, rows) = comp.into(); + if let Some(InbuiltType::Scalar { + width, + kind: ScalarKind::Float, + }) = generics.into_iter().next().and_then(|x| self.inbuilt(x)) + { + InbuiltType::Matrix { + columns, + rows, + width, + } + } else { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have a floating-point type as its generic parameter", + name + )) + .label(span, "eg. `f32`"), + ); + + InbuiltType::Matrix { + columns, + rows, + width: 4, + } + } + } else if ident.name == self.kws.atomic { + if generics.len() != 1 { + self.diagnostics.push( + WgslError::new("`atomic` must have exactly one generic parameter") + .marker(ty.span), + ); + } + + if let Some(InbuiltType::Scalar { kind, width }) = + generics.into_iter().next().and_then(|x| self.inbuilt(x)) + { + InbuiltType::Atomic { kind, width } + } else { + self.diagnostics.push( + WgslError::new( + "`atomic` must have a scalar type as its generic parameter", + ) + .marker(ty.span), + ); + InbuiltType::Atomic { + kind: ScalarKind::Sint, + width: 4, + } + } + } else if ident.name == self.kws.ptr { + let mut generics = generics.into_iter(); + let address_space = generics.next(); + let to = generics.next().map(|x| self.ty(x)); + let access_mode = generics.next(); + + let address_space = address_space + .and_then(|x| { + self.ty_to_ident(x, "address space") + .map(|x| (self.address_space(x), x.span)) + }) + .and_then(|(a, s)| a.map(|a| (a, s))); + + let access_mode = access_mode + .and_then(|access_mode| { + self.ty_to_ident(access_mode, "access mode") + .map(|x| (self.access_mode(x), x.span)) + }) + .and_then(|(a, s)| a.map(|a| (a, s))); + + let to = to.unwrap_or_else(|| { + self.diagnostics + .push(WgslError::new("expected type").marker(span)); + ir::Type { + kind: ir::TypeKind::Inbuilt(InbuiltType::Scalar { + kind: ScalarKind::Sint, + width: 4, + }), + span, + } + }); + + let address_space = address_space.map(|x| x.0).unwrap_or_else(|| { + self.diagnostics + .push(WgslError::new("expected address space").marker(span)); + AddressSpace::Function + }); + + let address_space = if let Some((mode, span)) = access_mode { + let mut x = address_space.into(); + match x { + crate::AddressSpace::Storage { ref mut access } => { + *access = mode.into() + } + _ => { + self.diagnostics.push( + WgslError::new(format!( + "cannot declare variable with access mode `{}` in address space `{}`", + mode, address_space + )) + .marker(span), + ); + } + } + + x + } else { + address_space.into() + }; + + InbuiltType::Pointer { + space: address_space, + to: Box::new(to), + } + } else if let Some(s) = self.sampled_texture.get(ident.name) { + let name = s.to_static_str(); + + if generics.len() != 1 { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have exactly 1 generic parameter", + name + )) + .marker(ty.span), + ); + } + + let sample_type = generics + .into_iter() + .next() + .map(|x| (x.span, self.inbuilt(x))) + .and_then(|(span, ty)| ty.map(|x| (x, span))); + let kind = match sample_type { + Some((InbuiltType::Scalar { kind, width }, span)) => { + if kind == ScalarKind::Bool || width != 4 { + self.diagnostics.push( + WgslError::new(format!("invalid sample type for `{}`", name)) + .label(span, "must be `u32`, `f32`, or `i32`"), + ); + } + kind + } + Some((_, span)) => { + self.diagnostics.push( + WgslError::new(format!("invalid sample type for `{}`", name)) + .label(span, "must be `u32`, `f32`, or `i32`"), + ); + ScalarKind::Float + } + None => ScalarKind::Float, + }; + + let (dim, arrayed, multi) = s.into(); + InbuiltType::Image { + dim, + arrayed, + class: ImageClass::Sampled { kind, multi }, + } + } else if let Some(depth) = self.depth_texture.get(ident.name) { + no_generics(self, generics, depth.to_static_str()); + + let (dim, arrayed, multi) = depth.into(); + InbuiltType::Image { + dim, + arrayed, + class: ImageClass::Depth { multi }, + } + } else if let Some(s) = self.storage_texture.get(ident.name) { + let name = s.to_static_str(); + + if generics.len() != 2 { + self.diagnostics.push( + WgslError::new(format!( + "`{}` must have exactly 2 generic parameters", + name + )) + .marker(ty.span), + ); + } + + let mut generics = generics.into_iter(); + let texel_format = generics + .next() + .and_then(|x| self.ty_to_ident(x, "texel format")) + .and_then(|x| self.texel_format(x)) + .unwrap_or(TexelFormat::Rgba8Unorm); + let access = generics + .next() + .and_then(|x| self.ty_to_ident(x, "access mode")) + .map(|x| (self.access_mode(x), x.span)); + + let access = if let Some((access, span)) = access { + let access = access.unwrap_or(AccessMode::Write); + if access != AccessMode::Write { + self.tu.features.require( + Feature::StorageImageRead, + span, + self.diagnostics, + ); + } + access.into() + } else { + StorageAccess::STORE + }; + + let (dim, arrayed) = s.into(); + InbuiltType::Image { + dim, + arrayed, + class: ImageClass::Storage { + format: texel_format.into(), + access, + }, + } + } else if let Some(s) = self.sampler.get(ident.name) { + no_generics(self, generics, s.to_static_str()); + InbuiltType::Sampler { + comparison: s.into(), + } + } else { + return None; + } + } + ast::TypeKind::Array(array, of, len) => { + if array.name == self.kws.array { + InbuiltType::Array { + of: Box::new(self.ty(*of)), + len: len.map(|x| self.expr(x)), + } + } else { + // Is `binding_array` + self.tu + .features + .require(Feature::BindingArray, array.span, self.diagnostics); + + InbuiltType::BindingArray { + of: Box::new(self.ty(*of)), + len: len.map(|x| self.expr(x)), + } + } + } + }; + + Some(ty) + } + + fn attrib(&mut self, attrib: ast::Attribute) -> Option { + let args = |this: &mut Self, args: usize| { + if attrib.exprs.len() != args { + this.diagnostics + .push(WgslError::new("expected 1 argument").marker(attrib.span)); + None + } else { + Some(()) + } + }; + let expr_as_ident = |this: &mut Self, expr: &ast::Expr| match expr.kind { + ExprKind::Ident(ref i) => { + if !i.generics.is_empty() || i.array_len.is_some() { + this.diagnostics + .push(WgslError::new("expected identifier").marker(expr.span)); + } + Some(i.name) + } + _ => None, + }; + + let span = attrib.span; + let ty = match attrib.name.name { + x if x == self.kws.align => args(self, 1) + .map(|_| AttributeType::Align(attrib.exprs.into_iter().next().unwrap())), + x if x == self.kws.binding => args(self, 1) + .map(|_| AttributeType::Binding(attrib.exprs.into_iter().next().unwrap())), + x if x == self.kws.builtin => args(self, 1).and_then(|_| { + expr_as_ident(self, &attrib.exprs[0]) + .and_then(|ident| self.builtin(ident).map(AttributeType::Builtin)) + }), + x if x == self.kws.compute => args(self, 0).map(|_| AttributeType::Compute), + x if x == self.kws.const_ => args(self, 0).map(|_| AttributeType::Const), + x if x == self.kws.fragment => args(self, 0).map(|_| AttributeType::Fragment), + x if x == self.kws.group => args(self, 1) + .map(|_| AttributeType::Group(attrib.exprs.into_iter().next().unwrap())), + x if x == self.kws.id => { + args(self, 1).map(|_| AttributeType::Id(attrib.exprs.into_iter().next().unwrap())) + } + x if x == self.kws.interpolate => { + if attrib.exprs.is_empty() || attrib.exprs.len() > 2 { + self.diagnostics + .push(WgslError::new("expected 1 or 2 arguments").marker(attrib.span)); + None + } else { + let ty = expr_as_ident(self, &attrib.exprs[0]) + .and_then(|x| self.interpolation_type(x)) + .unwrap_or(InterpolationType::Perspective); + let sample = attrib + .exprs + .get(1) + .and_then(|x| expr_as_ident(self, x)) + .and_then(|x| self.interpolation_sample(x)); + + if ty == InterpolationType::Flat && sample.is_some() { + let span = attrib.exprs[1].span; + self.diagnostics.push( + WgslError::new("flat interpolation must not have a sample type") + .marker(span), + ); + } + + Some(AttributeType::Interpolate(ty, sample)) + } + } + x if x == self.kws.invariant => args(self, 0).map(|_| AttributeType::Invariant), + x if x == self.kws.location => args(self, 1) + .map(|_| AttributeType::Location(attrib.exprs.into_iter().next().unwrap())), + x if x == self.kws.size => { + args(self, 1).map(|_| AttributeType::Size(attrib.exprs.into_iter().next().unwrap())) + } + x if x == self.kws.vertex => args(self, 0).map(|_| AttributeType::Vertex), + x if x == self.kws.workgroup_size => { + if attrib.exprs.is_empty() || attrib.exprs.len() > 3 { + self.diagnostics + .push(WgslError::new("expected 1, 2, or 3 arguments").marker(attrib.span)); + None + } else { + let mut iter = attrib.exprs.into_iter(); + let x = iter.next().unwrap(); + let y = iter.next(); + let z = iter.next(); + Some(AttributeType::WorkgroupSize(x, y, z)) + } + } + x if x == self.kws.early_depth_test => args(self, 1).map(|_| { + AttributeType::ConservativeDepth( + expr_as_ident(self, &attrib.exprs.into_iter().next().unwrap()) + .and_then(|x| self.conservative_depth(x)), + ) + }), + _ => { + self.diagnostics + .push(WgslError::new("unknown attribute").marker(attrib.name.span)); + None + } + }; + + ty.map(|ty| Attribute { span, ty }) + } + + fn access_mode(&mut self, ident: Ident) -> Option { + match self.access_mode.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown access mode").marker(ident.span)); + None + } + } + } + + fn address_space(&mut self, ident: Ident) -> Option { + match self.address_space.get(ident.name) { + Some(AddressSpace::Handle) => { + self.diagnostics.push( + WgslError::new("`handle` address space is not allowed here") + .marker(ident.span) + .note("consider removing the address space (``)"), + ); + Some(AddressSpace::Handle) + } + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown address space").marker(ident.span)); + None + } + } + } + + fn builtin(&mut self, ident: Ident) -> Option { + match self.builtin.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown builtin").marker(ident.span)); + None + } + } + } + + fn interpolation_sample(&mut self, ident: Ident) -> Option { + match self.interpolation_sample.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown interpolation sample").marker(ident.span)); + None + } + } + } + + fn interpolation_type(&mut self, ident: Ident) -> Option { + match self.interpolation_type.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown interpolation type").marker(ident.span)); + None + } + } + } + + fn texel_format(&mut self, ident: Ident) -> Option { + match self.texel_format.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown texel format").marker(ident.span)); + None + } + } + } + + fn conservative_depth(&mut self, ident: Ident) -> Option { + match self.conservative_depth.get(ident.name) { + Some(x) => Some(x), + None => { + self.diagnostics + .push(WgslError::new("unknown conservative depth").marker(ident.span)); + None + } + } + } + + fn ty_to_ident(&mut self, ty: ast::Type, expected: &str) -> Option { + match ty.kind { + ast::TypeKind::Ident(ident, ref generics) => { + if !generics.is_empty() { + self.diagnostics + .push(WgslError::new(format!("expected {}", expected)).marker(ty.span)); + } + Some(ident) + } + ast::TypeKind::Array(..) => { + self.diagnostics + .push(WgslError::new(format!("expected {}", expected)).marker(ty.span)); + None + } + } + } + + fn verify_ident(&mut self, ident: Ident) { + let text = self.intern.resolve(ident.name); + if let Some(m) = self.reserved_matcher.find(text) { + if m.len() == text.len() { + self.diagnostics.push( + WgslError::new("usage of reserved identifier") + .marker(ident.span) + .note( + "this is reserved by the WGSL spec, consider renaming the identifier", + ), + ); + } + } + } + + fn resolve_access(&mut self, ident: Ident) -> ir::ExprKind { + for scope in self.scopes.iter_mut().rev() { + if let Some(&mut (id, _, ref mut used)) = scope.get_mut(&ident.name) { + *used = true; + return ir::ExprKind::Local(id); + } + } + + if let Some(global) = self.index.get(ident.name) { + self.dependencies.insert(DeclDependency { + id: global, + usage: ident.span, + }); + ir::ExprKind::Global(global) + } else { + self.diagnostics + .push(WgslError::new("undefined identifier").marker(ident.span)); + ir::ExprKind::Error + } + } + + fn pop_scope(&mut self) { + self.scopes.pop().unwrap(); + } +} + +struct Kws { + align: Text, + binding: Text, + builtin: Text, + compute: Text, + const_: Text, + fragment: Text, + group: Text, + id: Text, + interpolate: Text, + invariant: Text, + location: Text, + size: Text, + vertex: Text, + workgroup_size: Text, + early_depth_test: Text, + array: Text, + atomic: Text, + ptr: Text, +} + +impl Kws { + fn init(intern: &mut Interner) -> Self { + Self { + align: intern.get_static("align"), + binding: intern.get_static("binding"), + builtin: intern.get_static("builtin"), + compute: intern.get_static("compute"), + const_: intern.get_static("const"), + fragment: intern.get_static("fragment"), + group: intern.get_static("group"), + id: intern.get_static("id"), + interpolate: intern.get_static("interpolate"), + invariant: intern.get_static("invariant"), + location: intern.get_static("location"), + size: intern.get_static("size"), + vertex: intern.get_static("vertex"), + workgroup_size: intern.get_static("workgroup_size"), + early_depth_test: intern.get_static("early_depth_test"), + array: intern.get_static("array"), + atomic: intern.get_static("atomic"), + ptr: intern.get_static("ptr"), + } + } +} diff --git a/src/front/wgsl/tests.rs b/src/front/wgsl/tests.rs deleted file mode 100644 index 33fc541acb..0000000000 --- a/src/front/wgsl/tests.rs +++ /dev/null @@ -1,458 +0,0 @@ -use super::parse_str; - -#[test] -fn parse_comment() { - parse_str( - "// - //// - ///////////////////////////////////////////////////////// asda - //////////////////// dad ////////// / - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // - ", - ) - .unwrap(); -} - -#[test] -fn parse_types() { - parse_str("let a : i32 = 2;").unwrap(); - assert!(parse_str("let 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(); - parse_str("var t: texture_storage_1d;").unwrap(); - parse_str("var t: texture_storage_3d;").unwrap(); -} - -#[test] -fn parse_type_inference() { - parse_str( - " - fn foo() { - let a = 2u; - let b: u32 = a; - var x = 3.; - var y = vec2(1, 2); - }", - ) - .unwrap(); - assert!(parse_str( - " - fn foo() { let c : i32 = 2.0; }", - ) - .is_err()); -} - -#[test] -fn parse_type_cast() { - parse_str( - " - let a : i32 = 2; - fn main() { - var x: f32 = f32(a); - x = f32(i32(a + 1) / 2); - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - let x: vec2 = vec2(1.0, 2.0); - let y: vec2 = vec2(x); - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - let x: vec2 = vec2(0.0); - } - ", - ) - .unwrap(); - assert!(parse_str( - " - fn main() { - let x: vec2 = vec2(0); - } - ", - ) - .is_err()); -} - -#[test] -fn parse_struct() { - parse_str( - " - struct Foo { x: i32 } - struct Bar { - @size(16) x: vec2, - @align(16) y: f32, - @size(32) @align(128) z: vec3, - }; - struct Empty {} - var s: Foo; - ", - ) - .unwrap(); -} - -#[test] -fn parse_standard_fun() { - parse_str( - " - fn main() { - var x: i32 = min(max(1, 2), 3); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_statement() { - parse_str( - " - fn main() { - ; - {} - {;} - } - ", - ) - .unwrap(); - - parse_str( - " - fn foo() {} - fn bar() { foo(); } - ", - ) - .unwrap(); -} - -#[test] -fn parse_if() { - parse_str( - " - fn main() { - if true { - discard; - } else {} - if 0 != 1 {} - if false { - return; - } else if true { - return; - } else {} - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_parentheses_if() { - parse_str( - " - fn main() { - if (true) { - discard; - } else {} - if (0 != 1) {} - if (false) { - return; - } else if (true) { - return; - } else {} - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_loop() { - parse_str( - " - fn main() { - var i: i32 = 0; - loop { - if i == 1 { break; } - continuing { i = 1; } - } - loop { - if i == 0 { continue; } - break; - } - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - var found: bool = false; - var i: i32 = 0; - while !found { - if i == 10 { - found = true; - } - - i = i + 1; - } - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - while true { - break; - } - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - var a: i32 = 0; - for(var i: i32 = 0; i < 4; i = i + 1) { - a = a + 2; - } - } - ", - ) - .unwrap(); - parse_str( - " - fn main() { - for(;;) { - break; - } - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_switch() { - parse_str( - " - fn main() { - var pos: f32; - switch (3) { - case 0, 1: { pos = 0.0; } - case 2: { pos = 1.0; fallthrough; } - case 3: {} - default: { pos = 3.0; } - } - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_switch_optional_colon_in_case() { - parse_str( - " - fn main() { - var pos: f32; - switch (3) { - case 0, 1 { pos = 0.0; } - case 2 { pos = 1.0; fallthrough; } - case 3 {} - default { pos = 3.0; } - } - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_parentheses_switch() { - parse_str( - " - fn main() { - var pos: f32; - switch pos > 1.0 { - default: { pos = 3.0; } - } - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_texture_load() { - parse_str( - " - var t: texture_3d; - fn foo() { - let r: vec4 = textureLoad(t, vec3(0.0, 1.0, 2.0), 1); - } - ", - ) - .unwrap(); - parse_str( - " - var t: texture_multisampled_2d_array; - fn foo() { - let r: vec4 = textureLoad(t, vec2(10, 20), 2, 3); - } - ", - ) - .unwrap(); - parse_str( - " - var t: texture_storage_1d_array; - fn foo() { - let r: vec4 = textureLoad(t, 10, 2); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_texture_store() { - parse_str( - " - var t: texture_storage_2d; - fn foo() { - textureStore(t, vec2(10, 20), vec4(0.0, 1.0, 2.0, 3.0)); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_texture_query() { - parse_str( - " - var t: texture_multisampled_2d_array; - fn foo() { - var dim: vec2 = textureDimensions(t); - dim = textureDimensions(t, 0); - let layers: i32 = textureNumLayers(t); - let samples: i32 = textureNumSamples(t); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_postfix() { - parse_str( - "fn foo() { - let x: f32 = vec4(1.0, 2.0, 3.0, 4.0).xyz.rgbr.aaaa.wz.g; - let y: f32 = fract(vec2(0.5, x)).x; - }", - ) - .unwrap(); -} - -#[test] -fn parse_expressions() { - parse_str("fn foo() { - let x: f32 = select(0.0, 1.0, true); - let y: vec2 = select(vec2(1.0, 1.0), vec2(x, x), vec2(x < 0.5, x > 0.5)); - let z: bool = !(0.0 == 1.0); - }").unwrap(); -} - -#[test] -fn parse_pointers() { - parse_str( - "fn foo() { - var x: f32 = 1.0; - let px = &x; - let py = frexp(0.5, px); - }", - ) - .unwrap(); -} - -#[test] -fn parse_struct_instantiation() { - parse_str( - " - struct Foo { - a: f32, - b: vec3, - } - - @fragment - fn fs_main() { - var foo: Foo = Foo(0.0, vec3(0.0, 1.0, 42.0)); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_array_length() { - parse_str( - " - struct Foo { - data: array - } // this is used as both input and output for convenience - - @group(0) @binding(0) - var foo: Foo; - - @group(0) @binding(1) - var bar: array; - - fn baz() { - var x: u32 = arrayLength(foo.data); - var y: u32 = arrayLength(bar); - } - ", - ) - .unwrap(); -} - -#[test] -fn parse_storage_buffers() { - parse_str( - " - @group(0) @binding(0) - var foo: array; - ", - ) - .unwrap(); - parse_str( - " - @group(0) @binding(0) - var foo: array; - ", - ) - .unwrap(); - parse_str( - " - @group(0) @binding(0) - var foo: array; - ", - ) - .unwrap(); - parse_str( - " - @group(0) @binding(0) - var foo: array; - ", - ) - .unwrap(); -} diff --git a/src/front/wgsl/text.rs b/src/front/wgsl/text.rs new file mode 100644 index 0000000000..f9ff8025d1 --- /dev/null +++ b/src/front/wgsl/text.rs @@ -0,0 +1,28 @@ +use lasso::{Rodeo, Spur}; + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub struct Text(Spur); + +pub struct Interner { + rodeo: Rodeo, +} + +impl Interner { + pub fn new() -> Self { + Self { + rodeo: Rodeo::new(), + } + } + + pub fn get(&mut self, text: &str) -> Text { + Text(self.rodeo.get_or_intern(text)) + } + + pub fn get_static(&mut self, text: &'static str) -> Text { + Text(self.rodeo.get_or_intern_static(text)) + } + + pub fn resolve(&self, text: Text) -> &str { + self.rodeo.resolve(&text.0) + } +} diff --git a/src/lib.rs b/src/lib.rs index c4893b73a2..e39ec2ed73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1225,12 +1225,8 @@ pub enum Expression { /// Reference a function parameter, by its index. /// - /// A `FunctionArgument` expression evaluates to a pointer to the argument's - /// value. You must use a [`Load`] expression to retrieve its value, or a - /// [`Store`] statement to assign it a new value. - /// - /// [`Load`]: Expression::Load - /// [`Store`]: Statement::Store + /// A `FunctionArgument` expression evaluates to the argument's + /// value. It is not a pointer to the argument. FunctionArgument(u32), /// Reference a global variable. @@ -1388,7 +1384,7 @@ pub enum Expression { }, /// Cast a simple type to another kind. As { - /// Source expression, which can only be a scalar or a vector. + /// Source expression, which can only be a scalar, vector, or matrix. expr: Handle, /// Target scalar kind. kind: ScalarKind, diff --git a/src/span.rs b/src/span.rs index a4670e2dad..75c1b6638c 100644 --- a/src/span.rs +++ b/src/span.rs @@ -38,7 +38,7 @@ impl Span { /// Returns the smallest `Span` possible that contains all the `Span`s /// defined in the `from` iterator - pub fn total_span>(from: T) -> Self { + pub fn total_span>(from: T) -> Self { let mut span: Self = Default::default(); for other in from { span.subsume(other); diff --git a/tests/in/access.wgsl b/tests/in/access.wgsl index c2e4d25b6e..21fe148382 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 d = array(a, i32(b), 3, 4, 5); + d[vi + 1u] = 42; + let value = d[vi]; _ = test_arr_as_arg(array, 5>()); diff --git a/tests/in/binding-arrays.wgsl b/tests/in/binding-arrays.wgsl index 491621f514..87cf6e2f42 100644 --- a/tests/in/binding-arrays.wgsl +++ b/tests/in/binding-arrays.wgsl @@ -1,6 +1,8 @@ +enable binding_array; + struct UniformIndex { index: u32 -}; +} @group(0) @binding(0) var texture_array_unbounded: binding_array>; @@ -23,7 +25,7 @@ var uni: UniformIndex; struct FragmentIn { @location(0) index: u32, -}; +} @fragment fn main(fragment_in: FragmentIn) -> @location(0) vec4 { @@ -34,9 +36,9 @@ fn main(fragment_in: FragmentIn) -> @location(0) vec4 { var i2 = vec2(0); var v1 = 0.0; var v4 = vec4(0.0); - + // This example is arranged in the order of the texture definitions in the wgsl spec - // + // // The first function uses texture_array_unbounded, the rest use texture_array_bounded to make sure // they both show up in the output. Functions that need depth use texture_array_2darray. // @@ -52,11 +54,11 @@ fn main(fragment_in: FragmentIn) -> @location(0) vec4 { v4 += textureGather(0, texture_array_bounded[0], samp[0], uv); v4 += textureGather(0, texture_array_bounded[uniform_index], samp[uniform_index], uv); - v4 += textureGather(0, texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); + v4 += textureGather(0, texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); v4 += textureGatherCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); v4 += textureGatherCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); - v4 += textureGatherCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + v4 += textureGatherCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); v4 += textureLoad(texture_array_unbounded[0], pix, 0); v4 += textureLoad(texture_array_unbounded[uniform_index], pix, 0); 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/control-flow.wgsl b/tests/in/control-flow.wgsl index 787742d71d..b33ade770d 100644 --- a/tests/in/control-flow.wgsl +++ b/tests/in/control-flow.wgsl @@ -24,11 +24,9 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { } case 3: { pos = 2; - fallthrough; } case 4: { pos = 3; - fallthrough; } default: { pos = 4; @@ -54,7 +52,6 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { } case 3: { pos = 2; - fallthrough; } case 4: {} default: { diff --git a/tests/in/extra.wgsl b/tests/in/extra.wgsl index ef68f4aa80..29188223c0 100644 --- a/tests/in/extra.wgsl +++ b/tests/in/extra.wgsl @@ -1,3 +1,5 @@ +enable f64; + struct PushConstants { index: u32, double: vec2, diff --git a/tests/in/globals.wgsl b/tests/in/globals.wgsl index 59820ab367..219f693f62 100644 --- a/tests/in/globals.wgsl +++ b/tests/in/globals.wgsl @@ -1,6 +1,6 @@ // Global variable & constant declarations -let Foo: bool = true; +const FooConst: bool = true; var wg : array; var at: atomic; diff --git a/tests/in/image.wgsl b/tests/in/image.wgsl index e1fb11a40f..234eb019b6 100644 --- a/tests/in/image.wgsl +++ b/tests/in/image.wgsl @@ -1,3 +1,5 @@ +enable storage_image_read; + @group(0) @binding(0) var image_mipmapped_src: texture_2d; @group(0) @binding(3) diff --git a/tests/in/lexical-scopes.wgsl b/tests/in/lexical-scopes.wgsl index 70a18a4885..9c008f3139 100644 --- a/tests/in/lexical-scopes.wgsl +++ b/tests/in/lexical-scopes.wgsl @@ -1,5 +1,5 @@ fn blockLexicalScope(a: bool) { - let a = 1.0; + let b = 1.0; { let a = 2; { @@ -7,37 +7,37 @@ fn blockLexicalScope(a: bool) { } let test = a == 3; } - let test = a == 2.0; + let test = b == 2.0; } fn ifLexicalScope(a: bool) { - let a = 1.0; - if (a == 1.0) { + let b = 1.0; + if (b == 1.0) { let a = true; } - let test = a == 2.0; + let test = b == 2.0; } fn loopLexicalScope(a: bool) { - let a = 1.0; + let b = 1.0; loop { let a = true; } - let test = a == 2.0; + let test = b == 2.0; } fn forLexicalScope(a: f32) { - let a = false; + let b = false; for (var a = 0; a < 1; a++) { - let a = 3.0; + let b = 3.0; } - let test = a == true; + let test = b == true; } fn whileLexicalScope(a: i32) { while (a > 2) { - let a = false; + let b = false; } let test = a == 1; } diff --git a/tests/in/operators.wgsl b/tests/in/operators.wgsl index 1f6155397b..736fa41cc9 100644 --- a/tests/in/operators.wgsl +++ b/tests/in/operators.wgsl @@ -1,8 +1,7 @@ -//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); +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/skybox.wgsl b/tests/in/skybox.wgsl index f4cc37a44b..4c6a68a120 100644 --- a/tests/in/skybox.wgsl +++ b/tests/in/skybox.wgsl @@ -22,7 +22,7 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { 1.0, ); - let inv_model_view = transpose(mat3x3(r_data.view.x.xyz, r_data.view.y.xyz, r_data.view.z.xyz)); + let inv_model_view = transpose(mat3x3(r_data.view[0].xyz, r_data.view[1].xyz, r_data.view[2].xyz)); let unprojected = r_data.proj_inv * pos; return VertexOutput(pos, inv_model_view * unprojected.xyz); } diff --git a/tests/out/analysis/collatz.info.ron b/tests/out/analysis/collatz.info.ron index cba89d5768..f00ceb4ddf 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(32), requirements: ( bits: 0, ), @@ -28,36 +28,18 @@ 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, ), ), - ref_count: 7, + ref_count: 1, assignable_global: None, ty: Value(Pointer( base: 1, @@ -71,13 +53,27 @@ bits: 0, ), ), - ref_count: 0, + ref_count: 1, assignable_global: None, ty: Value(Scalar( kind: Uint, width: 4, )), ), + ( + uniformity: ( + non_uniform_result: Some(4), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), ( uniformity: ( non_uniform_result: Some(5), @@ -85,7 +81,7 @@ bits: 0, ), ), - ref_count: 3, + ref_count: 1, assignable_global: None, ty: Value(Pointer( base: 1, @@ -94,7 +90,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(5), requirements: ( bits: 0, ), @@ -119,7 +115,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(5), requirements: ( bits: 0, ), @@ -133,7 +129,21 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(9), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(9), requirements: ( bits: 0, ), @@ -158,7 +168,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(9), requirements: ( bits: 0, ), @@ -183,7 +193,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(9), requirements: ( bits: 0, ), @@ -197,7 +207,21 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(15), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(15), requirements: ( bits: 0, ), @@ -222,7 +246,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(15), requirements: ( bits: 0, ), @@ -231,6 +255,20 @@ assignable_global: None, ty: Handle(1), ), + ( + uniformity: ( + non_uniform_result: Some(19), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), ( uniformity: ( non_uniform_result: None, @@ -247,7 +285,21 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(21), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(21), requirements: ( bits: 0, ), @@ -258,7 +310,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(21), requirements: ( bits: 0, ), @@ -283,7 +335,7 @@ ), ( uniformity: ( - non_uniform_result: Some(3), + non_uniform_result: Some(21), requirements: ( bits: 0, ), @@ -294,7 +346,35 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(26), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(27), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(27), requirements: ( bits: 0, ), @@ -319,7 +399,7 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(27), requirements: ( bits: 0, ), @@ -330,7 +410,35 @@ ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(31), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(32), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Value(Pointer( + base: 1, + space: Function, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(32), requirements: ( bits: 0, ), @@ -352,7 +460,7 @@ bits: 7, ), uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(32), requirements: ( bits: 0, ), @@ -367,12 +475,23 @@ expressions: [ ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(32), requirements: ( bits: 0, ), ), - ref_count: 2, + ref_count: 1, + assignable_global: None, + ty: Handle(1), + ), + ( + uniformity: ( + non_uniform_result: Some(2), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, assignable_global: Some(1), ty: Value(Pointer( base: 3, @@ -390,17 +509,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 +522,18 @@ ), ( uniformity: ( - non_uniform_result: Some(2), + non_uniform_result: Some(4), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: None, + ty: Handle(4), + ), + ( + uniformity: ( + non_uniform_result: Some(4), requirements: ( bits: 0, ), @@ -428,7 +547,7 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(2), requirements: ( bits: 0, ), @@ -446,39 +565,36 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(2), requirements: ( bits: 0, ), ), ref_count: 1, - assignable_global: Some(1), - ty: Value(Pointer( - base: 2, - space: Storage( - access: ( - bits: 3, - ), - ), - )), + assignable_global: None, + ty: Handle(1), ), ( uniformity: ( - non_uniform_result: Some(2), + non_uniform_result: Some(8), requirements: ( bits: 0, ), ), ref_count: 1, - assignable_global: None, - ty: Value(Scalar( - kind: Uint, - width: 4, + assignable_global: Some(1), + ty: Value(Pointer( + base: 3, + space: Storage( + access: ( + bits: 3, + ), + ), )), ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(8), requirements: ( bits: 0, ), @@ -486,7 +602,7 @@ ref_count: 1, assignable_global: Some(1), ty: Value(Pointer( - base: 1, + base: 2, space: Storage( access: ( bits: 3, @@ -496,25 +612,46 @@ ), ( uniformity: ( - non_uniform_result: Some(1), + non_uniform_result: Some(10), requirements: ( bits: 0, ), ), ref_count: 1, assignable_global: None, - ty: Handle(1), + ty: Handle(4), ), ( uniformity: ( - non_uniform_result: Some(5), + non_uniform_result: Some(10), requirements: ( bits: 0, ), ), ref_count: 1, assignable_global: None, - ty: Handle(1), + ty: Value(Scalar( + kind: Uint, + width: 4, + )), + ), + ( + uniformity: ( + non_uniform_result: Some(8), + requirements: ( + bits: 0, + ), + ), + ref_count: 1, + assignable_global: Some(1), + ty: Value(Pointer( + base: 1, + space: Storage( + access: ( + bits: 3, + ), + ), + )), ), ], sampling: [], diff --git a/tests/out/dot/quad.dot b/tests/out/dot/quad.dot index c4e242b3ae..68dad3e635 100644 --- a/tests/out/dot/quad.dot +++ b/tests/out/dot/quad.dot @@ -7,54 +7,55 @@ 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[1]" ] + ep0_e1 [ fillcolor="#ffffb3" label="[2] Constant" ] + ep0_e2 [ color="#8dd3c7" label="[3] Argument[0]" ] ep0_e3 [ color="#fdb462" label="[4] Multiply" ] - ep0_e1 -> ep0_e3 [ label="right" ] - ep0_e0 -> ep0_e3 [ label="left" ] + ep0_e2 -> ep0_e3 [ label="right" ] + ep0_e1 -> 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_e0 ep0_e6 } -> ep0_e7 ep0_s0 [ shape=square label="Root" ] ep0_s1 [ shape=square label="Emit" ] ep0_s2 [ shape=square label="Emit" ] - ep0_s3 [ shape=square label="Return" ] + ep0_s3 [ shape=square label="Emit" ] + ep0_s4 [ shape=square label="Return" ] ep0_s0 -> ep0_s1 [ arrowhead=tee label="" ] ep0_s1 -> ep0_s2 [ arrowhead=tee label="" ] ep0_s2 -> ep0_s3 [ arrowhead=tee label="" ] - ep0_e7 -> ep0_s3 [ label="value" ] + ep0_s3 -> ep0_s4 [ arrowhead=tee label="" ] + ep0_e7 -> ep0_s4 [ label="value" ] ep0_s1 -> ep0_e3 [ style=dotted ] ep0_s2 -> ep0_e6 [ style=dotted ] - ep0_s2 -> ep0_e7 [ style=dotted ] + ep0_s3 -> ep0_e7 [ style=dotted ] } subgraph cluster_ep1 { label="Fragment/'frag_main'" node [ style=filled ] - ep1_e0 [ fillcolor="#ffffb3" label="[1] Constant" ] + ep1_e0 [ color="#ffffb3" label="[1] Global" ] + g0 -> ep1_e0 [fillcolor=gray] ep1_e1 [ color="#ffffb3" label="[2] Global" ] g1 -> 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" ] + ep1_e2 [ color="#8dd3c7" label="[3] Argument[0]" ] + ep1_e3 [ color="#80b1d3" label="[4] ImageSample" ] + ep1_e1 -> ep1_e3 [ label="sampler" ] + ep1_e0 -> ep1_e3 [ label="image" ] + ep1_e2 -> 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" ] @@ -65,7 +66,8 @@ digraph Module { ep1_s7 [ shape=square label="Node" ] ep1_s8 [ shape=square label="Merge" ] ep1_s9 [ shape=square label="Emit" ] - ep1_s10 [ shape=square label="Return" ] + ep1_s10 [ shape=square label="Emit" ] + ep1_s11 [ shape=square label="Return" ] ep1_s0 -> ep1_s1 [ arrowhead=tee label="" ] ep1_s1 -> ep1_s2 [ arrowhead=tee label="" ] ep1_s2 -> ep1_s3 [ arrowhead=tee label="" ] @@ -77,34 +79,30 @@ 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_s9 -> ep1_e8 [ style=dotted ] - ep1_s9 -> ep1_e9 [ style=dotted ] + ep1_s10 -> ep1_s11 [ arrowhead=tee label="" ] + ep1_e6 -> ep1_s4 [ label="condition" ] + ep1_e8 -> ep1_s11 [ 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_s10 -> ep1_e8 [ 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..5bf775ee6d 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 _e6 = atomicAdd(_group_0_binding_0_cs.atom, 5); + tmp = _e6; + int _e11 = atomicAdd(_group_0_binding_0_cs.atom, -5); + tmp = _e11; int _e16 = atomicAnd(_group_0_binding_0_cs.atom, 5); tmp = _e16; - 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 _e21 = atomicOr(_group_0_binding_0_cs.atom, 5); + tmp = _e21; + int _e26 = atomicXor(_group_0_binding_0_cs.atom, 5); + tmp = _e26; + int _e31 = atomicMin(_group_0_binding_0_cs.atom, 5); tmp = _e31; + int _e36 = atomicMax(_group_0_binding_0_cs.atom, 5); + tmp = _e36; + int _e41 = atomicExchange(_group_0_binding_0_cs.atom, 5); + tmp = _e41; _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..b5a5f11443 100644 --- a/tests/out/glsl/access.foo_frag.Fragment.glsl +++ b/tests/out/glsl/access.foo_frag.Fragment.glsl @@ -25,13 +25,13 @@ layout(std430) buffer Bar_block_0Fragment { AlignedWrapper data[]; } _group_0_binding_0_fs; -layout(std430) buffer type_11_block_1Fragment { ivec2 _group_0_binding_2_fs; }; +layout(std430) buffer vec2i32__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..8819edb108 100644 --- a/tests/out/glsl/access.foo_vert.Vertex.glsl +++ b/tests/out/glsl/access.foo_vert.Vertex.glsl @@ -27,86 +27,90 @@ layout(std430) buffer Bar_block_0Vertex { uniform Baz_block_1Vertex { Baz _group_0_binding_1_vs; }; -layout(std430) buffer type_11_block_2Vertex { ivec2 _group_0_binding_2_vs; }; +layout(std430) buffer vec2i32__block_2Vertex { ivec2 _group_0_binding_2_vs; }; 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 _e3 = idx; + idx = (_e3 - 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 _e17 = idx; + vec2 unnamed_2 = _group_0_binding_1_vs.m[_e17]; 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]; + float unnamed_4 = _group_0_binding_1_vs.m[0][_e32]; int _e38 = idx; - int _e40 = idx; - float unnamed_6 = _group_0_binding_1_vs.m[_e38][_e40]; - t = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); - int _e52 = idx; - idx = (_e52 + 1); + float unnamed_5 = _group_0_binding_1_vs.m[_e38][1]; + int _e46 = idx; + int _e49 = idx; + float unnamed_6 = _group_0_binding_1_vs.m[_e46][_e49]; + Baz t_2 = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); + t = t_2; + int _e62 = idx; + idx = (_e62 + 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 _e85 = idx; + t.m[_e85] = 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 _e99 = idx; + t.m[0][_e99] = 20.0; + int _e105 = idx; + t.m[_e105][1] = 30.0; + int _e113 = idx; + int _e116 = idx; + t.m[_e113][_e116] = 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 _e3 = idx_1; + idx_1 = (_e3 - 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 _e26 = idx_1; + vec2 unnamed_10 = _group_0_binding_3_vs.am[0][_e26]; 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]; - 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 _e45 = idx_1; + float unnamed_12 = _group_0_binding_3_vs.am[0][0][_e45]; + int _e53 = idx_1; + float unnamed_13 = _group_0_binding_3_vs.am[0][_e53][1]; int _e63 = idx_1; - idx_1 = (_e63 + 1); + int _e66 = idx_1; + float unnamed_14 = _group_0_binding_3_vs.am[0][_e63][_e66]; + MatCx2InArray t_3 = 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)))); + t_1 = t_3; + int _e73 = idx_1; + idx_1 = (_e73 + 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); - 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; + t_1.am[0][_e107] = vec2(90.0); + t_1.am[0][0][1] = 10.0; + int _e125 = idx_1; + t_1.am[0][0][_e125] = 20.0; + int _e133 = idx_1; + t_1.am[0][_e133][1] = 30.0; + int _e143 = idx_1; + int _e146 = idx_1; + t_1.am[0][_e143][_e146] = 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 +125,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 d[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 +135,13 @@ 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 _e35 = read_from_private(foo); + int d_1[5] = int[5](a_1, int(b), 3, 4, 5); + d = d_1; + d[(vi + 1u)] = 42; + int value = d[vi]; + float _e53 = 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/bitcast.main.Compute.glsl b/tests/out/glsl/bitcast.main.Compute.glsl index 215aef8a58..cf90849a96 100644 --- a/tests/out/glsl/bitcast.main.Compute.glsl +++ b/tests/out/glsl/bitcast.main.Compute.glsl @@ -16,33 +16,42 @@ void main() { vec2 f2_ = vec2(0.0); vec3 f3_ = vec3(0.0); vec4 f4_ = vec4(0.0); - i2_ = ivec2(0); - i3_ = ivec3(0); - i4_ = ivec4(0); - u2_ = uvec2(0u); - u3_ = uvec3(0u); - u4_ = uvec4(0u); - f2_ = vec2(0.0); - f3_ = vec3(0.0); - f4_ = vec4(0.0); - ivec2 _e27 = i2_; - u2_ = uvec2(_e27); - ivec3 _e29 = i3_; - u3_ = uvec3(_e29); - ivec4 _e31 = i4_; - u4_ = uvec4(_e31); - uvec2 _e33 = u2_; - i2_ = ivec2(_e33); - uvec3 _e35 = u3_; - i3_ = ivec3(_e35); - uvec4 _e37 = u4_; - i4_ = ivec4(_e37); - ivec2 _e39 = i2_; - f2_ = intBitsToFloat(_e39); - ivec3 _e41 = i3_; - f3_ = intBitsToFloat(_e41); - ivec4 _e43 = i4_; - f4_ = intBitsToFloat(_e43); + ivec2 i2_1 = ivec2(0); + i2_ = i2_1; + ivec3 i3_1 = ivec3(0); + i3_ = i3_1; + ivec4 i4_1 = ivec4(0); + i4_ = i4_1; + uvec2 u2_1 = uvec2(0u); + u2_ = u2_1; + uvec3 u3_1 = uvec3(0u); + u3_ = u3_1; + uvec4 u4_1 = uvec4(0u); + u4_ = u4_1; + vec2 f2_1 = vec2(0.0); + f2_ = f2_1; + vec3 f3_1 = vec3(0.0); + f3_ = f3_1; + vec4 f4_1 = vec4(0.0); + f4_ = f4_1; + ivec2 _e28 = i2_; + u2_ = uvec2(_e28); + ivec3 _e32 = i3_; + u3_ = uvec3(_e32); + ivec4 _e36 = i4_; + u4_ = uvec4(_e36); + uvec2 _e40 = u2_; + i2_ = ivec2(_e40); + uvec3 _e44 = u3_; + i3_ = ivec3(_e44); + uvec4 _e48 = u4_; + i4_ = ivec4(_e48); + ivec2 _e52 = i2_; + f2_ = intBitsToFloat(_e52); + ivec3 _e56 = i3_; + f3_ = intBitsToFloat(_e56); + ivec4 _e60 = i4_; + f4_ = intBitsToFloat(_e60); return; } diff --git a/tests/out/glsl/bits.main.Compute.glsl b/tests/out/glsl/bits.main.Compute.glsl index 0cdc8906a7..04d06780f3 100644 --- a/tests/out/glsl/bits.main.Compute.glsl +++ b/tests/out/glsl/bits.main.Compute.glsl @@ -17,114 +17,124 @@ void main() { uvec4 u4_ = uvec4(0u); vec2 f2_ = vec2(0.0); vec4 f4_ = vec4(0.0); - i2_ = ivec2(0); - i3_ = ivec3(0); - i4_ = ivec4(0); - u2_ = uvec2(0u); - u3_ = uvec3(0u); - u4_ = uvec4(0u); - f2_ = vec2(0.0); - f4_ = vec4(0.0); - vec4 _e28 = f4_; - u = packSnorm4x8(_e28); - vec4 _e30 = f4_; - u = packUnorm4x8(_e30); - vec2 _e32 = f2_; - u = packSnorm2x16(_e32); - vec2 _e34 = f2_; - u = packUnorm2x16(_e34); - vec2 _e36 = f2_; - u = packHalf2x16(_e36); - uint _e38 = u; - f4_ = unpackSnorm4x8(_e38); - uint _e40 = u; - f4_ = unpackUnorm4x8(_e40); - uint _e42 = u; - f2_ = unpackSnorm2x16(_e42); - uint _e44 = u; - f2_ = unpackUnorm2x16(_e44); - uint _e46 = u; - f2_ = unpackHalf2x16(_e46); - int _e48 = i; - int _e49 = i; - i = bitfieldInsert(_e48, _e49, int(5u), int(10u)); - ivec2 _e53 = i2_; - ivec2 _e54 = i2_; - i2_ = bitfieldInsert(_e53, _e54, int(5u), int(10u)); - ivec3 _e58 = i3_; - ivec3 _e59 = i3_; - i3_ = bitfieldInsert(_e58, _e59, int(5u), int(10u)); - ivec4 _e63 = i4_; - ivec4 _e64 = i4_; - i4_ = bitfieldInsert(_e63, _e64, int(5u), int(10u)); - uint _e68 = u; - uint _e69 = u; - u = bitfieldInsert(_e68, _e69, int(5u), int(10u)); - uvec2 _e73 = u2_; - uvec2 _e74 = u2_; - u2_ = bitfieldInsert(_e73, _e74, int(5u), int(10u)); - uvec3 _e78 = u3_; - uvec3 _e79 = u3_; - u3_ = bitfieldInsert(_e78, _e79, int(5u), int(10u)); - uvec4 _e83 = u4_; - uvec4 _e84 = u4_; - u4_ = bitfieldInsert(_e83, _e84, int(5u), int(10u)); - int _e88 = i; - i = bitfieldExtract(_e88, int(5u), int(10u)); - ivec2 _e92 = i2_; - i2_ = bitfieldExtract(_e92, int(5u), int(10u)); - ivec3 _e96 = i3_; - i3_ = bitfieldExtract(_e96, int(5u), int(10u)); - ivec4 _e100 = i4_; - i4_ = bitfieldExtract(_e100, int(5u), int(10u)); - uint _e104 = u; - u = bitfieldExtract(_e104, int(5u), int(10u)); - uvec2 _e108 = u2_; - u2_ = bitfieldExtract(_e108, int(5u), int(10u)); - uvec3 _e112 = u3_; - u3_ = bitfieldExtract(_e112, int(5u), int(10u)); - uvec4 _e116 = u4_; - u4_ = bitfieldExtract(_e116, int(5u), int(10u)); - int _e120 = i; - i = findLSB(_e120); - uvec2 _e122 = u2_; - u2_ = uvec2(findLSB(_e122)); - ivec3 _e124 = i3_; - i3_ = findMSB(_e124); - uint _e126 = u; - u = uint(findMSB(_e126)); - int _e128 = i; - i = bitCount(_e128); - ivec2 _e130 = i2_; - i2_ = bitCount(_e130); - ivec3 _e132 = i3_; - i3_ = bitCount(_e132); - ivec4 _e134 = i4_; - i4_ = bitCount(_e134); - uint _e136 = u; - u = uint(bitCount(_e136)); - uvec2 _e138 = u2_; - u2_ = uvec2(bitCount(_e138)); - uvec3 _e140 = u3_; - u3_ = uvec3(bitCount(_e140)); - uvec4 _e142 = u4_; - u4_ = uvec4(bitCount(_e142)); - int _e144 = i; - i = bitfieldReverse(_e144); - ivec2 _e146 = i2_; - i2_ = bitfieldReverse(_e146); - ivec3 _e148 = i3_; - i3_ = bitfieldReverse(_e148); - ivec4 _e150 = i4_; - i4_ = bitfieldReverse(_e150); - uint _e152 = u; - u = bitfieldReverse(_e152); - uvec2 _e154 = u2_; - u2_ = bitfieldReverse(_e154); - uvec3 _e156 = u3_; - u3_ = bitfieldReverse(_e156); - uvec4 _e158 = u4_; - u4_ = bitfieldReverse(_e158); + i = 0; + ivec2 i2_1 = ivec2(0); + i2_ = i2_1; + ivec3 i3_1 = ivec3(0); + i3_ = i3_1; + ivec4 i4_1 = ivec4(0); + i4_ = i4_1; + u = 0u; + uvec2 u2_1 = uvec2(0u); + u2_ = u2_1; + uvec3 u3_1 = uvec3(0u); + u3_ = u3_1; + uvec4 u4_1 = uvec4(0u); + u4_ = u4_1; + vec2 f2_1 = vec2(0.0); + f2_ = f2_1; + vec4 f4_1 = vec4(0.0); + f4_ = f4_1; + vec4 _e29 = f4_; + u = packSnorm4x8(_e29); + vec4 _e33 = f4_; + u = packUnorm4x8(_e33); + vec2 _e37 = f2_; + u = packSnorm2x16(_e37); + vec2 _e41 = f2_; + u = packUnorm2x16(_e41); + vec2 _e45 = f2_; + u = packHalf2x16(_e45); + uint _e49 = u; + f4_ = unpackSnorm4x8(_e49); + uint _e53 = u; + f4_ = unpackUnorm4x8(_e53); + uint _e57 = u; + f2_ = unpackSnorm2x16(_e57); + uint _e61 = u; + f2_ = unpackUnorm2x16(_e61); + uint _e65 = u; + f2_ = unpackHalf2x16(_e65); + int _e69 = i; + int _e71 = i; + i = bitfieldInsert(_e69, _e71, int(5u), int(10u)); + ivec2 _e77 = i2_; + ivec2 _e79 = i2_; + i2_ = bitfieldInsert(_e77, _e79, int(5u), int(10u)); + ivec3 _e85 = i3_; + ivec3 _e87 = i3_; + i3_ = bitfieldInsert(_e85, _e87, int(5u), int(10u)); + ivec4 _e93 = i4_; + ivec4 _e95 = i4_; + i4_ = bitfieldInsert(_e93, _e95, int(5u), int(10u)); + uint _e101 = u; + uint _e103 = u; + u = bitfieldInsert(_e101, _e103, int(5u), int(10u)); + uvec2 _e109 = u2_; + uvec2 _e111 = u2_; + u2_ = bitfieldInsert(_e109, _e111, int(5u), int(10u)); + uvec3 _e117 = u3_; + uvec3 _e119 = u3_; + u3_ = bitfieldInsert(_e117, _e119, int(5u), int(10u)); + uvec4 _e125 = u4_; + uvec4 _e127 = u4_; + u4_ = bitfieldInsert(_e125, _e127, int(5u), int(10u)); + int _e133 = i; + i = bitfieldExtract(_e133, int(5u), int(10u)); + ivec2 _e139 = i2_; + i2_ = bitfieldExtract(_e139, int(5u), int(10u)); + ivec3 _e145 = i3_; + i3_ = bitfieldExtract(_e145, int(5u), int(10u)); + ivec4 _e151 = i4_; + i4_ = bitfieldExtract(_e151, int(5u), int(10u)); + uint _e157 = u; + u = bitfieldExtract(_e157, int(5u), int(10u)); + uvec2 _e163 = u2_; + u2_ = bitfieldExtract(_e163, int(5u), int(10u)); + uvec3 _e169 = u3_; + u3_ = bitfieldExtract(_e169, int(5u), int(10u)); + uvec4 _e175 = u4_; + u4_ = bitfieldExtract(_e175, int(5u), int(10u)); + int _e181 = i; + i = findLSB(_e181); + uvec2 _e185 = u2_; + u2_ = uvec2(findLSB(_e185)); + ivec3 _e189 = i3_; + i3_ = findMSB(_e189); + uint _e193 = u; + u = uint(findMSB(_e193)); + int _e197 = i; + i = bitCount(_e197); + ivec2 _e201 = i2_; + i2_ = bitCount(_e201); + ivec3 _e205 = i3_; + i3_ = bitCount(_e205); + ivec4 _e209 = i4_; + i4_ = bitCount(_e209); + uint _e213 = u; + u = uint(bitCount(_e213)); + uvec2 _e217 = u2_; + u2_ = uvec2(bitCount(_e217)); + uvec3 _e221 = u3_; + u3_ = uvec3(bitCount(_e221)); + uvec4 _e225 = u4_; + u4_ = uvec4(bitCount(_e225)); + int _e229 = i; + i = bitfieldReverse(_e229); + ivec2 _e233 = i2_; + i2_ = bitfieldReverse(_e233); + ivec3 _e237 = i3_; + i3_ = bitfieldReverse(_e237); + ivec4 _e241 = i4_; + i4_ = bitfieldReverse(_e241); + uint _e245 = u; + u = bitfieldReverse(_e245); + uvec2 _e249 = u2_; + u2_ = bitfieldReverse(_e249); + uvec3 _e253 = u3_; + u3_ = bitfieldReverse(_e253); + uvec4 _e257 = u4_; + u4_ = bitfieldReverse(_e257); return; } diff --git a/tests/out/glsl/boids.main.Compute.glsl b/tests/out/glsl/boids.main.Compute.glsl index 8253d50d94..8fb821c051 100644 --- a/tests/out/glsl/boids.main.Compute.glsl +++ b/tests/out/glsl/boids.main.Compute.glsl @@ -45,112 +45,118 @@ 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; - cMass = vec2(0.0, 0.0); - cVel = vec2(0.0, 0.0); - colVel = vec2(0.0, 0.0); + vec2 vPos_1 = _group_0_binding_1_cs.particles[index].pos; + vPos = vPos_1; + vec2 vVel_1 = _group_0_binding_1_cs.particles[index].vel; + vVel = vVel_1; + vec2 cMass_1 = vec2(0.0, 0.0); + cMass = cMass_1; + vec2 cVel_1 = vec2(0.0, 0.0); + cVel = cVel_1; + vec2 colVel_1 = vec2(0.0, 0.0); + colVel = colVel_1; + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e86 = i; - i = (_e86 + 1u); + uint _e116 = i; + i = (_e116 + 1u); } loop_init = false; - uint _e37 = i; - if ((_e37 >= 1500u)) { + uint _e35 = i; + if ((_e35 >= 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 _e44 = i; + vec2 _e47 = _group_0_binding_1_cs.particles[_e44].pos; + pos = _e47; + uint _e52 = i; + vec2 _e55 = _group_0_binding_1_cs.particles[_e52].vel; + vel = _e55; + vec2 _e58 = pos; + vec2 _e60 = vPos; + float _e64 = _group_0_binding_0_cs.rule1Distance; + if ((distance(_e58, _e60) < _e64)) { + vec2 _e67 = cMass; + vec2 _e69 = pos; + cMass = (_e67 + _e69); + int _e73 = cMassCount; + cMassCount = (_e73 + 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 _e78 = pos; + vec2 _e80 = vPos; + float _e84 = _group_0_binding_0_cs.rule2Distance; + if ((distance(_e78, _e80) < _e84)) { + vec2 _e87 = colVel; + vec2 _e89 = pos; + vec2 _e91 = vPos; + colVel = (_e87 - (_e89 - _e91)); } - 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 _e96 = pos; + vec2 _e98 = vPos; + float _e102 = _group_0_binding_0_cs.rule3Distance; + if ((distance(_e96, _e98) < _e102)) { + vec2 _e105 = cVel; + vec2 _e107 = vel; + cVel = (_e105 + _e107); + int _e111 = cVelCount; + cVelCount = (_e111 + 1); } } - int _e89 = cMassCount; - if ((_e89 > 0)) { - vec2 _e92 = cMass; - int _e93 = cMassCount; - vec2 _e97 = vPos; - cMass = ((_e92 / vec2(float(_e93))) - _e97); + int _e121 = cMassCount; + if ((_e121 > 0)) { + vec2 _e125 = cMass; + int _e127 = cMassCount; + vec2 _e132 = vPos; + cMass = ((_e125 / vec2(float(_e127))) - _e132); } - int _e99 = cVelCount; - if ((_e99 > 0)) { - vec2 _e102 = cVel; - int _e103 = cVelCount; - cVel = (_e102 / vec2(float(_e103))); + int _e136 = cVelCount; + if ((_e136 > 0)) { + vec2 _e140 = cVel; + int _e142 = cVelCount; + cVel = (_e140 / vec2(float(_e142))); } - 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 _e148 = vVel; + vec2 _e150 = cMass; + float _e153 = _group_0_binding_0_cs.rule1Scale; + vec2 _e157 = colVel; + float _e160 = _group_0_binding_0_cs.rule2Scale; + vec2 _e164 = cVel; + float _e167 = _group_0_binding_0_cs.rule3Scale; + vVel = (((_e148 + (_e150 * _e153)) + (_e157 * _e160)) + (_e164 * _e167)); + vec2 _e172 = vVel; + vec2 _e175 = vVel; + vVel = (normalize(_e172) * clamp(length(_e175), 0.0, 0.1)); + vec2 _e183 = vPos; + vec2 _e185 = vVel; + float _e188 = _group_0_binding_0_cs.deltaT; + vPos = (_e183 + (_e185 * _e188)); + float _e194 = vPos.x; + if ((_e194 < (-1.0))) { vPos.x = 1.0; } - float _e144 = vPos.x; - if ((_e144 > 1.0)) { - vPos.x = -1.0; + float _e203 = vPos.x; + if ((_e203 > 1.0)) { + vPos.x = (-1.0); } - float _e150 = vPos.y; - if ((_e150 < -1.0)) { + float _e212 = vPos.y; + if ((_e212 < (-1.0))) { vPos.y = 1.0; } - float _e156 = vPos.y; - if ((_e156 > 1.0)) { - vPos.y = -1.0; + float _e221 = vPos.y; + if ((_e221 > 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 _e229 = vPos; + _group_0_binding_2_cs.particles[index].pos = _e229; + vec2 _e235 = vVel; + _group_0_binding_2_cs.particles[index].vel = _e235; 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..db76548fea 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 _e0 = test_textureLoad_1d(0, 0); + vec4 _e3 = test_textureLoad_2d(ivec2(0, 0), 0); + vec4 _e6 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); + vec4 _e10 = test_textureLoad_3d(ivec3(0, 0, 0), 0); + vec4 _e13 = 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..7f0da1fd10 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 _e0 = test_textureLoad_1d(0, 0); + vec4 _e3 = test_textureLoad_2d(ivec2(0, 0), 0); + vec4 _e6 = test_textureLoad_2d_array(ivec2(0, 0), 0, 0); + vec4 _e10 = test_textureLoad_3d(ivec3(0, 0, 0), 0); + vec4 _e13 = 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/break-if.main.Compute.glsl b/tests/out/glsl/break-if.main.Compute.glsl index 025156af7b..9e58c15d16 100644 --- a/tests/out/glsl/break-if.main.Compute.glsl +++ b/tests/out/glsl/break-if.main.Compute.glsl @@ -22,14 +22,15 @@ void breakIfEmpty() { void breakIfEmptyBody(bool a) { bool b = false; bool c = false; + bool _e9 = c; + bool unnamed = (a == _e9); bool loop_init_1 = true; while(true) { if (!loop_init_1) { b = a; - bool _e2 = b; - c = (a != _e2); - bool _e5 = c; - bool unnamed = (a == _e5); + bool _e4 = b; + bool c_1 = (a != _e4); + c = c_1; if (unnamed) { break; } @@ -42,19 +43,20 @@ void breakIfEmptyBody(bool a) { void breakIf(bool a_1) { bool d = false; bool e = false; + bool _e9 = e; + bool unnamed_1 = (a_1 == _e9); bool loop_init_2 = true; while(true) { if (!loop_init_2) { - bool _e5 = e; - bool unnamed_1 = (a_1 == _e5); if (unnamed_1) { break; } } loop_init_2 = false; d = a_1; - bool _e2 = d; - e = (a_1 != _e2); + bool _e4 = d; + bool e_1 = (a_1 != _e4); + e = e_1; } return; } diff --git a/tests/out/glsl/control-flow.main.Compute.glsl b/tests/out/glsl/control-flow.main.Compute.glsl index 5446e36098..9c4692e7a1 100644 --- a/tests/out/glsl/control-flow.main.Compute.glsl +++ b/tests/out/glsl/control-flow.main.Compute.glsl @@ -57,10 +57,10 @@ void main() { break; case 3: pos = 2; - /* fallthrough */ + break; case 4: pos = 3; - /* fallthrough */ + break; default: pos = 4; break; @@ -71,8 +71,8 @@ void main() { default: break; } - int _e11 = pos; - switch(_e11) { + int _e17 = pos; + switch(_e17) { case 1: pos = 0; break; @@ -81,7 +81,7 @@ void main() { return; case 3: pos = 2; - /* fallthrough */ + return; case 4: return; default: diff --git a/tests/out/glsl/globals.main.Compute.glsl b/tests/out/glsl/globals.main.Compute.glsl index 0d5cb797bf..b8605454a3 100644 --- a/tests/out/glsl/globals.main.Compute.glsl +++ b/tests/out/glsl/globals.main.Compute.glsl @@ -15,17 +15,17 @@ shared uint at_1; layout(std430) buffer Foo_block_0Compute { Foo _group_0_binding_1_cs; }; -layout(std430) readonly buffer type_6_block_1Compute { vec2 _group_0_binding_2_cs[]; }; +layout(std430) readonly buffer arrayvec2f32__block_1Compute { vec2 _group_0_binding_2_cs[]; }; -uniform type_8_block_2Compute { vec4 _group_0_binding_3_cs[20]; }; +uniform arrayvec4f3220__block_2Compute { vec4 _group_0_binding_3_cs[20]; }; -uniform type_4_block_3Compute { vec3 _group_0_binding_4_cs; }; +uniform vec3f32__block_3Compute { vec3 _group_0_binding_4_cs; }; -uniform type_9_block_4Compute { mat3x2 _group_0_binding_5_cs; }; +uniform mat3x2f32__block_4Compute { mat3x2 _group_0_binding_5_cs; }; -uniform type_12_block_5Compute { mat2x4 _group_0_binding_6_cs[2][2]; }; +uniform arrayarraymat2x4f3222__block_5Compute { mat2x4 _group_0_binding_6_cs[2][2]; }; -uniform type_15_block_6Compute { mat4x2 _group_0_binding_7_cs[2][2]; }; +uniform arrayarraymat4x2f3222__block_6Compute { mat4x2 _group_0_binding_7_cs[2][2]; }; void test_msl_packed_vec3_as_arg(vec3 arg) { @@ -33,12 +33,13 @@ 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; + int _e18 = idx; + _group_0_binding_1_cs.v3_[_e18] = 3.0; Foo data = _group_0_binding_1_cs; vec3 unnamed = data.v3_; vec2 unnamed_1 = data.v3_.zx; @@ -50,26 +51,28 @@ void test_msl_packed_vec3_() { } void main() { - float Foo_1 = 1.0; - bool at = true; + float Foo_1 = 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; - 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; + mat4x2 _e5 = _group_0_binding_7_cs[0][0]; + vec4 _e13 = _group_0_binding_6_cs[0][0][0]; + wg[7] = (_e5 * _e13).x; + mat3x2 _e20 = _group_0_binding_5_cs; + vec3 _e22 = _group_0_binding_4_cs; + wg[6] = (_e20 * _e22).x; + float _e32 = _group_0_binding_2_cs[1].y; + wg[5] = _e32; + float _e40 = _group_0_binding_3_cs[0].w; + wg[4] = _e40; + float _e46 = _group_0_binding_1_cs.v1_; + wg[3] = _e46; + float _e53 = _group_0_binding_1_cs.v3_.x; + wg[2] = _e53; _group_0_binding_1_cs.v1_ = 4.0; wg[1] = float(uint(_group_0_binding_2_cs.length())); at_1 = 2u; + Foo_1 = 1.0; + at = true; return; } diff --git a/tests/out/glsl/image.texture_sample.Fragment.glsl b/tests/out/glsl/image.texture_sample.Fragment.glsl index 5ebec0fc45..90159fa957 100644 --- a/tests/out/glsl/image.texture_sample.Fragment.glsl +++ b/tests/out/glsl/image.texture_sample.Fragment.glsl @@ -15,8 +15,8 @@ void main() { vec4 s1d = texture(_group_0_binding_0_fs, vec2(tc.x, 0.0)); vec4 s2d = texture(_group_0_binding_1_fs, vec2(tc)); vec4 s2d_offset = textureOffset(_group_0_binding_1_fs, vec2(tc), ivec2(3, 1)); - vec4 s2d_level = textureLod(_group_0_binding_1_fs, vec2(tc), 2.299999952316284); - vec4 s2d_level_offset = textureLodOffset(_group_0_binding_1_fs, vec2(tc), 2.299999952316284, ivec2(3, 1)); + vec4 s2d_level = textureLod(_group_0_binding_1_fs, vec2(tc), 2.3); + vec4 s2d_level_offset = textureLodOffset(_group_0_binding_1_fs, vec2(tc), 2.3, ivec2(3, 1)); vec4 s2d_bias_offset = textureOffset(_group_0_binding_1_fs, vec2(tc), ivec2(3, 1), 2.0); _fs2p_location0 = ((((s1d + s2d) + s2d_offset) + s2d_level) + s2d_level_offset); return; diff --git a/tests/out/glsl/interpolate.vert_main.Vertex.glsl b/tests/out/glsl/interpolate.vert_main.Vertex.glsl index f423a3dc18..0351c92b1e 100644 --- a/tests/out/glsl/interpolate.vert_main.Vertex.glsl +++ b/tests/out/glsl/interpolate.vert_main.Vertex.glsl @@ -27,15 +27,15 @@ void main() { out_.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0); out_.perspective_centroid = 2197.0; out_.perspective_sample = 2744.0; - FragmentInput _e30 = out_; - gl_Position = _e30.position; - _vs2fs_location0 = _e30._flat; - _vs2fs_location1 = _e30._linear; - _vs2fs_location2 = _e30.linear_centroid; - _vs2fs_location3 = _e30.linear_sample; - _vs2fs_location4 = _e30.perspective; - _vs2fs_location5 = _e30.perspective_centroid; - _vs2fs_location6 = _e30.perspective_sample; + FragmentInput _e38 = out_; + gl_Position = _e38.position; + _vs2fs_location0 = _e38._flat; + _vs2fs_location1 = _e38._linear; + _vs2fs_location2 = _e38.linear_centroid; + _vs2fs_location3 = _e38.linear_sample; + _vs2fs_location4 = _e38.perspective; + _vs2fs_location5 = _e38.perspective_centroid; + _vs2fs_location6 = _e38.perspective_sample; return; } diff --git a/tests/out/glsl/operators.main.Compute.glsl b/tests/out/glsl/operators.main.Compute.glsl index 32716658fb..68a2b491a0 100644 --- a/tests/out/glsl/operators.main.Compute.glsl +++ b/tests/out/glsl/operators.main.Compute.glsl @@ -15,7 +15,7 @@ vec4 builtins() { vec4 s2_ = (true ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 0.0)); vec4 s3_ = mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(0.0, 0.0, 0.0, 0.0), bvec4(false, false, false, false)); vec4 m1_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), vec4(0.5, 0.5, 0.5, 0.5)); - vec4 m2_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), 0.10000000149011612); + vec4 m2_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), 0.1); float b1_ = intBitsToFloat(ivec4(1, 1, 1, 1).x); vec4 b2_ = intBitsToFloat(ivec4(1, 1, 1, 1)); ivec4 v_i32_zero = ivec4(vec4(0.0, 0.0, 0.0, 0.0)); @@ -30,13 +30,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 _e15 = a; - a = (_e15 / vec2(4.0)); + vec2 a_3 = vec2(2.0); + a = a_3; + vec2 _e4 = a; + a = (_e4 + vec2(1.0)); + vec2 _e9 = a; + a = (_e9 - vec2(3.0)); + vec2 _e14 = a; + a = (_e14 / vec2(4.0)); vec2 _e19 = a; return _e19; } @@ -60,10 +61,10 @@ float constructors() { float unnamed_6 = float(0.0); uvec2 unnamed_7 = uvec2(uvec2(0u, 0u)); 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; + uvec2 unnamed_9 = uvec2(uvec2(0u, 0u)); + mat2x3 unnamed_10 = mat2x3(mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); + float _e72 = foo.a.x; + return _e72; } void logical() { @@ -78,184 +79,187 @@ void logical() { } void arithmetic() { - ivec2 unnamed_19 = (-ivec2(1)); - vec2 unnamed_20 = (-vec2(1.0)); - int unnamed_21 = (2 + 1); - uint unnamed_22 = (2u + 1u); - float unnamed_23 = (2.0 + 1.0); - ivec2 unnamed_24 = (ivec2(2) + ivec2(1)); - uvec3 unnamed_25 = (uvec3(2u) + uvec3(1u)); - vec4 unnamed_26 = (vec4(2.0) + vec4(1.0)); - int unnamed_27 = (2 - 1); - uint unnamed_28 = (2u - 1u); - float unnamed_29 = (2.0 - 1.0); - ivec2 unnamed_30 = (ivec2(2) - ivec2(1)); - uvec3 unnamed_31 = (uvec3(2u) - uvec3(1u)); - vec4 unnamed_32 = (vec4(2.0) - vec4(1.0)); - int unnamed_33 = (2 * 1); - uint unnamed_34 = (2u * 1u); - float unnamed_35 = (2.0 * 1.0); - ivec2 unnamed_36 = (ivec2(2) * ivec2(1)); - uvec3 unnamed_37 = (uvec3(2u) * uvec3(1u)); - vec4 unnamed_38 = (vec4(2.0) * vec4(1.0)); - int unnamed_39 = (2 / 1); - uint unnamed_40 = (2u / 1u); - float unnamed_41 = (2.0 / 1.0); - ivec2 unnamed_42 = (ivec2(2) / ivec2(1)); - uvec3 unnamed_43 = (uvec3(2u) / uvec3(1u)); - vec4 unnamed_44 = (vec4(2.0) / vec4(1.0)); - int unnamed_45 = (2 % 1); - uint unnamed_46 = (2u % 1u); - float unnamed_47 = (2.0 - 1.0 * trunc(2.0 / 1.0)); - ivec2 unnamed_48 = (ivec2(2) % ivec2(1)); - uvec3 unnamed_49 = (uvec3(2u) % uvec3(1u)); - vec4 unnamed_50 = (vec4(2.0) - vec4(1.0) * trunc(vec4(2.0) / vec4(1.0))); - ivec2 unnamed_51 = (ivec2(2) + ivec2(1)); + float unnamed_19 = (-1.0); + ivec2 unnamed_20 = (-ivec2(1)); + vec2 unnamed_21 = (-vec2(1.0)); + int unnamed_22 = (2 + 1); + uint unnamed_23 = (2u + 1u); + float unnamed_24 = (2.0 + 1.0); + ivec2 unnamed_25 = (ivec2(2) + ivec2(1)); + uvec3 unnamed_26 = (uvec3(2u) + uvec3(1u)); + vec4 unnamed_27 = (vec4(2.0) + vec4(1.0)); + int unnamed_28 = (2 - 1); + uint unnamed_29 = (2u - 1u); + float unnamed_30 = (2.0 - 1.0); + ivec2 unnamed_31 = (ivec2(2) - ivec2(1)); + uvec3 unnamed_32 = (uvec3(2u) - uvec3(1u)); + vec4 unnamed_33 = (vec4(2.0) - vec4(1.0)); + int unnamed_34 = (2 * 1); + uint unnamed_35 = (2u * 1u); + float unnamed_36 = (2.0 * 1.0); + ivec2 unnamed_37 = (ivec2(2) * ivec2(1)); + uvec3 unnamed_38 = (uvec3(2u) * uvec3(1u)); + vec4 unnamed_39 = (vec4(2.0) * vec4(1.0)); + int unnamed_40 = (2 / 1); + uint unnamed_41 = (2u / 1u); + float unnamed_42 = (2.0 / 1.0); + ivec2 unnamed_43 = (ivec2(2) / ivec2(1)); + uvec3 unnamed_44 = (uvec3(2u) / uvec3(1u)); + vec4 unnamed_45 = (vec4(2.0) / vec4(1.0)); + int unnamed_46 = (2 % 1); + uint unnamed_47 = (2u % 1u); + float unnamed_48 = (2.0 - 1.0 * trunc(2.0 / 1.0)); + ivec2 unnamed_49 = (ivec2(2) % ivec2(1)); + uvec3 unnamed_50 = (uvec3(2u) % uvec3(1u)); + vec4 unnamed_51 = (vec4(2.0) - vec4(1.0) * trunc(vec4(2.0) / vec4(1.0))); ivec2 unnamed_52 = (ivec2(2) + ivec2(1)); - uvec2 unnamed_53 = (uvec2(2u) + uvec2(1u)); + ivec2 unnamed_53 = (ivec2(2) + ivec2(1)); uvec2 unnamed_54 = (uvec2(2u) + uvec2(1u)); - vec2 unnamed_55 = (vec2(2.0) + vec2(1.0)); + uvec2 unnamed_55 = (uvec2(2u) + uvec2(1u)); vec2 unnamed_56 = (vec2(2.0) + vec2(1.0)); - ivec2 unnamed_57 = (ivec2(2) - ivec2(1)); + vec2 unnamed_57 = (vec2(2.0) + vec2(1.0)); ivec2 unnamed_58 = (ivec2(2) - ivec2(1)); - uvec2 unnamed_59 = (uvec2(2u) - uvec2(1u)); + ivec2 unnamed_59 = (ivec2(2) - ivec2(1)); uvec2 unnamed_60 = (uvec2(2u) - uvec2(1u)); - vec2 unnamed_61 = (vec2(2.0) - vec2(1.0)); + uvec2 unnamed_61 = (uvec2(2u) - uvec2(1u)); vec2 unnamed_62 = (vec2(2.0) - vec2(1.0)); - ivec2 unnamed_63 = (ivec2(2) * 1); - ivec2 unnamed_64 = (2 * ivec2(1)); - uvec2 unnamed_65 = (uvec2(2u) * 1u); - uvec2 unnamed_66 = (2u * uvec2(1u)); - vec2 unnamed_67 = (vec2(2.0) * 1.0); - vec2 unnamed_68 = (2.0 * vec2(1.0)); - ivec2 unnamed_69 = (ivec2(2) / ivec2(1)); + vec2 unnamed_63 = (vec2(2.0) - vec2(1.0)); + ivec2 unnamed_64 = (ivec2(2) * 1); + ivec2 unnamed_65 = (2 * ivec2(1)); + uvec2 unnamed_66 = (uvec2(2u) * 1u); + uvec2 unnamed_67 = (2u * uvec2(1u)); + vec2 unnamed_68 = (vec2(2.0) * 1.0); + vec2 unnamed_69 = (2.0 * vec2(1.0)); ivec2 unnamed_70 = (ivec2(2) / ivec2(1)); - uvec2 unnamed_71 = (uvec2(2u) / uvec2(1u)); + ivec2 unnamed_71 = (ivec2(2) / ivec2(1)); uvec2 unnamed_72 = (uvec2(2u) / uvec2(1u)); - vec2 unnamed_73 = (vec2(2.0) / vec2(1.0)); + uvec2 unnamed_73 = (uvec2(2u) / uvec2(1u)); vec2 unnamed_74 = (vec2(2.0) / vec2(1.0)); - ivec2 unnamed_75 = (ivec2(2) % ivec2(1)); + vec2 unnamed_75 = (vec2(2.0) / vec2(1.0)); ivec2 unnamed_76 = (ivec2(2) % ivec2(1)); - uvec2 unnamed_77 = (uvec2(2u) % uvec2(1u)); + ivec2 unnamed_77 = (ivec2(2) % ivec2(1)); uvec2 unnamed_78 = (uvec2(2u) % uvec2(1u)); - vec2 unnamed_79 = (vec2(2.0) - vec2(1.0) * trunc(vec2(2.0) / vec2(1.0))); + uvec2 unnamed_79 = (uvec2(2u) % uvec2(1u)); vec2 unnamed_80 = (vec2(2.0) - vec2(1.0) * trunc(vec2(2.0) / vec2(1.0))); - mat3x3 unnamed_81 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) + mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - mat3x3 unnamed_82 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) - mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - mat3x3 unnamed_83 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * 1.0); - mat3x3 unnamed_84 = (2.0 * mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - vec3 unnamed_85 = (mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * vec4(1.0)); - vec4 unnamed_86 = (vec3(2.0) * mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - mat3x3 unnamed_87 = (mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * mat3x4(vec4(0.0, 0.0, 0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0))); + vec2 unnamed_81 = (vec2(2.0) - vec2(1.0) * trunc(vec2(2.0) / vec2(1.0))); + mat3x3 unnamed_82 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) + mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); + mat3x3 unnamed_83 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) - mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); + mat3x3 unnamed_84 = (mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * 1.0); + mat3x3 unnamed_85 = (2.0 * mat3x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); + vec3 unnamed_86 = (mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * vec4(1.0)); + vec4 unnamed_87 = (vec3(2.0) * mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); + mat3x3 unnamed_88 = (mat4x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0)) * mat3x4(vec4(0.0, 0.0, 0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0), vec4(0.0, 0.0, 0.0, 0.0))); } void bit() { - int unnamed_88 = (~1); - uint unnamed_89 = (~1u); - ivec2 unnamed_90 = (~ivec2(1)); - uvec3 unnamed_91 = (~uvec3(1u)); - int unnamed_92 = (2 | 1); - uint unnamed_93 = (2u | 1u); - ivec2 unnamed_94 = (ivec2(2) | ivec2(1)); - uvec3 unnamed_95 = (uvec3(2u) | uvec3(1u)); - int unnamed_96 = (2 & 1); - uint unnamed_97 = (2u & 1u); - ivec2 unnamed_98 = (ivec2(2) & ivec2(1)); - uvec3 unnamed_99 = (uvec3(2u) & uvec3(1u)); - int unnamed_100 = (2 ^ 1); - uint unnamed_101 = (2u ^ 1u); - ivec2 unnamed_102 = (ivec2(2) ^ ivec2(1)); - uvec3 unnamed_103 = (uvec3(2u) ^ uvec3(1u)); - int unnamed_104 = (2 << 1u); - uint unnamed_105 = (2u << 1u); - ivec2 unnamed_106 = (ivec2(2) << uvec2(1u)); - uvec3 unnamed_107 = (uvec3(2u) << uvec3(1u)); - int unnamed_108 = (2 >> 1u); - uint unnamed_109 = (2u >> 1u); - ivec2 unnamed_110 = (ivec2(2) >> uvec2(1u)); - uvec3 unnamed_111 = (uvec3(2u) >> uvec3(1u)); + int unnamed_89 = (~1); + uint unnamed_90 = (~1u); + ivec2 unnamed_91 = (~ivec2(1)); + uvec3 unnamed_92 = (~uvec3(1u)); + int unnamed_93 = (2 | 1); + uint unnamed_94 = (2u | 1u); + ivec2 unnamed_95 = (ivec2(2) | ivec2(1)); + uvec3 unnamed_96 = (uvec3(2u) | uvec3(1u)); + int unnamed_97 = (2 & 1); + uint unnamed_98 = (2u & 1u); + ivec2 unnamed_99 = (ivec2(2) & ivec2(1)); + uvec3 unnamed_100 = (uvec3(2u) & uvec3(1u)); + int unnamed_101 = (2 ^ 1); + uint unnamed_102 = (2u ^ 1u); + ivec2 unnamed_103 = (ivec2(2) ^ ivec2(1)); + uvec3 unnamed_104 = (uvec3(2u) ^ uvec3(1u)); + int unnamed_105 = (2 << 1u); + uint unnamed_106 = (2u << 1u); + ivec2 unnamed_107 = (ivec2(2) << uvec2(1u)); + uvec3 unnamed_108 = (uvec3(2u) << uvec3(1u)); + int unnamed_109 = (2 >> 1u); + uint unnamed_110 = (2u >> 1u); + ivec2 unnamed_111 = (ivec2(2) >> uvec2(1u)); + uvec3 unnamed_112 = (uvec3(2u) >> uvec3(1u)); } void comparison() { - bool unnamed_112 = (2 == 1); - bool unnamed_113 = (2u == 1u); - bool unnamed_114 = (2.0 == 1.0); - bvec2 unnamed_115 = equal(ivec2(2), ivec2(1)); - bvec3 unnamed_116 = equal(uvec3(2u), uvec3(1u)); - bvec4 unnamed_117 = equal(vec4(2.0), vec4(1.0)); - bool unnamed_118 = (2 != 1); - bool unnamed_119 = (2u != 1u); - bool unnamed_120 = (2.0 != 1.0); - bvec2 unnamed_121 = notEqual(ivec2(2), ivec2(1)); - bvec3 unnamed_122 = notEqual(uvec3(2u), uvec3(1u)); - bvec4 unnamed_123 = notEqual(vec4(2.0), vec4(1.0)); - bool unnamed_124 = (2 < 1); - bool unnamed_125 = (2u < 1u); - bool unnamed_126 = (2.0 < 1.0); - bvec2 unnamed_127 = lessThan(ivec2(2), ivec2(1)); - bvec3 unnamed_128 = lessThan(uvec3(2u), uvec3(1u)); - bvec4 unnamed_129 = lessThan(vec4(2.0), vec4(1.0)); - bool unnamed_130 = (2 <= 1); - bool unnamed_131 = (2u <= 1u); - bool unnamed_132 = (2.0 <= 1.0); - bvec2 unnamed_133 = lessThanEqual(ivec2(2), ivec2(1)); - bvec3 unnamed_134 = lessThanEqual(uvec3(2u), uvec3(1u)); - bvec4 unnamed_135 = lessThanEqual(vec4(2.0), vec4(1.0)); - bool unnamed_136 = (2 > 1); - bool unnamed_137 = (2u > 1u); - bool unnamed_138 = (2.0 > 1.0); - bvec2 unnamed_139 = greaterThan(ivec2(2), ivec2(1)); - bvec3 unnamed_140 = greaterThan(uvec3(2u), uvec3(1u)); - bvec4 unnamed_141 = greaterThan(vec4(2.0), vec4(1.0)); - bool unnamed_142 = (2 >= 1); - bool unnamed_143 = (2u >= 1u); - bool unnamed_144 = (2.0 >= 1.0); - bvec2 unnamed_145 = greaterThanEqual(ivec2(2), ivec2(1)); - bvec3 unnamed_146 = greaterThanEqual(uvec3(2u), uvec3(1u)); - bvec4 unnamed_147 = greaterThanEqual(vec4(2.0), vec4(1.0)); + bool unnamed_113 = (2 == 1); + bool unnamed_114 = (2u == 1u); + bool unnamed_115 = (2.0 == 1.0); + bvec2 unnamed_116 = equal(ivec2(2), ivec2(1)); + bvec3 unnamed_117 = equal(uvec3(2u), uvec3(1u)); + bvec4 unnamed_118 = equal(vec4(2.0), vec4(1.0)); + bool unnamed_119 = (2 != 1); + bool unnamed_120 = (2u != 1u); + bool unnamed_121 = (2.0 != 1.0); + bvec2 unnamed_122 = notEqual(ivec2(2), ivec2(1)); + bvec3 unnamed_123 = notEqual(uvec3(2u), uvec3(1u)); + bvec4 unnamed_124 = notEqual(vec4(2.0), vec4(1.0)); + bool unnamed_125 = (2 < 1); + bool unnamed_126 = (2u < 1u); + bool unnamed_127 = (2.0 < 1.0); + bvec2 unnamed_128 = lessThan(ivec2(2), ivec2(1)); + bvec3 unnamed_129 = lessThan(uvec3(2u), uvec3(1u)); + bvec4 unnamed_130 = lessThan(vec4(2.0), vec4(1.0)); + bool unnamed_131 = (2 <= 1); + bool unnamed_132 = (2u <= 1u); + bool unnamed_133 = (2.0 <= 1.0); + bvec2 unnamed_134 = lessThanEqual(ivec2(2), ivec2(1)); + bvec3 unnamed_135 = lessThanEqual(uvec3(2u), uvec3(1u)); + bvec4 unnamed_136 = lessThanEqual(vec4(2.0), vec4(1.0)); + bool unnamed_137 = (2 > 1); + bool unnamed_138 = (2u > 1u); + bool unnamed_139 = (2.0 > 1.0); + bvec2 unnamed_140 = greaterThan(ivec2(2), ivec2(1)); + bvec3 unnamed_141 = greaterThan(uvec3(2u), uvec3(1u)); + bvec4 unnamed_142 = greaterThan(vec4(2.0), vec4(1.0)); + bool unnamed_143 = (2 >= 1); + bool unnamed_144 = (2u >= 1u); + bool unnamed_145 = (2.0 >= 1.0); + bvec2 unnamed_146 = greaterThanEqual(ivec2(2), ivec2(1)); + bvec3 unnamed_147 = greaterThanEqual(uvec3(2u), uvec3(1u)); + bvec4 unnamed_148 = greaterThanEqual(vec4(2.0), vec4(1.0)); } void assignment() { - int a_1 = 1; - ivec3 vec0_ = ivec3(0, 0, 0); - int _e6 = a_1; - a_1 = (_e6 + 1); - int _e9 = a_1; - a_1 = (_e9 - 1); - int _e12 = a_1; + int a_1 = 0; + ivec3 vec0_ = ivec3(0); + a_1 = 1; + int _e3 = a_1; + a_1 = (_e3 + 1); + int _e7 = a_1; + a_1 = (_e7 - 1); + int _e11 = a_1; int _e13 = a_1; - a_1 = (_e12 * _e13); - int _e15 = a_1; + a_1 = (_e13 * _e11); int _e16 = a_1; - a_1 = (_e15 / _e16); int _e18 = a_1; - a_1 = (_e18 % 1); + a_1 = (_e18 / _e16); int _e21 = a_1; - a_1 = (_e21 & 0); - int _e24 = a_1; - a_1 = (_e24 | 0); - int _e27 = a_1; - a_1 = (_e27 ^ 0); - int _e30 = a_1; - a_1 = (_e30 << 2u); + a_1 = (_e21 % 1); + int _e25 = a_1; + a_1 = (_e25 & 0); + int _e29 = a_1; + a_1 = (_e29 | 0); 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 = (_e33 ^ 0); + int _e38 = a_1; + a_1 = (_e38 << 2u); + int _e42 = a_1; + a_1 = (_e42 >> 1u); + int _e45 = a_1; + a_1 = (_e45 + 1); + int _e49 = a_1; + a_1 = (_e49 - 1); + vec0_ = ivec3(0, 0, 0); + int _e57 = vec0_.y; + vec0_.y = (_e57 + 1); + int _e63 = vec0_.y; + vec0_.y = (_e63 - 1); return; } 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 _e2 = 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/push-constants.vert_main.Vertex.glsl b/tests/out/glsl/push-constants.vert_main.Vertex.glsl index 27cd7037ab..f516f71e35 100644 --- a/tests/out/glsl/push-constants.vert_main.Vertex.glsl +++ b/tests/out/glsl/push-constants.vert_main.Vertex.glsl @@ -16,8 +16,8 @@ layout(location = 0) in vec2 _p2vs_location0; void main() { vec2 pos = _p2vs_location0; uint vi = uint(gl_VertexID); - float _e5 = pc.multiplier; - gl_Position = vec4(((float(vi) * _e5) * pos), 0.0, 1.0); + float _e4 = pc.multiplier; + gl_Position = vec4(((float(vi) * _e4) * pos), 0.0, 1.0); return; } diff --git a/tests/out/glsl/quad.vert_main.Vertex.glsl b/tests/out/glsl/quad.vert_main.Vertex.glsl index 5a1f432b28..07b44f1bd1 100644 --- a/tests/out/glsl/quad.vert_main.Vertex.glsl +++ b/tests/out/glsl/quad.vert_main.Vertex.glsl @@ -14,7 +14,7 @@ smooth out vec2 _vs2fs_location0; void main() { vec2 pos = _p2vs_location0; vec2 uv = _p2vs_location1; - VertexOutput _tmp_return = VertexOutput(uv, vec4((1.2000000476837158 * pos), 0.0, 1.0)); + VertexOutput _tmp_return = VertexOutput(uv, vec4((1.2 * pos), 0.0, 1.0)); _vs2fs_location0 = _tmp_return.uv; gl_Position = _tmp_return.position; return; diff --git a/tests/out/glsl/shadow.fs_main.Fragment.glsl b/tests/out/glsl/shadow.fs_main.Fragment.glsl index 6c0fed4333..437e601f94 100644 --- a/tests/out/glsl/shadow.fs_main.Fragment.glsl +++ b/tests/out/glsl/shadow.fs_main.Fragment.glsl @@ -25,7 +25,7 @@ uniform Globals_block_0Fragment { Globals _group_0_binding_0_fs; }; uniform Entity_block_1Fragment { Entity _group_1_binding_0_fs; }; -layout(std430) readonly buffer type_6_block_2Fragment { Light _group_0_binding_1_fs[]; }; +layout(std430) readonly buffer arrayLight_block_2Fragment { Light _group_0_binding_1_fs[]; }; uniform highp sampler2DArrayShadow _group_0_binding_2_fs; @@ -37,7 +37,7 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { if ((homogeneous_coords.w <= 0.0)) { return 1.0; } - vec2 flip_correction = vec2(0.5, -0.5); + 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)); @@ -46,34 +46,40 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { 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); - bool loop_init = true; - while(true) { - if (!loop_init) { - uint _e20 = i; - i = (_e20 + 1u); + color = vec3(0.05, 0.05, 0.05); + { + i = 0u; + bool loop_init = true; + while(true) { + if (!loop_init) { + uint _e46 = i; + i = (_e46 + 1u); + } + loop_init = false; + uint _e8 = i; + uint _e12 = _group_0_binding_0_fs.num_lights.x; + if ((_e8 < min(_e12, 10u))) { + } else { + break; + } + { + uint _e18 = i; + Light light = _group_0_binding_1_fs[_e18]; + uint _e23 = i; + float _e21 = fetch_shadow(_e23, (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 _e43 = color; + color = (_e43 + ((_e21 * diffuse) * light.color.xyz)); + } } - loop_init = false; - uint _e14 = i; - uint _e17 = _group_0_binding_0_fs.num_lights.x; - if ((_e14 < min(_e17, 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)); } - vec3 _e46 = color; - vec4 _e50 = _group_1_binding_0_fs.color; - _fs2p_location0 = (vec4(_e46, 1.0) * _e50); + vec3 _e50 = color; + vec4 _e55 = _group_1_binding_0_fs.color; + _fs2p_location0 = (vec4(_e50, 1.0) * _e55); 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..75b62abdb5 100644 --- a/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl +++ b/tests/out/glsl/shadow.fs_main_without_storage.Fragment.glsl @@ -25,7 +25,7 @@ uniform Globals_block_0Fragment { Globals _group_0_binding_0_fs; }; uniform Entity_block_1Fragment { Entity _group_1_binding_0_fs; }; -uniform type_7_block_2Fragment { Light _group_0_binding_1_fs[10]; }; +uniform arrayLight10__block_2Fragment { Light _group_0_binding_1_fs[10]; }; uniform highp sampler2DArrayShadow _group_0_binding_2_fs; @@ -37,7 +37,7 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { if ((homogeneous_coords.w <= 0.0)) { return 1.0; } - vec2 flip_correction = vec2(0.5, -0.5); + 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)); @@ -46,34 +46,40 @@ float fetch_shadow(uint light_id, vec4 homogeneous_coords) { 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); - bool loop_init = true; - while(true) { - if (!loop_init) { - uint _e20 = i_1; - i_1 = (_e20 + 1u); + color_1 = vec3(0.05, 0.05, 0.05); + { + i_1 = 0u; + bool loop_init = true; + while(true) { + if (!loop_init) { + uint _e46 = i_1; + i_1 = (_e46 + 1u); + } + loop_init = false; + uint _e8 = i_1; + uint _e12 = _group_0_binding_0_fs.num_lights.x; + if ((_e8 < min(_e12, 10u))) { + } else { + break; + } + { + uint _e18 = i_1; + Light light = _group_0_binding_1_fs[_e18]; + uint _e23 = i_1; + float _e21 = fetch_shadow(_e23, (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 _e43 = color_1; + color_1 = (_e43 + ((_e21 * diffuse) * light.color.xyz)); + } } - loop_init = false; - uint _e14 = i_1; - uint _e17 = _group_0_binding_0_fs.num_lights.x; - if ((_e14 < min(_e17, 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)); } - vec3 _e46 = color_1; - vec4 _e50 = _group_1_binding_0_fs.color; - _fs2p_location0 = (vec4(_e46, 1.0) * _e50); + vec3 _e50 = color_1; + vec4 _e55 = _group_1_binding_0_fs.color; + _fs2p_location0 = (vec4(_e50, 1.0) * _e55); return; } diff --git a/tests/out/glsl/shadow.vs_main.Vertex.glsl b/tests/out/glsl/shadow.vs_main.Vertex.glsl index dce8b2f7d6..81aac877b5 100644 --- a/tests/out/glsl/shadow.vs_main.Vertex.glsl +++ b/tests/out/glsl/shadow.vs_main.Vertex.glsl @@ -35,16 +35,16 @@ void main() { ivec4 normal = _p2vs_location1; VertexOutput out_ = VertexOutput(vec4(0.0), vec3(0.0), vec4(0.0)); mat4x4 w = _group_1_binding_0_vs.world; - mat4x4 _e7 = _group_1_binding_0_vs.world; - vec4 world_pos = (_e7 * vec4(position)); + mat4x4 _e5 = _group_1_binding_0_vs.world; + vec4 world_pos = (_e5 * 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 _e31 = out_; + gl_Position = _e31.proj_position; + _vs2fs_location0 = _e31.world_normal; + _vs2fs_location1 = _e31.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..a8e878662c 100644 --- a/tests/out/glsl/skybox.vs_main.Vertex.glsl +++ b/tests/out/glsl/skybox.vs_main.Vertex.glsl @@ -19,17 +19,19 @@ void main() { uint vertex_index = uint(gl_VertexID); int tmp1_ = 0; 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); - 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); + int tmp1_1 = (int(vertex_index) / 2); + tmp1_ = tmp1_1; + int tmp2_1 = (int(vertex_index) & 1); + tmp2_ = tmp2_1; + int _e11 = tmp1_; + int _e18 = tmp2_; + vec4 pos = vec4(((float(_e11) * 4.0) - 1.0), ((float(_e18) * 4.0) - 1.0), 0.0, 1.0); + vec4 _e31 = _group_0_binding_0_vs.view[0]; + vec4 _e37 = _group_0_binding_0_vs.view[1]; + vec4 _e43 = _group_0_binding_0_vs.view[2]; + mat3x3 inv_model_view = transpose(mat3x3(_e31.xyz, _e37.xyz, _e43.xyz)); + mat4x4 _e49 = _group_0_binding_0_vs.proj_inv; + vec4 unprojected = (_e49 * 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..f6a2d17838 100644 --- a/tests/out/glsl/texture-arg.main.Fragment.glsl +++ b/tests/out/glsl/texture-arg.main.Fragment.glsl @@ -8,13 +8,13 @@ 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() { - vec4 _e2 = test(_group_0_binding_0_fs); - _fs2p_location0 = _e2; + vec4 _e0 = test(_group_0_binding_0_fs); + _fs2p_location0 = _e0; return; } diff --git a/tests/out/hlsl/access.hlsl b/tests/out/hlsl/access.hlsl index 5510ec05bc..54b8fe43b6 100644 --- a/tests/out/hlsl/access.hlsl +++ b/tests/out/hlsl/access.hlsl @@ -138,38 +138,40 @@ 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 _expr3 = idx; + idx = (_expr3 - 1); float3x2 unnamed = GetMatmOnBaz(baz); float2 unnamed_1 = GetMatmOnBaz(baz)[0]; - int _expr16 = idx; - float2 unnamed_2 = GetMatmOnBaz(baz)[_expr16]; + int _expr17 = idx; + float2 unnamed_2 = GetMatmOnBaz(baz)[_expr17]; float unnamed_3 = GetMatmOnBaz(baz)[0][1]; - int _expr28 = idx; - float unnamed_4 = GetMatmOnBaz(baz)[0][_expr28]; int _expr32 = idx; - float unnamed_5 = GetMatmOnBaz(baz)[_expr32][1]; + float unnamed_4 = GetMatmOnBaz(baz)[0][_expr32]; int _expr38 = idx; - int _expr40 = idx; - float unnamed_6 = GetMatmOnBaz(baz)[_expr38][_expr40]; - t = ConstructBaz(float3x2((1.0).xx, (2.0).xx, (3.0).xx)); - int _expr52 = idx; - idx = (_expr52 + 1); + float unnamed_5 = GetMatmOnBaz(baz)[_expr38][1]; + int _expr46 = idx; + int _expr49 = idx; + float unnamed_6 = GetMatmOnBaz(baz)[_expr46][_expr49]; + Baz t_2 = ConstructBaz(float3x2((1.0).xx, (2.0).xx, (3.0).xx)); + t = t_2; + int _expr62 = idx; + idx = (_expr62 + 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 _expr85 = idx; + SetMatVecmOnBaz(t, (90.0).xx, _expr85); 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 _expr99 = idx; + t.m_0[_expr99] = 20.0; + int _expr105 = idx; + SetMatScalarmOnBaz(t, 30.0, _expr105, 1); + int _expr113 = idx; + int _expr116 = idx; + SetMatScalarmOnBaz(t, 40.0, _expr113, _expr116); return; } @@ -181,47 +183,49 @@ 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 _expr3 = idx_1; + idx_1 = (_expr3 - 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 _expr26 = idx_1; + float2 unnamed_10 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr26); float unnamed_11 = nested_mat_cx2_.am[0]._0[1]; - 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)[1]; - int _expr55 = idx_1; - int _expr57 = idx_1; - float unnamed_14 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr55)[_expr57]; - 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 _expr45 = idx_1; + float unnamed_12 = nested_mat_cx2_.am[0]._0[_expr45]; + int _expr53 = idx_1; + float unnamed_13 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr53)[1]; int _expr63 = idx_1; - idx_1 = (_expr63 + 1); + int _expr66 = idx_1; + float unnamed_14 = __get_col_of_mat4x2(nested_mat_cx2_.am[0], _expr63)[_expr66]; + MatCx2InArray t_3 = 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)))); + t_1 = t_3; + int _expr73 = idx_1; + idx_1 = (_expr73 + 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); - t_1.am[0]._0[1] = 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); + __set_col_of_mat4x2(t_1.am[0], _expr107, (90.0).xx); + t_1.am[0]._0[1] = 10.0; + int _expr125 = idx_1; + t_1.am[0]._0[_expr125] = 20.0; + int _expr133 = idx_1; + __set_el_of_mat4x2(t_1.am[0], _expr133, 1, 30.0); + int _expr143 = idx_1; + int _expr146 = idx_1; + __set_el_of_mat4x2(t_1.am[0], _expr143, _expr146, 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 +254,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 d[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 +266,13 @@ 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 _e35 = read_from_private(foo); + int d_1[5] = Constructarray5_int_(a_1, int(b), 3, 4, 5); + d = d_1; + d[(vi + 1u)] = 42; + int value = d[vi]; + const float _e53 = 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 +308,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 _e6; bar.InterlockedAdd(96, 5, _e6); + tmp = _e6; + int _e11; bar.InterlockedAdd(96, -5, _e11); + tmp = _e11; int _e16; bar.InterlockedAnd(96, 5, _e16); tmp = _e16; - 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 _e21; bar.InterlockedOr(96, 5, _e21); + tmp = _e21; + int _e26; bar.InterlockedXor(96, 5, _e26); + tmp = _e26; + int _e31; bar.InterlockedMin(96, 5, _e31); tmp = _e31; + int _e36; bar.InterlockedMax(96, 5, _e36); + tmp = _e36; + int _e41; bar.InterlockedExchange(96, 5, _e41); + tmp = _e41; 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..8cdbf5fc89 100644 --- a/tests/out/hlsl/binding-arrays.hlsl +++ b/tests/out/hlsl/binding-arrays.hlsl @@ -52,132 +52,136 @@ 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; - i2_ = (0).xx; - v4_ = (0.0).xxxx; + i1_ = 0; + int2 i2_1 = (0).xx; + i2_ = i2_1; + v1_ = 0.0; + float4 v4_1 = (0.0).xxxx; + v4_ = v4_1; 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 _expr24 = i2_; + i2_ = (_expr24 + NagaDimensions2D(texture_array_unbounded[0])); + int2 _expr30 = i2_; + i2_ = (_expr30 + 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_; - 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])); - 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 _expr44 = texture_array_bounded[0].Gather(samp[0], uv); + float4 _expr46 = v4_; + v4_ = (_expr46 + _expr44); + float4 _expr52 = texture_array_bounded[uniform_index].Gather(samp[uniform_index], uv); + float4 _expr54 = v4_; + v4_ = (_expr54 + _expr52); + float4 _expr60 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].Gather(samp[NonUniformResourceIndex(non_uniform_index)], uv); + float4 _expr62 = v4_; + v4_ = (_expr62 + _expr60); + float4 _expr71 = texture_array_depth[0].GatherCmp(samp_comp[0], uv, 0.0); + float4 _expr73 = v4_; + v4_ = (_expr73 + _expr71); + float4 _expr80 = texture_array_depth[uniform_index].GatherCmp(samp_comp[uniform_index], uv, 0.0); + float4 _expr82 = v4_; + v4_ = (_expr82 + _expr80); + float4 _expr89 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].GatherCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr91 = v4_; + v4_ = (_expr91 + _expr89); + float4 _expr97 = texture_array_unbounded[0].Load(int3(pix, 0)); + float4 _expr99 = v4_; + v4_ = (_expr99 + _expr97); + float4 _expr104 = texture_array_unbounded[uniform_index].Load(int3(pix, 0)); + float4 _expr106 = v4_; + v4_ = (_expr106 + _expr104); + float4 _expr111 = texture_array_unbounded[NonUniformResourceIndex(non_uniform_index)].Load(int3(pix, 0)); + float4 _expr113 = v4_; + v4_ = (_expr113 + _expr111); + int _expr120 = i1_; + i1_ = (_expr120 + NagaNumLayers2DArray(texture_array_2darray[0])); + int _expr126 = i1_; + i1_ = (_expr126 + NagaNumLayers2DArray(texture_array_2darray[uniform_index])); + int _expr132 = i1_; + i1_ = (_expr132 + NagaNumLayers2DArray(texture_array_2darray[NonUniformResourceIndex(non_uniform_index)])); + int _expr139 = i1_; + i1_ = (_expr139 + NagaNumLevels2D(texture_array_bounded[0])); + int _expr145 = i1_; + i1_ = (_expr145 + NagaNumLevels2D(texture_array_bounded[uniform_index])); + int _expr151 = i1_; + i1_ = (_expr151 + NagaNumLevels2D(texture_array_bounded[NonUniformResourceIndex(non_uniform_index)])); + int _expr158 = i1_; + i1_ = (_expr158 + NagaMSNumSamples2D(texture_array_multisampled[0])); + int _expr164 = i1_; + i1_ = (_expr164 + NagaMSNumSamples2D(texture_array_multisampled[uniform_index])); + int _expr170 = i1_; + i1_ = (_expr170 + NagaMSNumSamples2D(texture_array_multisampled[NonUniformResourceIndex(non_uniform_index)])); + float4 _expr178 = texture_array_bounded[0].Sample(samp[0], uv); + float4 _expr180 = v4_; + v4_ = (_expr180 + _expr178); + float4 _expr186 = texture_array_bounded[uniform_index].Sample(samp[uniform_index], uv); + float4 _expr188 = v4_; + v4_ = (_expr188 + _expr186); + float4 _expr194 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].Sample(samp[NonUniformResourceIndex(non_uniform_index)], uv); + float4 _expr196 = v4_; + v4_ = (_expr196 + _expr194); + float4 _expr205 = texture_array_bounded[0].SampleBias(samp[0], uv, 0.0); + float4 _expr207 = v4_; + v4_ = (_expr207 + _expr205); + float4 _expr214 = texture_array_bounded[uniform_index].SampleBias(samp[uniform_index], uv, 0.0); 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_; + v4_ = (_expr216 + _expr214); + float4 _expr223 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleBias(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr225 = v4_; + v4_ = (_expr225 + _expr223); + float _expr234 = texture_array_depth[0].SampleCmp(samp_comp[0], uv, 0.0); + float _expr236 = v1_; + v1_ = (_expr236 + _expr234); + float _expr243 = texture_array_depth[uniform_index].SampleCmp(samp_comp[uniform_index], uv, 0.0); + float _expr245 = v1_; + v1_ = (_expr245 + _expr243); + float _expr252 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmp(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float _expr254 = v1_; + v1_ = (_expr254 + _expr252); + float _expr263 = texture_array_depth[0].SampleCmpLevelZero(samp_comp[0], uv, 0.0); float _expr265 = v1_; - return ((_expr258 + float4(v2_.x, v2_.y, v2_.x, v2_.y)) + (_expr265).xxxx); + v1_ = (_expr265 + _expr263); + float _expr272 = texture_array_depth[uniform_index].SampleCmpLevelZero(samp_comp[uniform_index], uv, 0.0); + float _expr274 = v1_; + v1_ = (_expr274 + _expr272); + float _expr281 = texture_array_depth[NonUniformResourceIndex(non_uniform_index)].SampleCmpLevelZero(samp_comp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float _expr283 = v1_; + v1_ = (_expr283 + _expr281); + float4 _expr291 = texture_array_bounded[0].SampleGrad(samp[0], uv, uv, uv); + float4 _expr293 = v4_; + v4_ = (_expr293 + _expr291); + float4 _expr299 = texture_array_bounded[uniform_index].SampleGrad(samp[uniform_index], uv, uv, uv); + float4 _expr301 = v4_; + v4_ = (_expr301 + _expr299); + float4 _expr307 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleGrad(samp[NonUniformResourceIndex(non_uniform_index)], uv, uv, uv); + float4 _expr309 = v4_; + v4_ = (_expr309 + _expr307); + float4 _expr318 = texture_array_bounded[0].SampleLevel(samp[0], uv, 0.0); + float4 _expr320 = v4_; + v4_ = (_expr320 + _expr318); + float4 _expr327 = texture_array_bounded[uniform_index].SampleLevel(samp[uniform_index], uv, 0.0); + float4 _expr329 = v4_; + v4_ = (_expr329 + _expr327); + float4 _expr336 = texture_array_bounded[NonUniformResourceIndex(non_uniform_index)].SampleLevel(samp[NonUniformResourceIndex(non_uniform_index)], uv, 0.0); + float4 _expr338 = v4_; + v4_ = (_expr338 + _expr336); + float4 _expr344 = v4_; + texture_array_storage[0][pix] = _expr344; + float4 _expr348 = v4_; + texture_array_storage[uniform_index][pix] = _expr348; + float4 _expr352 = v4_; + texture_array_storage[NonUniformResourceIndex(non_uniform_index)][pix] = _expr352; + int2 _expr354 = i2_; + int _expr356 = i1_; + float2 v2_ = float2((_expr354 + (_expr356).xx)); + float4 _expr361 = v4_; + float _expr369 = v1_; + return ((_expr361 + float4(v2_.x, v2_.y, v2_.x, v2_.y)) + (_expr369).xxxx); } diff --git a/tests/out/hlsl/boids.hlsl b/tests/out/hlsl/boids.hlsl index fb4640a766..bbc273e0b4 100644 --- a/tests/out/hlsl/boids.hlsl +++ b/tests/out/hlsl/boids.hlsl @@ -27,121 +27,127 @@ 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; - cMass = float2(0.0, 0.0); - cVel = float2(0.0, 0.0); - colVel = float2(0.0, 0.0); + float2 vPos_1 = asfloat(particlesSrc.Load2(0+index*16+0)); + vPos = vPos_1; + float2 vVel_1 = asfloat(particlesSrc.Load2(8+index*16+0)); + vVel = vVel_1; + float2 cMass_1 = float2(0.0, 0.0); + cMass = cMass_1; + float2 cVel_1 = float2(0.0, 0.0); + cVel = cVel_1; + float2 colVel_1 = float2(0.0, 0.0); + colVel = colVel_1; + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _expr86 = i; - i = (_expr86 + 1u); + uint _expr116 = i; + i = (_expr116 + 1u); } loop_init = false; - uint _expr37 = i; - if ((_expr37 >= NUM_PARTICLES)) { + uint _expr35 = i; + if ((_expr35 >= 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 _expr44 = i; + float2 _expr47 = asfloat(particlesSrc.Load2(0+_expr44*16+0)); + pos = _expr47; + uint _expr52 = i; + float2 _expr55 = asfloat(particlesSrc.Load2(8+_expr52*16+0)); + vel = _expr55; + float2 _expr58 = pos; + float2 _expr60 = vPos; + float _expr64 = params.rule1Distance; + if ((distance(_expr58, _expr60) < _expr64)) { + float2 _expr67 = cMass; + float2 _expr69 = pos; + cMass = (_expr67 + _expr69); + int _expr73 = cMassCount; + cMassCount = (_expr73 + 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 _expr78 = pos; + float2 _expr80 = vPos; + float _expr84 = params.rule2Distance; + if ((distance(_expr78, _expr80) < _expr84)) { + float2 _expr87 = colVel; + float2 _expr89 = pos; + float2 _expr91 = vPos; + colVel = (_expr87 - (_expr89 - _expr91)); } - 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 _expr96 = pos; + float2 _expr98 = vPos; + float _expr102 = params.rule3Distance; + if ((distance(_expr96, _expr98) < _expr102)) { + float2 _expr105 = cVel; + float2 _expr107 = vel; + cVel = (_expr105 + _expr107); + int _expr111 = cVelCount; + cVelCount = (_expr111 + 1); } } - int _expr89 = cMassCount; - if ((_expr89 > 0)) { - float2 _expr92 = cMass; - int _expr93 = cMassCount; - float2 _expr97 = vPos; - cMass = ((_expr92 / (float(_expr93)).xx) - _expr97); + int _expr121 = cMassCount; + if ((_expr121 > 0)) { + float2 _expr125 = cMass; + int _expr127 = cMassCount; + float2 _expr132 = vPos; + cMass = ((_expr125 / (float(_expr127)).xx) - _expr132); } - int _expr99 = cVelCount; - if ((_expr99 > 0)) { - float2 _expr102 = cVel; - int _expr103 = cVelCount; - cVel = (_expr102 / (float(_expr103)).xx); + int _expr136 = cVelCount; + if ((_expr136 > 0)) { + float2 _expr140 = cVel; + int _expr142 = cVelCount; + cVel = (_expr140 / (float(_expr142)).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 _expr148 = vVel; + float2 _expr150 = cMass; + float _expr153 = params.rule1Scale; + float2 _expr157 = colVel; + float _expr160 = params.rule2Scale; + float2 _expr164 = cVel; + float _expr167 = params.rule3Scale; + vVel = (((_expr148 + (_expr150 * _expr153)) + (_expr157 * _expr160)) + (_expr164 * _expr167)); + float2 _expr172 = vVel; + float2 _expr175 = vVel; + vVel = (normalize(_expr172) * clamp(length(_expr175), 0.0, 0.1)); + float2 _expr183 = vPos; + float2 _expr185 = vVel; + float _expr188 = params.deltaT; + vPos = (_expr183 + (_expr185 * _expr188)); + float _expr194 = vPos.x; + if ((_expr194 < -1.0)) { vPos.x = 1.0; } - float _expr144 = vPos.x; - if ((_expr144 > 1.0)) { + float _expr203 = vPos.x; + if ((_expr203 > 1.0)) { vPos.x = -1.0; } - float _expr150 = vPos.y; - if ((_expr150 < -1.0)) { + float _expr212 = vPos.y; + if ((_expr212 < -1.0)) { vPos.y = 1.0; } - float _expr156 = vPos.y; - if ((_expr156 > 1.0)) { + float _expr221 = vPos.y; + if ((_expr221 > 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 _expr229 = vPos; + particlesDst.Store2(0+index*16+0, asuint(_expr229)); + float2 _expr235 = vVel; + particlesDst.Store2(8+index*16+0, asuint(_expr235)); return; } diff --git a/tests/out/hlsl/break-if.hlsl b/tests/out/hlsl/break-if.hlsl index fc91096a98..79b2067a8a 100644 --- a/tests/out/hlsl/break-if.hlsl +++ b/tests/out/hlsl/break-if.hlsl @@ -18,14 +18,15 @@ void breakIfEmptyBody(bool a) bool b = (bool)0; bool c = (bool)0; + bool _expr9 = c; + bool unnamed = (a == _expr9); bool loop_init_1 = true; while(true) { if (!loop_init_1) { b = a; - bool _expr2 = b; - c = (a != _expr2); - bool _expr5 = c; - bool unnamed = (a == _expr5); + bool _expr4 = b; + bool c_1 = (a != _expr4); + c = c_1; if (unnamed) { break; } @@ -40,19 +41,20 @@ void breakIf(bool a_1) bool d = (bool)0; bool e = (bool)0; + bool _expr9 = e; + bool unnamed_1 = (a_1 == _expr9); bool loop_init_2 = true; while(true) { if (!loop_init_2) { - bool _expr5 = e; - bool unnamed_1 = (a_1 == _expr5); if (unnamed_1) { break; } } loop_init_2 = false; d = a_1; - bool _expr2 = d; - e = (a_1 != _expr2); + bool _expr4 = d; + bool e_1 = (a_1 != _expr4); + e = e_1; } return; } diff --git a/tests/out/hlsl/collatz.hlsl b/tests/out/hlsl/collatz.hlsl index d74efad893..85648c2d1a 100644 --- a/tests/out/hlsl/collatz.hlsl +++ b/tests/out/hlsl/collatz.hlsl @@ -4,35 +4,40 @@ 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)) { } else { break; } - uint _expr8 = n; - if (((_expr8 % 2u) == 0u)) { - uint _expr13 = n; - n = (_expr13 / 2u); - } else { - uint _expr17 = n; - n = ((3u * _expr17) + 1u); + { + uint _expr9 = n; + if (((_expr9 % 2u) == 0u)) { + uint _expr15 = n; + n = (_expr15 / 2u); + } else { + { + uint _expr21 = n; + n = ((3u * _expr21) + 1u); + } + } + uint _expr27 = i; + i = (_expr27 + 1u); } - uint _expr21 = i; - i = (_expr21 + 1u); } - uint _expr24 = i; - return _expr24; + uint _expr32 = i; + return _expr32; } [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 _expr6 = asuint(v_indices.Load(global_id.x*4+0)); + const uint _e0 = collatz_iterations(_expr6); + v_indices.Store(global_id.x*4+0, asuint(_e0)); return; } diff --git a/tests/out/hlsl/control-flow.hlsl b/tests/out/hlsl/control-flow.hlsl index 4b879ef20c..0565a1fbfd 100644 --- a/tests/out/hlsl/control-flow.hlsl +++ b/tests/out/hlsl/control-flow.hlsl @@ -60,24 +60,11 @@ void main(uint3 global_id : SV_DispatchThreadID) break; } case 3: { - { - pos = 2; - } - { - pos = 3; - } - { - pos = 4; - } + pos = 2; break; } case 4: { - { - pos = 3; - } - { - pos = 4; - } + pos = 3; break; } default: { @@ -93,8 +80,8 @@ void main(uint3 global_id : SV_DispatchThreadID) break; } } - int _expr11 = pos; - switch(_expr11) { + int _expr17 = pos; + switch(_expr17) { case 1: { pos = 0; break; @@ -104,12 +91,8 @@ void main(uint3 global_id : SV_DispatchThreadID) return; } case 3: { - { - pos = 2; - } - { - return; - } + pos = 2; + return; } case 4: { return; diff --git a/tests/out/hlsl/globals.hlsl b/tests/out/hlsl/globals.hlsl index def5c8dbb2..d1a3db10d8 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 FooConst = true; typedef struct { float2 _0; float2 _1; float2 _2; } __mat3x2; float2 __get_col_of_mat3x2(__mat3x2 mat, uint idx) { @@ -80,13 +80,14 @@ 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)); + int _expr18 = idx; + alignment.Store(_expr18*4+0, asuint(3.0)); Foo data = ConstructFoo(asfloat(alignment.Load3(0)), asfloat(alignment.Load(12))); float3 unnamed = data.v3_; float2 unnamed_1 = data.v3_.zx; @@ -107,26 +108,28 @@ uint NagaBufferLength(ByteAddressBuffer buffer) [numthreads(1, 1, 1)] void main() { - float Foo_1 = 1.0; - bool at = true; + float Foo_1 = (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; - 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; + float4x2 _expr5 = ((float4x2)global_nested_arrays_of_matrices_4x2_[0][0]); + float4 _expr13 = global_nested_arrays_of_matrices_2x4_[0][0][0]; + wg[7] = mul(_expr13, _expr5).x; + float3x2 _expr20 = ((float3x2)global_mat); + float3 _expr22 = global_vec; + wg[6] = mul(_expr22, _expr20).x; + float _expr32 = asfloat(dummy.Load(4+8)); + wg[5] = _expr32; + float _expr40 = float_vecs[0].w; + wg[4] = _expr40; + float _expr46 = asfloat(alignment.Load(12)); + wg[3] = _expr46; + float _expr53 = asfloat(alignment.Load(0+0)); + wg[2] = _expr53; alignment.Store(12, asuint(4.0)); wg[1] = float(((NagaBufferLength(dummy) - 0) / 8)); at_1 = 2u; + Foo_1 = 1.0; + at = true; return; } diff --git a/tests/out/hlsl/image.hlsl b/tests/out/hlsl/image.hlsl index a21e308dac..a193c53f23 100644 --- a/tests/out/hlsl/image.hlsl +++ b/tests/out/hlsl/image.hlsl @@ -236,8 +236,8 @@ float4 texture_sample() : SV_Target0 float4 s1d = image_1d.Sample(sampler_reg, tc.x); float4 s2d = image_2d.Sample(sampler_reg, tc); float4 s2d_offset = image_2d.Sample(sampler_reg, tc, int2(3, 1)); - float4 s2d_level = image_2d.SampleLevel(sampler_reg, tc, 2.299999952316284); - float4 s2d_level_offset = image_2d.SampleLevel(sampler_reg, tc, 2.299999952316284, int2(3, 1)); + float4 s2d_level = image_2d.SampleLevel(sampler_reg, tc, 2.3); + float4 s2d_level_offset = image_2d.SampleLevel(sampler_reg, tc, 2.3, int2(3, 1)); float4 s2d_bias_offset = image_2d.SampleBias(sampler_reg, tc, 2.0, int2(3, 1)); return ((((s1d + s2d) + s2d_offset) + s2d_level) + s2d_level_offset); } diff --git a/tests/out/hlsl/interface.hlsl b/tests/out/hlsl/interface.hlsl index c88d1ee774..5d975b6975 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; + index = 2u; uint _expr9 = index; return float4(float((_NagaConstants.base_vertex + in1_.index)), float((_NagaConstants.base_instance + in2_.index)), float(_expr9), 0.0); } diff --git a/tests/out/hlsl/interpolate.hlsl b/tests/out/hlsl/interpolate.hlsl index a9bd0c346b..beb240ab6f 100644 --- a/tests/out/hlsl/interpolate.hlsl +++ b/tests/out/hlsl/interpolate.hlsl @@ -44,8 +44,8 @@ VertexOutput_vert_main vert_main() out_.perspective = float4(729.0, 1000.0, 1331.0, 1728.0); out_.perspective_centroid = 2197.0; out_.perspective_sample = 2744.0; - FragmentInput _expr30 = out_; - const FragmentInput fragmentinput = _expr30; + FragmentInput _expr38 = out_; + const FragmentInput fragmentinput = _expr38; const VertexOutput_vert_main fragmentinput_1 = { fragmentinput._flat, fragmentinput._linear, fragmentinput.linear_centroid, fragmentinput.linear_sample, fragmentinput.perspective, fragmentinput.perspective_centroid, fragmentinput.perspective_sample, fragmentinput.position }; return fragmentinput_1; } diff --git a/tests/out/hlsl/operators.hlsl b/tests/out/hlsl/operators.hlsl index 48e8fee09e..17fdf46e29 100644 --- a/tests/out/hlsl/operators.hlsl +++ b/tests/out/hlsl/operators.hlsl @@ -30,7 +30,7 @@ float4 builtins() float4 s2_ = (true ? float4(1.0, 1.0, 1.0, 1.0) : float4(0.0, 0.0, 0.0, 0.0)); float4 s3_ = (bool4(false, false, false, false) ? float4(0.0, 0.0, 0.0, 0.0) : float4(1.0, 1.0, 1.0, 1.0)); float4 m1_ = lerp(float4(0.0, 0.0, 0.0, 0.0), float4(1.0, 1.0, 1.0, 1.0), float4(0.5, 0.5, 0.5, 0.5)); - float4 m2_ = lerp(float4(0.0, 0.0, 0.0, 0.0), float4(1.0, 1.0, 1.0, 1.0), 0.10000000149011612); + float4 m2_ = lerp(float4(0.0, 0.0, 0.0, 0.0), float4(1.0, 1.0, 1.0, 1.0), 0.1); float b1_ = float(int4(1, 1, 1, 1).x); float4 b2_ = float4(int4(1, 1, 1, 1)); int4 v_i32_zero = int4(float4(0.0, 0.0, 0.0, 0.0)); @@ -48,13 +48,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 _expr15 = a; - a = (_expr15 / (4.0).xx); + float2 a_3 = (2.0).xx; + a = a_3; + float2 _expr4 = a; + a = (_expr4 + (1.0).xx); + float2 _expr9 = a; + a = (_expr9 - (3.0).xx); + float2 _expr14 = a; + a = (_expr14 / (4.0).xx); float2 _expr19 = a; return _expr19; } @@ -89,16 +90,16 @@ float constructors() float2x3 unnamed_8 = float2x3(float2x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); uint2 unnamed_9 = uint2(uint2(0u, 0u)); float2x3 unnamed_10 = float2x3(float2x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float _expr75 = foo.a.x; - return _expr75; + float _expr72 = foo.a.x; + return _expr72; } void logical() { bool unnamed_11 = !true; bool2 unnamed_12 = !(true).xx; - bool unnamed_13 = (true || false); - bool unnamed_14 = (true && false); + bool unnamed_13 = (true | false); + bool unnamed_14 = (true & false); bool unnamed_15 = (true | false); bool3 unnamed_16 = ((true).xxx | (false).xxx); bool unnamed_17 = (true & false); @@ -107,190 +108,193 @@ void logical() void arithmetic() { - int2 unnamed_19 = -(1).xx; - float2 unnamed_20 = -(1.0).xx; - int unnamed_21 = (2 + 1); - uint unnamed_22 = (2u + 1u); - float unnamed_23 = (2.0 + 1.0); - int2 unnamed_24 = ((2).xx + (1).xx); - uint3 unnamed_25 = ((2u).xxx + (1u).xxx); - float4 unnamed_26 = ((2.0).xxxx + (1.0).xxxx); - int unnamed_27 = (2 - 1); - uint unnamed_28 = (2u - 1u); - float unnamed_29 = (2.0 - 1.0); - int2 unnamed_30 = ((2).xx - (1).xx); - uint3 unnamed_31 = ((2u).xxx - (1u).xxx); - float4 unnamed_32 = ((2.0).xxxx - (1.0).xxxx); - int unnamed_33 = (2 * 1); - uint unnamed_34 = (2u * 1u); - float unnamed_35 = (2.0 * 1.0); - int2 unnamed_36 = ((2).xx * (1).xx); - uint3 unnamed_37 = ((2u).xxx * (1u).xxx); - float4 unnamed_38 = ((2.0).xxxx * (1.0).xxxx); - int unnamed_39 = (2 / 1); - uint unnamed_40 = (2u / 1u); - float unnamed_41 = (2.0 / 1.0); - int2 unnamed_42 = ((2).xx / (1).xx); - uint3 unnamed_43 = ((2u).xxx / (1u).xxx); - float4 unnamed_44 = ((2.0).xxxx / (1.0).xxxx); - int unnamed_45 = (2 % 1); - uint unnamed_46 = (2u % 1u); - float unnamed_47 = fmod(2.0, 1.0); - int2 unnamed_48 = ((2).xx % (1).xx); - uint3 unnamed_49 = ((2u).xxx % (1u).xxx); - float4 unnamed_50 = fmod((2.0).xxxx, (1.0).xxxx); - int2 unnamed_51 = ((2).xx + (1).xx); + float unnamed_19 = -1.0; + int2 unnamed_20 = -(1).xx; + float2 unnamed_21 = -(1.0).xx; + int unnamed_22 = (2 + 1); + uint unnamed_23 = (2u + 1u); + float unnamed_24 = (2.0 + 1.0); + int2 unnamed_25 = ((2).xx + (1).xx); + uint3 unnamed_26 = ((2u).xxx + (1u).xxx); + float4 unnamed_27 = ((2.0).xxxx + (1.0).xxxx); + int unnamed_28 = (2 - 1); + uint unnamed_29 = (2u - 1u); + float unnamed_30 = (2.0 - 1.0); + int2 unnamed_31 = ((2).xx - (1).xx); + uint3 unnamed_32 = ((2u).xxx - (1u).xxx); + float4 unnamed_33 = ((2.0).xxxx - (1.0).xxxx); + int unnamed_34 = (2 * 1); + uint unnamed_35 = (2u * 1u); + float unnamed_36 = (2.0 * 1.0); + int2 unnamed_37 = ((2).xx * (1).xx); + uint3 unnamed_38 = ((2u).xxx * (1u).xxx); + float4 unnamed_39 = ((2.0).xxxx * (1.0).xxxx); + int unnamed_40 = (2 / 1); + uint unnamed_41 = (2u / 1u); + float unnamed_42 = (2.0 / 1.0); + int2 unnamed_43 = ((2).xx / (1).xx); + uint3 unnamed_44 = ((2u).xxx / (1u).xxx); + float4 unnamed_45 = ((2.0).xxxx / (1.0).xxxx); + int unnamed_46 = (2 % 1); + uint unnamed_47 = (2u % 1u); + float unnamed_48 = fmod(2.0, 1.0); + int2 unnamed_49 = ((2).xx % (1).xx); + uint3 unnamed_50 = ((2u).xxx % (1u).xxx); + float4 unnamed_51 = fmod((2.0).xxxx, (1.0).xxxx); int2 unnamed_52 = ((2).xx + (1).xx); - uint2 unnamed_53 = ((2u).xx + (1u).xx); + int2 unnamed_53 = ((2).xx + (1).xx); uint2 unnamed_54 = ((2u).xx + (1u).xx); - float2 unnamed_55 = ((2.0).xx + (1.0).xx); + uint2 unnamed_55 = ((2u).xx + (1u).xx); float2 unnamed_56 = ((2.0).xx + (1.0).xx); - int2 unnamed_57 = ((2).xx - (1).xx); + float2 unnamed_57 = ((2.0).xx + (1.0).xx); int2 unnamed_58 = ((2).xx - (1).xx); - uint2 unnamed_59 = ((2u).xx - (1u).xx); + int2 unnamed_59 = ((2).xx - (1).xx); uint2 unnamed_60 = ((2u).xx - (1u).xx); - float2 unnamed_61 = ((2.0).xx - (1.0).xx); + uint2 unnamed_61 = ((2u).xx - (1u).xx); float2 unnamed_62 = ((2.0).xx - (1.0).xx); - int2 unnamed_63 = ((2).xx * 1); - int2 unnamed_64 = (2 * (1).xx); - uint2 unnamed_65 = ((2u).xx * 1u); - uint2 unnamed_66 = (2u * (1u).xx); - float2 unnamed_67 = ((2.0).xx * 1.0); - float2 unnamed_68 = (2.0 * (1.0).xx); - int2 unnamed_69 = ((2).xx / (1).xx); + float2 unnamed_63 = ((2.0).xx - (1.0).xx); + int2 unnamed_64 = ((2).xx * 1); + int2 unnamed_65 = (2 * (1).xx); + uint2 unnamed_66 = ((2u).xx * 1u); + uint2 unnamed_67 = (2u * (1u).xx); + float2 unnamed_68 = ((2.0).xx * 1.0); + float2 unnamed_69 = (2.0 * (1.0).xx); int2 unnamed_70 = ((2).xx / (1).xx); - uint2 unnamed_71 = ((2u).xx / (1u).xx); + int2 unnamed_71 = ((2).xx / (1).xx); uint2 unnamed_72 = ((2u).xx / (1u).xx); - float2 unnamed_73 = ((2.0).xx / (1.0).xx); + uint2 unnamed_73 = ((2u).xx / (1u).xx); float2 unnamed_74 = ((2.0).xx / (1.0).xx); - int2 unnamed_75 = ((2).xx % (1).xx); + float2 unnamed_75 = ((2.0).xx / (1.0).xx); int2 unnamed_76 = ((2).xx % (1).xx); - uint2 unnamed_77 = ((2u).xx % (1u).xx); + int2 unnamed_77 = ((2).xx % (1).xx); uint2 unnamed_78 = ((2u).xx % (1u).xx); - float2 unnamed_79 = fmod((2.0).xx, (1.0).xx); + uint2 unnamed_79 = ((2u).xx % (1u).xx); float2 unnamed_80 = fmod((2.0).xx, (1.0).xx); - float3x3 unnamed_81 = (float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)) + float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float3x3 unnamed_82 = (float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)) - float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float3x3 unnamed_83 = mul(1.0, float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float3x3 unnamed_84 = mul(float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)), 2.0); - float3 unnamed_85 = mul((1.0).xxxx, float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); - float4 unnamed_86 = mul(float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)), (2.0).xxx); - float3x3 unnamed_87 = mul(float3x4(float4(0.0, 0.0, 0.0, 0.0), float4(0.0, 0.0, 0.0, 0.0), float4(0.0, 0.0, 0.0, 0.0)), float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); + float2 unnamed_81 = fmod((2.0).xx, (1.0).xx); + float3x3 unnamed_82 = (float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)) + float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); + float3x3 unnamed_83 = (float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)) - float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); + float3x3 unnamed_84 = mul(1.0, float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); + float3x3 unnamed_85 = mul(float3x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)), 2.0); + float3 unnamed_86 = mul((1.0).xxxx, float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); + float4 unnamed_87 = mul(float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)), (2.0).xxx); + float3x3 unnamed_88 = mul(float3x4(float4(0.0, 0.0, 0.0, 0.0), float4(0.0, 0.0, 0.0, 0.0), float4(0.0, 0.0, 0.0, 0.0)), float4x3(float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0))); } void bit() { - int unnamed_88 = ~1; - uint unnamed_89 = ~1u; - int2 unnamed_90 = ~(1).xx; - uint3 unnamed_91 = ~(1u).xxx; - int unnamed_92 = (2 | 1); - uint unnamed_93 = (2u | 1u); - int2 unnamed_94 = ((2).xx | (1).xx); - uint3 unnamed_95 = ((2u).xxx | (1u).xxx); - int unnamed_96 = (2 & 1); - uint unnamed_97 = (2u & 1u); - int2 unnamed_98 = ((2).xx & (1).xx); - uint3 unnamed_99 = ((2u).xxx & (1u).xxx); - int unnamed_100 = (2 ^ 1); - uint unnamed_101 = (2u ^ 1u); - int2 unnamed_102 = ((2).xx ^ (1).xx); - uint3 unnamed_103 = ((2u).xxx ^ (1u).xxx); - int unnamed_104 = (2 << 1u); - uint unnamed_105 = (2u << 1u); - int2 unnamed_106 = ((2).xx << (1u).xx); - uint3 unnamed_107 = ((2u).xxx << (1u).xxx); - int unnamed_108 = (2 >> 1u); - uint unnamed_109 = (2u >> 1u); - int2 unnamed_110 = ((2).xx >> (1u).xx); - uint3 unnamed_111 = ((2u).xxx >> (1u).xxx); + int unnamed_89 = ~1; + uint unnamed_90 = ~1u; + int2 unnamed_91 = ~(1).xx; + uint3 unnamed_92 = ~(1u).xxx; + int unnamed_93 = (2 | 1); + uint unnamed_94 = (2u | 1u); + int2 unnamed_95 = ((2).xx | (1).xx); + uint3 unnamed_96 = ((2u).xxx | (1u).xxx); + int unnamed_97 = (2 & 1); + uint unnamed_98 = (2u & 1u); + int2 unnamed_99 = ((2).xx & (1).xx); + uint3 unnamed_100 = ((2u).xxx & (1u).xxx); + int unnamed_101 = (2 ^ 1); + uint unnamed_102 = (2u ^ 1u); + int2 unnamed_103 = ((2).xx ^ (1).xx); + uint3 unnamed_104 = ((2u).xxx ^ (1u).xxx); + int unnamed_105 = (2 << 1u); + uint unnamed_106 = (2u << 1u); + int2 unnamed_107 = ((2).xx << (1u).xx); + uint3 unnamed_108 = ((2u).xxx << (1u).xxx); + int unnamed_109 = (2 >> 1u); + uint unnamed_110 = (2u >> 1u); + int2 unnamed_111 = ((2).xx >> (1u).xx); + uint3 unnamed_112 = ((2u).xxx >> (1u).xxx); } void comparison() { - bool unnamed_112 = (2 == 1); - bool unnamed_113 = (2u == 1u); - bool unnamed_114 = (2.0 == 1.0); - bool2 unnamed_115 = ((2).xx == (1).xx); - bool3 unnamed_116 = ((2u).xxx == (1u).xxx); - bool4 unnamed_117 = ((2.0).xxxx == (1.0).xxxx); - bool unnamed_118 = (2 != 1); - bool unnamed_119 = (2u != 1u); - bool unnamed_120 = (2.0 != 1.0); - bool2 unnamed_121 = ((2).xx != (1).xx); - bool3 unnamed_122 = ((2u).xxx != (1u).xxx); - bool4 unnamed_123 = ((2.0).xxxx != (1.0).xxxx); - bool unnamed_124 = (2 < 1); - bool unnamed_125 = (2u < 1u); - bool unnamed_126 = (2.0 < 1.0); - bool2 unnamed_127 = ((2).xx < (1).xx); - bool3 unnamed_128 = ((2u).xxx < (1u).xxx); - bool4 unnamed_129 = ((2.0).xxxx < (1.0).xxxx); - bool unnamed_130 = (2 <= 1); - bool unnamed_131 = (2u <= 1u); - bool unnamed_132 = (2.0 <= 1.0); - bool2 unnamed_133 = ((2).xx <= (1).xx); - bool3 unnamed_134 = ((2u).xxx <= (1u).xxx); - bool4 unnamed_135 = ((2.0).xxxx <= (1.0).xxxx); - bool unnamed_136 = (2 > 1); - bool unnamed_137 = (2u > 1u); - bool unnamed_138 = (2.0 > 1.0); - bool2 unnamed_139 = ((2).xx > (1).xx); - bool3 unnamed_140 = ((2u).xxx > (1u).xxx); - bool4 unnamed_141 = ((2.0).xxxx > (1.0).xxxx); - bool unnamed_142 = (2 >= 1); - bool unnamed_143 = (2u >= 1u); - bool unnamed_144 = (2.0 >= 1.0); - bool2 unnamed_145 = ((2).xx >= (1).xx); - bool3 unnamed_146 = ((2u).xxx >= (1u).xxx); - bool4 unnamed_147 = ((2.0).xxxx >= (1.0).xxxx); + bool unnamed_113 = (2 == 1); + bool unnamed_114 = (2u == 1u); + bool unnamed_115 = (2.0 == 1.0); + bool2 unnamed_116 = ((2).xx == (1).xx); + bool3 unnamed_117 = ((2u).xxx == (1u).xxx); + bool4 unnamed_118 = ((2.0).xxxx == (1.0).xxxx); + bool unnamed_119 = (2 != 1); + bool unnamed_120 = (2u != 1u); + bool unnamed_121 = (2.0 != 1.0); + bool2 unnamed_122 = ((2).xx != (1).xx); + bool3 unnamed_123 = ((2u).xxx != (1u).xxx); + bool4 unnamed_124 = ((2.0).xxxx != (1.0).xxxx); + bool unnamed_125 = (2 < 1); + bool unnamed_126 = (2u < 1u); + bool unnamed_127 = (2.0 < 1.0); + bool2 unnamed_128 = ((2).xx < (1).xx); + bool3 unnamed_129 = ((2u).xxx < (1u).xxx); + bool4 unnamed_130 = ((2.0).xxxx < (1.0).xxxx); + bool unnamed_131 = (2 <= 1); + bool unnamed_132 = (2u <= 1u); + bool unnamed_133 = (2.0 <= 1.0); + bool2 unnamed_134 = ((2).xx <= (1).xx); + bool3 unnamed_135 = ((2u).xxx <= (1u).xxx); + bool4 unnamed_136 = ((2.0).xxxx <= (1.0).xxxx); + bool unnamed_137 = (2 > 1); + bool unnamed_138 = (2u > 1u); + bool unnamed_139 = (2.0 > 1.0); + bool2 unnamed_140 = ((2).xx > (1).xx); + bool3 unnamed_141 = ((2u).xxx > (1u).xxx); + bool4 unnamed_142 = ((2.0).xxxx > (1.0).xxxx); + bool unnamed_143 = (2 >= 1); + bool unnamed_144 = (2u >= 1u); + bool unnamed_145 = (2.0 >= 1.0); + bool2 unnamed_146 = ((2).xx >= (1).xx); + bool3 unnamed_147 = ((2u).xxx >= (1u).xxx); + bool4 unnamed_148 = ((2.0).xxxx >= (1.0).xxxx); } void assignment() { - int a_1 = 1; - int3 vec0_ = int3(0, 0, 0); + int a_1 = (int)0; + int3 vec0_ = (int3)0; - int _expr6 = a_1; - a_1 = (_expr6 + 1); - int _expr9 = a_1; - a_1 = (_expr9 - 1); - int _expr12 = a_1; + a_1 = 1; + int _expr3 = a_1; + a_1 = (_expr3 + 1); + int _expr7 = a_1; + a_1 = (_expr7 - 1); + int _expr11 = a_1; int _expr13 = a_1; - a_1 = (_expr12 * _expr13); - int _expr15 = a_1; + a_1 = (_expr13 * _expr11); int _expr16 = a_1; - a_1 = (_expr15 / _expr16); int _expr18 = a_1; - a_1 = (_expr18 % 1); + a_1 = (_expr18 / _expr16); int _expr21 = a_1; - a_1 = (_expr21 & 0); - int _expr24 = a_1; - a_1 = (_expr24 | 0); - int _expr27 = a_1; - a_1 = (_expr27 ^ 0); - int _expr30 = a_1; - a_1 = (_expr30 << 2u); + a_1 = (_expr21 % 1); + int _expr25 = a_1; + a_1 = (_expr25 & 0); + int _expr29 = a_1; + a_1 = (_expr29 | 0); 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 = (_expr33 ^ 0); + int _expr38 = a_1; + a_1 = (_expr38 << 2u); + int _expr42 = a_1; + a_1 = (_expr42 >> 1u); + int _expr45 = a_1; + a_1 = (_expr45 + 1); + int _expr49 = a_1; + a_1 = (_expr49 - 1); + vec0_ = int3(0, 0, 0); + int _expr57 = vec0_.y; + vec0_.y = (_expr57 + 1); + int _expr63 = vec0_.y; + vec0_.y = (_expr63 - 1); return; } [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 _e2 = 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/push-constants.hlsl b/tests/out/hlsl/push-constants.hlsl index 22b4b6acdf..1e6a30c6bc 100644 --- a/tests/out/hlsl/push-constants.hlsl +++ b/tests/out/hlsl/push-constants.hlsl @@ -21,8 +21,8 @@ struct FragmentInput_main { float4 vert_main(float2 pos : LOC0, uint vi : SV_VertexID) : SV_Position { - float _expr5 = pc.multiplier; - return float4(((float((_NagaConstants.base_vertex + vi)) * _expr5) * pos), 0.0, 1.0); + float _expr4 = pc.multiplier; + return float4(((float((_NagaConstants.base_vertex + vi)) * _expr4) * pos), 0.0, 1.0); } float4 main(FragmentInput_main fragmentinput_main) : SV_Target0 diff --git a/tests/out/hlsl/quad.hlsl b/tests/out/hlsl/quad.hlsl index 9a987af1ce..a70757f37c 100644 --- a/tests/out/hlsl/quad.hlsl +++ b/tests/out/hlsl/quad.hlsl @@ -1,4 +1,4 @@ -static const float c_scale = 1.2000000476837158; +static const float c_scale = 1.2; struct VertexOutput { float2 uv : LOC0; diff --git a/tests/out/hlsl/shadow.hlsl b/tests/out/hlsl/shadow.hlsl index a3942386b5..c08ff5d114 100644 --- a/tests/out/hlsl/shadow.hlsl +++ b/tests/out/hlsl/shadow.hlsl @@ -1,4 +1,4 @@ -static const float3 c_ambient = float3(0.05000000074505806, 0.05000000074505806, 0.05000000074505806); +static const float3 c_ambient = float3(0.05, 0.05, 0.05); static const uint c_max_lights = 10; struct Globals { @@ -65,14 +65,14 @@ VertexOutput_vs_main vs_main(int4 position : LOC0, int4 normal : LOC1) VertexOutput out_ = (VertexOutput)0; float4x4 w = u_entity.world; - float4x4 _expr7 = u_entity.world; - float4 world_pos = mul(float4(position), _expr7); + float4x4 _expr5 = u_entity.world; + float4 world_pos = mul(float4(position), _expr5); 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 _expr31 = out_; + const VertexOutput vertexoutput = _expr31; const VertexOutput_vs_main vertexoutput_1 = { vertexoutput.world_normal, vertexoutput.world_position, vertexoutput.proj_position }; return vertexoutput_1; } @@ -88,67 +88,79 @@ 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); - bool loop_init = true; - while(true) { - if (!loop_init) { - uint _expr20 = i; - i = (_expr20 + 1u); + color = float3(0.05, 0.05, 0.05); + { + i = 0u; + bool loop_init = true; + while(true) { + if (!loop_init) { + uint _expr46 = i; + i = (_expr46 + 1u); + } + loop_init = false; + uint _expr8 = i; + uint _expr12 = u_globals.num_lights.x; + if ((_expr8 < min(_expr12, c_max_lights))) { + } else { + break; + } + { + uint _expr18 = i; + Light light = ConstructLight(float4x4(asfloat(s_lights.Load4(_expr18*96+0+0)), asfloat(s_lights.Load4(_expr18*96+0+16)), asfloat(s_lights.Load4(_expr18*96+0+32)), asfloat(s_lights.Load4(_expr18*96+0+48))), asfloat(s_lights.Load4(_expr18*96+64)), asfloat(s_lights.Load4(_expr18*96+80))); + uint _expr23 = i; + const float _e21 = fetch_shadow(_expr23, 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 _expr43 = color; + color = (_expr43 + ((_e21 * diffuse) * light.color.xyz)); + } } - loop_init = false; - uint _expr14 = i; - uint _expr17 = u_globals.num_lights.x; - if ((_expr14 < min(_expr17, 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)); } - float3 _expr46 = color; - float4 _expr50 = u_entity.color; - return (float4(_expr46, 1.0) * _expr50); + float3 _expr50 = color; + float4 _expr55 = u_entity.color; + return (float4(_expr50, 1.0) * _expr55); } 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); - bool loop_init_1 = true; - while(true) { - if (!loop_init_1) { - uint _expr20 = i_1; - i_1 = (_expr20 + 1u); - } - loop_init_1 = false; - uint _expr14 = i_1; - uint _expr17 = u_globals.num_lights.x; - if ((_expr14 < min(_expr17, c_max_lights))) { - } else { - break; + color_1 = float3(0.05, 0.05, 0.05); + { + i_1 = 0u; + bool loop_init_1 = true; + while(true) { + if (!loop_init_1) { + uint _expr46 = i_1; + i_1 = (_expr46 + 1u); + } + loop_init_1 = false; + uint _expr8 = i_1; + uint _expr12 = u_globals.num_lights.x; + if ((_expr8 < min(_expr12, c_max_lights))) { + } else { + break; + } + { + uint _expr18 = i_1; + Light light_1 = u_lights[_expr18]; + uint _expr23 = i_1; + const float _e21 = fetch_shadow(_expr23, 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 _expr43 = color_1; + color_1 = (_expr43 + ((_e21 * diffuse_1) * light_1.color.xyz)); + } } - 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)); } - float3 _expr46 = color_1; - float4 _expr50 = u_entity.color; - return (float4(_expr46, 1.0) * _expr50); + float3 _expr50 = color_1; + float4 _expr55 = u_entity.color; + return (float4(_expr50, 1.0) * _expr55); } diff --git a/tests/out/hlsl/skybox.hlsl b/tests/out/hlsl/skybox.hlsl index 7d5714a22d..e5ee2ec58f 100644 --- a/tests/out/hlsl/skybox.hlsl +++ b/tests/out/hlsl/skybox.hlsl @@ -41,17 +41,19 @@ VertexOutput_vs_main vs_main(uint vertex_index : SV_VertexID) int tmp1_ = (int)0; int tmp2_ = (int)0; - 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); - 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); + int tmp1_1 = (int((_NagaConstants.base_vertex + vertex_index)) / 2); + tmp1_ = tmp1_1; + int tmp2_1 = (int((_NagaConstants.base_vertex + vertex_index)) & 1); + tmp2_ = tmp2_1; + int _expr11 = tmp1_; + int _expr18 = tmp2_; + float4 pos = float4(((float(_expr11) * 4.0) - 1.0), ((float(_expr18) * 4.0) - 1.0), 0.0, 1.0); + float4 _expr31 = r_data.view[0]; + float4 _expr37 = r_data.view[1]; + float4 _expr43 = r_data.view[2]; + float3x3 inv_model_view = transpose(float3x3(_expr31.xyz, _expr37.xyz, _expr43.xyz)); + float4x4 _expr49 = r_data.proj_inv; + float4 unprojected = mul(pos, _expr49); 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 +62,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..ee56b7c64d 100644 --- a/tests/out/hlsl/texture-arg.hlsl +++ b/tests/out/hlsl/texture-arg.hlsl @@ -4,12 +4,12 @@ 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 { - const float4 _e2 = test(Texture, Sampler); - return _e2; + const float4 _e0 = test(Texture, Sampler); + return _e0; } diff --git a/tests/out/ir/collatz.ron b/tests/out/ir/collatz.ron index 2f3d06d137..049c4d5f20 100644 --- a/tests/out/ir/collatz.ron +++ b/tests/out/ir/collatz.ron @@ -1,14 +1,14 @@ ( types: [ ( - name: None, + name: Some("u32"), inner: Scalar( kind: Uint, width: 4, ), ), ( - name: None, + name: Some("array"), inner: Array( base: 1, size: Dynamic, @@ -30,13 +30,35 @@ ), ), ( - name: None, + name: Some("vec3"), inner: Vector( size: Tri, kind: Uint, width: 4, ), ), + ( + name: Some("ptr"), + inner: Pointer( + base: 3, + space: Storage( + access: ( + bits: 3, + ), + ), + ), + ), + ( + name: Some("ptr>"), + inner: Pointer( + base: 2, + space: Storage( + access: ( + bits: 3, + ), + ), + ), + ), ], constants: [ ( @@ -111,17 +133,17 @@ ( name: Some("i"), ty: 1, - init: Some(1), + init: None, ), ], expressions: [ - GlobalVariable(1), FunctionArgument(0), LocalVariable(1), Constant(1), LocalVariable(2), + LocalVariable(1), Load( - pointer: 3, + pointer: 5, ), Constant(2), Binary( @@ -129,63 +151,78 @@ left: 6, right: 7, ), + LocalVariable(1), Load( - pointer: 3, + pointer: 9, ), Constant(3), Binary( op: Modulo, - left: 9, - right: 10, + left: 10, + right: 11, ), Constant(1), Binary( op: Equal, - left: 11, - right: 12, + left: 12, + right: 13, ), + LocalVariable(1), Load( - pointer: 3, + pointer: 15, ), Constant(3), Binary( op: Divide, - left: 14, - right: 15, + left: 16, + right: 17, ), + LocalVariable(1), Constant(4), + LocalVariable(1), Load( - pointer: 3, + pointer: 21, ), Binary( op: Multiply, - left: 17, - right: 18, + left: 20, + right: 22, ), Constant(2), Binary( op: Add, - left: 19, - right: 20, + left: 23, + right: 24, ), + LocalVariable(1), + LocalVariable(2), Load( - pointer: 5, + pointer: 27, ), Constant(2), Binary( op: Add, - left: 22, - right: 23, + left: 28, + right: 29, ), + LocalVariable(2), + LocalVariable(2), Load( - pointer: 5, + pointer: 32, ), ], - named_expressions: {}, + named_expressions: { + 1: "n", + 3: "i", + }, body: [ Store( - pointer: 3, - value: 2, + pointer: 2, + value: 1, + ), + Store( + pointer: 4, + value: 3, ), Loop( body: [ @@ -204,71 +241,79 @@ 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: 9, + end: 10, + )), + Emit(( + start: 11, + end: 12, + )), + Emit(( + start: 13, + end: 14, + )), + If( + condition: 14, + accept: [ + Emit(( + start: 15, + end: 16, + )), + Emit(( + start: 17, + end: 18, + )), + Store( + pointer: 19, + value: 18, + ), + ], + reject: [ + Block([ + Emit(( + start: 21, + end: 22, + )), + Emit(( + start: 22, + end: 23, + )), + Emit(( + start: 24, + end: 25, + )), + Store( + pointer: 26, + value: 25, + ), + ]), + ], + ), + Emit(( + start: 27, + end: 28, + )), + Emit(( + start: 29, + end: 30, + )), + Store( + pointer: 31, + value: 30, + ), + ]), ], continuing: [], break_if: None, ), Emit(( - start: 24, - end: 25, + start: 32, + end: 33, )), Return( - value: Some(25), + value: Some(33), ), ], ), @@ -291,53 +336,79 @@ result: None, local_variables: [], expressions: [ + CallResult(1), GlobalVariable(1), - FunctionArgument(0), AccessIndex( - base: 1, + base: 2, index: 0, ), + FunctionArgument(0), AccessIndex( - base: 2, + base: 4, index: 0, ), Access( base: 3, - index: 4, + index: 5, ), + Load( + pointer: 6, + ), + GlobalVariable(1), AccessIndex( - base: 1, + base: 8, index: 0, ), + FunctionArgument(0), AccessIndex( - base: 2, + base: 10, index: 0, ), Access( - base: 6, - index: 7, + base: 9, + index: 11, ), - Load( - pointer: 8, - ), - CallResult(1), ], named_expressions: {}, body: [ Emit(( start: 2, - end: 9, + end: 3, + )), + Emit(( + start: 4, + end: 5, + )), + Emit(( + start: 5, + end: 6, + )), + Emit(( + start: 6, + end: 7, )), Call( function: 1, arguments: [ - 9, + 7, ], - result: Some(10), + result: Some(1), ), + Emit(( + start: 8, + end: 9, + )), + Emit(( + start: 10, + end: 11, + )), + Emit(( + start: 11, + end: 12, + )), Store( - pointer: 5, - value: 10, + pointer: 12, + value: 1, ), Return( value: None, diff --git a/tests/out/msl/access.msl b/tests/out/msl/access.msl index 19e4ab21d7..1ca1aa052d 100644 --- a/tests/out/msl/access.msl +++ b/tests/out/msl/access.msl @@ -8,148 +8,189 @@ struct _mslBufferSizes { uint size1; }; +typedef uint u32_; +typedef metal::uint3 vec3u32_; +typedef int i32_; struct GlobalConst { - uint a; + u32_ a; char _pad1[12]; metal::packed_uint3 b; - int c; + i32_ c; }; struct AlignedWrapper { - int value; + i32_ value; }; -struct type_5 { - metal::float2x2 inner[2]; +typedef metal::float4x3 mat4x3f32_; +typedef metal::float2x2 mat2x2f32_; +struct arraymat2x2f322_ { + mat2x2f32_ inner[2u]; }; -struct type_8 { - metal::uint2 inner[2]; +typedef metal::atomic_int atomici32_; +typedef metal::uint2 vec2u32_; +struct arrayvec2u322_ { + vec2u32_ inner[2u]; }; -typedef AlignedWrapper type_9[1]; +typedef AlignedWrapper arrayAlignedWrapper[1]; struct Bar { - metal::float4x3 _matrix; - type_5 matrix_array; - metal::atomic_int atom; + mat4x3f32_ _matrix; + arraymat2x2f322_ matrix_array; + atomici32_ atom; char _pad3[4]; - type_8 arr; - type_9 data; + arrayvec2u322_ arr; + arrayAlignedWrapper data; }; +typedef metal::float3x2 mat3x2f32_; struct Baz { - metal::float3x2 m; + mat3x2f32_ m; }; -struct type_13 { - metal::float4x2 inner[2]; +typedef metal::int2 vec2i32_; +typedef constant Baz& ptruniformBaz; +typedef constant mat3x2f32_& ptruniformmat3x2f32_; +typedef constant metal::float2& ptruniformvec2f32_; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef thread Baz& ptrfunctionBaz; +typedef thread mat3x2f32_& ptrfunctionmat3x2f32_; +typedef thread metal::float2& ptrfunctionvec2f32_; +typedef metal::float4x2 mat4x2f32_; +struct arraymat4x2f322_ { + mat4x2f32_ inner[2u]; }; struct MatCx2InArray { - type_13 am; + arraymat4x2f322_ am; }; -struct type_17 { - float inner[10]; +typedef constant MatCx2InArray& ptruniformMatCx2InArray; +typedef constant arraymat4x2f322_& ptruniformarraymat4x2f322_; +typedef constant mat4x2f32_& ptruniformmat4x2f32_; +typedef thread MatCx2InArray& ptrfunctionMatCx2InArray; +typedef thread arraymat4x2f322_& ptrfunctionarraymat4x2f322_; +typedef thread mat4x2f32_& ptrfunctionmat4x2f32_; +typedef thread f32_& ptrfunctionf32_; +struct arrayf3210_ { + f32_ inner[10u]; }; -struct type_18 { - type_17 inner[5]; +struct arrayarrayf32105_ { + arrayf3210_ inner[5u]; }; -struct type_21 { - int inner[5]; +typedef metal::float4 vec4f32_; +typedef device Bar& ptrstorageBar; +typedef device mat4x3f32_& ptrstoragemat4x3f32_; +typedef device metal::float3& ptrstoragevec3f32_; +typedef metal::float3 vec3f32_; +typedef device arrayAlignedWrapper& ptrstoragearrayAlignedWrapper; +typedef device AlignedWrapper& ptrstorageAlignedWrapper; +typedef device i32_& ptrstoragei32_; +struct arrayi325_ { + i32_ inner[5u]; }; -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 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}; +typedef thread arrayi325_& ptrfunctionarrayi325_; +typedef metal::int4 vec4i32_; +typedef device atomici32_& ptrstorageatomici32_; +typedef threadgroup u32_& ptrworkgroupu32_; +constant vec3u32_ const_vec3u32_ = {0u, 0u, 0u}; +constant GlobalConst const_GlobalConst = {0u, {}, const_vec3u32_, 0}; +constant vec2f32_ const_vec2f32_ = {0.0, 0.0}; +constant mat4x2f32_ const_mat4x2f32_ = {const_vec2f32_, const_vec2f32_, const_vec2f32_, const_vec2f32_}; +constant arraymat4x2f322_ const_arraymat4x2f322_ = {const_mat4x2f32_, const_mat4x2f32_}; +constant arrayf3210_ const_arrayf3210_ = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; +constant arrayarrayf32105_ const_arrayarrayf32105_ = {const_arrayf3210_, const_arrayf3210_, const_arrayf3210_, const_arrayf3210_, const_arrayf3210_}; +constant vec2i32_ const_vec2i32_ = {0, 0}; void test_matrix_within_struct_accesses( constant Baz& baz ) { - int idx = 1; + i32_ idx = {}; Baz t = {}; - int _e6 = idx; - idx = _e6 - 1; - metal::float3x2 unnamed = baz.m; + idx = 1; + i32_ _e3 = idx; + idx = _e3 - 1; + mat3x2f32_ unnamed = baz.m; metal::float2 unnamed_1 = baz.m[0]; - int _e16 = idx; - metal::float2 unnamed_2 = baz.m[_e16]; + i32_ _e17 = idx; + metal::float2 unnamed_2 = baz.m[_e17]; 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]; - t = Baz {metal::float3x2(metal::float2(1.0), metal::float2(2.0), metal::float2(3.0))}; - int _e52 = idx; - idx = _e52 + 1; + i32_ _e32 = idx; + float unnamed_4 = baz.m[0][_e32]; + i32_ _e38 = idx; + float unnamed_5 = baz.m[_e38].y; + i32_ _e46 = idx; + i32_ _e49 = idx; + float unnamed_6 = baz.m[_e46][_e49]; + Baz t_2 = Baz {metal::float3x2(metal::float2(1.0), metal::float2(2.0), metal::float2(3.0))}; + t = t_2; + i32_ _e62 = idx; + idx = _e62 + 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); + i32_ _e85 = idx; + t.m[_e85] = 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; + i32_ _e99 = idx; + t.m[0][_e99] = 20.0; + i32_ _e105 = idx; + t.m[_e105].y = 30.0; + i32_ _e113 = idx; + i32_ _e116 = idx; + t.m[_e113][_e116] = 40.0; return; } void test_matrix_within_array_within_struct_accesses( constant MatCx2InArray& nested_mat_cx2_ ) { - int idx_1 = 1; + i32_ idx_1 = {}; MatCx2InArray t_1 = {}; - int _e7 = idx_1; - idx_1 = _e7 - 1; - type_13 unnamed_7 = nested_mat_cx2_.am; - metal::float4x2 unnamed_8 = nested_mat_cx2_.am.inner[0]; + idx_1 = 1; + i32_ _e3 = idx_1; + idx_1 = _e3 - 1; + arraymat4x2f322_ unnamed_7 = nested_mat_cx2_.am; + mat4x2f32_ 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]; + i32_ _e26 = idx_1; + metal::float2 unnamed_10 = nested_mat_cx2_.am.inner[0][_e26]; 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]; + i32_ _e45 = idx_1; + float unnamed_12 = nested_mat_cx2_.am.inner[0][0][_e45]; + i32_ _e53 = idx_1; + float unnamed_13 = nested_mat_cx2_.am.inner[0][_e53].y; + i32_ _e63 = idx_1; + i32_ _e66 = idx_1; + float unnamed_14 = nested_mat_cx2_.am.inner[0][_e63][_e66]; + MatCx2InArray t_3 = MatCx2InArray {const_arraymat4x2f322_}; + t_1 = t_3; + i32_ _e73 = idx_1; + idx_1 = _e73 + 1; + for(int _i=0; _i<2; ++_i) t_1.am.inner[_i] = const_arraymat4x2f322_.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); + i32_ _e107 = idx_1; + t_1.am.inner[0][_e107] = 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; + i32_ _e125 = idx_1; + t_1.am.inner[0][0][_e125] = 20.0; + i32_ _e133 = idx_1; + t_1.am.inner[0][_e133].y = 30.0; + i32_ _e143 = idx_1; + i32_ _e146 = idx_1; + t_1.am.inner[0][_e143][_e146] = 40.0; return; } -float read_from_private( - thread float& foo_1 +f32_ read_from_private( + ptrfunctionf32_ foo_1 ) { - float _e6 = foo_1; - return _e6; + f32_ _e1 = foo_1; + return _e1; } -float test_arr_as_arg( - type_18 a +f32_ test_arr_as_arg( + arrayarrayf32105_ a ) { return a.inner[4].inner[9]; } void assign_through_ptr_fn( - threadgroup uint& p + ptrworkgroupu32_ p ) { p = 42u; return; @@ -161,29 +202,31 @@ struct foo_vertOutput { metal::float4 member [[position]]; }; vertex foo_vertOutput foo_vert( - uint vi [[vertex_id]] + u32_ vi [[vertex_id]] , device Bar const& bar [[buffer(0)]] , constant Baz& baz [[buffer(1)]] -, device metal::int2 const& qux [[buffer(2)]] +, device vec2i32_ const& qux [[buffer(2)]] , constant MatCx2InArray& nested_mat_cx2_ [[buffer(3)]] , constant _mslBufferSizes& _buffer_sizes [[buffer(24)]] ) { - float foo = 0.0; - type_21 c = {}; - float baz_1 = foo; + f32_ foo = {}; + arrayi325_ d = {}; + foo = 0.0; + f32_ baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(baz); test_matrix_within_array_within_struct_accesses(nested_mat_cx2_); - metal::float4x3 _matrix = bar._matrix; - type_8 arr = bar.arr; + mat4x3f32_ _matrix = bar._matrix; + arrayvec2u322_ 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_); + i32_ a_1 = bar.data[(1 + (_buffer_sizes.size1 - 120 - 8) / 8) - 2u].value; + vec2i32_ c = qux; + f32_ _e35 = read_from_private(foo); + arrayi325_ d_1 = arrayi325_ {a_1, static_cast(b), 3, 4, 5}; + for(int _i=0; _i<5; ++_i) d.inner[_i] = d_1.inner[_i]; + d.inner[vi + 1u] = 42; + i32_ value = d.inner[vi]; + f32_ _e53 = test_arr_as_arg(const_arrayarrayf32105_); return foo_vertOutput { metal::float4(_matrix * static_cast(metal::int4(value)), 2.0) }; } @@ -193,14 +236,14 @@ struct foo_fragOutput { }; fragment foo_fragOutput foo_frag( device Bar& bar [[buffer(0)]] -, device metal::int2& qux [[buffer(2)]] +, device vec2i32_& qux [[buffer(2)]] , constant _mslBufferSizes& _buffer_sizes [[buffer(24)]] ) { bar._matrix[1].z = 1.0; bar._matrix = metal::float4x3(metal::float3(0.0), metal::float3(1.0), metal::float3(2.0), metal::float3(3.0)); - for(int _i=0; _i<2; ++_i) bar.arr.inner[_i] = type_8 {metal::uint2(0u), metal::uint2(1u)}.inner[_i]; + for(int _i=0; _i<2; ++_i) bar.arr.inner[_i] = arrayvec2u322_ {metal::uint2(0u), metal::uint2(1u)}.inner[_i]; bar.data[1].value = 1; - qux = const_type_11_; + qux = const_vec2i32_; return foo_fragOutput { metal::float4(0.0) }; } @@ -209,31 +252,31 @@ kernel void atomics( device Bar& bar [[buffer(0)]] , constant _mslBufferSizes& _buffer_sizes [[buffer(24)]] ) { - int tmp = {}; + i32_ 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 _e6 = metal::atomic_fetch_add_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e6; + int _e11 = metal::atomic_fetch_sub_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e11; int _e16 = metal::atomic_fetch_and_explicit(&bar.atom, 5, metal::memory_order_relaxed); tmp = _e16; - 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 _e21 = metal::atomic_fetch_or_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e21; + int _e26 = metal::atomic_fetch_xor_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e26; + int _e31 = metal::atomic_fetch_min_explicit(&bar.atom, 5, metal::memory_order_relaxed); tmp = _e31; + int _e36 = metal::atomic_fetch_max_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e36; + int _e41 = metal::atomic_exchange_explicit(&bar.atom, 5, metal::memory_order_relaxed); + tmp = _e41; metal::atomic_store_explicit(&bar.atom, value_1, metal::memory_order_relaxed); return; } kernel void assign_through_ptr( - threadgroup uint& val + threadgroup u32_& val ) { assign_through_ptr_fn(val); return; diff --git a/tests/out/msl/binding-arrays.msl b/tests/out/msl/binding-arrays.msl index ba3c3c8b06..1ee14024f1 100644 --- a/tests/out/msl/binding-arrays.msl +++ b/tests/out/msl/binding-arrays.msl @@ -10,15 +10,22 @@ struct DefaultConstructible { return T {}; } }; +typedef uint u32_; struct UniformIndex { - uint index; + u32_ index; }; struct FragmentIn { - uint index; + u32_ index; }; +typedef metal::float4 vec4f32_; +typedef constant UniformIndex& ptruniformUniformIndex; +typedef int i32_; +typedef metal::int2 vec2i32_; +typedef float f32_; +typedef metal::float2 vec2f32_; struct main_Input { - uint index [[user(loc0), flat]]; + u32_ index [[user(loc0), flat]]; }; struct main_Output { metal::float4 member [[color(0)]]; @@ -26,147 +33,151 @@ struct main_Output { fragment main_Output main_( main_Input varyings [[stage_in]] , metal::array, 10> texture_array_unbounded [[texture(0)]] -, metal::array, 5> texture_array_bounded [[user(fake0)]] -, metal::array, 5> texture_array_2darray [[user(fake0)]] -, metal::array, 5> texture_array_multisampled [[user(fake0)]] -, metal::array, 5> texture_array_depth [[user(fake0)]] -, metal::array, 5> texture_array_storage [[user(fake0)]] -, metal::array samp [[user(fake0)]] -, metal::array samp_comp [[user(fake0)]] +, metal::array, 5u> texture_array_bounded [[user(fake0)]] +, metal::array, 5u> texture_array_2darray [[user(fake0)]] +, metal::array, 5u> texture_array_multisampled [[user(fake0)]] +, metal::array, 5u> texture_array_depth [[user(fake0)]] +, metal::array, 5u> texture_array_storage [[user(fake0)]] +, metal::array samp [[user(fake0)]] +, metal::array samp_comp [[user(fake0)]] , constant UniformIndex& uni [[user(fake0)]] ) { const FragmentIn fragment_in = { varyings.index }; - int i1_ = 0; - metal::int2 i2_ = {}; - float v1_ = 0.0; - metal::float4 v4_ = {}; - uint uniform_index = uni.index; - uint non_uniform_index = fragment_in.index; - i2_ = metal::int2(0); - v4_ = metal::float4(0.0); + i32_ i1_ = {}; + vec2i32_ i2_ = {}; + f32_ v1_ = {}; + vec4f32_ v4_ = {}; + u32_ uniform_index = uni.index; + u32_ non_uniform_index = fragment_in.index; + i1_ = 0; + metal::int2 i2_1 = metal::int2(0); + i2_ = i2_1; + v1_ = 0.0; + metal::float4 v4_1 = metal::float4(0.0); + v4_ = v4_1; 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_; + vec2i32_ _e24 = i2_; + i2_ = _e24 + metal::int2(texture_array_unbounded[0].get_width(), texture_array_unbounded[0].get_height()); + vec2i32_ _e30 = i2_; + i2_ = _e30 + metal::int2(texture_array_unbounded[uniform_index].get_width(), texture_array_unbounded[uniform_index].get_height()); + vec2i32_ _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::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()); - 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_; + metal::float4 _e44 = texture_array_bounded[0].gather(samp[0], uv); + vec4f32_ _e46 = v4_; + v4_ = _e46 + _e44; + metal::float4 _e52 = texture_array_bounded[uniform_index].gather(samp[uniform_index], uv); + vec4f32_ _e54 = v4_; + v4_ = _e54 + _e52; + metal::float4 _e60 = texture_array_bounded[non_uniform_index].gather(samp[non_uniform_index], uv); + vec4f32_ _e62 = v4_; + v4_ = _e62 + _e60; + metal::float4 _e71 = texture_array_depth[0].gather_compare(samp_comp[0], uv, 0.0); + vec4f32_ _e73 = v4_; + v4_ = _e73 + _e71; + metal::float4 _e80 = texture_array_depth[uniform_index].gather_compare(samp_comp[uniform_index], uv, 0.0); + vec4f32_ _e82 = v4_; + v4_ = _e82 + _e80; + metal::float4 _e89 = texture_array_depth[non_uniform_index].gather_compare(samp_comp[non_uniform_index], uv, 0.0); + vec4f32_ _e91 = v4_; + v4_ = _e91 + _e89; + metal::float4 _e97 = (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()); + vec4f32_ _e99 = v4_; + v4_ = _e99 + _e97; + metal::float4 _e104 = (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()); + vec4f32_ _e106 = v4_; + v4_ = _e106 + _e104; + metal::float4 _e111 = (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()); + vec4f32_ _e113 = v4_; + v4_ = _e113 + _e111; + i32_ _e120 = i1_; + i1_ = _e120 + int(texture_array_2darray[0].get_array_size()); + i32_ _e126 = i1_; + i1_ = _e126 + int(texture_array_2darray[uniform_index].get_array_size()); + i32_ _e132 = i1_; + i1_ = _e132 + int(texture_array_2darray[non_uniform_index].get_array_size()); + i32_ _e139 = i1_; + i1_ = _e139 + int(texture_array_bounded[0].get_num_mip_levels()); + i32_ _e145 = i1_; + i1_ = _e145 + int(texture_array_bounded[uniform_index].get_num_mip_levels()); + i32_ _e151 = i1_; + i1_ = _e151 + int(texture_array_bounded[non_uniform_index].get_num_mip_levels()); + i32_ _e158 = i1_; + i1_ = _e158 + int(texture_array_multisampled[0].get_num_samples()); + i32_ _e164 = i1_; + i1_ = _e164 + int(texture_array_multisampled[uniform_index].get_num_samples()); + i32_ _e170 = i1_; + i1_ = _e170 + int(texture_array_multisampled[non_uniform_index].get_num_samples()); + metal::float4 _e178 = texture_array_bounded[0].sample(samp[0], uv); + vec4f32_ _e180 = v4_; + v4_ = _e180 + _e178; + metal::float4 _e186 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv); + vec4f32_ _e188 = v4_; + v4_ = _e188 + _e186; + metal::float4 _e194 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv); + vec4f32_ _e196 = v4_; + v4_ = _e196 + _e194; + metal::float4 _e205 = texture_array_bounded[0].sample(samp[0], uv, metal::bias(0.0)); + vec4f32_ _e207 = v4_; + v4_ = _e207 + _e205; + metal::float4 _e214 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::bias(0.0)); + vec4f32_ _e216 = v4_; + v4_ = _e216 + _e214; + metal::float4 _e223 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::bias(0.0)); + vec4f32_ _e225 = v4_; + v4_ = _e225 + _e223; + float _e234 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); + f32_ _e236 = v1_; + v1_ = _e236 + _e234; + float _e243 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); + f32_ _e245 = v1_; + v1_ = _e245 + _e243; + float _e252 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); + f32_ _e254 = v1_; + v1_ = _e254 + _e252; + float _e263 = texture_array_depth[0].sample_compare(samp_comp[0], uv, 0.0); + f32_ _e265 = v1_; + v1_ = _e265 + _e263; + float _e272 = texture_array_depth[uniform_index].sample_compare(samp_comp[uniform_index], uv, 0.0); + f32_ _e274 = v1_; + v1_ = _e274 + _e272; + float _e281 = texture_array_depth[non_uniform_index].sample_compare(samp_comp[non_uniform_index], uv, 0.0); + f32_ _e283 = v1_; + v1_ = _e283 + _e281; + metal::float4 _e291 = texture_array_bounded[0].sample(samp[0], uv, metal::gradient2d(uv, uv)); + vec4f32_ _e293 = v4_; + v4_ = _e293 + _e291; + metal::float4 _e299 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::gradient2d(uv, uv)); + vec4f32_ _e301 = v4_; + v4_ = _e301 + _e299; + metal::float4 _e307 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::gradient2d(uv, uv)); + vec4f32_ _e309 = v4_; + v4_ = _e309 + _e307; + metal::float4 _e318 = texture_array_bounded[0].sample(samp[0], uv, metal::level(0.0)); + vec4f32_ _e320 = v4_; + v4_ = _e320 + _e318; + metal::float4 _e327 = texture_array_bounded[uniform_index].sample(samp[uniform_index], uv, metal::level(0.0)); + vec4f32_ _e329 = v4_; + v4_ = _e329 + _e327; + metal::float4 _e336 = texture_array_bounded[non_uniform_index].sample(samp[non_uniform_index], uv, metal::level(0.0)); + vec4f32_ _e338 = v4_; + v4_ = _e338 + _e336; + vec4f32_ _e344 = 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(_e344, metal::uint2(pix)); } - metal::float4 _e250 = v4_; + vec4f32_ _e348 = 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(_e348, metal::uint2(pix)); } - metal::float4 _e252 = v4_; + vec4f32_ _e352 = 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(_e352, 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) }; + vec2i32_ _e354 = i2_; + i32_ _e356 = i1_; + metal::float2 v2_ = static_cast(_e354 + metal::int2(_e356)); + vec4f32_ _e361 = v4_; + f32_ _e369 = v1_; + return main_Output { (_e361 + metal::float4(v2_.x, v2_.y, v2_.x, v2_.y)) + metal::float4(_e369) }; } diff --git a/tests/out/msl/bitcast.msl b/tests/out/msl/bitcast.msl index a0cf093b7f..8f10aeabbf 100644 --- a/tests/out/msl/bitcast.msl +++ b/tests/out/msl/bitcast.msl @@ -4,44 +4,65 @@ using metal::uint; +typedef int i32_; +typedef metal::int2 vec2i32_; +typedef metal::int3 vec3i32_; +typedef metal::int4 vec4i32_; +typedef uint u32_; +typedef metal::uint2 vec2u32_; +typedef metal::uint3 vec3u32_; +typedef metal::uint4 vec4u32_; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef metal::float3 vec3f32_; +typedef metal::float4 vec4f32_; kernel void main_( ) { - metal::int2 i2_ = {}; - metal::int3 i3_ = {}; - metal::int4 i4_ = {}; - metal::uint2 u2_ = {}; - metal::uint3 u3_ = {}; - metal::uint4 u4_ = {}; - metal::float2 f2_ = {}; - metal::float3 f3_ = {}; - metal::float4 f4_ = {}; - i2_ = metal::int2(0); - i3_ = metal::int3(0); - i4_ = metal::int4(0); - u2_ = metal::uint2(0u); - u3_ = metal::uint3(0u); - u4_ = metal::uint4(0u); - f2_ = metal::float2(0.0); - f3_ = metal::float3(0.0); - f4_ = metal::float4(0.0); - metal::int2 _e27 = i2_; - u2_ = as_type(_e27); - metal::int3 _e29 = i3_; - u3_ = as_type(_e29); - metal::int4 _e31 = i4_; - u4_ = as_type(_e31); - metal::uint2 _e33 = u2_; - i2_ = as_type(_e33); - metal::uint3 _e35 = u3_; - i3_ = as_type(_e35); - metal::uint4 _e37 = u4_; - i4_ = as_type(_e37); - metal::int2 _e39 = i2_; - f2_ = as_type(_e39); - metal::int3 _e41 = i3_; - f3_ = as_type(_e41); - metal::int4 _e43 = i4_; - f4_ = as_type(_e43); + vec2i32_ i2_ = {}; + vec3i32_ i3_ = {}; + vec4i32_ i4_ = {}; + vec2u32_ u2_ = {}; + vec3u32_ u3_ = {}; + vec4u32_ u4_ = {}; + vec2f32_ f2_ = {}; + vec3f32_ f3_ = {}; + vec4f32_ f4_ = {}; + metal::int2 i2_1 = metal::int2(0); + i2_ = i2_1; + metal::int3 i3_1 = metal::int3(0); + i3_ = i3_1; + metal::int4 i4_1 = metal::int4(0); + i4_ = i4_1; + metal::uint2 u2_1 = metal::uint2(0u); + u2_ = u2_1; + metal::uint3 u3_1 = metal::uint3(0u); + u3_ = u3_1; + metal::uint4 u4_1 = metal::uint4(0u); + u4_ = u4_1; + metal::float2 f2_1 = metal::float2(0.0); + f2_ = f2_1; + metal::float3 f3_1 = metal::float3(0.0); + f3_ = f3_1; + metal::float4 f4_1 = metal::float4(0.0); + f4_ = f4_1; + vec2i32_ _e28 = i2_; + u2_ = as_type(_e28); + vec3i32_ _e32 = i3_; + u3_ = as_type(_e32); + vec4i32_ _e36 = i4_; + u4_ = as_type(_e36); + vec2u32_ _e40 = u2_; + i2_ = as_type(_e40); + vec3u32_ _e44 = u3_; + i3_ = as_type(_e44); + vec4u32_ _e48 = u4_; + i4_ = as_type(_e48); + vec2i32_ _e52 = i2_; + f2_ = as_type(_e52); + vec3i32_ _e56 = i3_; + f3_ = as_type(_e56); + vec4i32_ _e60 = i4_; + f4_ = as_type(_e60); return; } diff --git a/tests/out/msl/bits.msl b/tests/out/msl/bits.msl index 9c9eedaebf..77c2fd8d5c 100644 --- a/tests/out/msl/bits.msl +++ b/tests/out/msl/bits.msl @@ -4,126 +4,147 @@ using metal::uint; +typedef int i32_; +typedef metal::int2 vec2i32_; +typedef metal::int3 vec3i32_; +typedef metal::int4 vec4i32_; +typedef uint u32_; +typedef metal::uint2 vec2u32_; +typedef metal::uint3 vec3u32_; +typedef metal::uint4 vec4u32_; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef metal::float4 vec4f32_; kernel void main_( ) { - int i = 0; - metal::int2 i2_ = {}; - metal::int3 i3_ = {}; - metal::int4 i4_ = {}; - uint u = 0u; - metal::uint2 u2_ = {}; - metal::uint3 u3_ = {}; - metal::uint4 u4_ = {}; - metal::float2 f2_ = {}; - metal::float4 f4_ = {}; - i2_ = metal::int2(0); - i3_ = metal::int3(0); - i4_ = metal::int4(0); - u2_ = metal::uint2(0u); - u3_ = metal::uint3(0u); - u4_ = metal::uint4(0u); - f2_ = metal::float2(0.0); - f4_ = metal::float4(0.0); - metal::float4 _e28 = f4_; - u = metal::pack_float_to_snorm4x8(_e28); - metal::float4 _e30 = f4_; - u = metal::pack_float_to_unorm4x8(_e30); - metal::float2 _e32 = f2_; - u = metal::pack_float_to_snorm2x16(_e32); - metal::float2 _e34 = f2_; - u = metal::pack_float_to_unorm2x16(_e34); - metal::float2 _e36 = f2_; - u = as_type(half2(_e36)); - uint _e38 = u; - f4_ = metal::unpack_snorm4x8_to_float(_e38); - uint _e40 = u; - f4_ = metal::unpack_unorm4x8_to_float(_e40); - uint _e42 = u; - f2_ = metal::unpack_snorm2x16_to_float(_e42); - uint _e44 = u; - f2_ = metal::unpack_unorm2x16_to_float(_e44); - uint _e46 = u; - f2_ = float2(as_type(_e46)); - int _e48 = i; - int _e49 = i; - i = metal::insert_bits(_e48, _e49, 5u, 10u); - metal::int2 _e53 = i2_; - metal::int2 _e54 = i2_; - i2_ = metal::insert_bits(_e53, _e54, 5u, 10u); - metal::int3 _e58 = i3_; - metal::int3 _e59 = i3_; - i3_ = metal::insert_bits(_e58, _e59, 5u, 10u); - metal::int4 _e63 = i4_; - metal::int4 _e64 = i4_; - i4_ = metal::insert_bits(_e63, _e64, 5u, 10u); - uint _e68 = u; - uint _e69 = u; - u = metal::insert_bits(_e68, _e69, 5u, 10u); - metal::uint2 _e73 = u2_; - metal::uint2 _e74 = u2_; - u2_ = metal::insert_bits(_e73, _e74, 5u, 10u); - metal::uint3 _e78 = u3_; - metal::uint3 _e79 = u3_; - u3_ = metal::insert_bits(_e78, _e79, 5u, 10u); - metal::uint4 _e83 = u4_; - metal::uint4 _e84 = u4_; - u4_ = metal::insert_bits(_e83, _e84, 5u, 10u); - int _e88 = i; - i = metal::extract_bits(_e88, 5u, 10u); - metal::int2 _e92 = i2_; - i2_ = metal::extract_bits(_e92, 5u, 10u); - metal::int3 _e96 = i3_; - i3_ = metal::extract_bits(_e96, 5u, 10u); - metal::int4 _e100 = i4_; - i4_ = metal::extract_bits(_e100, 5u, 10u); - uint _e104 = u; - u = metal::extract_bits(_e104, 5u, 10u); - metal::uint2 _e108 = u2_; - u2_ = metal::extract_bits(_e108, 5u, 10u); - metal::uint3 _e112 = u3_; - u3_ = metal::extract_bits(_e112, 5u, 10u); - metal::uint4 _e116 = u4_; - u4_ = metal::extract_bits(_e116, 5u, 10u); - int _e120 = i; - i = (((metal::ctz(_e120) + 1) % 33) - 1); - metal::uint2 _e122 = u2_; - u2_ = (((metal::ctz(_e122) + 1) % 33) - 1); - metal::int3 _e124 = i3_; - i3_ = (((metal::clz(_e124) + 1) % 33) - 1); - uint _e126 = u; - u = (((metal::clz(_e126) + 1) % 33) - 1); - int _e128 = i; - i = metal::popcount(_e128); - metal::int2 _e130 = i2_; - i2_ = metal::popcount(_e130); - metal::int3 _e132 = i3_; - i3_ = metal::popcount(_e132); - metal::int4 _e134 = i4_; - i4_ = metal::popcount(_e134); - uint _e136 = u; - u = metal::popcount(_e136); - metal::uint2 _e138 = u2_; - u2_ = metal::popcount(_e138); - metal::uint3 _e140 = u3_; - u3_ = metal::popcount(_e140); - metal::uint4 _e142 = u4_; - u4_ = metal::popcount(_e142); - int _e144 = i; - i = metal::reverse_bits(_e144); - metal::int2 _e146 = i2_; - i2_ = metal::reverse_bits(_e146); - metal::int3 _e148 = i3_; - i3_ = metal::reverse_bits(_e148); - metal::int4 _e150 = i4_; - i4_ = metal::reverse_bits(_e150); - uint _e152 = u; - u = metal::reverse_bits(_e152); - metal::uint2 _e154 = u2_; - u2_ = metal::reverse_bits(_e154); - metal::uint3 _e156 = u3_; - u3_ = metal::reverse_bits(_e156); - metal::uint4 _e158 = u4_; - u4_ = metal::reverse_bits(_e158); + i32_ i = {}; + vec2i32_ i2_ = {}; + vec3i32_ i3_ = {}; + vec4i32_ i4_ = {}; + u32_ u = {}; + vec2u32_ u2_ = {}; + vec3u32_ u3_ = {}; + vec4u32_ u4_ = {}; + vec2f32_ f2_ = {}; + vec4f32_ f4_ = {}; + i = 0; + metal::int2 i2_1 = metal::int2(0); + i2_ = i2_1; + metal::int3 i3_1 = metal::int3(0); + i3_ = i3_1; + metal::int4 i4_1 = metal::int4(0); + i4_ = i4_1; + u = 0u; + metal::uint2 u2_1 = metal::uint2(0u); + u2_ = u2_1; + metal::uint3 u3_1 = metal::uint3(0u); + u3_ = u3_1; + metal::uint4 u4_1 = metal::uint4(0u); + u4_ = u4_1; + metal::float2 f2_1 = metal::float2(0.0); + f2_ = f2_1; + metal::float4 f4_1 = metal::float4(0.0); + f4_ = f4_1; + vec4f32_ _e29 = f4_; + u = metal::pack_float_to_snorm4x8(_e29); + vec4f32_ _e33 = f4_; + u = metal::pack_float_to_unorm4x8(_e33); + vec2f32_ _e37 = f2_; + u = metal::pack_float_to_snorm2x16(_e37); + vec2f32_ _e41 = f2_; + u = metal::pack_float_to_unorm2x16(_e41); + vec2f32_ _e45 = f2_; + u = as_type(half2(_e45)); + u32_ _e49 = u; + f4_ = metal::unpack_snorm4x8_to_float(_e49); + u32_ _e53 = u; + f4_ = metal::unpack_unorm4x8_to_float(_e53); + u32_ _e57 = u; + f2_ = metal::unpack_snorm2x16_to_float(_e57); + u32_ _e61 = u; + f2_ = metal::unpack_unorm2x16_to_float(_e61); + u32_ _e65 = u; + f2_ = float2(as_type(_e65)); + i32_ _e69 = i; + i32_ _e71 = i; + i = metal::insert_bits(_e69, _e71, 5u, 10u); + vec2i32_ _e77 = i2_; + vec2i32_ _e79 = i2_; + i2_ = metal::insert_bits(_e77, _e79, 5u, 10u); + vec3i32_ _e85 = i3_; + vec3i32_ _e87 = i3_; + i3_ = metal::insert_bits(_e85, _e87, 5u, 10u); + vec4i32_ _e93 = i4_; + vec4i32_ _e95 = i4_; + i4_ = metal::insert_bits(_e93, _e95, 5u, 10u); + u32_ _e101 = u; + u32_ _e103 = u; + u = metal::insert_bits(_e101, _e103, 5u, 10u); + vec2u32_ _e109 = u2_; + vec2u32_ _e111 = u2_; + u2_ = metal::insert_bits(_e109, _e111, 5u, 10u); + vec3u32_ _e117 = u3_; + vec3u32_ _e119 = u3_; + u3_ = metal::insert_bits(_e117, _e119, 5u, 10u); + vec4u32_ _e125 = u4_; + vec4u32_ _e127 = u4_; + u4_ = metal::insert_bits(_e125, _e127, 5u, 10u); + i32_ _e133 = i; + i = metal::extract_bits(_e133, 5u, 10u); + vec2i32_ _e139 = i2_; + i2_ = metal::extract_bits(_e139, 5u, 10u); + vec3i32_ _e145 = i3_; + i3_ = metal::extract_bits(_e145, 5u, 10u); + vec4i32_ _e151 = i4_; + i4_ = metal::extract_bits(_e151, 5u, 10u); + u32_ _e157 = u; + u = metal::extract_bits(_e157, 5u, 10u); + vec2u32_ _e163 = u2_; + u2_ = metal::extract_bits(_e163, 5u, 10u); + vec3u32_ _e169 = u3_; + u3_ = metal::extract_bits(_e169, 5u, 10u); + vec4u32_ _e175 = u4_; + u4_ = metal::extract_bits(_e175, 5u, 10u); + i32_ _e181 = i; + i = (((metal::ctz(_e181) + 1) % 33) - 1); + vec2u32_ _e185 = u2_; + u2_ = (((metal::ctz(_e185) + 1) % 33) - 1); + vec3i32_ _e189 = i3_; + i3_ = (((metal::clz(_e189) + 1) % 33) - 1); + u32_ _e193 = u; + u = (((metal::clz(_e193) + 1) % 33) - 1); + i32_ _e197 = i; + i = metal::popcount(_e197); + vec2i32_ _e201 = i2_; + i2_ = metal::popcount(_e201); + vec3i32_ _e205 = i3_; + i3_ = metal::popcount(_e205); + vec4i32_ _e209 = i4_; + i4_ = metal::popcount(_e209); + u32_ _e213 = u; + u = metal::popcount(_e213); + vec2u32_ _e217 = u2_; + u2_ = metal::popcount(_e217); + vec3u32_ _e221 = u3_; + u3_ = metal::popcount(_e221); + vec4u32_ _e225 = u4_; + u4_ = metal::popcount(_e225); + i32_ _e229 = i; + i = metal::reverse_bits(_e229); + vec2i32_ _e233 = i2_; + i2_ = metal::reverse_bits(_e233); + vec3i32_ _e237 = i3_; + i3_ = metal::reverse_bits(_e237); + vec4i32_ _e241 = i4_; + i4_ = metal::reverse_bits(_e241); + u32_ _e245 = u; + u = metal::reverse_bits(_e245); + vec2u32_ _e249 = u2_; + u2_ = metal::reverse_bits(_e249); + vec3u32_ _e253 = u3_; + u3_ = metal::reverse_bits(_e253); + vec4u32_ _e257 = u4_; + u4_ = metal::reverse_bits(_e257); return; } diff --git a/tests/out/msl/boids.msl b/tests/out/msl/boids.msl index fd46d1f21c..cf07a6288c 100644 --- a/tests/out/msl/boids.msl +++ b/tests/out/msl/boids.msl @@ -10,152 +10,171 @@ struct _mslBufferSizes { }; constexpr constant unsigned NUM_PARTICLES = 1500u; +typedef uint u32_; +typedef metal::float2 vec2f32_; struct Particle { - metal::float2 pos; - metal::float2 vel; + vec2f32_ pos; + vec2f32_ vel; }; +typedef float f32_; struct SimParams { - float deltaT; - float rule1Distance; - float rule2Distance; - float rule3Distance; - float rule1Scale; - float rule2Scale; - float rule3Scale; + f32_ deltaT; + f32_ rule1Distance; + f32_ rule2Distance; + f32_ rule3Distance; + f32_ rule1Scale; + f32_ rule2Scale; + f32_ rule3Scale; }; -typedef Particle type_3[1]; +typedef Particle arrayParticle[1]; struct Particles { - type_3 particles; + arrayParticle particles; }; +typedef metal::uint3 vec3u32_; +typedef device Particles& ptrstorageParticles; +typedef device arrayParticle& ptrstoragearrayParticle; +typedef device Particle& ptrstorageParticle; +typedef int i32_; +typedef constant SimParams& ptruniformSimParams; +typedef thread vec2f32_& ptrfunctionvec2f32_; +typedef device Particles& ptrstorageParticles_1; +typedef device arrayParticle& ptrstoragearrayParticle_1; +typedef device Particle& ptrstorageParticle_1; struct main_Input { }; kernel void main_( - metal::uint3 global_invocation_id [[thread_position_in_grid]] + vec3u32_ global_invocation_id [[thread_position_in_grid]] , constant SimParams& params [[buffer(0)]] , device Particles const& particlesSrc [[buffer(1)]] , device Particles& particlesDst [[buffer(2)]] , constant _mslBufferSizes& _buffer_sizes [[buffer(3)]] ) { - metal::float2 vPos = {}; - metal::float2 vVel = {}; - metal::float2 cMass = {}; - metal::float2 cVel = {}; - metal::float2 colVel = {}; - int cMassCount = 0; - int cVelCount = 0; - metal::float2 pos = {}; - metal::float2 vel = {}; - uint i = 0u; + vec2f32_ vPos = {}; + vec2f32_ vVel = {}; + vec2f32_ cMass = {}; + vec2f32_ cVel = {}; + vec2f32_ colVel = {}; + i32_ cMassCount = {}; + i32_ cVelCount = {}; + vec2f32_ pos = {}; + vec2f32_ vel = {}; + u32_ 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; - cMass = metal::float2(0.0, 0.0); - cVel = metal::float2(0.0, 0.0); - colVel = metal::float2(0.0, 0.0); + vec2f32_ vPos_1 = particlesSrc.particles[index].pos; + vPos = vPos_1; + vec2f32_ vVel_1 = particlesSrc.particles[index].vel; + vVel = vVel_1; + vec2f32_ cMass_1 = metal::float2(0.0, 0.0); + cMass = cMass_1; + vec2f32_ cVel_1 = metal::float2(0.0, 0.0); + cVel = cVel_1; + vec2f32_ colVel_1 = metal::float2(0.0, 0.0); + colVel = colVel_1; + cMassCount = 0; + cVelCount = 0; + i = 0u; bool loop_init = true; while(true) { if (!loop_init) { - uint _e86 = i; - i = _e86 + 1u; + u32_ _e116 = i; + i = _e116 + 1u; } loop_init = false; - uint _e37 = i; - if (_e37 >= NUM_PARTICLES) { + u32_ _e35 = i; + if (_e35 >= NUM_PARTICLES) { break; } - uint _e39 = i; + u32_ _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; + u32_ _e44 = i; + vec2f32_ _e47 = particlesSrc.particles[_e44].pos; + pos = _e47; + u32_ _e52 = i; + vec2f32_ _e55 = particlesSrc.particles[_e52].vel; + vel = _e55; + vec2f32_ _e58 = pos; + vec2f32_ _e60 = vPos; + f32_ _e64 = params.rule1Distance; + if (metal::distance(_e58, _e60) < _e64) { + vec2f32_ _e67 = cMass; + vec2f32_ _e69 = pos; + cMass = _e67 + _e69; + i32_ _e73 = cMassCount; + cMassCount = _e73 + 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); + vec2f32_ _e78 = pos; + vec2f32_ _e80 = vPos; + f32_ _e84 = params.rule2Distance; + if (metal::distance(_e78, _e80) < _e84) { + vec2f32_ _e87 = colVel; + vec2f32_ _e89 = pos; + vec2f32_ _e91 = vPos; + colVel = _e87 - (_e89 - _e91); } - 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; + vec2f32_ _e96 = pos; + vec2f32_ _e98 = vPos; + f32_ _e102 = params.rule3Distance; + if (metal::distance(_e96, _e98) < _e102) { + vec2f32_ _e105 = cVel; + vec2f32_ _e107 = vel; + cVel = _e105 + _e107; + i32_ _e111 = cVelCount; + cVelCount = _e111 + 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; + i32_ _e121 = cMassCount; + if (_e121 > 0) { + vec2f32_ _e125 = cMass; + i32_ _e127 = cMassCount; + vec2f32_ _e132 = vPos; + cMass = (_e125 / metal::float2(static_cast(_e127))) - _e132; } - int _e99 = cVelCount; - if (_e99 > 0) { - metal::float2 _e102 = cVel; - int _e103 = cVelCount; - cVel = _e102 / metal::float2(static_cast(_e103)); + i32_ _e136 = cVelCount; + if (_e136 > 0) { + vec2f32_ _e140 = cVel; + i32_ _e142 = cVelCount; + cVel = _e140 / metal::float2(static_cast(_e142)); } - 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) { + vec2f32_ _e148 = vVel; + vec2f32_ _e150 = cMass; + f32_ _e153 = params.rule1Scale; + vec2f32_ _e157 = colVel; + f32_ _e160 = params.rule2Scale; + vec2f32_ _e164 = cVel; + f32_ _e167 = params.rule3Scale; + vVel = ((_e148 + (_e150 * _e153)) + (_e157 * _e160)) + (_e164 * _e167); + vec2f32_ _e172 = vVel; + vec2f32_ _e175 = vVel; + vVel = metal::normalize(_e172) * metal::clamp(metal::length(_e175), 0.0, 0.1); + vec2f32_ _e183 = vPos; + vec2f32_ _e185 = vVel; + f32_ _e188 = params.deltaT; + vPos = _e183 + (_e185 * _e188); + float _e194 = vPos.x; + if (_e194 < -1.0) { vPos.x = 1.0; } - float _e144 = vPos.x; - if (_e144 > 1.0) { + float _e203 = vPos.x; + if (_e203 > 1.0) { vPos.x = -1.0; } - float _e150 = vPos.y; - if (_e150 < -1.0) { + float _e212 = vPos.y; + if (_e212 < -1.0) { vPos.y = 1.0; } - float _e156 = vPos.y; - if (_e156 > 1.0) { + float _e221 = vPos.y; + if (_e221 > 1.0) { vPos.y = -1.0; } - metal::float2 _e164 = vPos; - particlesDst.particles[index].pos = _e164; - metal::float2 _e168 = vVel; - particlesDst.particles[index].vel = _e168; + vec2f32_ _e229 = vPos; + particlesDst.particles[index].pos = _e229; + vec2f32_ _e235 = vVel; + particlesDst.particles[index].vel = _e235; return; } diff --git a/tests/out/msl/bounds-check-image-restrict.msl b/tests/out/msl/bounds-check-image-restrict.msl index b2f6eca4d8..0d8ff4020e 100644 --- a/tests/out/msl/bounds-check-image-restrict.msl +++ b/tests/out/msl/bounds-check-image-restrict.msl @@ -4,92 +4,97 @@ using metal::uint; -constant metal::int2 const_type_4_ = {0, 0}; -constant metal::int3 const_type_7_ = {0, 0, 0}; -constant metal::float4 const_type_2_ = {0.0, 0.0, 0.0, 0.0}; +typedef int i32_; +typedef metal::float4 vec4f32_; +typedef metal::int2 vec2i32_; +typedef metal::int3 vec3i32_; +typedef float f32_; +constant vec2i32_ const_vec2i32_ = {0, 0}; +constant vec3i32_ const_vec3i32_ = {0, 0, 0}; +constant vec4f32_ const_vec4f32_ = {0.0, 0.0, 0.0, 0.0}; -metal::float4 test_textureLoad_1d( - int coords, - int level, +vec4f32_ test_textureLoad_1d( + i32_ coords, + i32_ level, metal::texture1d image_1d ) { metal::float4 _e3 = image_1d.read(metal::min(uint(coords), image_1d.get_width() - 1)); return _e3; } -metal::float4 test_textureLoad_2d( - metal::int2 coords_1, - int level_1, +vec4f32_ test_textureLoad_2d( + vec2i32_ coords_1, + i32_ 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( - metal::int2 coords_2, - int index, - int level_2, +vec4f32_ test_textureLoad_2d_array( + vec2i32_ coords_2, + i32_ index, + i32_ 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( - metal::int3 coords_3, - int level_3, +vec4f32_ test_textureLoad_3d( + vec3i32_ coords_3, + i32_ 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( - metal::int2 coords_4, - int _sample, +vec4f32_ test_textureLoad_multisampled_2d( + vec2i32_ coords_4, + i32_ _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( - metal::int2 coords_5, - int level_4, +f32_ test_textureLoad_depth_2d( + vec2i32_ coords_5, + i32_ 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( - metal::int2 coords_6, - int index_1, - int level_5, +f32_ test_textureLoad_depth_2d_array( + vec2i32_ coords_6, + i32_ index_1, + i32_ 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( - metal::int2 coords_7, - int _sample_1, +f32_ test_textureLoad_depth_multisampled_2d( + vec2i32_ coords_7, + i32_ _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( - int coords_8, - metal::float4 value, + i32_ coords_8, + vec4f32_ value, metal::texture1d image_storage_1d ) { image_storage_1d.write(value, metal::min(uint(coords_8), image_storage_1d.get_width() - 1)); @@ -97,8 +102,8 @@ void test_textureStore_1d( } void test_textureStore_2d( - metal::int2 coords_9, - metal::float4 value_1, + vec2i32_ coords_9, + vec4f32_ value_1, metal::texture2d image_storage_2d ) { image_storage_2d.write(value_1, metal::min(metal::uint2(coords_9), metal::uint2(image_storage_2d.get_width(), image_storage_2d.get_height()) - 1)); @@ -106,9 +111,9 @@ void test_textureStore_2d( } void test_textureStore_2d_array( - metal::int2 coords_10, - int array_index, - metal::float4 value_2, + vec2i32_ coords_10, + i32_ array_index, + vec4f32_ value_2, metal::texture2d_array image_storage_2d_array ) { image_storage_2d_array.write(value_2, metal::min(metal::uint2(coords_10), metal::uint2(image_storage_2d_array.get_width(), image_storage_2d_array.get_height()) - 1), metal::min(uint(array_index), image_storage_2d_array.get_array_size() - 1)); @@ -116,8 +121,8 @@ void test_textureStore_2d_array( } void test_textureStore_3d( - metal::int3 coords_11, - metal::float4 value_3, + vec3i32_ coords_11, + vec4f32_ value_3, metal::texture3d image_storage_3d ) { image_storage_3d.write(value_3, metal::min(metal::uint3(coords_11), metal::uint3(image_storage_3d.get_width(), image_storage_3d.get_height(), image_storage_3d.get_depth()) - 1)); @@ -138,14 +143,14 @@ 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); - 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); - test_textureStore_3d(const_type_7_, const_type_2_, image_storage_3d); + vec4f32_ _e0 = test_textureLoad_1d(0, 0, image_1d); + vec4f32_ _e3 = test_textureLoad_2d(const_vec2i32_, 0, image_2d); + vec4f32_ _e6 = test_textureLoad_2d_array(const_vec2i32_, 0, 0, image_2d_array); + vec4f32_ _e10 = test_textureLoad_3d(const_vec3i32_, 0, image_3d); + vec4f32_ _e13 = test_textureLoad_multisampled_2d(const_vec2i32_, 0, image_multisampled_2d); + test_textureStore_1d(0, const_vec4f32_, image_storage_1d); + test_textureStore_2d(const_vec2i32_, const_vec4f32_, image_storage_2d); + test_textureStore_2d_array(const_vec2i32_, 0, const_vec4f32_, image_storage_2d_array); + test_textureStore_3d(const_vec3i32_, const_vec4f32_, image_storage_3d); return fragment_shaderOutput { metal::float4(0.0, 0.0, 0.0, 0.0) }; } diff --git a/tests/out/msl/bounds-check-image-rzsw.msl b/tests/out/msl/bounds-check-image-rzsw.msl index 16cbf5c0a6..96617eb96e 100644 --- a/tests/out/msl/bounds-check-image-rzsw.msl +++ b/tests/out/msl/bounds-check-image-rzsw.msl @@ -10,87 +10,92 @@ struct DefaultConstructible { return T {}; } }; -constant metal::int2 const_type_4_ = {0, 0}; -constant metal::int3 const_type_7_ = {0, 0, 0}; -constant metal::float4 const_type_2_ = {0.0, 0.0, 0.0, 0.0}; +typedef int i32_; +typedef metal::float4 vec4f32_; +typedef metal::int2 vec2i32_; +typedef metal::int3 vec3i32_; +typedef float f32_; +constant vec2i32_ const_vec2i32_ = {0, 0}; +constant vec3i32_ const_vec3i32_ = {0, 0, 0}; +constant vec4f32_ const_vec4f32_ = {0.0, 0.0, 0.0, 0.0}; -metal::float4 test_textureLoad_1d( - int coords, - int level, +vec4f32_ test_textureLoad_1d( + i32_ coords, + i32_ level, metal::texture1d image_1d ) { metal::float4 _e3 = (uint(level) < image_1d.get_num_mip_levels() && uint(coords) < image_1d.get_width() ? image_1d.read(uint(coords)): DefaultConstructible()); return _e3; } -metal::float4 test_textureLoad_2d( - metal::int2 coords_1, - int level_1, +vec4f32_ test_textureLoad_2d( + vec2i32_ coords_1, + i32_ 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( - metal::int2 coords_2, - int index, - int level_2, +vec4f32_ test_textureLoad_2d_array( + vec2i32_ coords_2, + i32_ index, + i32_ 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( - metal::int3 coords_3, - int level_3, +vec4f32_ test_textureLoad_3d( + vec3i32_ coords_3, + i32_ 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( - metal::int2 coords_4, - int _sample, +vec4f32_ test_textureLoad_multisampled_2d( + vec2i32_ coords_4, + i32_ _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( - metal::int2 coords_5, - int level_4, +f32_ test_textureLoad_depth_2d( + vec2i32_ coords_5, + i32_ 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( - metal::int2 coords_6, - int index_1, - int level_5, +f32_ test_textureLoad_depth_2d_array( + vec2i32_ coords_6, + i32_ index_1, + i32_ 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( - metal::int2 coords_7, - int _sample_1, +f32_ test_textureLoad_depth_multisampled_2d( + vec2i32_ coords_7, + i32_ _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( - int coords_8, - metal::float4 value, + i32_ coords_8, + vec4f32_ value, metal::texture1d image_storage_1d ) { if (uint(coords_8) < image_storage_1d.get_width()) { @@ -100,8 +105,8 @@ void test_textureStore_1d( } void test_textureStore_2d( - metal::int2 coords_9, - metal::float4 value_1, + vec2i32_ coords_9, + vec4f32_ value_1, metal::texture2d image_storage_2d ) { if (metal::all(metal::uint2(coords_9) < metal::uint2(image_storage_2d.get_width(), image_storage_2d.get_height()))) { @@ -111,9 +116,9 @@ void test_textureStore_2d( } void test_textureStore_2d_array( - metal::int2 coords_10, - int array_index, - metal::float4 value_2, + vec2i32_ coords_10, + i32_ array_index, + vec4f32_ value_2, metal::texture2d_array image_storage_2d_array ) { if (uint(array_index) < image_storage_2d_array.get_array_size() && metal::all(metal::uint2(coords_10) < metal::uint2(image_storage_2d_array.get_width(), image_storage_2d_array.get_height()))) { @@ -123,8 +128,8 @@ void test_textureStore_2d_array( } void test_textureStore_3d( - metal::int3 coords_11, - metal::float4 value_3, + vec3i32_ coords_11, + vec4f32_ value_3, metal::texture3d image_storage_3d ) { if (metal::all(metal::uint3(coords_11) < metal::uint3(image_storage_3d.get_width(), image_storage_3d.get_height(), image_storage_3d.get_depth()))) { @@ -147,14 +152,14 @@ 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); - 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); - test_textureStore_3d(const_type_7_, const_type_2_, image_storage_3d); + vec4f32_ _e0 = test_textureLoad_1d(0, 0, image_1d); + vec4f32_ _e3 = test_textureLoad_2d(const_vec2i32_, 0, image_2d); + vec4f32_ _e6 = test_textureLoad_2d_array(const_vec2i32_, 0, 0, image_2d_array); + vec4f32_ _e10 = test_textureLoad_3d(const_vec3i32_, 0, image_3d); + vec4f32_ _e13 = test_textureLoad_multisampled_2d(const_vec2i32_, 0, image_multisampled_2d); + test_textureStore_1d(0, const_vec4f32_, image_storage_1d); + test_textureStore_2d(const_vec2i32_, const_vec4f32_, image_storage_2d); + test_textureStore_2d_array(const_vec2i32_, 0, const_vec4f32_, image_storage_2d_array); + test_textureStore_3d(const_vec3i32_, const_vec4f32_, image_storage_3d); return fragment_shaderOutput { metal::float4(0.0, 0.0, 0.0, 0.0) }; } diff --git a/tests/out/msl/bounds-check-restrict.msl b/tests/out/msl/bounds-check-restrict.msl index a614e59240..782edc0521 100644 --- a/tests/out/msl/bounds-check-restrict.msl +++ b/tests/out/msl/bounds-check-restrict.msl @@ -8,38 +8,48 @@ struct _mslBufferSizes { uint size0; }; -struct type_1 { - float inner[10]; +typedef float f32_; +struct arrayf3210_ { + f32_ inner[10u]; }; -typedef float type_4[1]; +typedef metal::float4 vec4f32_; +typedef metal::float3x4 mat3x4f32_; +typedef f32_ arrayf32_[1]; struct Globals { - type_1 a; + arrayf3210_ a; char _pad1[8]; - metal::float4 v; - metal::float3x4 m; - type_4 d; + vec4f32_ v; + mat3x4f32_ m; + arrayf32_ d; }; - -float index_array( - int i, +typedef int i32_; +typedef device Globals& ptrstorageGlobals; +typedef device arrayf3210_& ptrstoragearrayf3210_; +typedef device arrayf32_& ptrstoragearrayf32_; +typedef device vec4f32_& ptrstoragevec4f32_; +typedef device mat3x4f32_& ptrstoragemat3x4f32_; +typedef device metal::float4& ptrstoragevec4f32_1; + +f32_ index_array( + i32_ i, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { - float _e4 = globals.a.inner[metal::min(unsigned(i), 9u)]; + f32_ _e4 = globals.a.inner[metal::min(unsigned(i), 9u)]; return _e4; } -float index_dynamic_array( - int i_1, +f32_ index_dynamic_array( + i32_ i_1, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { - float _e4 = globals.d[metal::min(unsigned(i_1), (_buffer_sizes.size0 - 112 - 4) / 4)]; + f32_ _e4 = globals.d[metal::min(unsigned(i_1), (_buffer_sizes.size0 - 112 - 4) / 4)]; return _e4; } -float index_vector( - int i_2, +f32_ index_vector( + i32_ i_2, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -47,15 +57,15 @@ float index_vector( return _e4; } -float index_vector_by_value( - metal::float4 v, - int i_3 +f32_ index_vector_by_value( + vec4f32_ v, + i32_ i_3 ) { return v[metal::min(unsigned(i_3), 3u)]; } -metal::float4 index_matrix( - int i_4, +vec4f32_ index_matrix( + i32_ i_4, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -63,9 +73,9 @@ metal::float4 index_matrix( return _e4; } -float index_twice( - int i_5, - int j, +f32_ index_twice( + i32_ i_5, + i32_ j, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -73,28 +83,28 @@ float index_twice( return _e6; } -float index_expensive( - int i_6, +f32_ index_expensive( + i32_ i_6, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { - float _e11 = globals.a.inner[metal::min(unsigned(static_cast(metal::sin(static_cast(i_6) / 100.0) * 100.0)), 9u)]; + f32_ _e11 = globals.a.inner[metal::min(unsigned(static_cast(metal::sin(static_cast(i_6) / 100.0) * 100.0)), 9u)]; return _e11; } -float index_in_bounds( +f32_ index_in_bounds( device Globals const& globals, 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; + f32_ _e4 = globals.a.inner[9]; + float _e9 = globals.v.w; + float _e17 = globals.m[2].w; + return (_e4 + _e9) + _e17; } void set_array( - int i_7, - float v_1, + i32_ i_7, + f32_ v_1, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -103,8 +113,8 @@ void set_array( } void set_dynamic_array( - int i_8, - float v_2, + i32_ i_8, + f32_ v_2, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -113,8 +123,8 @@ void set_dynamic_array( } void set_vector( - int i_9, - float v_3, + i32_ i_9, + f32_ v_3, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -123,8 +133,8 @@ void set_vector( } void set_matrix( - int i_10, - metal::float4 v_4, + i32_ i_10, + vec4f32_ v_4, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -133,9 +143,9 @@ void set_matrix( } void set_index_twice( - int i_11, - int j_1, - float v_5, + i32_ i_11, + i32_ j_1, + f32_ v_5, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -144,8 +154,8 @@ void set_index_twice( } void set_expensive( - int i_12, - float v_6, + i32_ i_12, + f32_ v_6, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -154,7 +164,7 @@ void set_expensive( } void set_in_bounds( - float v_7, + f32_ v_7, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { diff --git a/tests/out/msl/bounds-check-zero-atomic.msl b/tests/out/msl/bounds-check-zero-atomic.msl index c76ba1b549..36b11c455f 100644 --- a/tests/out/msl/bounds-check-zero-atomic.msl +++ b/tests/out/msl/bounds-check-zero-atomic.msl @@ -14,17 +14,24 @@ struct _mslBufferSizes { uint size0; }; -struct type_1 { - metal::atomic_uint inner[10]; +typedef metal::atomic_uint atomicu32_; +struct arrayatomicu3210_ { + atomicu32_ inner[10u]; }; -typedef metal::atomic_uint type_2[1]; +typedef atomicu32_ arrayatomicu32_[1]; struct Globals { - metal::atomic_uint a; - type_1 b; - type_2 c; + atomicu32_ a; + arrayatomicu3210_ b; + arrayatomicu32_ c; }; +typedef uint u32_; +typedef device Globals& ptrstorageGlobals; +typedef device atomicu32_& ptrstorageatomicu32_; +typedef int i32_; +typedef device arrayatomicu3210_& ptrstoragearrayatomicu3210_; +typedef device arrayatomicu32_& ptrstoragearrayatomicu32_; -uint fetch_add_atomic( +u32_ fetch_add_atomic( device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -32,8 +39,8 @@ uint fetch_add_atomic( return _e3; } -uint fetch_add_atomic_static_sized_array( - int i, +u32_ fetch_add_atomic_static_sized_array( + i32_ i, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -41,8 +48,8 @@ uint fetch_add_atomic_static_sized_array( return _e5; } -uint fetch_add_atomic_dynamic_sized_array( - int i_1, +u32_ fetch_add_atomic_dynamic_sized_array( + i32_ i_1, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { diff --git a/tests/out/msl/bounds-check-zero.msl b/tests/out/msl/bounds-check-zero.msl index b45550d5ae..1d606ab9b5 100644 --- a/tests/out/msl/bounds-check-zero.msl +++ b/tests/out/msl/bounds-check-zero.msl @@ -14,38 +14,48 @@ struct _mslBufferSizes { uint size0; }; -struct type_1 { - float inner[10]; +typedef float f32_; +struct arrayf3210_ { + f32_ inner[10u]; }; -typedef float type_4[1]; +typedef metal::float4 vec4f32_; +typedef metal::float3x4 mat3x4f32_; +typedef f32_ arrayf32_[1]; struct Globals { - type_1 a; + arrayf3210_ a; char _pad1[8]; - metal::float4 v; - metal::float3x4 m; - type_4 d; + vec4f32_ v; + mat3x4f32_ m; + arrayf32_ d; }; - -float index_array( - int i, +typedef int i32_; +typedef device Globals& ptrstorageGlobals; +typedef device arrayf3210_& ptrstoragearrayf3210_; +typedef device arrayf32_& ptrstoragearrayf32_; +typedef device vec4f32_& ptrstoragevec4f32_; +typedef device mat3x4f32_& ptrstoragemat3x4f32_; +typedef device metal::float4& ptrstoragevec4f32_1; + +f32_ index_array( + i32_ i, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { - float _e4 = uint(i) < 10 ? globals.a.inner[i] : DefaultConstructible(); + f32_ _e4 = uint(i) < 10 ? globals.a.inner[i] : DefaultConstructible(); return _e4; } -float index_dynamic_array( - int i_1, +f32_ index_dynamic_array( + i32_ i_1, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { - float _e4 = uint(i_1) < 1 + (_buffer_sizes.size0 - 112 - 4) / 4 ? globals.d[i_1] : DefaultConstructible(); + f32_ _e4 = uint(i_1) < 1 + (_buffer_sizes.size0 - 112 - 4) / 4 ? globals.d[i_1] : DefaultConstructible(); return _e4; } -float index_vector( - int i_2, +f32_ index_vector( + i32_ i_2, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -53,15 +63,15 @@ float index_vector( return _e4; } -float index_vector_by_value( - metal::float4 v, - int i_3 +f32_ index_vector_by_value( + vec4f32_ v, + i32_ i_3 ) { return uint(i_3) < 4 ? v[i_3] : DefaultConstructible(); } -metal::float4 index_matrix( - int i_4, +vec4f32_ index_matrix( + i32_ i_4, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -69,9 +79,9 @@ metal::float4 index_matrix( return _e4; } -float index_twice( - int i_5, - int j, +f32_ index_twice( + i32_ i_5, + i32_ j, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -79,29 +89,29 @@ float index_twice( return _e6; } -float index_expensive( - int i_6, +f32_ index_expensive( + i32_ i_6, device Globals const& globals, constant _mslBufferSizes& _buffer_sizes ) { int _e9 = static_cast(metal::sin(static_cast(i_6) / 100.0) * 100.0); - float _e11 = uint(_e9) < 10 ? globals.a.inner[_e9] : DefaultConstructible(); + f32_ _e11 = uint(_e9) < 10 ? globals.a.inner[_e9] : DefaultConstructible(); return _e11; } -float index_in_bounds( +f32_ index_in_bounds( device Globals const& globals, 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; + f32_ _e4 = globals.a.inner[9]; + float _e9 = globals.v.w; + float _e17 = globals.m[2].w; + return (_e4 + _e9) + _e17; } void set_array( - int i_7, - float v_1, + i32_ i_7, + f32_ v_1, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -112,8 +122,8 @@ void set_array( } void set_dynamic_array( - int i_8, - float v_2, + i32_ i_8, + f32_ v_2, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -124,8 +134,8 @@ void set_dynamic_array( } void set_vector( - int i_9, - float v_3, + i32_ i_9, + f32_ v_3, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -136,8 +146,8 @@ void set_vector( } void set_matrix( - int i_10, - metal::float4 v_4, + i32_ i_10, + vec4f32_ v_4, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -148,9 +158,9 @@ void set_matrix( } void set_index_twice( - int i_11, - int j_1, - float v_5, + i32_ i_11, + i32_ j_1, + f32_ v_5, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -161,8 +171,8 @@ void set_index_twice( } void set_expensive( - int i_12, - float v_6, + i32_ i_12, + f32_ v_6, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { @@ -174,7 +184,7 @@ void set_expensive( } void set_in_bounds( - float v_7, + f32_ v_7, device Globals& globals, constant _mslBufferSizes& _buffer_sizes ) { diff --git a/tests/out/msl/break-if.msl b/tests/out/msl/break-if.msl index 600cca60d8..ef60cd0069 100644 --- a/tests/out/msl/break-if.msl +++ b/tests/out/msl/break-if.msl @@ -4,6 +4,7 @@ using metal::uint; +typedef bool bool_; void breakIfEmpty( ) { @@ -20,19 +21,20 @@ void breakIfEmpty( } void breakIfEmptyBody( - bool a + bool_ a ) { - bool b = {}; - bool c = {}; + bool_ b = {}; + bool_ c = {}; + bool_ _e9 = c; + bool unnamed = a == _e9; bool loop_init_1 = true; while(true) { if (!loop_init_1) { b = a; - bool _e2 = b; - c = a != _e2; - bool _e5 = c; - bool unnamed = a == _e5; - if (a == c) { + bool_ _e4 = b; + bool c_1 = a != _e4; + c = c_1; + if (unnamed) { break; } } @@ -42,23 +44,24 @@ void breakIfEmptyBody( } void breakIf( - bool a_1 + bool_ a_1 ) { - bool d = {}; - bool e = {}; + bool_ d = {}; + bool_ e = {}; + bool_ _e9 = e; + bool unnamed_1 = a_1 == _e9; bool loop_init_2 = true; while(true) { if (!loop_init_2) { - bool _e5 = e; - bool unnamed_1 = a_1 == _e5; - if (a_1 == e) { + if (unnamed_1) { break; } } loop_init_2 = false; d = a_1; - bool _e2 = d; - e = a_1 != _e2; + bool_ _e4 = d; + bool e_1 = a_1 != _e4; + e = e_1; } return; } diff --git a/tests/out/msl/collatz.msl b/tests/out/msl/collatz.msl index 2189632d08..e62838de87 100644 --- a/tests/out/msl/collatz.msl +++ b/tests/out/msl/collatz.msl @@ -8,47 +8,56 @@ struct _mslBufferSizes { uint size0; }; -typedef uint type_1[1]; +typedef uint u32_; +typedef u32_ arrayu32_[1]; struct PrimeIndices { - type_1 data; + arrayu32_ data; }; +typedef metal::uint3 vec3u32_; +typedef device PrimeIndices& ptrstoragePrimeIndices; +typedef device arrayu32_& ptrstoragearrayu32_; -uint collatz_iterations( - uint n_base +u32_ collatz_iterations( + u32_ n_base ) { - uint n = {}; - uint i = 0u; + u32_ n = {}; + u32_ i = {}; n = n_base; + i = 0u; while(true) { - uint _e5 = n; + u32_ _e5 = n; if (_e5 > 1u) { } else { break; } - uint _e8 = n; - if ((_e8 % 2u) == 0u) { - uint _e13 = n; - n = _e13 / 2u; - } else { - uint _e17 = n; - n = (3u * _e17) + 1u; + { + u32_ _e9 = n; + if ((_e9 % 2u) == 0u) { + u32_ _e15 = n; + n = _e15 / 2u; + } else { + { + u32_ _e21 = n; + n = (3u * _e21) + 1u; + } + } + u32_ _e27 = i; + i = _e27 + 1u; } - uint _e21 = i; - i = _e21 + 1u; } - uint _e24 = i; - return _e24; + u32_ _e32 = i; + return _e32; } struct main_Input { }; kernel void main_( - metal::uint3 global_id [[thread_position_in_grid]] + vec3u32_ global_id [[thread_position_in_grid]] , 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; + u32_ _e6 = v_indices.data[global_id.x]; + u32_ _e0 = collatz_iterations(_e6); + v_indices.data[global_id.x] = _e0; return; } diff --git a/tests/out/msl/control-flow.msl b/tests/out/msl/control-flow.msl index 4a0b805663..ba84209de5 100644 --- a/tests/out/msl/control-flow.msl +++ b/tests/out/msl/control-flow.msl @@ -4,9 +4,11 @@ using metal::uint; +typedef metal::uint3 vec3u32_; +typedef int i32_; void switch_default_break( - int i + i32_ i ) { switch(i) { default: { @@ -29,7 +31,7 @@ void switch_case_break( } void loop_switch_continue( - int x + i32_ x ) { while(true) { switch(x) { @@ -47,9 +49,9 @@ void loop_switch_continue( struct main_Input { }; kernel void main_( - metal::uint3 global_id [[thread_position_in_grid]] + vec3u32_ global_id [[thread_position_in_grid]] ) { - int pos = {}; + i32_ pos = {}; metal::threadgroup_barrier(metal::mem_flags::mem_device); metal::threadgroup_barrier(metal::mem_flags::mem_threadgroup); switch(1) { @@ -58,7 +60,7 @@ kernel void main_( break; } } - int _e4 = pos; + i32_ _e4 = pos; switch(_e4) { case 1: { pos = 0; @@ -70,9 +72,11 @@ kernel void main_( } case 3: { pos = 2; + break; } case 4: { pos = 3; + break; } default: { pos = 4; @@ -87,8 +91,8 @@ kernel void main_( break; } } - int _e11 = pos; - switch(_e11) { + i32_ _e17 = pos; + switch(_e17) { case 1: { pos = 0; break; @@ -99,6 +103,7 @@ kernel void main_( } case 3: { pos = 2; + return; } case 4: { return; diff --git a/tests/out/msl/extra.msl b/tests/out/msl/extra.msl index 8288dfad92..1ecaebb3c8 100644 --- a/tests/out/msl/extra.msl +++ b/tests/out/msl/extra.msl @@ -4,32 +4,40 @@ using metal::uint; +typedef uint u32_; +typedef metal::float2 vec2f64_; struct PushConstants { - uint index; + u32_ index; char _pad1[12]; - metal::float2 double_; + vec2f64_ double_; }; +typedef metal::float4 vec4f32_; struct FragmentIn { - metal::float4 color; - uint primitive_index; + vec4f32_ color; + u32_ primitive_index; }; +typedef constant PushConstants& ptrpush_constantPushConstants; +typedef float f32_; +typedef metal::float3 vec3f32_; struct main_Input { - metal::float4 color [[user(loc0), center_perspective]]; + vec4f32_ color [[user(loc0), center_perspective]]; }; struct main_Output { metal::float4 member [[color(0)]]; }; fragment main_Output main_( main_Input varyings [[stage_in]] -, uint primitive_index [[primitive_id]] +, u32_ primitive_index [[primitive_id]] , constant PushConstants& pc [[buffer(1)]] ) { const FragmentIn in = { varyings.color, primitive_index }; - uint _e4 = pc.index; + u32_ _e4 = pc.index; if (in.primitive_index == _e4) { return main_Output { in.color }; } else { - return main_Output { metal::float4(metal::float3(1.0) - in.color.xyz, in.color.w) }; + { + return main_Output { metal::float4(metal::float3(1.0) - in.color.xyz, in.color.w) }; + } } } diff --git a/tests/out/msl/functions.msl b/tests/out/msl/functions.msl index 31f57c656e..aeba3360d7 100644 --- a/tests/out/msl/functions.msl +++ b/tests/out/msl/functions.msl @@ -4,16 +4,23 @@ using metal::uint; +typedef metal::float2 vec2f32_; +typedef float f32_; +typedef int i32_; +typedef metal::int2 vec2i32_; +typedef uint u32_; +typedef metal::uint3 vec3u32_; +typedef metal::int4 vec4i32_; -metal::float2 test_fma( +vec2f32_ test_fma( ) { - metal::float2 a = metal::float2(2.0, 2.0); - metal::float2 b = metal::float2(0.5, 0.5); - metal::float2 c = metal::float2(0.5, 0.5); + vec2f32_ a = metal::float2(2.0, 2.0); + vec2f32_ b = metal::float2(0.5, 0.5); + vec2f32_ c = metal::float2(0.5, 0.5); return metal::fma(a, b, c); } -int test_integer_dot_product( +i32_ test_integer_dot_product( ) { metal::int2 a_2_ = metal::int2(1); metal::int2 b_2_ = metal::int2(1); @@ -29,7 +36,7 @@ int test_integer_dot_product( kernel void main_( ) { - metal::float2 _e0 = test_fma(); - int _e1 = test_integer_dot_product(); + vec2f32_ _e0 = test_fma(); + i32_ _e1 = test_integer_dot_product(); return; } diff --git a/tests/out/msl/globals.msl b/tests/out/msl/globals.msl index b461cce3f4..ca079270e1 100644 --- a/tests/out/msl/globals.msl +++ b/tests/out/msl/globals.msl @@ -8,35 +8,60 @@ struct _mslBufferSizes { uint size3; }; -constexpr constant bool Foo_2 = true; -struct type_2 { - float inner[10u]; +constexpr constant bool FooConst = true; +typedef bool bool_; +typedef float f32_; +struct arrayf3210_ { + f32_ inner[10u]; }; +typedef metal::atomic_uint atomicu32_; +typedef metal::float3 vec3f32_; struct Foo { metal::packed_float3 v3_; - float v1_; + f32_ v1_; }; -typedef metal::float2 type_6[1]; -struct type_8 { - metal::float4 inner[20]; +typedef metal::float2 vec2f32_; +typedef vec2f32_ arrayvec2f32_[1]; +typedef metal::float4 vec4f32_; +struct arrayvec4f3220_ { + vec4f32_ inner[20u]; }; -struct type_11 { - metal::float2x4 inner[2]; +typedef metal::float3x2 mat3x2f32_; +typedef metal::float2x4 mat2x4f32_; +struct arraymat2x4f322_ { + mat2x4f32_ inner[2u]; }; -struct type_12 { - type_11 inner[2]; +struct arrayarraymat2x4f3222_ { + arraymat2x4f322_ inner[2u]; }; -struct type_14 { - metal::float4x2 inner[2]; +typedef metal::float4x2 mat4x2f32_; +struct arraymat4x2f322_ { + mat4x2f32_ inner[2u]; }; -struct type_15 { - type_14 inner[2]; +struct arrayarraymat4x2f3222_ { + arraymat4x2f322_ inner[2u]; }; -constant metal::float3 const_type_4_ = {0.0, 0.0, 0.0}; -constant metal::float3x3 const_type_17_ = {const_type_4_, const_type_4_, const_type_4_}; +typedef device Foo& ptrstorageFoo; +typedef int i32_; +typedef device vec3f32_& ptrstoragevec3f32_; +typedef metal::float3x3 mat3x3f32_; +typedef constant arrayarraymat4x2f3222_& ptruniformarrayarraymat4x2f3222_; +typedef constant arraymat4x2f322_& ptruniformarraymat4x2f322_; +typedef constant arrayarraymat2x4f3222_& ptruniformarrayarraymat2x4f3222_; +typedef constant arraymat2x4f322_& ptruniformarraymat2x4f322_; +typedef constant mat2x4f32_& ptruniformmat2x4f32_; +typedef threadgroup arrayf3210_& ptrworkgrouparrayf3210_; +typedef device arrayvec2f32_& ptrstoragearrayvec2f32_; +typedef device vec2f32_& ptrstoragevec2f32_; +typedef constant arrayvec4f3220_& ptruniformarrayvec4f3220_; +typedef constant vec4f32_& ptruniformvec4f32_; +typedef uint u32_; +typedef threadgroup atomicu32_& ptrworkgroupatomicu32_; +constant vec3f32_ const_vec3f32_ = {0.0, 0.0, 0.0}; +constant mat3x3f32_ const_mat3x3f32_ = {const_vec3f32_, const_vec3f32_, const_vec3f32_}; void test_msl_packed_vec3_as_arg( - metal::float3 arg + vec3f32_ arg ) { return; } @@ -44,53 +69,56 @@ void test_msl_packed_vec3_as_arg( void test_msl_packed_vec3_( device Foo& alignment ) { - int idx = 1; + i32_ 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; + i32_ _e18 = idx; + alignment.v3_[_e18] = 3.0; Foo data = alignment; - metal::float3 unnamed = data.v3_; + vec3f32_ unnamed = data.v3_; metal::float2 unnamed_1 = metal::float3(data.v3_).zx; test_msl_packed_vec3_as_arg(data.v3_); - metal::float3 unnamed_2 = metal::float3(data.v3_) * const_type_17_; - metal::float3 unnamed_3 = const_type_17_ * metal::float3(data.v3_); - metal::float3 unnamed_4 = data.v3_ * 2.0; - metal::float3 unnamed_5 = 2.0 * data.v3_; + metal::float3 unnamed_2 = metal::float3(data.v3_) * const_mat3x3f32_; + metal::float3 unnamed_3 = const_mat3x3f32_ * metal::float3(data.v3_); + vec3f32_ unnamed_4 = data.v3_ * 2.0; + vec3f32_ unnamed_5 = 2.0 * data.v3_; } kernel void main_( - threadgroup type_2& wg -, threadgroup metal::atomic_uint& at_1 + threadgroup arrayf3210_& wg +, threadgroup atomicu32_& at_1 , device Foo& alignment [[user(fake0)]] -, device type_6 const& dummy [[user(fake0)]] -, constant type_8& float_vecs [[user(fake0)]] -, constant metal::float3& global_vec [[user(fake0)]] -, constant metal::float3x2& global_mat [[user(fake0)]] -, constant type_12& global_nested_arrays_of_matrices_2x4_ [[user(fake0)]] -, constant type_15& global_nested_arrays_of_matrices_4x2_ [[user(fake0)]] +, device arrayvec2f32_ const& dummy [[user(fake0)]] +, constant arrayvec4f3220_& float_vecs [[user(fake0)]] +, constant vec3f32_& global_vec [[user(fake0)]] +, constant mat3x2f32_& global_mat [[user(fake0)]] +, constant arrayarraymat2x4f3222_& global_nested_arrays_of_matrices_2x4_ [[user(fake0)]] +, constant arrayarraymat4x2f3222_& global_nested_arrays_of_matrices_4x2_ [[user(fake0)]] , constant _mslBufferSizes& _buffer_sizes [[user(fake0)]] ) { - float Foo_1 = 1.0; - bool at = true; + f32_ Foo_1 = {}; + 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; - 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; + mat4x2f32_ _e5 = global_nested_arrays_of_matrices_4x2_.inner[0].inner[0]; + metal::float4 _e13 = global_nested_arrays_of_matrices_2x4_.inner[0].inner[0][0]; + wg.inner[7] = (_e5 * _e13).x; + mat3x2f32_ _e20 = global_mat; + vec3f32_ _e22 = global_vec; + wg.inner[6] = (_e20 * _e22).x; + float _e32 = dummy[1].y; + wg.inner[5] = _e32; + float _e40 = float_vecs.inner[0].w; + wg.inner[4] = _e40; + f32_ _e46 = alignment.v1_; + wg.inner[3] = _e46; + float _e53 = alignment.v3_[0]; + wg.inner[2] = _e53; 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 = 1.0; + at = true; return; } diff --git a/tests/out/msl/image.msl b/tests/out/msl/image.msl index 16839dfbe7..db71cd644f 100644 --- a/tests/out/msl/image.msl +++ b/tests/out/msl/image.msl @@ -4,12 +4,23 @@ using metal::uint; -constant metal::int2 const_type_9_ = {3, 1}; +typedef metal::uint3 vec3u32_; +typedef metal::uint2 vec2u32_; +typedef metal::int2 vec2i32_; +typedef int i32_; +typedef uint u32_; +typedef metal::uint4 vec4u32_; +typedef float f32_; +typedef metal::float4 vec4f32_; +typedef metal::int3 vec3i32_; +typedef metal::float2 vec2f32_; +typedef metal::float3 vec3f32_; +constant vec2i32_ const_vec2i32_ = {3, 1}; struct main_Input { }; kernel void main_( - metal::uint3 local_id [[thread_position_in_threadgroup]] + vec3u32_ local_id [[thread_position_in_threadgroup]] , metal::texture2d image_mipmapped_src [[user(fake0)]] , metal::texture2d_ms image_multisampled_src [[user(fake0)]] , metal::texture2d image_storage_src [[user(fake0)]] @@ -32,7 +43,7 @@ kernel void main_( struct depth_loadInput { }; kernel void depth_load( - metal::uint3 local_id_1 [[thread_position_in_threadgroup]] + vec3u32_ local_id_1 [[thread_position_in_threadgroup]] , metal::depth2d_ms image_depth_multisampled_src [[user(fake0)]] , metal::texture2d image_storage_src [[user(fake0)]] , metal::texture1d image_dst [[user(fake0)]] @@ -110,10 +121,10 @@ fragment texture_sampleOutput texture_sample( metal::float2 tc = metal::float2(0.5); metal::float4 s1d = image_1d.sample(sampler_reg, tc.x); metal::float4 s2d = image_2d.sample(sampler_reg, tc); - metal::float4 s2d_offset = image_2d.sample(sampler_reg, tc, const_type_9_); - metal::float4 s2d_level = image_2d.sample(sampler_reg, tc, metal::level(2.299999952316284)); - metal::float4 s2d_level_offset = image_2d.sample(sampler_reg, tc, metal::level(2.299999952316284), const_type_9_); - metal::float4 s2d_bias_offset = image_2d.sample(sampler_reg, tc, metal::bias(2.0), const_type_9_); + metal::float4 s2d_offset = image_2d.sample(sampler_reg, tc, const_vec2i32_); + metal::float4 s2d_level = image_2d.sample(sampler_reg, tc, metal::level(2.3)); + metal::float4 s2d_level_offset = image_2d.sample(sampler_reg, tc, metal::level(2.3), const_vec2i32_); + metal::float4 s2d_bias_offset = image_2d.sample(sampler_reg, tc, metal::bias(2.0), const_vec2i32_); return texture_sampleOutput { (((s1d + s2d) + s2d_offset) + s2d_level) + s2d_level_offset }; } @@ -145,9 +156,9 @@ fragment gatherOutput gather( ) { metal::float2 tc_2 = metal::float2(0.5); metal::float4 s2d_1 = image_2d.gather(sampler_reg, tc_2, int2(0), metal::component::y); - metal::float4 s2d_offset_1 = image_2d.gather(sampler_reg, tc_2, const_type_9_, metal::component::w); + metal::float4 s2d_offset_1 = image_2d.gather(sampler_reg, tc_2, const_vec2i32_, metal::component::w); metal::float4 s2d_depth_1 = image_2d_depth.gather_compare(sampler_cmp, tc_2, 0.5); - metal::float4 s2d_depth_offset = image_2d_depth.gather_compare(sampler_cmp, tc_2, 0.5, const_type_9_); + metal::float4 s2d_depth_offset = image_2d_depth.gather_compare(sampler_cmp, tc_2, 0.5, const_vec2i32_); return gatherOutput { ((s2d_1 + s2d_offset_1) + s2d_depth_1) + s2d_depth_offset }; } diff --git a/tests/out/msl/interface.msl b/tests/out/msl/interface.msl index 9b8013531c..f3619f5bfe 100644 --- a/tests/out/msl/interface.msl +++ b/tests/out/msl/interface.msl @@ -4,27 +4,33 @@ using metal::uint; +typedef metal::float4 vec4f32_; +typedef float f32_; struct VertexOutput { - metal::float4 position; - float _varying; + vec4f32_ position; + f32_ _varying; }; +typedef uint u32_; struct FragmentOutput { - float depth; - uint sample_mask; - float color; + f32_ depth; + u32_ sample_mask; + f32_ color; }; -struct type_4 { - uint inner[1]; +typedef bool bool_; +struct arrayu321_ { + u32_ inner[1u]; }; +typedef metal::uint3 vec3u32_; +typedef threadgroup arrayu321_& ptrworkgrouparrayu321_; struct Input1_ { - uint index; + u32_ index; }; struct Input2_ { - uint index; + u32_ index; }; struct vertex_Input { - uint color [[attribute(10)]]; + u32_ color [[attribute(10)]]; }; struct vertex_Output { metal::float4 position [[position, invariant]]; @@ -33,18 +39,18 @@ struct vertex_Output { }; vertex vertex_Output vertex_( vertex_Input varyings [[stage_in]] -, uint vertex_index [[vertex_id]] -, uint instance_index [[instance_id]] +, u32_ vertex_index [[vertex_id]] +, u32_ instance_index [[instance_id]] ) { const auto color = varyings.color; - uint tmp = (vertex_index + instance_index) + color; + u32_ tmp = (vertex_index + instance_index) + color; const auto _tmp = VertexOutput {metal::float4(1.0), static_cast(tmp)}; return vertex_Output { _tmp.position, _tmp._varying, 1.0 }; } struct fragment_Input { - float _varying [[user(loc1), center_perspective]]; + f32_ _varying [[user(loc1), center_perspective]]; }; struct fragment_Output { float depth [[depth(any)]]; @@ -53,13 +59,13 @@ struct fragment_Output { }; fragment fragment_Output fragment_( fragment_Input varyings_1 [[stage_in]] -, metal::float4 position [[position]] -, bool front_facing [[front_facing]] -, uint sample_index [[sample_id]] -, uint sample_mask [[sample_mask]] +, vec4f32_ position [[position]] +, bool_ front_facing [[front_facing]] +, u32_ sample_index [[sample_id]] +, u32_ sample_mask [[sample_mask]] ) { const VertexOutput in = { position, varyings_1._varying }; - uint mask = sample_mask & (1u << sample_index); + u32_ mask = sample_mask & (1u << sample_index); float color_1 = front_facing ? 1.0 : 0.0; const auto _tmp = FragmentOutput {in._varying, mask, color_1}; return fragment_Output { _tmp.depth, _tmp.sample_mask, _tmp.color }; @@ -69,12 +75,12 @@ fragment fragment_Output fragment_( struct compute_Input { }; kernel void compute_( - metal::uint3 global_id [[thread_position_in_grid]] -, metal::uint3 local_id [[thread_position_in_threadgroup]] -, uint local_index [[thread_index_in_threadgroup]] -, metal::uint3 wg_id [[threadgroup_position_in_grid]] -, metal::uint3 num_wgs [[threadgroups_per_grid]] -, threadgroup type_4& output + vec3u32_ global_id [[thread_position_in_grid]] +, vec3u32_ local_id [[thread_position_in_threadgroup]] +, u32_ local_index [[thread_index_in_threadgroup]] +, vec3u32_ wg_id [[threadgroup_position_in_grid]] +, vec3u32_ num_wgs [[threadgroups_per_grid]] +, threadgroup arrayu321_& output ) { output.inner[0] = (((global_id.x + local_id.x) + local_index) + wg_id.x) + num_wgs.x; return; @@ -88,12 +94,13 @@ struct vertex_two_structsOutput { float _point_size [[point_size]]; }; vertex vertex_two_structsOutput vertex_two_structs( - uint index_1 [[vertex_id]] -, uint index_2 [[instance_id]] + u32_ index_1 [[vertex_id]] +, u32_ index_2 [[instance_id]] ) { const Input1_ in1_ = { index_1 }; const Input2_ in2_ = { index_2 }; - uint index = 2u; - uint _e9 = index; + u32_ index = {}; + index = 2u; + u32_ _e9 = index; return vertex_two_structsOutput { metal::float4(static_cast(in1_.index), static_cast(in2_.index), static_cast(_e9), 0.0), 1.0 }; } diff --git a/tests/out/msl/interpolate.msl b/tests/out/msl/interpolate.msl index 5d8b67111e..ed2148bfa6 100644 --- a/tests/out/msl/interpolate.msl +++ b/tests/out/msl/interpolate.msl @@ -4,16 +4,22 @@ using metal::uint; +typedef metal::float4 vec4f32_; +typedef uint u32_; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef metal::float3 vec3f32_; struct FragmentInput { - metal::float4 position; - uint _flat; - float _linear; - metal::float2 linear_centroid; - metal::float3 linear_sample; - metal::float4 perspective; - float perspective_centroid; - float perspective_sample; + vec4f32_ position; + u32_ _flat; + f32_ _linear; + vec2f32_ linear_centroid; + vec3f32_ linear_sample; + vec4f32_ perspective; + f32_ perspective_centroid; + f32_ perspective_sample; }; +typedef thread FragmentInput& ptrfunctionFragmentInput; struct vert_mainOutput { metal::float4 position [[position]]; @@ -36,24 +42,24 @@ vertex vert_mainOutput vert_main( out.perspective = metal::float4(729.0, 1000.0, 1331.0, 1728.0); out.perspective_centroid = 2197.0; out.perspective_sample = 2744.0; - FragmentInput _e30 = out; - const auto _tmp = _e30; + FragmentInput _e38 = out; + const auto _tmp = _e38; return vert_mainOutput { _tmp.position, _tmp._flat, _tmp._linear, _tmp.linear_centroid, _tmp.linear_sample, _tmp.perspective, _tmp.perspective_centroid, _tmp.perspective_sample }; } struct frag_mainInput { - uint _flat [[user(loc0), flat]]; - float _linear [[user(loc1), center_no_perspective]]; - metal::float2 linear_centroid [[user(loc2), centroid_no_perspective]]; - metal::float3 linear_sample [[user(loc3), sample_no_perspective]]; - metal::float4 perspective [[user(loc4), center_perspective]]; - float perspective_centroid [[user(loc5), centroid_perspective]]; - float perspective_sample [[user(loc6), sample_perspective]]; + u32_ _flat [[user(loc0), flat]]; + f32_ _linear [[user(loc1), center_no_perspective]]; + vec2f32_ linear_centroid [[user(loc2), centroid_no_perspective]]; + vec3f32_ linear_sample [[user(loc3), sample_no_perspective]]; + vec4f32_ perspective [[user(loc4), center_perspective]]; + f32_ perspective_centroid [[user(loc5), centroid_perspective]]; + f32_ perspective_sample [[user(loc6), sample_perspective]]; }; fragment void frag_main( frag_mainInput varyings_1 [[stage_in]] -, metal::float4 position [[position]] +, vec4f32_ position [[position]] ) { const FragmentInput val = { position, varyings_1._flat, varyings_1._linear, varyings_1.linear_centroid, varyings_1.linear_sample, varyings_1.perspective, varyings_1.perspective_centroid, varyings_1.perspective_sample }; return; diff --git a/tests/out/msl/math-functions.msl b/tests/out/msl/math-functions.msl index 6ee0093d00..36cc515de4 100644 --- a/tests/out/msl/math-functions.msl +++ b/tests/out/msl/math-functions.msl @@ -4,7 +4,11 @@ using metal::uint; -constant metal::int2 const_type = {0, 0}; +typedef float f32_; +typedef metal::float4 vec4f32_; +typedef metal::int2 vec2i32_; +typedef int i32_; +constant vec2i32_ const_vec2i32_ = {0, 0}; vertex void main_( ) { @@ -14,6 +18,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_vec2i32_.x * const_vec2i32_.x + const_vec2i32_.y * const_vec2i32_.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 0c3872000f..5e889dd4f2 100644 --- a/tests/out/msl/operators.msl +++ b/tests/out/msl/operators.msl @@ -4,101 +4,126 @@ using metal::uint; +typedef metal::float4 vec4f32_; +typedef metal::int4 vec4i32_; +typedef bool bool_; +typedef metal::bool4 vec4bool; +typedef float f32_; +typedef int i32_; +typedef metal::float2 vec2f32_; +typedef metal::float3 vec3f32_; +typedef metal::bool3 vec3bool; struct Foo { - metal::float4 a; - int b; + vec4f32_ a; + i32_ b; }; -struct type_12 { - Foo inner[3]; +typedef metal::float2x2 mat2x2f32_; +typedef metal::float4x4 mat4x4f32_; +typedef uint u32_; +typedef metal::uint2 vec2u32_; +struct arrayFoo3_ { + Foo inner[3u]; }; -struct type_13 { - int inner[4u]; +struct arrayi324_ { + i32_ 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::float2 const_type_4_ = {0.0, 0.0}; -constant metal::float2x2 const_type_7_ = {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 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}; +typedef metal::float2x3 mat2x3f32_; +typedef thread Foo& ptrfunctionFoo; +typedef thread vec4f32_& ptrfunctionvec4f32_; +typedef metal::bool2 vec2bool; +typedef metal::int2 vec2i32_; +typedef metal::uint3 vec3u32_; +typedef metal::float3x3 mat3x3f32_; +typedef metal::float4x3 mat4x3f32_; +typedef metal::float3x4 mat3x4f32_; +typedef metal::int3 vec3i32_; +typedef thread vec3i32_& ptrfunctionvec3i32_; +constant vec4f32_ v_f32_one = {1.0, 1.0, 1.0, 1.0}; +constant vec4f32_ v_f32_zero = {0.0, 0.0, 0.0, 0.0}; +constant vec4f32_ v_f32_half = {0.5, 0.5, 0.5, 0.5}; +constant vec4i32_ v_i32_one = {1, 1, 1, 1}; +constant vec2u32_ const_vec2u32_ = {0u, 0u}; +constant vec2f32_ const_vec2f32_ = {0.0, 0.0}; +constant mat2x2f32_ const_mat2x2f32_ = {const_vec2f32_, const_vec2f32_}; +constant vec4f32_ const_vec4f32_ = {0.0, 0.0, 0.0, 0.0}; +constant Foo const_Foo = {const_vec4f32_, 0}; +constant arrayFoo3_ const_arrayFoo3_ = {const_Foo, const_Foo, const_Foo}; +constant vec3f32_ const_vec3f32_ = {0.0, 0.0, 0.0}; +constant mat2x3f32_ const_mat2x3f32_ = {const_vec3f32_, const_vec3f32_}; +constant mat3x3f32_ const_mat3x3f32_ = {const_vec3f32_, const_vec3f32_, const_vec3f32_}; +constant mat4x3f32_ const_mat4x3f32_ = {const_vec3f32_, const_vec3f32_, const_vec3f32_, const_vec3f32_}; +constant mat3x4f32_ const_mat3x4f32_ = {const_vec4f32_, const_vec4f32_, const_vec4f32_}; +constant vec3i32_ const_vec3i32_ = {0, 0, 0}; -metal::float4 builtins( +vec4f32_ builtins( ) { int s1_ = true ? 1 : 0; - metal::float4 s2_ = true ? v_f32_one : v_f32_zero; - metal::float4 s3_ = metal::select(v_f32_one, v_f32_zero, metal::bool4(false, false, false, false)); - metal::float4 m1_ = metal::mix(v_f32_zero, v_f32_one, v_f32_half); - metal::float4 m2_ = metal::mix(v_f32_zero, v_f32_one, 0.10000000149011612); + vec4f32_ s2_ = true ? v_f32_one : v_f32_zero; + vec4f32_ s3_ = metal::select(v_f32_one, v_f32_zero, metal::bool4(false, false, false, false)); + vec4f32_ m1_ = metal::mix(v_f32_zero, v_f32_one, v_f32_half); + vec4f32_ m2_ = metal::mix(v_f32_zero, v_f32_one, 0.1); float b1_ = as_type(v_i32_one.x); metal::float4 b2_ = as_type(v_i32_one); metal::int4 v_i32_zero = static_cast(v_f32_zero); return ((((static_cast(metal::int4(s1_) + v_i32_zero) + s2_) + m1_) + m2_) + metal::float4(b1_)) + b2_; } -metal::float4 splat( +vec4f32_ splat( ) { metal::float2 a_2 = ((metal::float2(1.0) + metal::float2(2.0)) - metal::float2(3.0)) / metal::float2(4.0); metal::int4 b = metal::int4(5) % metal::int4(2); return a_2.xyxy + static_cast(b); } -metal::float2 splat_assignment( +vec2f32_ 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 _e15 = a; - a = _e15 / metal::float2(4.0); - metal::float2 _e19 = a; + vec2f32_ a = {}; + metal::float2 a_3 = metal::float2(2.0); + a = a_3; + vec2f32_ _e4 = a; + a = _e4 + metal::float2(1.0); + vec2f32_ _e9 = a; + a = _e9 - metal::float2(3.0); + vec2f32_ _e14 = a; + a = _e14 / metal::float2(4.0); + vec2f32_ _e19 = a; return _e19; } -metal::float3 bool_cast( - metal::float3 x +vec3f32_ bool_cast( + vec3f32_ x ) { metal::bool3 y = static_cast(x); return static_cast(y); } -float constructors( +f32_ constructors( ) { Foo foo = {}; foo = Foo {metal::float4(1.0), 1}; - metal::float2x2 mat2comp = metal::float2x2(metal::float2(1.0, 0.0), metal::float2(0.0, 1.0)); - 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)); + mat2x2f32_ mat2comp = metal::float2x2(metal::float2(1.0, 0.0), metal::float2(0.0, 1.0)); + mat4x4f32_ 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}; + mat2x2f32_ unnamed_1 = metal::float2x2(metal::float2(0.0), metal::float2(0.0)); + arrayi324_ unnamed_2 = arrayi324_ {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_vec2u32_); + metal::float2x3 unnamed_8 = metal::float2x3(const_mat2x3f32_); + metal::uint2 unnamed_9 = static_cast(const_vec2u32_); + metal::float2x3 unnamed_10 = metal::float2x3(const_mat2x3f32_); + float _e72 = foo.a.x; + return _e72; } void logical( ) { bool unnamed_11 = !true; metal::bool2 unnamed_12 = !metal::bool2(true); - bool unnamed_13 = true || false; - bool unnamed_14 = true && false; + bool unnamed_13 = true | false; + bool unnamed_14 = true & false; bool unnamed_15 = true | false; metal::bool3 unnamed_16 = metal::bool3(true) | metal::bool3(false); bool unnamed_17 = true & false; @@ -107,188 +132,191 @@ void logical( void arithmetic( ) { - metal::int2 unnamed_19 = -metal::int2(1); - metal::float2 unnamed_20 = -metal::float2(1.0); - int unnamed_21 = 2 + 1; - uint unnamed_22 = 2u + 1u; - float unnamed_23 = 2.0 + 1.0; - metal::int2 unnamed_24 = metal::int2(2) + metal::int2(1); - metal::uint3 unnamed_25 = metal::uint3(2u) + metal::uint3(1u); - metal::float4 unnamed_26 = metal::float4(2.0) + metal::float4(1.0); - int unnamed_27 = 2 - 1; - uint unnamed_28 = 2u - 1u; - float unnamed_29 = 2.0 - 1.0; - metal::int2 unnamed_30 = metal::int2(2) - metal::int2(1); - metal::uint3 unnamed_31 = metal::uint3(2u) - metal::uint3(1u); - metal::float4 unnamed_32 = metal::float4(2.0) - metal::float4(1.0); - int unnamed_33 = 2 * 1; - uint unnamed_34 = 2u * 1u; - float unnamed_35 = 2.0 * 1.0; - metal::int2 unnamed_36 = metal::int2(2) * metal::int2(1); - metal::uint3 unnamed_37 = metal::uint3(2u) * metal::uint3(1u); - metal::float4 unnamed_38 = metal::float4(2.0) * metal::float4(1.0); - int unnamed_39 = 2 / 1; - uint unnamed_40 = 2u / 1u; - float unnamed_41 = 2.0 / 1.0; - metal::int2 unnamed_42 = metal::int2(2) / metal::int2(1); - metal::uint3 unnamed_43 = metal::uint3(2u) / metal::uint3(1u); - metal::float4 unnamed_44 = metal::float4(2.0) / metal::float4(1.0); - int unnamed_45 = 2 % 1; - uint unnamed_46 = 2u % 1u; - float unnamed_47 = metal::fmod(2.0, 1.0); - metal::int2 unnamed_48 = metal::int2(2) % metal::int2(1); - metal::uint3 unnamed_49 = metal::uint3(2u) % metal::uint3(1u); - metal::float4 unnamed_50 = metal::fmod(metal::float4(2.0), metal::float4(1.0)); - metal::int2 unnamed_51 = metal::int2(2) + metal::int2(1); + float unnamed_19 = -1.0; + metal::int2 unnamed_20 = -metal::int2(1); + metal::float2 unnamed_21 = -metal::float2(1.0); + int unnamed_22 = 2 + 1; + uint unnamed_23 = 2u + 1u; + float unnamed_24 = 2.0 + 1.0; + metal::int2 unnamed_25 = metal::int2(2) + metal::int2(1); + metal::uint3 unnamed_26 = metal::uint3(2u) + metal::uint3(1u); + metal::float4 unnamed_27 = metal::float4(2.0) + metal::float4(1.0); + int unnamed_28 = 2 - 1; + uint unnamed_29 = 2u - 1u; + float unnamed_30 = 2.0 - 1.0; + metal::int2 unnamed_31 = metal::int2(2) - metal::int2(1); + metal::uint3 unnamed_32 = metal::uint3(2u) - metal::uint3(1u); + metal::float4 unnamed_33 = metal::float4(2.0) - metal::float4(1.0); + int unnamed_34 = 2 * 1; + uint unnamed_35 = 2u * 1u; + float unnamed_36 = 2.0 * 1.0; + metal::int2 unnamed_37 = metal::int2(2) * metal::int2(1); + metal::uint3 unnamed_38 = metal::uint3(2u) * metal::uint3(1u); + metal::float4 unnamed_39 = metal::float4(2.0) * metal::float4(1.0); + int unnamed_40 = 2 / 1; + uint unnamed_41 = 2u / 1u; + float unnamed_42 = 2.0 / 1.0; + metal::int2 unnamed_43 = metal::int2(2) / metal::int2(1); + metal::uint3 unnamed_44 = metal::uint3(2u) / metal::uint3(1u); + metal::float4 unnamed_45 = metal::float4(2.0) / metal::float4(1.0); + int unnamed_46 = 2 % 1; + uint unnamed_47 = 2u % 1u; + float unnamed_48 = metal::fmod(2.0, 1.0); + metal::int2 unnamed_49 = metal::int2(2) % metal::int2(1); + metal::uint3 unnamed_50 = metal::uint3(2u) % metal::uint3(1u); + metal::float4 unnamed_51 = metal::fmod(metal::float4(2.0), metal::float4(1.0)); metal::int2 unnamed_52 = metal::int2(2) + metal::int2(1); - metal::uint2 unnamed_53 = metal::uint2(2u) + metal::uint2(1u); + metal::int2 unnamed_53 = metal::int2(2) + metal::int2(1); metal::uint2 unnamed_54 = metal::uint2(2u) + metal::uint2(1u); - metal::float2 unnamed_55 = metal::float2(2.0) + metal::float2(1.0); + metal::uint2 unnamed_55 = metal::uint2(2u) + metal::uint2(1u); metal::float2 unnamed_56 = metal::float2(2.0) + metal::float2(1.0); - metal::int2 unnamed_57 = metal::int2(2) - metal::int2(1); + metal::float2 unnamed_57 = metal::float2(2.0) + metal::float2(1.0); metal::int2 unnamed_58 = metal::int2(2) - metal::int2(1); - metal::uint2 unnamed_59 = metal::uint2(2u) - metal::uint2(1u); + metal::int2 unnamed_59 = metal::int2(2) - metal::int2(1); metal::uint2 unnamed_60 = metal::uint2(2u) - metal::uint2(1u); - metal::float2 unnamed_61 = metal::float2(2.0) - metal::float2(1.0); + metal::uint2 unnamed_61 = metal::uint2(2u) - metal::uint2(1u); metal::float2 unnamed_62 = metal::float2(2.0) - metal::float2(1.0); - metal::int2 unnamed_63 = metal::int2(2) * 1; - metal::int2 unnamed_64 = 2 * metal::int2(1); - metal::uint2 unnamed_65 = metal::uint2(2u) * 1u; - metal::uint2 unnamed_66 = 2u * metal::uint2(1u); - metal::float2 unnamed_67 = metal::float2(2.0) * 1.0; - metal::float2 unnamed_68 = 2.0 * metal::float2(1.0); - metal::int2 unnamed_69 = metal::int2(2) / metal::int2(1); + metal::float2 unnamed_63 = metal::float2(2.0) - metal::float2(1.0); + metal::int2 unnamed_64 = metal::int2(2) * 1; + metal::int2 unnamed_65 = 2 * metal::int2(1); + metal::uint2 unnamed_66 = metal::uint2(2u) * 1u; + metal::uint2 unnamed_67 = 2u * metal::uint2(1u); + metal::float2 unnamed_68 = metal::float2(2.0) * 1.0; + metal::float2 unnamed_69 = 2.0 * metal::float2(1.0); metal::int2 unnamed_70 = metal::int2(2) / metal::int2(1); - metal::uint2 unnamed_71 = metal::uint2(2u) / metal::uint2(1u); + metal::int2 unnamed_71 = metal::int2(2) / metal::int2(1); metal::uint2 unnamed_72 = metal::uint2(2u) / metal::uint2(1u); - metal::float2 unnamed_73 = metal::float2(2.0) / metal::float2(1.0); + metal::uint2 unnamed_73 = metal::uint2(2u) / metal::uint2(1u); metal::float2 unnamed_74 = metal::float2(2.0) / metal::float2(1.0); - metal::int2 unnamed_75 = metal::int2(2) % metal::int2(1); + metal::float2 unnamed_75 = metal::float2(2.0) / metal::float2(1.0); metal::int2 unnamed_76 = metal::int2(2) % metal::int2(1); - metal::uint2 unnamed_77 = metal::uint2(2u) % metal::uint2(1u); + metal::int2 unnamed_77 = metal::int2(2) % metal::int2(1); 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::uint2 unnamed_79 = metal::uint2(2u) % metal::uint2(1u); 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::float2 unnamed_81 = metal::fmod(metal::float2(2.0), metal::float2(1.0)); + mat3x3f32_ unnamed_82 = const_mat3x3f32_ + const_mat3x3f32_; + mat3x3f32_ unnamed_83 = const_mat3x3f32_ - const_mat3x3f32_; + mat3x3f32_ unnamed_84 = const_mat3x3f32_ * 1.0; + mat3x3f32_ unnamed_85 = 2.0 * const_mat3x3f32_; + metal::float3 unnamed_86 = const_mat4x3f32_ * metal::float4(1.0); + metal::float4 unnamed_87 = metal::float3(2.0) * const_mat4x3f32_; + metal::float3x3 unnamed_88 = const_mat4x3f32_ * const_mat3x4f32_; } void bit( ) { - int unnamed_88 = ~1; - uint unnamed_89 = ~1u; - metal::int2 unnamed_90 = ~metal::int2(1); - metal::uint3 unnamed_91 = ~metal::uint3(1u); - int unnamed_92 = 2 | 1; - uint unnamed_93 = 2u | 1u; - metal::int2 unnamed_94 = metal::int2(2) | metal::int2(1); - metal::uint3 unnamed_95 = metal::uint3(2u) | metal::uint3(1u); - int unnamed_96 = 2 & 1; - uint unnamed_97 = 2u & 1u; - metal::int2 unnamed_98 = metal::int2(2) & metal::int2(1); - metal::uint3 unnamed_99 = metal::uint3(2u) & metal::uint3(1u); - int unnamed_100 = 2 ^ 1; - uint unnamed_101 = 2u ^ 1u; - metal::int2 unnamed_102 = metal::int2(2) ^ metal::int2(1); - metal::uint3 unnamed_103 = metal::uint3(2u) ^ metal::uint3(1u); - int unnamed_104 = 2 << 1u; - uint unnamed_105 = 2u << 1u; - metal::int2 unnamed_106 = metal::int2(2) << metal::uint2(1u); - metal::uint3 unnamed_107 = metal::uint3(2u) << metal::uint3(1u); - int unnamed_108 = 2 >> 1u; - uint unnamed_109 = 2u >> 1u; - metal::int2 unnamed_110 = metal::int2(2) >> metal::uint2(1u); - metal::uint3 unnamed_111 = metal::uint3(2u) >> metal::uint3(1u); + int unnamed_89 = ~1; + uint unnamed_90 = ~1u; + metal::int2 unnamed_91 = ~metal::int2(1); + metal::uint3 unnamed_92 = ~metal::uint3(1u); + int unnamed_93 = 2 | 1; + uint unnamed_94 = 2u | 1u; + metal::int2 unnamed_95 = metal::int2(2) | metal::int2(1); + metal::uint3 unnamed_96 = metal::uint3(2u) | metal::uint3(1u); + int unnamed_97 = 2 & 1; + uint unnamed_98 = 2u & 1u; + metal::int2 unnamed_99 = metal::int2(2) & metal::int2(1); + metal::uint3 unnamed_100 = metal::uint3(2u) & metal::uint3(1u); + int unnamed_101 = 2 ^ 1; + uint unnamed_102 = 2u ^ 1u; + metal::int2 unnamed_103 = metal::int2(2) ^ metal::int2(1); + metal::uint3 unnamed_104 = metal::uint3(2u) ^ metal::uint3(1u); + int unnamed_105 = 2 << 1u; + uint unnamed_106 = 2u << 1u; + metal::int2 unnamed_107 = metal::int2(2) << metal::uint2(1u); + metal::uint3 unnamed_108 = metal::uint3(2u) << metal::uint3(1u); + int unnamed_109 = 2 >> 1u; + uint unnamed_110 = 2u >> 1u; + metal::int2 unnamed_111 = metal::int2(2) >> metal::uint2(1u); + metal::uint3 unnamed_112 = metal::uint3(2u) >> metal::uint3(1u); } void comparison( ) { - bool unnamed_112 = 2 == 1; - bool unnamed_113 = 2u == 1u; - bool unnamed_114 = 2.0 == 1.0; - metal::bool2 unnamed_115 = metal::int2(2) == metal::int2(1); - metal::bool3 unnamed_116 = metal::uint3(2u) == metal::uint3(1u); - metal::bool4 unnamed_117 = metal::float4(2.0) == metal::float4(1.0); - bool unnamed_118 = 2 != 1; - bool unnamed_119 = 2u != 1u; - bool unnamed_120 = 2.0 != 1.0; - metal::bool2 unnamed_121 = metal::int2(2) != metal::int2(1); - metal::bool3 unnamed_122 = metal::uint3(2u) != metal::uint3(1u); - metal::bool4 unnamed_123 = metal::float4(2.0) != metal::float4(1.0); - bool unnamed_124 = 2 < 1; - bool unnamed_125 = 2u < 1u; - bool unnamed_126 = 2.0 < 1.0; - metal::bool2 unnamed_127 = metal::int2(2) < metal::int2(1); - metal::bool3 unnamed_128 = metal::uint3(2u) < metal::uint3(1u); - metal::bool4 unnamed_129 = metal::float4(2.0) < metal::float4(1.0); - bool unnamed_130 = 2 <= 1; - bool unnamed_131 = 2u <= 1u; - bool unnamed_132 = 2.0 <= 1.0; - metal::bool2 unnamed_133 = metal::int2(2) <= metal::int2(1); - metal::bool3 unnamed_134 = metal::uint3(2u) <= metal::uint3(1u); - metal::bool4 unnamed_135 = metal::float4(2.0) <= metal::float4(1.0); - bool unnamed_136 = 2 > 1; - bool unnamed_137 = 2u > 1u; - bool unnamed_138 = 2.0 > 1.0; - metal::bool2 unnamed_139 = metal::int2(2) > metal::int2(1); - metal::bool3 unnamed_140 = metal::uint3(2u) > metal::uint3(1u); - metal::bool4 unnamed_141 = metal::float4(2.0) > metal::float4(1.0); - bool unnamed_142 = 2 >= 1; - bool unnamed_143 = 2u >= 1u; - bool unnamed_144 = 2.0 >= 1.0; - metal::bool2 unnamed_145 = metal::int2(2) >= metal::int2(1); - metal::bool3 unnamed_146 = metal::uint3(2u) >= metal::uint3(1u); - metal::bool4 unnamed_147 = metal::float4(2.0) >= metal::float4(1.0); + bool unnamed_113 = 2 == 1; + bool unnamed_114 = 2u == 1u; + bool unnamed_115 = 2.0 == 1.0; + metal::bool2 unnamed_116 = metal::int2(2) == metal::int2(1); + metal::bool3 unnamed_117 = metal::uint3(2u) == metal::uint3(1u); + metal::bool4 unnamed_118 = metal::float4(2.0) == metal::float4(1.0); + bool unnamed_119 = 2 != 1; + bool unnamed_120 = 2u != 1u; + bool unnamed_121 = 2.0 != 1.0; + metal::bool2 unnamed_122 = metal::int2(2) != metal::int2(1); + metal::bool3 unnamed_123 = metal::uint3(2u) != metal::uint3(1u); + metal::bool4 unnamed_124 = metal::float4(2.0) != metal::float4(1.0); + bool unnamed_125 = 2 < 1; + bool unnamed_126 = 2u < 1u; + bool unnamed_127 = 2.0 < 1.0; + metal::bool2 unnamed_128 = metal::int2(2) < metal::int2(1); + metal::bool3 unnamed_129 = metal::uint3(2u) < metal::uint3(1u); + metal::bool4 unnamed_130 = metal::float4(2.0) < metal::float4(1.0); + bool unnamed_131 = 2 <= 1; + bool unnamed_132 = 2u <= 1u; + bool unnamed_133 = 2.0 <= 1.0; + metal::bool2 unnamed_134 = metal::int2(2) <= metal::int2(1); + metal::bool3 unnamed_135 = metal::uint3(2u) <= metal::uint3(1u); + metal::bool4 unnamed_136 = metal::float4(2.0) <= metal::float4(1.0); + bool unnamed_137 = 2 > 1; + bool unnamed_138 = 2u > 1u; + bool unnamed_139 = 2.0 > 1.0; + metal::bool2 unnamed_140 = metal::int2(2) > metal::int2(1); + metal::bool3 unnamed_141 = metal::uint3(2u) > metal::uint3(1u); + metal::bool4 unnamed_142 = metal::float4(2.0) > metal::float4(1.0); + bool unnamed_143 = 2 >= 1; + bool unnamed_144 = 2u >= 1u; + bool unnamed_145 = 2.0 >= 1.0; + metal::bool2 unnamed_146 = metal::int2(2) >= metal::int2(1); + metal::bool3 unnamed_147 = metal::uint3(2u) >= metal::uint3(1u); + metal::bool4 unnamed_148 = metal::float4(2.0) >= metal::float4(1.0); } void assignment( ) { - int a_1 = 1; - metal::int3 vec0_ = const_type_18_; - int _e6 = a_1; - a_1 = _e6 + 1; - int _e9 = a_1; - a_1 = _e9 - 1; - int _e12 = a_1; - int _e13 = a_1; - a_1 = _e12 * _e13; - int _e15 = a_1; - int _e16 = a_1; - a_1 = _e15 / _e16; - int _e18 = a_1; - a_1 = _e18 % 1; - int _e21 = a_1; - a_1 = _e21 & 0; - int _e24 = a_1; - a_1 = _e24 | 0; - int _e27 = a_1; - a_1 = _e27 ^ 0; - 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; + i32_ a_1 = {}; + vec3i32_ vec0_ = {}; + a_1 = 1; + i32_ _e3 = a_1; + a_1 = _e3 + 1; + i32_ _e7 = a_1; + a_1 = _e7 - 1; + i32_ _e11 = a_1; + i32_ _e13 = a_1; + a_1 = _e13 * _e11; + i32_ _e16 = a_1; + i32_ _e18 = a_1; + a_1 = _e18 / _e16; + i32_ _e21 = a_1; + a_1 = _e21 % 1; + i32_ _e25 = a_1; + a_1 = _e25 & 0; + i32_ _e29 = a_1; + a_1 = _e29 | 0; + i32_ _e33 = a_1; + a_1 = _e33 ^ 0; + i32_ _e38 = a_1; + a_1 = _e38 << 2u; + i32_ _e42 = a_1; + a_1 = _e42 >> 1u; + i32_ _e45 = a_1; + a_1 = _e45 + 1; + i32_ _e49 = a_1; + a_1 = _e49 - 1; + vec0_ = const_vec3i32_; + int _e57 = vec0_.y; + vec0_.y = _e57 + 1; + int _e63 = vec0_.y; + vec0_.y = _e63 - 1; return; } kernel void main_( ) { - metal::float4 _e4 = builtins(); - metal::float4 _e5 = splat(); - metal::float3 _e7 = bool_cast(v_f32_one.xyz); - float _e8 = constructors(); + vec4f32_ _e0 = builtins(); + vec4f32_ _e1 = splat(); + vec3f32_ _e2 = bool_cast(v_f32_one.xyz); + f32_ _e5 = constructors(); logical(); arithmetic(); bit(); diff --git a/tests/out/msl/padding.msl b/tests/out/msl/padding.msl index 90b2c2eb11..1b62b86e3d 100644 --- a/tests/out/msl/padding.msl +++ b/tests/out/msl/padding.msl @@ -4,24 +4,31 @@ using metal::uint; +typedef metal::float3 vec3f32_; struct S { - metal::float3 a; + vec3f32_ a; }; +typedef float f32_; struct Test { S a; - float b; + f32_ b; }; -struct type_2 { - metal::float3 inner[2]; +struct arrayvec3f322_ { + vec3f32_ inner[2u]; }; struct Test2_ { - type_2 a; - float b; + arrayvec3f322_ a; + f32_ b; }; +typedef metal::float4x3 mat4x3f32_; struct Test3_ { - metal::float4x3 a; - float b; + mat4x3f32_ a; + f32_ b; }; +typedef metal::float4 vec4f32_; +typedef constant Test& ptruniformTest; +typedef constant Test2_& ptruniformTest2_; +typedef constant Test3_& ptruniformTest3_; struct vertex_Output { metal::float4 member [[position]]; @@ -31,8 +38,8 @@ vertex vertex_Output vertex_( , constant Test2_& input2_ [[buffer(1)]] , constant Test3_& input3_ [[buffer(2)]] ) { - float _e6 = input1_.b; - float _e9 = input2_.b; - float _e12 = input3_.b; - return vertex_Output { ((metal::float4(1.0) * _e6) * _e9) * _e12 }; + f32_ _e4 = input1_.b; + f32_ _e8 = input2_.b; + f32_ _e12 = input3_.b; + 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..da7f53022e 100644 --- a/tests/out/msl/policy-mix.msl +++ b/tests/out/msl/policy-mix.msl @@ -10,45 +10,57 @@ struct DefaultConstructible { return T {}; } }; -struct type_1 { - metal::float4 inner[10]; +typedef metal::float4 vec4f32_; +struct arrayvec4f3210_ { + vec4f32_ inner[10u]; }; struct InStorage { - type_1 a; + arrayvec4f3210_ a; }; -struct type_2 { - metal::float4 inner[20]; +struct arrayvec4f3220_ { + vec4f32_ inner[20u]; }; struct InUniform { - type_2 a; + arrayvec4f3220_ a; }; -struct type_5 { - float inner[30]; +typedef float f32_; +struct arrayf3230_ { + f32_ inner[30u]; }; -struct type_6 { - float inner[40]; +struct arrayf3240_ { + f32_ inner[40u]; }; -struct type_9 { - metal::float4 inner[2]; +typedef metal::int2 vec2i32_; +typedef int i32_; +struct arrayvec4f322_ { + vec4f32_ inner[2u]; }; +typedef device InStorage& ptrstorageInStorage; +typedef device arrayvec4f3210_& ptrstoragearrayvec4f3210_; +typedef constant InUniform& ptruniformInUniform; +typedef constant arrayvec4f3220_& ptruniformarrayvec4f3220_; +typedef threadgroup arrayf3230_& ptrworkgrouparrayf3230_; +typedef thread arrayf3240_& ptrprivatearrayf3240_; +typedef thread arrayvec4f322_& ptrfunctionarrayvec4f322_; -metal::float4 mock_function( - metal::int2 c, - int i, - int l, +vec4f32_ mock_function( + vec2i32_ c, + i32_ i, + i32_ l, device InStorage const& in_storage, constant InUniform& in_uniform, metal::texture2d_array image_2d_array, - threadgroup type_5& in_workgroup, - thread type_6& in_private + threadgroup arrayf3230_& in_workgroup, + thread arrayf3240_& in_private ) { - 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]; + arrayvec4f322_ in_function = {}; + arrayvec4f322_ in_function_1 = arrayvec4f322_ {metal::float4(0.707, 0.0, 0.0, 1.0), metal::float4(0.0, 0.707, 0.0, 1.0)}; + for(int _i=0; _i<2; ++_i) in_function.inner[_i] = in_function_1.inner[_i]; + vec4f32_ _e16 = in_storage.a.inner[i]; + vec4f32_ _e21 = 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)]; - 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; + f32_ _e32 = in_workgroup.inner[metal::min(unsigned(i), 29u)]; + f32_ _e38 = in_private.inner[metal::min(unsigned(i), 39u)]; + vec4f32_ _e44 = in_function.inner[metal::min(unsigned(i), 1u)]; + return ((((_e16 + _e21) + _e27) + metal::float4(_e32)) + metal::float4(_e38)) + _e44; } diff --git a/tests/out/msl/quad.msl b/tests/out/msl/quad.msl index a6beb30b8c..b8f313bc92 100644 --- a/tests/out/msl/quad.msl +++ b/tests/out/msl/quad.msl @@ -4,15 +4,18 @@ using metal::uint; -constexpr constant float c_scale = 1.2000000476837158; +constexpr constant float c_scale = 1.2; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef metal::float4 vec4f32_; struct VertexOutput { - metal::float2 uv; - metal::float4 position; + vec2f32_ uv; + vec4f32_ position; }; struct vert_mainInput { - metal::float2 pos [[attribute(0)]]; - metal::float2 uv [[attribute(1)]]; + vec2f32_ pos [[attribute(0)]]; + vec2f32_ uv [[attribute(1)]]; }; struct vert_mainOutput { metal::float2 uv [[user(loc0), center_perspective]]; @@ -29,7 +32,7 @@ vertex vert_mainOutput vert_main( struct frag_mainInput { - metal::float2 uv_1 [[user(loc0), center_perspective]]; + vec2f32_ uv_1 [[user(loc0), center_perspective]]; }; struct frag_mainOutput { metal::float4 member_1 [[color(0)]]; diff --git a/tests/out/msl/shadow.msl b/tests/out/msl/shadow.msl index 651a89841a..1e503f4264 100644 --- a/tests/out/msl/shadow.msl +++ b/tests/out/msl/shadow.msl @@ -9,40 +9,57 @@ struct _mslBufferSizes { }; constexpr constant unsigned c_max_lights = 10u; +typedef metal::float4x4 mat4x4f32_; +typedef metal::uint4 vec4u32_; struct Globals { - metal::float4x4 view_proj; - metal::uint4 num_lights; + mat4x4f32_ view_proj; + vec4u32_ num_lights; }; +typedef metal::float4 vec4f32_; struct Entity { - metal::float4x4 world; - metal::float4 color; + mat4x4f32_ world; + vec4f32_ color; }; +typedef metal::float3 vec3f32_; struct VertexOutput { - metal::float4 proj_position; - metal::float3 world_normal; - metal::float4 world_position; + vec4f32_ proj_position; + vec3f32_ world_normal; + vec4f32_ world_position; }; +typedef metal::int4 vec4i32_; +typedef constant Entity& ptruniformEntity; +typedef metal::float3x3 mat3x3f32_; +typedef metal::int3 vec3i32_; +typedef thread VertexOutput& ptrfunctionVertexOutput; +typedef constant Globals& ptruniformGlobals; struct Light { - metal::float4x4 proj; - metal::float4 pos; - metal::float4 color; + mat4x4f32_ proj; + vec4f32_ pos; + vec4f32_ color; }; -typedef Light type_6[1]; -struct type_7 { - Light inner[10]; +typedef Light arrayLight[1]; +struct arrayLight10_ { + Light inner[10u]; }; -constant metal::float3 c_ambient = {0.05000000074505806, 0.05000000074505806, 0.05000000074505806}; +typedef uint u32_; +typedef float f32_; +typedef metal::float2 vec2f32_; +typedef int i32_; +typedef constant vec4u32_& ptruniformvec4u32_; +typedef device arrayLight& ptrstoragearrayLight; +typedef constant arrayLight10_& ptruniformarrayLight10_; +constant vec3f32_ c_ambient = {0.05, 0.05, 0.05}; -float fetch_shadow( - uint light_id, - metal::float4 homogeneous_coords, +f32_ fetch_shadow( + u32_ light_id, + vec4f32_ homogeneous_coords, metal::depth2d_array t_shadow, metal::sampler sampler_shadow ) { if (homogeneous_coords.w <= 0.0) { return 1.0; } - metal::float2 flip_correction = metal::float2(0.5, -0.5); + vec2f32_ 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); @@ -50,8 +67,8 @@ float fetch_shadow( } struct vs_mainInput { - metal::int4 position [[attribute(0)]]; - metal::int4 normal [[attribute(1)]]; + vec4i32_ position [[attribute(0)]]; + vec4i32_ normal [[attribute(1)]]; }; struct vs_mainOutput { metal::float4 proj_position [[position]]; @@ -66,111 +83,123 @@ vertex vs_mainOutput vs_main( const auto position = varyings.position; const auto normal = varyings.normal; VertexOutput out = {}; - metal::float4x4 w = u_entity.world; - metal::float4x4 _e7 = u_entity.world; - metal::float4 world_pos = _e7 * static_cast(position); + mat4x4f32_ w = u_entity.world; + mat4x4f32_ _e5 = u_entity.world; + metal::float4 world_pos = _e5 * 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; + mat4x4f32_ _e26 = u_globals.view_proj; + out.proj_position = _e26 * world_pos; + VertexOutput _e31 = out; + const auto _tmp = _e31; return vs_mainOutput { _tmp.proj_position, _tmp.world_normal, _tmp.world_position }; } struct fs_mainInput { - metal::float3 world_normal [[user(loc0), center_perspective]]; - metal::float4 world_position [[user(loc1), center_perspective]]; + vec3f32_ world_normal [[user(loc0), center_perspective]]; + vec4f32_ world_position [[user(loc1), center_perspective]]; }; struct fs_mainOutput { metal::float4 member_1 [[color(0)]]; }; fragment fs_mainOutput fs_main( fs_mainInput varyings_1 [[stage_in]] -, metal::float4 proj_position [[position]] +, vec4f32_ proj_position [[position]] , constant Globals& u_globals [[user(fake0)]] , constant Entity& u_entity [[user(fake0)]] -, device type_6 const& s_lights [[user(fake0)]] +, device arrayLight const& s_lights [[user(fake0)]] , metal::depth2d_array t_shadow [[user(fake0)]] , metal::sampler sampler_shadow [[user(fake0)]] , 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 normal_1 = metal::normalize(in.world_normal); - bool loop_init = true; - while(true) { - if (!loop_init) { - uint _e20 = i; - i = _e20 + 1u; - } - loop_init = false; - uint _e14 = i; - uint _e17 = u_globals.num_lights.x; - if (_e14 < metal::min(_e17, c_max_lights)) { - } else { - break; + vec3f32_ color = {}; + u32_ i = {}; + vec3f32_ normal_1 = metal::normalize(in.world_normal); + color = c_ambient; + { + i = 0u; + bool loop_init = true; + while(true) { + if (!loop_init) { + u32_ _e46 = i; + i = _e46 + 1u; + } + loop_init = false; + u32_ _e8 = i; + uint _e12 = u_globals.num_lights.x; + if (_e8 < metal::min(_e12, c_max_lights)) { + } else { + break; + } + { + u32_ _e18 = i; + Light light = s_lights[_e18]; + u32_ _e23 = i; + f32_ _e21 = fetch_shadow(_e23, 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)); + vec3f32_ _e43 = color; + color = _e43 + ((_e21 * diffuse) * light.color.xyz); + } } - 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); } - metal::float3 _e46 = color; - metal::float4 _e50 = u_entity.color; - return fs_mainOutput { metal::float4(_e46, 1.0) * _e50 }; + vec3f32_ _e50 = color; + vec4f32_ _e55 = u_entity.color; + return fs_mainOutput { metal::float4(_e50, 1.0) * _e55 }; } struct fs_main_without_storageInput { - metal::float3 world_normal [[user(loc0), center_perspective]]; - metal::float4 world_position [[user(loc1), center_perspective]]; + vec3f32_ world_normal [[user(loc0), center_perspective]]; + vec4f32_ world_position [[user(loc1), center_perspective]]; }; struct fs_main_without_storageOutput { metal::float4 member_2 [[color(0)]]; }; fragment fs_main_without_storageOutput fs_main_without_storage( fs_main_without_storageInput varyings_2 [[stage_in]] -, metal::float4 proj_position_1 [[position]] +, vec4f32_ proj_position_1 [[position]] , constant Globals& u_globals [[user(fake0)]] , constant Entity& u_entity [[user(fake0)]] -, constant type_7& u_lights [[user(fake0)]] +, constant arrayLight10_& u_lights [[user(fake0)]] , metal::depth2d_array t_shadow [[user(fake0)]] , 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 normal_2 = metal::normalize(in_1.world_normal); - bool loop_init_1 = true; - while(true) { - if (!loop_init_1) { - uint _e20 = i_1; - i_1 = _e20 + 1u; - } - loop_init_1 = false; - uint _e14 = i_1; - uint _e17 = u_globals.num_lights.x; - if (_e14 < metal::min(_e17, c_max_lights)) { - } else { - break; + vec3f32_ color_1 = {}; + u32_ i_1 = {}; + vec3f32_ 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) { + u32_ _e46 = i_1; + i_1 = _e46 + 1u; + } + loop_init_1 = false; + u32_ _e8 = i_1; + uint _e12 = u_globals.num_lights.x; + if (_e8 < metal::min(_e12, c_max_lights)) { + } else { + break; + } + { + u32_ _e18 = i_1; + Light light_1 = u_lights.inner[_e18]; + u32_ _e23 = i_1; + f32_ _e21 = fetch_shadow(_e23, 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)); + vec3f32_ _e43 = color_1; + color_1 = _e43 + ((_e21 * diffuse_1) * light_1.color.xyz); + } } - 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); } - metal::float3 _e46 = color_1; - metal::float4 _e50 = u_entity.color; - return fs_main_without_storageOutput { metal::float4(_e46, 1.0) * _e50 }; + vec3f32_ _e50 = color_1; + vec4f32_ _e55 = u_entity.color; + return fs_main_without_storageOutput { metal::float4(_e50, 1.0) * _e55 }; } diff --git a/tests/out/msl/skybox.msl b/tests/out/msl/skybox.msl index c25770d4ff..3fb9e02f5a 100644 --- a/tests/out/msl/skybox.msl +++ b/tests/out/msl/skybox.msl @@ -4,14 +4,24 @@ using metal::uint; +typedef metal::float4 vec4f32_; +typedef metal::float3 vec3f32_; struct VertexOutput { - metal::float4 position; - metal::float3 uv; + vec4f32_ position; + vec3f32_ uv; }; +typedef metal::float4x4 mat4x4f32_; struct Data { - metal::float4x4 proj_inv; - metal::float4x4 view; + mat4x4f32_ proj_inv; + mat4x4f32_ view; }; +typedef uint u32_; +typedef int i32_; +typedef float f32_; +typedef constant Data& ptruniformData; +typedef constant mat4x4f32_& ptruniformmat4x4f32_; +typedef constant metal::float4& ptruniformvec4f32_; +typedef metal::float3x3 mat3x3f32_; struct vs_mainInput { }; @@ -20,36 +30,38 @@ struct vs_mainOutput { metal::float3 uv [[user(loc0), center_perspective]]; }; vertex vs_mainOutput vs_main( - uint vertex_index [[vertex_id]] + u32_ vertex_index [[vertex_id]] , constant Data& r_data [[buffer(0)]] ) { - int tmp1_ = {}; - 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); - 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; + i32_ tmp1_ = {}; + i32_ tmp2_ = {}; + int tmp1_1 = static_cast(vertex_index) / 2; + tmp1_ = tmp1_1; + int tmp2_1 = static_cast(vertex_index) & 1; + tmp2_ = tmp2_1; + i32_ _e11 = tmp1_; + i32_ _e18 = tmp2_; + vec4f32_ pos = metal::float4((static_cast(_e11) * 4.0) - 1.0, (static_cast(_e18) * 4.0) - 1.0, 0.0, 1.0); + metal::float4 _e31 = r_data.view[0]; + metal::float4 _e37 = r_data.view[1]; + metal::float4 _e43 = r_data.view[2]; + metal::float3x3 inv_model_view = metal::transpose(metal::float3x3(_e31.xyz, _e37.xyz, _e43.xyz)); + mat4x4f32_ _e49 = r_data.proj_inv; + metal::float4 unprojected = _e49 * pos; const auto _tmp = VertexOutput {pos, inv_model_view * unprojected.xyz}; return vs_mainOutput { _tmp.position, _tmp.uv }; } struct fs_mainInput { - metal::float3 uv [[user(loc0), center_perspective]]; + vec3f32_ uv [[user(loc0), center_perspective]]; }; struct fs_mainOutput { metal::float4 member_1 [[color(0)]]; }; fragment fs_mainOutput fs_main( fs_mainInput varyings_1 [[stage_in]] -, metal::float4 position [[position]] +, vec4f32_ position [[position]] , metal::texturecube r_texture [[texture(0)]] ) { constexpr metal::sampler r_sampler( @@ -61,6 +73,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/standard.msl b/tests/out/msl/standard.msl index d21930c061..e1521171ae 100644 --- a/tests/out/msl/standard.msl +++ b/tests/out/msl/standard.msl @@ -4,6 +4,7 @@ using metal::uint; +typedef metal::float4 vec4f32_; struct derivativesInput { }; @@ -11,10 +12,10 @@ struct derivativesOutput { metal::float4 member [[color(0)]]; }; fragment derivativesOutput derivatives( - metal::float4 foo [[position]] + vec4f32_ foo [[position]] ) { - metal::float4 x = metal::dfdx(foo); - metal::float4 y = metal::dfdy(foo); - metal::float4 z = metal::fwidth(foo); + vec4f32_ x = metal::dfdx(foo); + vec4f32_ y = metal::dfdy(foo); + vec4f32_ z = metal::fwidth(foo); return derivativesOutput { (x + y) * z }; } diff --git a/tests/out/msl/texture-arg.msl b/tests/out/msl/texture-arg.msl index ba0be05e18..cff685ef59 100644 --- a/tests/out/msl/texture-arg.msl +++ b/tests/out/msl/texture-arg.msl @@ -4,13 +4,16 @@ using metal::uint; +typedef metal::float4 vec4f32_; +typedef float f32_; +typedef metal::float2 vec2f32_; -metal::float4 test( +vec4f32_ 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 { @@ -20,6 +23,6 @@ fragment main_Output main_( metal::texture2d Texture [[user(fake0)]] , metal::sampler Sampler [[user(fake0)]] ) { - metal::float4 _e2 = test(Texture, Sampler); - return main_Output { _e2 }; + vec4f32_ _e0 = test(Texture, Sampler); + return main_Output { _e0 }; } diff --git a/tests/out/spv/access.spvasm b/tests/out/spv/access.spvasm index fe7e75d4a4..f9c7bf3233 100644 --- a/tests/out/spv/access.spvasm +++ b/tests/out/spv/access.spvasm @@ -1,61 +1,105 @@ ; 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 %241 "foo_vert" %236 %239 +OpEntryPoint Fragment %278 "foo_frag" %277 +OpEntryPoint GLCompute %297 "atomics" +OpEntryPoint GLCompute %320 "assign_through_ptr" +OpExecutionMode %278 OriginUpperLeft +OpExecutionMode %297 LocalSize 1 1 1 +OpExecutionMode %320 LocalSize 1 1 1 OpSource GLSL 450 +OpName %4 "u32" +OpName %35 "vec3" +OpName %6 "i32" OpMemberName %36 0 "a" OpMemberName %36 1 "b" OpMemberName %36 2 "c" OpName %36 "GlobalConst" OpMemberName %37 0 "value" OpName %37 "AlignedWrapper" +OpName %38 "mat4x3" +OpName %40 "mat2x2" +OpName %42 "array, 2>" +OpName %6 "atomic" +OpName %43 "vec2" +OpName %44 "array, 2>" +OpName %45 "array" OpMemberName %46 0 "_matrix" OpMemberName %46 1 "matrix_array" OpMemberName %46 2 "atom" OpMemberName %46 3 "arr" OpMemberName %46 4 "data" OpName %46 "Bar" +OpName %47 "mat3x2" 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 %49 "vec2" +OpName %50 "ptr" +OpName %51 "ptr>" +OpName %52 "ptr>" +OpName %10 "f32" +OpName %41 "vec2" +OpName %53 "ptr" +OpName %54 "ptr>" +OpName %55 "ptr>" +OpName %56 "mat4x2" +OpName %57 "array, 2>" +OpMemberName %58 0 "am" +OpName %58 "MatCx2InArray" +OpName %59 "ptr" +OpName %60 "ptr, 2>>" +OpName %61 "ptr>" +OpName %62 "ptr" +OpName %63 "ptr, 2>>" +OpName %64 "ptr>" +OpName %65 "ptr" +OpName %66 "array" +OpName %67 "array, 5>" +OpName %68 "vec4" +OpName %69 "ptr" +OpName %70 "ptr>" +OpName %71 "ptr>" +OpName %39 "vec3" +OpName %72 "ptr>" +OpName %73 "ptr" +OpName %74 "ptr" +OpName %75 "array" +OpName %76 "ptr>" +OpName %77 "vec4" +OpName %78 "ptr>" +OpName %79 "ptr" +OpName %88 "global_const" +OpName %90 "bar" +OpName %91 "baz" +OpName %94 "qux" +OpName %97 "nested_mat_cx2" +OpName %100 "val" +OpName %101 "idx" +OpName %104 "t" +OpName %107 "test_matrix_within_struct_accesses" +OpName %159 "idx" +OpName %161 "t" +OpName %164 "test_matrix_within_array_within_struct_accesses" +OpName %214 "foo" +OpName %215 "read_from_private" +OpName %220 "a" +OpName %221 "test_arr_as_arg" +OpName %227 "p" +OpName %228 "assign_through_ptr_fn" +OpName %231 "foo" +OpName %233 "d" +OpName %236 "vi" +OpName %241 "foo_vert" +OpName %278 "foo_frag" +OpName %294 "tmp" +OpName %297 "atomics" +OpName %320 "assign_through_ptr" OpMemberDecorate %36 0 Offset 0 OpMemberDecorate %36 1 Offset 16 OpMemberDecorate %36 2 Offset 28 @@ -75,37 +119,37 @@ OpMemberDecorate %46 4 Offset 120 OpMemberDecorate %48 0 Offset 0 OpMemberDecorate %48 0 ColMajor OpMemberDecorate %48 0 MatrixStride 8 -OpDecorate %51 ArrayStride 32 -OpMemberDecorate %52 0 Offset 0 -OpMemberDecorate %52 0 ColMajor -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 %57 ArrayStride 32 +OpMemberDecorate %58 0 Offset 0 +OpMemberDecorate %58 0 ColMajor +OpMemberDecorate %58 0 MatrixStride 8 +OpDecorate %66 ArrayStride 4 +OpDecorate %67 ArrayStride 40 +OpDecorate %75 ArrayStride 4 +OpDecorate %90 DescriptorSet 0 +OpDecorate %90 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 %91 DescriptorSet 0 +OpDecorate %91 Binding 1 +OpDecorate %92 Block +OpMemberDecorate %92 0 Offset 0 +OpDecorate %94 DescriptorSet 0 +OpDecorate %94 Binding 2 +OpDecorate %95 Block +OpMemberDecorate %95 0 Offset 0 +OpDecorate %97 DescriptorSet 0 +OpDecorate %97 Binding 3 +OpDecorate %98 Block +OpMemberDecorate %98 0 Offset 0 +OpDecorate %236 BuiltIn VertexIndex +OpDecorate %239 BuiltIn Position +OpDecorate %277 Location 0 %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 0 %6 = OpTypeInt 32 1 %5 = OpConstant %6 0 -%7 = OpConstant %6 2 +%7 = OpConstant %4 2 %8 = OpConstant %6 1 %10 = OpTypeFloat 32 %9 = OpConstant %10 1.0 @@ -123,13 +167,13 @@ OpDecorate %273 Location 0 %22 = OpConstant %10 0.0 %23 = OpConstant %10 8.0 %24 = OpConstant %10 7.0 -%25 = OpConstant %6 10 -%26 = OpConstant %6 5 +%25 = OpConstant %4 10 +%26 = OpConstant %4 5 %27 = OpConstant %6 4 %28 = OpConstant %6 9 %29 = OpConstant %4 3 -%30 = OpConstant %4 2 -%31 = OpConstant %6 3 +%30 = OpConstant %6 3 +%31 = OpConstant %6 5 %32 = OpConstant %4 1 %33 = OpConstant %6 42 %34 = OpConstant %4 42 @@ -148,341 +192,347 @@ OpDecorate %273 Location 0 %47 = OpTypeMatrix %41 3 %48 = OpTypeStruct %47 %49 = OpTypeVector %6 2 -%50 = OpTypeMatrix %41 4 -%51 = OpTypeArray %50 %7 -%52 = OpTypeStruct %51 -%53 = OpTypePointer Function %10 -%54 = OpTypeArray %10 %25 -%55 = OpTypeArray %54 %26 -%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 +%50 = OpTypePointer Uniform %48 +%51 = OpTypePointer Uniform %47 +%52 = OpTypePointer Uniform %41 +%53 = OpTypePointer Function %48 +%54 = OpTypePointer Function %47 +%55 = OpTypePointer Function %41 +%56 = OpTypeMatrix %41 4 +%57 = OpTypeArray %56 %7 +%58 = OpTypeStruct %57 +%59 = OpTypePointer Uniform %58 +%60 = OpTypePointer Uniform %57 +%61 = OpTypePointer Uniform %56 +%62 = OpTypePointer Function %58 +%63 = OpTypePointer Function %57 +%64 = OpTypePointer Function %56 +%65 = OpTypePointer Function %10 +%66 = OpTypeArray %10 %25 +%67 = OpTypeArray %66 %26 +%68 = OpTypeVector %10 4 +%69 = OpTypePointer StorageBuffer %46 +%70 = OpTypePointer StorageBuffer %38 +%71 = OpTypePointer StorageBuffer %39 +%72 = OpTypePointer StorageBuffer %45 +%73 = OpTypePointer StorageBuffer %37 +%74 = OpTypePointer StorageBuffer %6 +%75 = OpTypeArray %6 %26 +%76 = OpTypePointer Function %75 +%77 = OpTypeVector %6 4 +%78 = OpTypePointer StorageBuffer %6 +%79 = OpTypePointer Workgroup %4 +%80 = OpConstantComposite %35 %3 %3 %3 +%81 = OpConstantComposite %36 %3 %80 %5 +%82 = OpConstantComposite %41 %22 %22 +%83 = OpConstantComposite %56 %82 %82 %82 %82 +%84 = OpConstantComposite %57 %83 %83 +%85 = OpConstantComposite %66 %22 %22 %22 %22 %22 %22 %22 %22 %22 %22 +%86 = OpConstantComposite %67 %85 %85 %85 %85 %85 +%87 = OpConstantComposite %49 %5 %5 +%89 = OpTypePointer Private %36 +%88 = OpVariable %89 Private %81 +%90 = OpVariable %69 StorageBuffer +%92 = OpTypeStruct %48 +%93 = OpTypePointer Uniform %92 +%91 = OpVariable %93 Uniform +%95 = OpTypeStruct %49 +%96 = OpTypePointer StorageBuffer %95 +%94 = OpVariable %96 StorageBuffer +%98 = OpTypeStruct %58 +%99 = OpTypePointer Uniform %98 +%97 = OpVariable %99 Uniform +%100 = OpVariable %79 Workgroup +%102 = OpTypePointer Function %6 +%103 = OpConstantNull %6 +%105 = OpConstantNull %48 +%108 = OpTypeFunction %2 +%120 = OpTypePointer Uniform %10 +%150 = OpTypePointer Function %10 +%160 = OpConstantNull %6 +%162 = OpConstantNull %58 +%216 = OpTypeFunction %10 %65 +%222 = OpTypeFunction %10 %67 +%229 = OpTypeFunction %2 %79 +%232 = OpConstantNull %10 +%234 = OpConstantNull %75 +%237 = OpTypePointer Input %4 +%236 = OpVariable %237 Input +%240 = OpTypePointer Output %68 +%239 = OpVariable %240 Output +%243 = OpTypePointer StorageBuffer %49 +%252 = OpTypePointer StorageBuffer %44 +%255 = OpTypePointer StorageBuffer %10 +%260 = OpConstant %4 4 +%277 = OpVariable %240 Output +%295 = OpConstantNull %6 +%301 = OpConstant %4 64 +%107 = OpFunction %2 None %108 +%106 = OpLabel +%101 = OpVariable %102 Function %103 +%104 = OpVariable %53 Function %105 +%109 = OpAccessChain %50 %91 %3 +OpBranch %110 +%110 = OpLabel +OpStore %101 %8 +%111 = OpLoad %6 %101 +%112 = OpISub %6 %111 %8 +OpStore %101 %112 +%113 = OpAccessChain %51 %109 %3 +%114 = OpLoad %47 %113 +%115 = OpAccessChain %52 %109 %3 %3 +%116 = OpLoad %41 %115 +%117 = OpLoad %6 %101 +%118 = OpAccessChain %52 %109 %3 %117 +%119 = OpLoad %41 %118 +%121 = OpAccessChain %120 %109 %3 %3 %32 +%122 = OpLoad %10 %121 +%123 = OpLoad %6 %101 +%124 = OpAccessChain %120 %109 %3 %3 %123 +%125 = OpLoad %10 %124 +%126 = OpLoad %6 %101 +%127 = OpAccessChain %120 %109 %3 %126 %32 +%128 = OpLoad %10 %127 +%129 = OpLoad %6 %101 +%130 = OpLoad %6 %101 +%131 = OpAccessChain %120 %109 %3 %129 %130 +%132 = OpLoad %10 %131 +%133 = OpCompositeConstruct %41 %9 %9 +%134 = OpCompositeConstruct %41 %11 %11 +%135 = OpCompositeConstruct %41 %12 %12 +%136 = OpCompositeConstruct %47 %133 %134 %135 +%137 = OpCompositeConstruct %48 %136 +OpStore %104 %137 +%138 = OpLoad %6 %101 +%139 = OpIAdd %6 %138 %8 +OpStore %101 %139 +%140 = OpCompositeConstruct %41 %13 %13 +%141 = OpCompositeConstruct %41 %14 %14 +%142 = OpCompositeConstruct %41 %15 %15 +%143 = OpCompositeConstruct %47 %140 %141 %142 +%144 = OpAccessChain %54 %104 %3 +OpStore %144 %143 +%145 = OpCompositeConstruct %41 %16 %16 +%146 = OpAccessChain %55 %104 %3 %3 +OpStore %146 %145 +%147 = OpCompositeConstruct %41 %17 %17 +%148 = OpLoad %6 %101 +%149 = OpAccessChain %55 %104 %3 %148 +OpStore %149 %147 +%151 = OpAccessChain %150 %104 %3 %3 %32 +OpStore %151 %18 +%152 = OpLoad %6 %101 +%153 = OpAccessChain %150 %104 %3 %3 %152 +OpStore %153 %19 +%154 = OpLoad %6 %101 +%155 = OpAccessChain %150 %104 %3 %154 %32 +OpStore %155 %20 +%156 = OpLoad %6 %101 +%157 = OpLoad %6 %101 +%158 = OpAccessChain %150 %104 %3 %156 %157 +OpStore %158 %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 +%164 = OpFunction %2 None %108 +%163 = OpLabel +%159 = OpVariable %102 Function %160 +%161 = OpVariable %62 Function %162 +%165 = OpAccessChain %59 %97 %3 +OpBranch %166 +%166 = OpLabel +OpStore %159 %8 +%167 = OpLoad %6 %159 +%168 = OpISub %6 %167 %8 +OpStore %159 %168 +%169 = OpAccessChain %60 %165 %3 +%170 = OpLoad %57 %169 +%171 = OpAccessChain %61 %165 %3 %3 +%172 = OpLoad %56 %171 +%173 = OpAccessChain %52 %165 %3 %3 %3 +%174 = OpLoad %41 %173 +%175 = OpLoad %6 %159 +%176 = OpAccessChain %52 %165 %3 %3 %175 +%177 = OpLoad %41 %176 +%178 = OpAccessChain %120 %165 %3 %3 %3 %32 %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 -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 +%180 = OpLoad %6 %159 +%181 = OpAccessChain %120 %165 %3 %3 %3 %180 +%182 = OpLoad %10 %181 +%183 = OpLoad %6 %159 +%184 = OpAccessChain %120 %165 %3 %3 %183 %32 +%185 = OpLoad %10 %184 +%186 = OpLoad %6 %159 +%187 = OpLoad %6 %159 +%188 = OpAccessChain %120 %165 %3 %3 %186 %187 +%189 = OpLoad %10 %188 +%190 = OpCompositeConstruct %58 %84 +OpStore %161 %190 +%191 = OpLoad %6 %159 +%192 = OpIAdd %6 %191 %8 +OpStore %159 %192 +%193 = OpAccessChain %63 %161 %3 +OpStore %193 %84 +%194 = OpCompositeConstruct %41 %23 %23 +%195 = OpCompositeConstruct %41 %24 %24 +%196 = OpCompositeConstruct %41 %13 %13 +%197 = OpCompositeConstruct %41 %14 %14 +%198 = OpCompositeConstruct %56 %194 %195 %196 %197 +%199 = OpAccessChain %64 %161 %3 %3 +OpStore %199 %198 +%200 = OpCompositeConstruct %41 %16 %16 +%201 = OpAccessChain %55 %161 %3 %3 %3 +OpStore %201 %200 +%202 = OpCompositeConstruct %41 %17 %17 +%203 = OpLoad %6 %159 +%204 = OpAccessChain %55 %161 %3 %3 %203 +OpStore %204 %202 +%205 = OpAccessChain %150 %161 %3 %3 %3 %32 +OpStore %205 %18 +%206 = OpLoad %6 %159 +%207 = OpAccessChain %150 %161 %3 %3 %3 %206 +OpStore %207 %19 +%208 = OpLoad %6 %159 +%209 = OpAccessChain %150 %161 %3 %3 %208 %32 +OpStore %209 %20 +%210 = OpLoad %6 %159 +%211 = OpLoad %6 %159 +%212 = OpAccessChain %150 %161 %3 %3 %210 %211 +OpStore %212 %21 OpReturn OpFunctionEnd -%207 = OpFunction %10 None %208 -%206 = OpFunctionParameter %53 -%205 = OpLabel -OpBranch %209 -%209 = OpLabel -%210 = OpLoad %10 %206 -OpReturnValue %210 +%215 = OpFunction %10 None %216 +%214 = OpFunctionParameter %65 +%213 = OpLabel +OpBranch %217 +%217 = OpLabel +%218 = OpLoad %10 %214 +OpReturnValue %218 OpFunctionEnd -%213 = OpFunction %10 None %214 -%212 = OpFunctionParameter %55 -%211 = OpLabel -OpBranch %215 -%215 = OpLabel -%216 = OpCompositeExtract %54 %212 4 -%217 = OpCompositeExtract %10 %216 9 -OpReturnValue %217 +%221 = OpFunction %10 None %222 +%220 = OpFunctionParameter %67 +%219 = OpLabel +OpBranch %223 +%223 = OpLabel +%224 = OpCompositeExtract %66 %220 4 +%225 = OpCompositeExtract %10 %224 9 +OpReturnValue %225 OpFunctionEnd -%220 = OpFunction %2 None %221 -%219 = OpFunctionParameter %59 -%218 = OpLabel -OpBranch %222 -%222 = OpLabel -OpStore %219 %34 +%228 = OpFunction %2 None %229 +%227 = OpFunctionParameter %79 +%226 = OpLabel +OpBranch %230 +%230 = OpLabel +OpStore %227 %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 +%241 = OpFunction %2 None %108 +%235 = OpLabel +%231 = OpVariable %65 Function %232 +%233 = OpVariable %76 Function %234 +%238 = OpLoad %4 %236 +%242 = OpAccessChain %50 %91 %3 +%244 = OpAccessChain %243 %94 %3 +%245 = OpAccessChain %59 %97 %3 +OpBranch %246 +%246 = OpLabel +OpStore %231 %22 +%247 = OpLoad %10 %231 +OpStore %231 %9 +%248 = OpFunctionCall %2 %107 +%249 = OpFunctionCall %2 %164 +%250 = OpAccessChain %70 %90 %3 +%251 = OpLoad %38 %250 +%253 = OpAccessChain %252 %90 %29 +%254 = OpLoad %44 %253 +%256 = OpAccessChain %255 %90 %3 %29 %3 +%257 = OpLoad %10 %256 +%258 = OpArrayLength %4 %90 4 +%259 = OpISub %4 %258 %7 +%261 = OpAccessChain %74 %90 %260 %259 %3 +%262 = OpLoad %6 %261 +%263 = OpLoad %49 %244 +%264 = OpFunctionCall %10 %215 %231 +%265 = OpConvertFToS %6 %257 +%266 = OpCompositeConstruct %75 %262 %265 %30 %27 %31 +OpStore %233 %266 +%267 = OpIAdd %4 %238 %32 +%268 = OpAccessChain %102 %233 %267 +OpStore %268 %33 +%269 = OpAccessChain %102 %233 %238 +%270 = OpLoad %6 %269 +%271 = OpFunctionCall %10 %221 %86 +%272 = OpCompositeConstruct %77 %270 %270 %270 %270 +%273 = OpConvertSToF %68 %272 +%274 = OpMatrixTimesVector %39 %251 %273 +%275 = OpCompositeConstruct %68 %274 %11 +OpStore %239 %275 OpReturn OpFunctionEnd -%274 = OpFunction %2 None %89 -%272 = OpLabel -%275 = OpAccessChain %92 %75 %3 -OpBranch %276 +%278 = OpFunction %2 None %108 %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 +%279 = OpAccessChain %243 %94 %3 +OpBranch %280 +%280 = OpLabel +%281 = OpAccessChain %255 %90 %3 %32 %7 +OpStore %281 %9 +%282 = OpCompositeConstruct %39 %22 %22 %22 +%283 = OpCompositeConstruct %39 %9 %9 %9 +%284 = OpCompositeConstruct %39 %11 %11 %11 +%285 = OpCompositeConstruct %39 %12 %12 %12 +%286 = OpCompositeConstruct %38 %282 %283 %284 %285 +%287 = OpAccessChain %70 %90 %3 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 +%288 = OpCompositeConstruct %43 %3 %3 +%289 = OpCompositeConstruct %43 %32 %32 +%290 = OpCompositeConstruct %44 %288 %289 +%291 = OpAccessChain %252 %90 %29 +OpStore %291 %290 +%292 = OpAccessChain %74 %90 %260 %32 %3 +OpStore %292 %8 +OpStore %279 %87 +%293 = OpCompositeConstruct %68 %22 %22 %22 %22 +OpStore %277 %293 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 +%297 = OpFunction %2 None %108 +%296 = OpLabel +%294 = OpVariable %102 Function %295 +OpBranch %298 +%298 = OpLabel +%299 = OpAccessChain %78 %90 %7 +%300 = OpAtomicLoad %6 %299 %8 %301 +%303 = OpAccessChain %78 %90 %7 +%302 = OpAtomicIAdd %6 %303 %8 %301 %31 +OpStore %294 %302 +%305 = OpAccessChain %78 %90 %7 +%304 = OpAtomicISub %6 %305 %8 %301 %31 +OpStore %294 %304 +%307 = OpAccessChain %78 %90 %7 +%306 = OpAtomicAnd %6 %307 %8 %301 %31 +OpStore %294 %306 +%309 = OpAccessChain %78 %90 %7 +%308 = OpAtomicOr %6 %309 %8 %301 %31 +OpStore %294 %308 +%311 = OpAccessChain %78 %90 %7 +%310 = OpAtomicXor %6 %311 %8 %301 %31 +OpStore %294 %310 +%313 = OpAccessChain %78 %90 %7 +%312 = OpAtomicSMin %6 %313 %8 %301 %31 +OpStore %294 %312 +%315 = OpAccessChain %78 %90 %7 +%314 = OpAtomicSMax %6 %315 %8 %301 %31 +OpStore %294 %314 +%317 = OpAccessChain %78 %90 %7 +%316 = OpAtomicExchange %6 %317 %8 %301 %31 +OpStore %294 %316 +%318 = OpAccessChain %78 %90 %7 +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 %108 +%319 = OpLabel +OpBranch %321 +%321 = OpLabel +%322 = OpFunctionCall %2 %228 %100 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..4529af03a1 100644 --- a/tests/out/spv/binding-arrays.spvasm +++ b/tests/out/spv/binding-arrays.spvasm @@ -1,557 +1,561 @@ ; 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 %69 "main" %64 %67 +OpExecutionMode %69 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 %29 DescriptorSet 0 +OpDecorate %29 Binding 0 OpDecorate %33 DescriptorSet 0 -OpDecorate %33 Binding 2 +OpDecorate %33 Binding 1 OpDecorate %35 DescriptorSet 0 -OpDecorate %35 Binding 3 +OpDecorate %35 Binding 2 OpDecorate %37 DescriptorSet 0 -OpDecorate %37 Binding 4 +OpDecorate %37 Binding 3 OpDecorate %39 DescriptorSet 0 -OpDecorate %39 Binding 5 +OpDecorate %39 Binding 4 OpDecorate %41 DescriptorSet 0 -OpDecorate %41 Binding 6 +OpDecorate %41 Binding 5 OpDecorate %43 DescriptorSet 0 -OpDecorate %43 Binding 7 +OpDecorate %43 Binding 6 OpDecorate %45 DescriptorSet 0 -OpDecorate %45 Binding 8 -OpDecorate %46 Block -OpMemberDecorate %46 0 Offset 0 -OpDecorate %60 Location 0 -OpDecorate %60 Flat -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 %45 Binding 7 +OpDecorate %47 DescriptorSet 0 +OpDecorate %47 Binding 8 +OpDecorate %48 Block +OpMemberDecorate %48 0 Offset 0 +OpDecorate %64 Location 0 +OpDecorate %64 Flat +OpDecorate %67 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 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 5 -%5 = OpConstant %4 0 -%7 = OpTypeFloat 32 -%6 = OpConstant %7 0.0 -%8 = OpTypeInt 32 0 -%9 = OpTypeStruct %8 -%10 = OpTypeImage %7 2D 0 0 0 1 Unknown +%6 = OpTypeInt 32 1 +%5 = OpConstant %6 0 +%8 = OpTypeFloat 32 +%7 = OpConstant %8 0.0 +%9 = OpTypeStruct %4 +%10 = OpTypeImage %8 2D 0 0 0 1 Unknown %11 = OpTypeRuntimeArray %10 %12 = OpTypeArray %10 %3 -%13 = OpTypeImage %7 2D 0 1 0 1 Unknown +%13 = OpTypeImage %8 2D 0 1 0 1 Unknown %14 = OpTypeArray %13 %3 -%15 = OpTypeImage %7 2D 0 0 1 1 Unknown +%15 = OpTypeImage %8 2D 0 0 1 1 Unknown %16 = OpTypeArray %15 %3 -%17 = OpTypeImage %7 2D 1 0 0 1 Unknown +%17 = OpTypeImage %8 2D 1 0 0 1 Unknown %18 = OpTypeArray %17 %3 -%19 = OpTypeImage %7 2D 0 0 0 2 Rgba32f +%19 = OpTypeImage %8 2D 0 0 0 2 Rgba32f %20 = OpTypeArray %19 %3 %21 = OpTypeSampler %22 = OpTypeArray %21 %3 %23 = OpTypeArray %21 %3 -%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 +%24 = OpTypeStruct %4 +%25 = OpTypeVector %8 4 +%26 = OpTypePointer Uniform %9 +%27 = OpTypeVector %6 2 +%28 = OpTypeVector %8 2 +%32 = OpConstant %4 10 +%31 = OpTypeArray %10 %32 +%30 = OpTypePointer UniformConstant %31 +%29 = OpVariable %30 UniformConstant +%34 = OpTypePointer UniformConstant %12 %33 = OpVariable %34 UniformConstant -%36 = OpTypePointer UniformConstant %16 +%36 = OpTypePointer UniformConstant %14 %35 = OpVariable %36 UniformConstant -%38 = OpTypePointer UniformConstant %18 +%38 = OpTypePointer UniformConstant %16 %37 = OpVariable %38 UniformConstant -%40 = OpTypePointer UniformConstant %20 +%40 = OpTypePointer UniformConstant %18 %39 = OpVariable %40 UniformConstant -%42 = OpTypePointer UniformConstant %22 +%42 = OpTypePointer UniformConstant %20 %41 = OpVariable %42 UniformConstant -%44 = OpTypePointer UniformConstant %23 +%44 = OpTypePointer UniformConstant %22 %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 +%46 = OpTypePointer UniformConstant %23 +%45 = OpVariable %46 UniformConstant +%48 = OpTypeStruct %9 +%49 = OpTypePointer Uniform %48 +%47 = OpVariable %49 Uniform +%51 = OpTypePointer Function %6 +%52 = OpConstantNull %6 +%54 = OpTypePointer Function %27 +%55 = OpConstantNull %27 +%57 = OpTypePointer Function %8 +%58 = OpConstantNull %8 +%60 = OpTypePointer Function %25 +%61 = OpConstantNull %25 +%65 = OpTypePointer Input %4 +%64 = OpVariable %65 Input +%68 = OpTypePointer Output %25 +%67 = OpVariable %68 Output +%70 = OpTypeFunction %2 +%71 = OpConstant %4 0 +%74 = OpTypePointer Uniform %4 +%82 = OpTypePointer UniformConstant %10 +%100 = OpTypePointer UniformConstant %21 +%103 = OpTypeSampledImage %10 +%124 = OpTypePointer UniformConstant %21 +%127 = OpTypePointer UniformConstant %17 +%130 = OpTypeSampledImage %17 +%153 = OpTypeBool +%154 = OpConstantNull %25 +%160 = OpTypeVector %153 2 +%170 = OpConstantNull %25 +%185 = OpConstantNull %25 +%198 = OpTypePointer UniformConstant %13 +%201 = OpTypeVector %6 3 +%233 = OpTypePointer UniformConstant %15 +%393 = OpTypePointer UniformConstant %19 +%69 = OpFunction %2 None %70 +%62 = OpLabel +%53 = OpVariable %54 Function %55 +%59 = OpVariable %60 Function %61 %50 = OpVariable %51 Function %52 -%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 +%56 = OpVariable %57 Function %58 +%66 = OpLoad %4 %64 +%63 = OpCompositeConstruct %24 %66 +%72 = OpAccessChain %26 %47 %71 +OpBranch %73 +%73 = OpLabel +%75 = OpAccessChain %74 %72 %71 +%76 = OpLoad %4 %75 +%77 = OpCompositeExtract %4 %63 0 +OpStore %50 %5 +%78 = OpCompositeConstruct %27 %5 %5 +OpStore %53 %78 +OpStore %56 %7 +%79 = OpCompositeConstruct %25 %7 %7 %7 %7 +OpStore %59 %79 +%80 = OpCompositeConstruct %28 %7 %7 +%81 = OpCompositeConstruct %27 %5 %5 +%83 = OpAccessChain %82 %29 %71 +%84 = OpLoad %10 %83 +%85 = OpImageQuerySizeLod %27 %84 %71 +%86 = OpLoad %27 %53 +%87 = OpIAdd %27 %86 %85 +OpStore %53 %87 +%88 = OpAccessChain %82 %29 %76 +%89 = OpLoad %10 %88 +%90 = OpImageQuerySizeLod %27 %89 %71 +%91 = OpLoad %27 %53 +%92 = OpIAdd %27 %91 %90 +OpStore %53 %92 +%93 = OpAccessChain %82 %29 %77 +%94 = OpLoad %10 %93 +%95 = OpImageQuerySizeLod %27 %94 %71 +%96 = OpLoad %27 %53 +%97 = OpIAdd %27 %96 %95 +OpStore %53 %97 +%98 = OpAccessChain %82 %33 %71 +%99 = OpLoad %10 %98 +%101 = OpAccessChain %100 %43 %71 +%102 = OpLoad %21 %101 +%104 = OpSampledImage %103 %99 %102 +%105 = OpImageGather %25 %104 %80 %71 +%106 = OpLoad %25 %59 +%107 = OpFAdd %25 %106 %105 +OpStore %59 %107 +%108 = OpAccessChain %82 %33 %76 +%109 = OpLoad %10 %108 +%110 = OpAccessChain %100 %43 %76 +%111 = OpLoad %21 %110 +%112 = OpSampledImage %103 %109 %111 +%113 = OpImageGather %25 %112 %80 %71 +%114 = OpLoad %25 %59 +%115 = OpFAdd %25 %114 %113 +OpStore %59 %115 +%116 = OpAccessChain %82 %33 %77 +%117 = OpLoad %10 %116 +%118 = OpAccessChain %100 %43 %77 +%119 = OpLoad %21 %118 +%120 = OpSampledImage %103 %117 %119 +%121 = OpImageGather %25 %120 %80 %71 +%122 = OpLoad %25 %59 +%123 = OpFAdd %25 %122 %121 +OpStore %59 %123 +%125 = OpAccessChain %124 %45 %71 +%126 = OpLoad %21 %125 +%128 = OpAccessChain %127 %39 %71 +%129 = OpLoad %17 %128 +%131 = OpSampledImage %130 %129 %126 +%132 = OpImageDrefGather %25 %131 %80 %7 +%133 = OpLoad %25 %59 +%134 = OpFAdd %25 %133 %132 +OpStore %59 %134 +%135 = OpAccessChain %124 %45 %76 +%136 = OpLoad %21 %135 +%137 = OpAccessChain %127 %39 %76 +%138 = OpLoad %17 %137 +%139 = OpSampledImage %130 %138 %136 +%140 = OpImageDrefGather %25 %139 %80 %7 +%141 = OpLoad %25 %59 +%142 = OpFAdd %25 %141 %140 +OpStore %59 %142 +%143 = OpAccessChain %124 %45 %77 +%144 = OpLoad %21 %143 +%145 = OpAccessChain %127 %39 %77 +%146 = OpLoad %17 %145 +%147 = OpSampledImage %130 %146 %144 +%148 = OpImageDrefGather %25 %147 %80 %7 +%149 = OpLoad %25 %59 +%150 = OpFAdd %25 %149 %148 +OpStore %59 %150 +%151 = OpAccessChain %82 %29 %71 +%152 = OpLoad %10 %151 +%155 = OpImageQueryLevels %6 %152 +%156 = OpULessThan %153 %5 %155 +OpSelectionMerge %157 None +OpBranchConditional %156 %158 %157 +%158 = OpLabel +%159 = OpImageQuerySizeLod %27 %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 %59 +%167 = OpFAdd %25 %166 %165 +OpStore %59 %167 +%168 = OpAccessChain %82 %29 %76 +%169 = OpLoad %10 %168 +%171 = OpImageQueryLevels %6 %169 +%172 = OpULessThan %153 %5 %171 +OpSelectionMerge %173 None +OpBranchConditional %172 %174 %173 +%174 = OpLabel +%175 = OpImageQuerySizeLod %27 %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 %59 +%182 = OpFAdd %25 %181 %180 +OpStore %59 %182 +%183 = OpAccessChain %82 %29 %77 +%184 = OpLoad %10 %183 +%186 = OpImageQueryLevels %6 %184 +%187 = OpULessThan %153 %5 %186 +OpSelectionMerge %188 None +OpBranchConditional %187 %189 %188 +%189 = OpLabel +%190 = OpImageQuerySizeLod %27 %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 %59 +%197 = OpFAdd %25 %196 %195 +OpStore %59 %197 +%199 = OpAccessChain %198 %35 %71 +%200 = OpLoad %13 %199 +%202 = OpImageQuerySizeLod %201 %200 %71 +%203 = OpCompositeExtract %6 %202 2 +%204 = OpLoad %6 %50 +%205 = OpIAdd %6 %204 %203 +OpStore %50 %205 +%206 = OpAccessChain %198 %35 %76 +%207 = OpLoad %13 %206 +%208 = OpImageQuerySizeLod %201 %207 %71 +%209 = OpCompositeExtract %6 %208 2 +%210 = OpLoad %6 %50 +%211 = OpIAdd %6 %210 %209 +OpStore %50 %211 +%212 = OpAccessChain %198 %35 %77 +%213 = OpLoad %13 %212 +%214 = OpImageQuerySizeLod %201 %213 %71 +%215 = OpCompositeExtract %6 %214 2 +%216 = OpLoad %6 %50 +%217 = OpIAdd %6 %216 %215 +OpStore %50 %217 +%218 = OpAccessChain %82 %33 %71 +%219 = OpLoad %10 %218 +%220 = OpImageQueryLevels %6 %219 +%221 = OpLoad %6 %50 +%222 = OpIAdd %6 %221 %220 +OpStore %50 %222 +%223 = OpAccessChain %82 %33 %76 +%224 = OpLoad %10 %223 +%225 = OpImageQueryLevels %6 %224 +%226 = OpLoad %6 %50 +%227 = OpIAdd %6 %226 %225 +OpStore %50 %227 +%228 = OpAccessChain %82 %33 %77 +%229 = OpLoad %10 %228 +%230 = OpImageQueryLevels %6 %229 +%231 = OpLoad %6 %50 +%232 = OpIAdd %6 %231 %230 +OpStore %50 %232 +%234 = OpAccessChain %233 %37 %71 +%235 = OpLoad %15 %234 +%236 = OpImageQuerySamples %6 %235 +%237 = OpLoad %6 %50 +%238 = OpIAdd %6 %237 %236 +OpStore %50 %238 +%239 = OpAccessChain %233 %37 %76 +%240 = OpLoad %15 %239 +%241 = OpImageQuerySamples %6 %240 +%242 = OpLoad %6 %50 +%243 = OpIAdd %6 %242 %241 +OpStore %50 %243 +%244 = OpAccessChain %233 %37 %77 +%245 = OpLoad %15 %244 +%246 = OpImageQuerySamples %6 %245 +%247 = OpLoad %6 %50 +%248 = OpIAdd %6 %247 %246 +OpStore %50 %248 +%249 = OpAccessChain %82 %33 %71 +%250 = OpLoad %10 %249 +%251 = OpAccessChain %100 %43 %71 +%252 = OpLoad %21 %251 +%253 = OpSampledImage %103 %250 %252 +%254 = OpImageSampleImplicitLod %25 %253 %80 +%255 = OpLoad %25 %59 +%256 = OpFAdd %25 %255 %254 +OpStore %59 %256 +%257 = OpAccessChain %82 %33 %76 +%258 = OpLoad %10 %257 +%259 = OpAccessChain %100 %43 %76 +%260 = OpLoad %21 %259 +%261 = OpSampledImage %103 %258 %260 +%262 = OpImageSampleImplicitLod %25 %261 %80 +%263 = OpLoad %25 %59 +%264 = OpFAdd %25 %263 %262 +OpStore %59 %264 +%265 = OpAccessChain %82 %33 %77 +%266 = OpLoad %10 %265 +%267 = OpAccessChain %100 %43 %77 +%268 = OpLoad %21 %267 +%269 = OpSampledImage %103 %266 %268 +%270 = OpImageSampleImplicitLod %25 %269 %80 +%271 = OpLoad %25 %59 +%272 = OpFAdd %25 %271 %270 +OpStore %59 %272 +%273 = OpAccessChain %82 %33 %71 +%274 = OpLoad %10 %273 +%275 = OpAccessChain %100 %43 %71 +%276 = OpLoad %21 %275 +%277 = OpSampledImage %103 %274 %276 +%278 = OpImageSampleImplicitLod %25 %277 %80 Bias %7 +%279 = OpLoad %25 %59 +%280 = OpFAdd %25 %279 %278 +OpStore %59 %280 +%281 = OpAccessChain %82 %33 %76 +%282 = OpLoad %10 %281 +%283 = OpAccessChain %100 %43 %76 +%284 = OpLoad %21 %283 +%285 = OpSampledImage %103 %282 %284 +%286 = OpImageSampleImplicitLod %25 %285 %80 Bias %7 +%287 = OpLoad %25 %59 +%288 = OpFAdd %25 %287 %286 +OpStore %59 %288 +%289 = OpAccessChain %82 %33 %77 +%290 = OpLoad %10 %289 +%291 = OpAccessChain %100 %43 %77 +%292 = OpLoad %21 %291 +%293 = OpSampledImage %103 %290 %292 +%294 = OpImageSampleImplicitLod %25 %293 %80 Bias %7 +%295 = OpLoad %25 %59 +%296 = OpFAdd %25 %295 %294 +OpStore %59 %296 +%297 = OpAccessChain %127 %39 %71 +%298 = OpLoad %17 %297 +%299 = OpAccessChain %124 %45 %71 +%300 = OpLoad %21 %299 +%301 = OpSampledImage %130 %298 %300 +%302 = OpImageSampleDrefImplicitLod %8 %301 %80 %7 +%303 = OpLoad %8 %56 +%304 = OpFAdd %8 %303 %302 +OpStore %56 %304 +%305 = OpAccessChain %127 %39 %76 +%306 = OpLoad %17 %305 +%307 = OpAccessChain %124 %45 %76 +%308 = OpLoad %21 %307 +%309 = OpSampledImage %130 %306 %308 +%310 = OpImageSampleDrefImplicitLod %8 %309 %80 %7 +%311 = OpLoad %8 %56 +%312 = OpFAdd %8 %311 %310 +OpStore %56 %312 +%313 = OpAccessChain %127 %39 %77 +%314 = OpLoad %17 %313 +%315 = OpAccessChain %124 %45 %77 +%316 = OpLoad %21 %315 +%317 = OpSampledImage %130 %314 %316 +%318 = OpImageSampleDrefImplicitLod %8 %317 %80 %7 +%319 = OpLoad %8 %56 +%320 = OpFAdd %8 %319 %318 +OpStore %56 %320 +%321 = OpAccessChain %127 %39 %71 +%322 = OpLoad %17 %321 +%323 = OpAccessChain %124 %45 %71 +%324 = OpLoad %21 %323 +%325 = OpSampledImage %130 %322 %324 +%326 = OpImageSampleDrefExplicitLod %8 %325 %80 %7 Lod %7 +%327 = OpLoad %8 %56 +%328 = OpFAdd %8 %327 %326 +OpStore %56 %328 +%329 = OpAccessChain %127 %39 %76 +%330 = OpLoad %17 %329 +%331 = OpAccessChain %124 %45 %76 +%332 = OpLoad %21 %331 +%333 = OpSampledImage %130 %330 %332 +%334 = OpImageSampleDrefExplicitLod %8 %333 %80 %7 Lod %7 +%335 = OpLoad %8 %56 +%336 = OpFAdd %8 %335 %334 +OpStore %56 %336 +%337 = OpAccessChain %127 %39 %77 +%338 = OpLoad %17 %337 +%339 = OpAccessChain %124 %45 %77 +%340 = OpLoad %21 %339 +%341 = OpSampledImage %130 %338 %340 +%342 = OpImageSampleDrefExplicitLod %8 %341 %80 %7 Lod %7 +%343 = OpLoad %8 %56 +%344 = OpFAdd %8 %343 %342 +OpStore %56 %344 +%345 = OpAccessChain %82 %33 %71 +%346 = OpLoad %10 %345 +%347 = OpAccessChain %100 %43 %71 +%348 = OpLoad %21 %347 +%349 = OpSampledImage %103 %346 %348 +%350 = OpImageSampleExplicitLod %25 %349 %80 Grad %80 %80 +%351 = OpLoad %25 %59 +%352 = OpFAdd %25 %351 %350 +OpStore %59 %352 +%353 = OpAccessChain %82 %33 %76 +%354 = OpLoad %10 %353 +%355 = OpAccessChain %100 %43 %76 +%356 = OpLoad %21 %355 +%357 = OpSampledImage %103 %354 %356 +%358 = OpImageSampleExplicitLod %25 %357 %80 Grad %80 %80 +%359 = OpLoad %25 %59 +%360 = OpFAdd %25 %359 %358 +OpStore %59 %360 +%361 = OpAccessChain %82 %33 %77 +%362 = OpLoad %10 %361 +%363 = OpAccessChain %100 %43 %77 +%364 = OpLoad %21 %363 +%365 = OpSampledImage %103 %362 %364 +%366 = OpImageSampleExplicitLod %25 %365 %80 Grad %80 %80 +%367 = OpLoad %25 %59 +%368 = OpFAdd %25 %367 %366 +OpStore %59 %368 +%369 = OpAccessChain %82 %33 %71 +%370 = OpLoad %10 %369 +%371 = OpAccessChain %100 %43 %71 +%372 = OpLoad %21 %371 +%373 = OpSampledImage %103 %370 %372 +%374 = OpImageSampleExplicitLod %25 %373 %80 Lod %7 +%375 = OpLoad %25 %59 +%376 = OpFAdd %25 %375 %374 +OpStore %59 %376 +%377 = OpAccessChain %82 %33 %76 +%378 = OpLoad %10 %377 +%379 = OpAccessChain %100 %43 %76 +%380 = OpLoad %21 %379 +%381 = OpSampledImage %103 %378 %380 +%382 = OpImageSampleExplicitLod %25 %381 %80 Lod %7 +%383 = OpLoad %25 %59 +%384 = OpFAdd %25 %383 %382 +OpStore %59 %384 +%385 = OpAccessChain %82 %33 %77 +%386 = OpLoad %10 %385 +%387 = OpAccessChain %100 %43 %77 +%388 = OpLoad %21 %387 +%389 = OpSampledImage %103 %386 %388 +%390 = OpImageSampleExplicitLod %25 %389 %80 Lod %7 +%391 = OpLoad %25 %59 +%392 = OpFAdd %25 %391 %390 +OpStore %59 %392 +%394 = OpAccessChain %393 %41 %71 +%395 = OpLoad %19 %394 +%396 = OpLoad %25 %59 +%397 = OpImageQuerySize %27 %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 %41 %76 +%403 = OpLoad %19 %402 +%404 = OpLoad %25 %59 +%405 = OpImageQuerySize %27 %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 %41 %77 +%411 = OpLoad %19 %410 +%412 = OpLoad %25 %59 +%413 = OpImageQuerySize %27 %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 %27 %53 +%419 = OpLoad %6 %50 +%420 = OpCompositeConstruct %27 %419 %419 +%421 = OpIAdd %27 %418 %420 +%422 = OpConvertSToF %28 %421 +%423 = OpLoad %25 %59 +%424 = OpCompositeExtract %8 %422 0 +%425 = OpCompositeExtract %8 %422 1 +%426 = OpCompositeExtract %8 %422 0 +%427 = OpCompositeExtract %8 %422 1 +%428 = OpCompositeConstruct %25 %424 %425 %426 %427 +%429 = OpFAdd %25 %423 %428 +%430 = OpLoad %8 %56 +%431 = OpCompositeConstruct %25 %430 %430 %430 %430 +%432 = OpFAdd %25 %429 %431 +OpStore %67 %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..d6b7975fb9 100644 --- a/tests/out/spv/boids.spvasm +++ b/tests/out/spv/boids.spvasm @@ -1,66 +1,80 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 213 +; Bound: 219 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 %56 "main" %53 +OpExecutionMode %56 LocalSize 64 1 1 OpSource GLSL 450 OpName %3 "NUM_PARTICLES" -OpMemberName %16 0 "pos" -OpMemberName %16 1 "vel" -OpName %16 "Particle" -OpMemberName %17 0 "deltaT" -OpMemberName %17 1 "rule1Distance" -OpMemberName %17 2 "rule2Distance" -OpMemberName %17 3 "rule3Distance" -OpMemberName %17 4 "rule1Scale" -OpMemberName %17 5 "rule2Scale" -OpMemberName %17 6 "rule3Scale" -OpName %17 "SimParams" -OpMemberName %19 0 "particles" -OpName %19 "Particles" -OpName %21 "params" -OpName %24 "particlesSrc" -OpName %26 "particlesDst" -OpName %27 "vPos" -OpName %30 "vVel" -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 %4 "u32" +OpName %14 "vec2" +OpMemberName %15 0 "pos" +OpMemberName %15 1 "vel" +OpName %15 "Particle" +OpName %6 "f32" +OpMemberName %16 0 "deltaT" +OpMemberName %16 1 "rule1Distance" +OpMemberName %16 2 "rule2Distance" +OpMemberName %16 3 "rule3Distance" +OpMemberName %16 4 "rule1Scale" +OpMemberName %16 5 "rule2Scale" +OpMemberName %16 6 "rule3Scale" +OpName %16 "SimParams" +OpName %17 "array" +OpMemberName %18 0 "particles" +OpName %18 "Particles" +OpName %19 "vec3" +OpName %20 "ptr" +OpName %21 "ptr>" +OpName %22 "ptr" +OpName %8 "i32" +OpName %23 "ptr" +OpName %24 "ptr>" +OpName %20 "ptr" +OpName %21 "ptr>" +OpName %22 "ptr" +OpName %25 "params" +OpName %28 "particlesSrc" +OpName %29 "particlesDst" +OpName %30 "vPos" +OpName %32 "vVel" +OpName %34 "cMass" +OpName %36 "cVel" +OpName %38 "colVel" +OpName %40 "cMassCount" +OpName %43 "cVelCount" +OpName %45 "pos" +OpName %47 "vel" +OpName %49 "i" +OpName %53 "global_invocation_id" +OpName %56 "main" +OpMemberDecorate %15 0 Offset 0 +OpMemberDecorate %15 1 Offset 8 OpMemberDecorate %16 0 Offset 0 -OpMemberDecorate %16 1 Offset 8 -OpMemberDecorate %17 0 Offset 0 -OpMemberDecorate %17 1 Offset 4 -OpMemberDecorate %17 2 Offset 8 -OpMemberDecorate %17 3 Offset 12 -OpMemberDecorate %17 4 Offset 16 -OpMemberDecorate %17 5 Offset 20 -OpMemberDecorate %17 6 Offset 24 -OpDecorate %18 ArrayStride 16 -OpMemberDecorate %19 0 Offset 0 -OpDecorate %21 DescriptorSet 0 -OpDecorate %21 Binding 0 -OpDecorate %22 Block -OpMemberDecorate %22 0 Offset 0 -OpDecorate %24 NonWritable -OpDecorate %24 DescriptorSet 0 -OpDecorate %24 Binding 1 -OpDecorate %19 Block -OpDecorate %26 DescriptorSet 0 -OpDecorate %26 Binding 2 -OpDecorate %19 Block -OpDecorate %48 BuiltIn GlobalInvocationId +OpMemberDecorate %16 1 Offset 4 +OpMemberDecorate %16 2 Offset 8 +OpMemberDecorate %16 3 Offset 12 +OpMemberDecorate %16 4 Offset 16 +OpMemberDecorate %16 5 Offset 20 +OpMemberDecorate %16 6 Offset 24 +OpDecorate %17 ArrayStride 16 +OpMemberDecorate %18 0 Offset 0 +OpDecorate %25 DescriptorSet 0 +OpDecorate %25 Binding 0 +OpDecorate %26 Block +OpMemberDecorate %26 0 Offset 0 +OpDecorate %28 NonWritable +OpDecorate %28 DescriptorSet 0 +OpDecorate %28 Binding 1 +OpDecorate %18 Block +OpDecorate %29 DescriptorSet 0 +OpDecorate %29 Binding 2 +OpDecorate %18 Block +OpDecorate %53 BuiltIn GlobalInvocationId %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 1500 @@ -72,271 +86,280 @@ OpDecorate %48 BuiltIn GlobalInvocationId %10 = OpConstant %8 1 %11 = OpConstant %4 1 %12 = OpConstant %6 0.1 -%13 = OpConstant %6 -1.0 -%14 = OpConstant %6 1.0 -%15 = OpTypeVector %6 2 -%16 = OpTypeStruct %15 %15 -%17 = OpTypeStruct %6 %6 %6 %6 %6 %6 %6 -%18 = OpTypeRuntimeArray %16 -%19 = OpTypeStruct %18 -%20 = OpTypeVector %4 3 -%22 = OpTypeStruct %17 -%23 = OpTypePointer Uniform %22 -%21 = OpVariable %23 Uniform -%25 = OpTypePointer StorageBuffer %19 -%24 = OpVariable %25 StorageBuffer -%26 = OpVariable %25 StorageBuffer -%28 = OpTypePointer Function %15 -%29 = OpConstantNull %15 -%31 = OpConstantNull %15 -%33 = OpConstantNull %15 -%35 = OpConstantNull %15 -%37 = OpConstantNull %15 -%39 = OpTypePointer Function %8 -%42 = OpConstantNull %15 -%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 -%34 = OpVariable %28 Function %35 -%27 = OpVariable %28 Function %29 -%41 = OpVariable %28 Function %42 -%36 = OpVariable %28 Function %37 -%30 = OpVariable %28 Function %31 -%43 = OpVariable %28 Function %44 -%38 = OpVariable %39 Function %7 -%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 -OpReturn +%13 = OpConstant %6 1.0 +%14 = OpTypeVector %6 2 +%15 = OpTypeStruct %14 %14 +%16 = OpTypeStruct %6 %6 %6 %6 %6 %6 %6 +%17 = OpTypeRuntimeArray %15 +%18 = OpTypeStruct %17 +%19 = OpTypeVector %4 3 +%20 = OpTypePointer StorageBuffer %18 +%21 = OpTypePointer StorageBuffer %17 +%22 = OpTypePointer StorageBuffer %15 +%23 = OpTypePointer Uniform %16 +%24 = OpTypePointer Function %14 +%26 = OpTypeStruct %16 +%27 = OpTypePointer Uniform %26 +%25 = OpVariable %27 Uniform +%28 = OpVariable %20 StorageBuffer +%29 = OpVariable %20 StorageBuffer +%31 = OpConstantNull %14 +%33 = OpConstantNull %14 +%35 = OpConstantNull %14 +%37 = OpConstantNull %14 +%39 = OpConstantNull %14 +%41 = OpTypePointer Function %8 +%42 = OpConstantNull %8 +%44 = OpConstantNull %8 +%46 = OpConstantNull %14 +%48 = OpConstantNull %14 +%50 = OpTypePointer Function %4 +%51 = OpConstantNull %4 +%54 = OpTypePointer Input %19 +%53 = OpVariable %54 Input +%57 = OpTypeFunction %2 +%61 = OpTypeBool +%65 = OpTypePointer StorageBuffer %14 +%94 = OpTypePointer Uniform %6 +%108 = OpConstant %4 2 +%122 = OpConstant %4 3 +%157 = OpConstant %4 4 +%163 = OpConstant %4 5 +%169 = OpConstant %4 6 +%186 = OpTypePointer Function %6 +%56 = OpFunction %2 None %57 +%52 = OpLabel +%49 = OpVariable %50 Function %51 +%43 = OpVariable %41 Function %44 +%36 = OpVariable %24 Function %37 +%30 = OpVariable %24 Function %31 +%45 = OpVariable %24 Function %46 +%38 = OpVariable %24 Function %39 +%32 = OpVariable %24 Function %33 +%47 = OpVariable %24 Function %48 +%40 = OpVariable %41 Function %42 +%34 = OpVariable %24 Function %35 +%55 = OpLoad %19 %53 +%58 = OpAccessChain %23 %25 %9 +OpBranch %59 %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 +%60 = OpCompositeExtract %4 %55 0 +%62 = OpUGreaterThanEqual %61 %60 %3 +OpSelectionMerge %63 None +OpBranchConditional %62 %64 %63 +%64 = OpLabel +OpReturn +%63 = OpLabel +%66 = OpAccessChain %65 %28 %9 %60 %9 +%67 = OpLoad %14 %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 +%68 = OpAccessChain %65 %28 %9 %60 %11 +%69 = OpLoad %14 %68 +OpStore %32 %69 +%70 = OpCompositeConstruct %14 %5 %5 +OpStore %34 %70 +%71 = OpCompositeConstruct %14 %5 %5 +OpStore %36 %71 +%72 = OpCompositeConstruct %14 %5 %5 +OpStore %38 %72 +OpStore %40 %7 +OpStore %43 %7 +OpStore %49 %9 OpBranch %73 %73 = OpLabel -%75 = OpLoad %4 %45 -%76 = OpUGreaterThanEqual %57 %75 %3 -OpSelectionMerge %77 None -OpBranchConditional %76 %78 %77 -%78 = OpLabel -OpBranch %72 -%77 = OpLabel -%79 = OpLoad %4 %45 -%80 = OpIEqual %57 %79 %56 -OpSelectionMerge %81 None -OpBranchConditional %80 %82 %81 -%82 = OpLabel -OpBranch %74 -%81 = OpLabel -%83 = OpLoad %4 %45 -%84 = OpAccessChain %63 %24 %9 %83 %9 -%85 = OpLoad %15 %84 -OpStore %41 %85 -%86 = OpLoad %4 %45 -%87 = OpAccessChain %63 %24 %9 %86 %11 -%88 = OpLoad %15 %87 -OpStore %43 %88 -%89 = OpLoad %15 %41 -%90 = OpLoad %15 %27 -%91 = OpExtInst %6 %1 Distance %89 %90 -%93 = OpAccessChain %92 %54 %11 -%94 = OpLoad %6 %93 -%95 = OpFOrdLessThan %57 %91 %94 -OpSelectionMerge %96 None -OpBranchConditional %95 %97 %96 -%97 = OpLabel -%98 = OpLoad %15 %32 -%99 = OpLoad %15 %41 -%100 = OpFAdd %15 %98 %99 -OpStore %32 %100 -%101 = OpLoad %8 %38 -%102 = OpIAdd %8 %101 %10 -OpStore %38 %102 -OpBranch %96 -%96 = OpLabel -%103 = OpLoad %15 %41 -%104 = OpLoad %15 %27 -%105 = OpExtInst %6 %1 Distance %103 %104 -%107 = OpAccessChain %92 %54 %106 -%108 = OpLoad %6 %107 -%109 = OpFOrdLessThan %57 %105 %108 -OpSelectionMerge %110 None -OpBranchConditional %109 %111 %110 -%111 = OpLabel -%112 = OpLoad %15 %36 -%113 = OpLoad %15 %41 -%114 = OpLoad %15 %27 -%115 = OpFSub %15 %113 %114 -%116 = OpFSub %15 %112 %115 -OpStore %36 %116 -OpBranch %110 -%110 = OpLabel -%117 = OpLoad %15 %41 -%118 = OpLoad %15 %27 -%119 = OpExtInst %6 %1 Distance %117 %118 -%121 = OpAccessChain %92 %54 %120 -%122 = OpLoad %6 %121 -%123 = OpFOrdLessThan %57 %119 %122 -OpSelectionMerge %124 None -OpBranchConditional %123 %125 %124 -%125 = OpLabel -%126 = OpLoad %15 %34 -%127 = OpLoad %15 %43 -%128 = OpFAdd %15 %126 %127 -OpStore %34 %128 -%129 = OpLoad %8 %40 -%130 = OpIAdd %8 %129 %10 -OpStore %40 %130 -OpBranch %124 -%124 = OpLabel +OpLoopMerge %74 %76 None +OpBranch %75 +%75 = OpLabel +%77 = OpLoad %4 %49 +%78 = OpUGreaterThanEqual %61 %77 %3 +OpSelectionMerge %79 None +OpBranchConditional %78 %80 %79 +%80 = OpLabel OpBranch %74 +%79 = OpLabel +%81 = OpLoad %4 %49 +%82 = OpIEqual %61 %81 %60 +OpSelectionMerge %83 None +OpBranchConditional %82 %84 %83 +%84 = OpLabel +OpBranch %76 +%83 = OpLabel +%85 = OpLoad %4 %49 +%86 = OpAccessChain %65 %28 %9 %85 %9 +%87 = OpLoad %14 %86 +OpStore %45 %87 +%88 = OpLoad %4 %49 +%89 = OpAccessChain %65 %28 %9 %88 %11 +%90 = OpLoad %14 %89 +OpStore %47 %90 +%91 = OpLoad %14 %45 +%92 = OpLoad %14 %30 +%93 = OpExtInst %6 %1 Distance %91 %92 +%95 = OpAccessChain %94 %58 %11 +%96 = OpLoad %6 %95 +%97 = OpFOrdLessThan %61 %93 %96 +OpSelectionMerge %98 None +OpBranchConditional %97 %99 %98 +%99 = OpLabel +%100 = OpLoad %14 %34 +%101 = OpLoad %14 %45 +%102 = OpFAdd %14 %100 %101 +OpStore %34 %102 +%103 = OpLoad %8 %40 +%104 = OpIAdd %8 %103 %10 +OpStore %40 %104 +OpBranch %98 +%98 = OpLabel +%105 = OpLoad %14 %45 +%106 = OpLoad %14 %30 +%107 = OpExtInst %6 %1 Distance %105 %106 +%109 = OpAccessChain %94 %58 %108 +%110 = OpLoad %6 %109 +%111 = OpFOrdLessThan %61 %107 %110 +OpSelectionMerge %112 None +OpBranchConditional %111 %113 %112 +%113 = OpLabel +%114 = OpLoad %14 %38 +%115 = OpLoad %14 %45 +%116 = OpLoad %14 %30 +%117 = OpFSub %14 %115 %116 +%118 = OpFSub %14 %114 %117 +OpStore %38 %118 +OpBranch %112 +%112 = OpLabel +%119 = OpLoad %14 %45 +%120 = OpLoad %14 %30 +%121 = OpExtInst %6 %1 Distance %119 %120 +%123 = OpAccessChain %94 %58 %122 +%124 = OpLoad %6 %123 +%125 = OpFOrdLessThan %61 %121 %124 +OpSelectionMerge %126 None +OpBranchConditional %125 %127 %126 +%127 = OpLabel +%128 = OpLoad %14 %36 +%129 = OpLoad %14 %47 +%130 = OpFAdd %14 %128 %129 +OpStore %36 %130 +%131 = OpLoad %8 %43 +%132 = OpIAdd %8 %131 %10 +OpStore %43 %132 +OpBranch %126 +%126 = OpLabel +OpBranch %76 +%76 = OpLabel +%133 = OpLoad %4 %49 +%134 = OpIAdd %4 %133 %11 +OpStore %49 %134 +OpBranch %73 %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 +%135 = OpLoad %8 %40 +%136 = OpSGreaterThan %61 %135 %7 +OpSelectionMerge %137 None +OpBranchConditional %136 %138 %137 +%138 = OpLabel +%139 = OpLoad %14 %34 +%140 = OpLoad %8 %40 +%141 = OpConvertSToF %6 %140 +%142 = OpCompositeConstruct %14 %141 %141 +%143 = OpFDiv %14 %139 %142 +%144 = OpLoad %14 %30 +%145 = OpFSub %14 %143 %144 +OpStore %34 %145 +OpBranch %137 +%137 = OpLabel +%146 = OpLoad %8 %43 +%147 = OpSGreaterThan %61 %146 %7 +OpSelectionMerge %148 None +OpBranchConditional %147 %149 %148 +%149 = OpLabel +%150 = OpLoad %14 %36 +%151 = OpLoad %8 %43 +%152 = OpConvertSToF %6 %151 +%153 = OpCompositeConstruct %14 %152 %152 +%154 = OpFDiv %14 %150 %153 +OpStore %36 %154 +OpBranch %148 +%148 = OpLabel +%155 = OpLoad %14 %32 +%156 = OpLoad %14 %34 +%158 = OpAccessChain %94 %58 %157 +%159 = OpLoad %6 %158 +%160 = OpVectorTimesScalar %14 %156 %159 +%161 = OpFAdd %14 %155 %160 +%162 = OpLoad %14 %38 +%164 = OpAccessChain %94 %58 %163 +%165 = OpLoad %6 %164 +%166 = OpVectorTimesScalar %14 %162 %165 +%167 = OpFAdd %14 %161 %166 +%168 = OpLoad %14 %36 +%170 = OpAccessChain %94 %58 %169 +%171 = OpLoad %6 %170 +%172 = OpVectorTimesScalar %14 %168 %171 +%173 = OpFAdd %14 %167 %172 +OpStore %32 %173 +%174 = OpLoad %14 %32 +%175 = OpExtInst %14 %1 Normalize %174 +%176 = OpLoad %14 %32 +%177 = OpExtInst %6 %1 Length %176 +%178 = OpExtInst %6 %1 FClamp %177 %5 %12 +%179 = OpVectorTimesScalar %14 %175 %178 +OpStore %32 %179 +%180 = OpLoad %14 %30 +%181 = OpLoad %14 %32 +%182 = OpAccessChain %94 %58 %9 +%183 = OpLoad %6 %182 +%184 = OpVectorTimesScalar %14 %181 %183 +%185 = OpFAdd %14 %180 %184 +OpStore %30 %185 +%187 = OpAccessChain %186 %30 %9 +%188 = OpLoad %6 %187 +%189 = OpFNegate %6 %13 +%190 = OpFOrdLessThan %61 %188 %189 +OpSelectionMerge %191 None +OpBranchConditional %190 %192 %191 +%192 = OpLabel +%193 = OpAccessChain %186 %30 %9 +OpStore %193 %13 +OpBranch %191 +%191 = OpLabel +%194 = OpAccessChain %186 %30 %9 +%195 = OpLoad %6 %194 +%196 = OpFOrdGreaterThan %61 %195 %13 +OpSelectionMerge %197 None +OpBranchConditional %196 %198 %197 +%198 = OpLabel +%199 = OpFNegate %6 %13 +%200 = OpAccessChain %186 %30 %9 +OpStore %200 %199 +OpBranch %197 +%197 = OpLabel +%201 = OpAccessChain %186 %30 %11 +%202 = OpLoad %6 %201 +%203 = OpFNegate %6 %13 +%204 = OpFOrdLessThan %61 %202 %203 +OpSelectionMerge %205 None +OpBranchConditional %204 %206 %205 %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 +%207 = OpAccessChain %186 %30 %11 +OpStore %207 %13 +OpBranch %205 +%205 = OpLabel +%208 = OpAccessChain %186 %30 %11 +%209 = OpLoad %6 %208 +%210 = OpFOrdGreaterThan %61 %209 %13 +OpSelectionMerge %211 None +OpBranchConditional %210 %212 %211 +%212 = OpLabel +%213 = OpFNegate %6 %13 +%214 = OpAccessChain %186 %30 %11 +OpStore %214 %213 +OpBranch %211 +%211 = OpLabel +%215 = OpLoad %14 %30 +%216 = OpAccessChain %65 %29 %9 %60 %9 +OpStore %216 %215 +%217 = OpLoad %14 %32 +%218 = OpAccessChain %65 %29 %9 %60 %11 +OpStore %218 %217 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/bounds-check-image-restrict.spvasm b/tests/out/spv/bounds-check-image-restrict.spvasm index 51d53f3d03..77acb04a8d 100644 --- a/tests/out/spv/bounds-check-image-restrict.spvasm +++ b/tests/out/spv/bounds-check-image-restrict.spvasm @@ -11,6 +11,23 @@ OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %222 "fragment_shader" %220 OpExecutionMode %222 OriginUpperLeft OpSource GLSL 450 +OpName %7 "texture_1d" +OpName %4 "i32" +OpName %8 "vec4" +OpName %9 "texture_2d" +OpName %10 "vec2" +OpName %11 "texture_2d_array" +OpName %12 "texture_3d" +OpName %13 "vec3" +OpName %14 "texture_multisampled_2d" +OpName %15 "texture_depth_2d" +OpName %6 "f32" +OpName %16 "texture_depth_2d_array" +OpName %17 "texture_depth_multisampled_2d" +OpName %18 "texture_storage_1d" +OpName %19 "texture_storage_2d" +OpName %20 "texture_storage_2d_array" +OpName %21 "texture_storage_3d" OpName %25 "image_1d" OpName %27 "image_2d" OpName %29 "image_2d_array" diff --git a/tests/out/spv/bounds-check-image-rzsw.spvasm b/tests/out/spv/bounds-check-image-rzsw.spvasm index 3c8e79009a..d56cb63a61 100644 --- a/tests/out/spv/bounds-check-image-rzsw.spvasm +++ b/tests/out/spv/bounds-check-image-rzsw.spvasm @@ -11,6 +11,23 @@ OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %252 "fragment_shader" %250 OpExecutionMode %252 OriginUpperLeft OpSource GLSL 450 +OpName %7 "texture_1d" +OpName %4 "i32" +OpName %8 "vec4" +OpName %9 "texture_2d" +OpName %10 "vec2" +OpName %11 "texture_2d_array" +OpName %12 "texture_3d" +OpName %13 "vec3" +OpName %14 "texture_multisampled_2d" +OpName %15 "texture_depth_2d" +OpName %6 "f32" +OpName %16 "texture_depth_2d_array" +OpName %17 "texture_depth_multisampled_2d" +OpName %18 "texture_storage_1d" +OpName %19 "texture_storage_2d" +OpName %20 "texture_storage_2d_array" +OpName %21 "texture_storage_3d" OpName %25 "image_1d" OpName %27 "image_2d" OpName %29 "image_2d_array" diff --git a/tests/out/spv/bounds-check-restrict.spvasm b/tests/out/spv/bounds-check-restrict.spvasm index 1927123467..1eecc4fe96 100644 --- a/tests/out/spv/bounds-check-restrict.spvasm +++ b/tests/out/spv/bounds-check-restrict.spvasm @@ -7,120 +7,120 @@ OpCapability Linkage OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpDecorate %10 ArrayStride 4 -OpDecorate %13 ArrayStride 4 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 48 -OpMemberDecorate %14 2 Offset 64 -OpMemberDecorate %14 2 ColMajor -OpMemberDecorate %14 2 MatrixStride 16 -OpMemberDecorate %14 3 Offset 112 -OpDecorate %15 DescriptorSet 0 -OpDecorate %15 Binding 0 -OpDecorate %14 Block +OpDecorate %11 ArrayStride 4 +OpDecorate %14 ArrayStride 4 +OpMemberDecorate %15 0 Offset 0 +OpMemberDecorate %15 1 Offset 48 +OpMemberDecorate %15 2 Offset 64 +OpMemberDecorate %15 2 ColMajor +OpMemberDecorate %15 2 MatrixStride 16 +OpMemberDecorate %15 3 Offset 112 +OpDecorate %22 DescriptorSet 0 +OpDecorate %22 Binding 0 +OpDecorate %15 Block %2 = OpTypeVoid -%4 = OpTypeInt 32 1 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 10 %6 = OpTypeFloat 32 %5 = OpConstant %6 100.0 -%7 = OpConstant %4 9 -%8 = OpConstant %4 3 -%9 = OpConstant %4 2 -%10 = OpTypeArray %6 %3 -%11 = OpTypeVector %6 4 -%12 = OpTypeMatrix %11 3 -%13 = OpTypeRuntimeArray %6 -%14 = OpTypeStruct %10 %11 %12 %13 -%16 = OpTypePointer StorageBuffer %14 -%15 = OpVariable %16 StorageBuffer -%20 = OpTypeFunction %6 %4 -%22 = OpTypePointer StorageBuffer %10 -%23 = OpTypePointer StorageBuffer %6 -%25 = OpTypeInt 32 0 -%24 = OpConstant %25 9 -%27 = OpConstant %25 0 -%34 = OpTypePointer StorageBuffer %13 -%36 = OpConstant %25 1 -%39 = OpConstant %25 3 -%46 = OpTypePointer StorageBuffer %11 -%47 = OpTypePointer StorageBuffer %6 -%55 = OpTypeFunction %6 %11 %4 -%62 = OpTypeFunction %11 %4 -%64 = OpTypePointer StorageBuffer %12 -%65 = OpTypePointer StorageBuffer %11 -%66 = OpConstant %25 2 -%74 = OpTypeFunction %6 %4 %4 +%8 = OpTypeInt 32 1 +%7 = OpConstant %8 9 +%9 = OpConstant %8 3 +%10 = OpConstant %8 2 +%11 = OpTypeArray %6 %3 +%12 = OpTypeVector %6 4 +%13 = OpTypeMatrix %12 3 +%14 = OpTypeRuntimeArray %6 +%15 = OpTypeStruct %11 %12 %13 %14 +%16 = OpTypePointer StorageBuffer %15 +%17 = OpTypePointer StorageBuffer %11 +%18 = OpTypePointer StorageBuffer %14 +%19 = OpTypePointer StorageBuffer %12 +%20 = OpTypePointer StorageBuffer %13 +%21 = OpTypePointer StorageBuffer %12 +%22 = OpVariable %16 StorageBuffer +%26 = OpTypeFunction %6 %8 +%28 = OpTypePointer StorageBuffer %6 +%29 = OpConstant %4 9 +%31 = OpConstant %4 0 +%39 = OpConstant %4 1 +%42 = OpConstant %4 3 +%49 = OpTypePointer StorageBuffer %6 +%57 = OpTypeFunction %6 %12 %8 +%64 = OpTypeFunction %12 %8 +%66 = OpConstant %4 2 +%74 = OpTypeFunction %6 %8 %8 %94 = OpTypeFunction %6 -%108 = OpTypeFunction %2 %4 %6 -%132 = OpTypeFunction %2 %4 %11 -%141 = OpTypeFunction %2 %4 %4 %6 +%108 = OpTypeFunction %2 %8 %6 +%132 = OpTypeFunction %2 %8 %12 +%141 = OpTypeFunction %2 %8 %8 %6 %161 = OpTypeFunction %2 %6 -%19 = OpFunction %6 None %20 -%18 = OpFunctionParameter %4 -%17 = OpLabel -OpBranch %21 -%21 = OpLabel -%26 = OpExtInst %25 %1 UMin %18 %24 -%28 = OpAccessChain %23 %15 %27 %26 -%29 = OpLoad %6 %28 -OpReturnValue %29 +%25 = OpFunction %6 None %26 +%24 = OpFunctionParameter %8 +%23 = OpLabel +OpBranch %27 +%27 = OpLabel +%30 = OpExtInst %4 %1 UMin %24 %29 +%32 = OpAccessChain %28 %22 %31 %30 +%33 = OpLoad %6 %32 +OpReturnValue %33 OpFunctionEnd -%32 = OpFunction %6 None %20 -%31 = OpFunctionParameter %4 -%30 = OpLabel -OpBranch %33 -%33 = OpLabel -%35 = OpArrayLength %25 %15 3 -%37 = OpISub %25 %35 %36 -%38 = OpExtInst %25 %1 UMin %31 %37 -%40 = OpAccessChain %23 %15 %39 %38 -%41 = OpLoad %6 %40 -OpReturnValue %41 +%36 = OpFunction %6 None %26 +%35 = OpFunctionParameter %8 +%34 = OpLabel +OpBranch %37 +%37 = OpLabel +%38 = OpArrayLength %4 %22 3 +%40 = OpISub %4 %38 %39 +%41 = OpExtInst %4 %1 UMin %35 %40 +%43 = OpAccessChain %28 %22 %42 %41 +%44 = OpLoad %6 %43 +OpReturnValue %44 OpFunctionEnd -%44 = OpFunction %6 None %20 -%43 = OpFunctionParameter %4 -%42 = OpLabel -OpBranch %45 +%47 = OpFunction %6 None %26 +%46 = OpFunctionParameter %8 %45 = OpLabel -%48 = OpExtInst %25 %1 UMin %43 %39 -%49 = OpAccessChain %47 %15 %36 %48 -%50 = OpLoad %6 %49 -OpReturnValue %50 +OpBranch %48 +%48 = OpLabel +%50 = OpExtInst %4 %1 UMin %46 %42 +%51 = OpAccessChain %49 %22 %39 %50 +%52 = OpLoad %6 %51 +OpReturnValue %52 OpFunctionEnd -%54 = OpFunction %6 None %55 -%52 = OpFunctionParameter %11 -%53 = OpFunctionParameter %4 -%51 = OpLabel -OpBranch %56 -%56 = OpLabel -%57 = OpExtInst %25 %1 UMin %53 %39 -%58 = OpVectorExtractDynamic %6 %52 %57 -OpReturnValue %58 +%56 = OpFunction %6 None %57 +%54 = OpFunctionParameter %12 +%55 = OpFunctionParameter %8 +%53 = OpLabel +OpBranch %58 +%58 = OpLabel +%59 = OpExtInst %4 %1 UMin %55 %42 +%60 = OpVectorExtractDynamic %6 %54 %59 +OpReturnValue %60 OpFunctionEnd -%61 = OpFunction %11 None %62 -%60 = OpFunctionParameter %4 -%59 = OpLabel -OpBranch %63 -%63 = OpLabel -%67 = OpExtInst %25 %1 UMin %60 %66 -%68 = OpAccessChain %65 %15 %66 %67 -%69 = OpLoad %11 %68 +%63 = OpFunction %12 None %64 +%62 = OpFunctionParameter %8 +%61 = OpLabel +OpBranch %65 +%65 = OpLabel +%67 = OpExtInst %4 %1 UMin %62 %66 +%68 = OpAccessChain %21 %22 %66 %67 +%69 = OpLoad %12 %68 OpReturnValue %69 OpFunctionEnd %73 = OpFunction %6 None %74 -%71 = OpFunctionParameter %4 -%72 = OpFunctionParameter %4 +%71 = OpFunctionParameter %8 +%72 = OpFunctionParameter %8 %70 = OpLabel OpBranch %75 %75 = OpLabel -%76 = OpExtInst %25 %1 UMin %72 %39 -%77 = OpExtInst %25 %1 UMin %71 %66 -%78 = OpAccessChain %47 %15 %66 %77 %76 +%76 = OpExtInst %4 %1 UMin %72 %42 +%77 = OpExtInst %4 %1 UMin %71 %66 +%78 = OpAccessChain %49 %22 %66 %77 %76 %79 = OpLoad %6 %78 OpReturnValue %79 OpFunctionEnd -%82 = OpFunction %6 None %20 -%81 = OpFunctionParameter %4 +%82 = OpFunction %6 None %26 +%81 = OpFunctionParameter %8 %80 = OpLabel OpBranch %83 %83 = OpLabel @@ -128,9 +128,9 @@ OpBranch %83 %85 = OpFDiv %6 %84 %5 %86 = OpExtInst %6 %1 Sin %85 %87 = OpFMul %6 %86 %5 -%88 = OpConvertFToS %4 %87 -%89 = OpExtInst %25 %1 UMin %88 %24 -%90 = OpAccessChain %23 %15 %27 %89 +%88 = OpConvertFToS %8 %87 +%89 = OpExtInst %4 %1 UMin %88 %29 +%90 = OpAccessChain %28 %22 %31 %89 %91 = OpLoad %6 %90 OpReturnValue %91 OpFunctionEnd @@ -138,77 +138,77 @@ OpFunctionEnd %92 = OpLabel OpBranch %95 %95 = OpLabel -%96 = OpAccessChain %23 %15 %27 %24 +%96 = OpAccessChain %28 %22 %31 %29 %97 = OpLoad %6 %96 -%98 = OpAccessChain %47 %15 %36 %39 +%98 = OpAccessChain %49 %22 %39 %42 %99 = OpLoad %6 %98 %100 = OpFAdd %6 %97 %99 -%101 = OpAccessChain %47 %15 %66 %66 %39 +%101 = OpAccessChain %49 %22 %66 %66 %42 %102 = OpLoad %6 %101 %103 = OpFAdd %6 %100 %102 OpReturnValue %103 OpFunctionEnd %107 = OpFunction %2 None %108 -%105 = OpFunctionParameter %4 +%105 = OpFunctionParameter %8 %106 = OpFunctionParameter %6 %104 = OpLabel OpBranch %109 %109 = OpLabel -%110 = OpExtInst %25 %1 UMin %105 %24 -%111 = OpAccessChain %23 %15 %27 %110 +%110 = OpExtInst %4 %1 UMin %105 %29 +%111 = OpAccessChain %28 %22 %31 %110 OpStore %111 %106 OpReturn OpFunctionEnd %115 = OpFunction %2 None %108 -%113 = OpFunctionParameter %4 +%113 = OpFunctionParameter %8 %114 = OpFunctionParameter %6 %112 = OpLabel OpBranch %116 %116 = OpLabel -%117 = OpArrayLength %25 %15 3 -%118 = OpISub %25 %117 %36 -%119 = OpExtInst %25 %1 UMin %113 %118 -%120 = OpAccessChain %23 %15 %39 %119 +%117 = OpArrayLength %4 %22 3 +%118 = OpISub %4 %117 %39 +%119 = OpExtInst %4 %1 UMin %113 %118 +%120 = OpAccessChain %28 %22 %42 %119 OpStore %120 %114 OpReturn OpFunctionEnd %124 = OpFunction %2 None %108 -%122 = OpFunctionParameter %4 +%122 = OpFunctionParameter %8 %123 = OpFunctionParameter %6 %121 = OpLabel OpBranch %125 %125 = OpLabel -%126 = OpExtInst %25 %1 UMin %122 %39 -%127 = OpAccessChain %47 %15 %36 %126 +%126 = OpExtInst %4 %1 UMin %122 %42 +%127 = OpAccessChain %49 %22 %39 %126 OpStore %127 %123 OpReturn OpFunctionEnd %131 = OpFunction %2 None %132 -%129 = OpFunctionParameter %4 -%130 = OpFunctionParameter %11 +%129 = OpFunctionParameter %8 +%130 = OpFunctionParameter %12 %128 = OpLabel OpBranch %133 %133 = OpLabel -%134 = OpExtInst %25 %1 UMin %129 %66 -%135 = OpAccessChain %65 %15 %66 %134 +%134 = OpExtInst %4 %1 UMin %129 %66 +%135 = OpAccessChain %21 %22 %66 %134 OpStore %135 %130 OpReturn OpFunctionEnd %140 = OpFunction %2 None %141 -%137 = OpFunctionParameter %4 -%138 = OpFunctionParameter %4 +%137 = OpFunctionParameter %8 +%138 = OpFunctionParameter %8 %139 = OpFunctionParameter %6 %136 = OpLabel OpBranch %142 %142 = OpLabel -%143 = OpExtInst %25 %1 UMin %138 %39 -%144 = OpExtInst %25 %1 UMin %137 %66 -%145 = OpAccessChain %47 %15 %66 %144 %143 +%143 = OpExtInst %4 %1 UMin %138 %42 +%144 = OpExtInst %4 %1 UMin %137 %66 +%145 = OpAccessChain %49 %22 %66 %144 %143 OpStore %145 %139 OpReturn OpFunctionEnd %149 = OpFunction %2 None %108 -%147 = OpFunctionParameter %4 +%147 = OpFunctionParameter %8 %148 = OpFunctionParameter %6 %146 = OpLabel OpBranch %150 @@ -217,9 +217,9 @@ OpBranch %150 %152 = OpFDiv %6 %151 %5 %153 = OpExtInst %6 %1 Sin %152 %154 = OpFMul %6 %153 %5 -%155 = OpConvertFToS %4 %154 -%156 = OpExtInst %25 %1 UMin %155 %24 -%157 = OpAccessChain %23 %15 %27 %156 +%155 = OpConvertFToS %8 %154 +%156 = OpExtInst %4 %1 UMin %155 %29 +%157 = OpAccessChain %28 %22 %31 %156 OpStore %157 %148 OpReturn OpFunctionEnd @@ -228,11 +228,11 @@ OpFunctionEnd %158 = OpLabel OpBranch %162 %162 = OpLabel -%163 = OpAccessChain %23 %15 %27 %24 +%163 = OpAccessChain %28 %22 %31 %29 OpStore %163 %159 -%164 = OpAccessChain %47 %15 %36 %39 +%164 = OpAccessChain %49 %22 %39 %42 OpStore %164 %159 -%165 = OpAccessChain %47 %15 %66 %66 %39 +%165 = OpAccessChain %49 %22 %66 %66 %42 OpStore %165 %159 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/bounds-check-zero.spvasm b/tests/out/spv/bounds-check-zero.spvasm index 5e5aac07fa..a198c4cdd8 100644 --- a/tests/out/spv/bounds-check-zero.spvasm +++ b/tests/out/spv/bounds-check-zero.spvasm @@ -1,320 +1,319 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 209 +; Bound: 208 OpCapability Shader OpCapability Linkage OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpDecorate %10 ArrayStride 4 -OpDecorate %13 ArrayStride 4 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 48 -OpMemberDecorate %14 2 Offset 64 -OpMemberDecorate %14 2 ColMajor -OpMemberDecorate %14 2 MatrixStride 16 -OpMemberDecorate %14 3 Offset 112 -OpDecorate %15 DescriptorSet 0 -OpDecorate %15 Binding 0 -OpDecorate %14 Block +OpDecorate %11 ArrayStride 4 +OpDecorate %14 ArrayStride 4 +OpMemberDecorate %15 0 Offset 0 +OpMemberDecorate %15 1 Offset 48 +OpMemberDecorate %15 2 Offset 64 +OpMemberDecorate %15 2 ColMajor +OpMemberDecorate %15 2 MatrixStride 16 +OpMemberDecorate %15 3 Offset 112 +OpDecorate %22 DescriptorSet 0 +OpDecorate %22 Binding 0 +OpDecorate %15 Block %2 = OpTypeVoid -%4 = OpTypeInt 32 1 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 10 %6 = OpTypeFloat 32 %5 = OpConstant %6 100.0 -%7 = OpConstant %4 9 -%8 = OpConstant %4 3 -%9 = OpConstant %4 2 -%10 = OpTypeArray %6 %3 -%11 = OpTypeVector %6 4 -%12 = OpTypeMatrix %11 3 -%13 = OpTypeRuntimeArray %6 -%14 = OpTypeStruct %10 %11 %12 %13 -%16 = OpTypePointer StorageBuffer %14 -%15 = OpVariable %16 StorageBuffer -%20 = OpTypeFunction %6 %4 -%22 = OpTypePointer StorageBuffer %10 -%23 = OpTypePointer StorageBuffer %6 -%25 = OpTypeInt 32 0 -%24 = OpConstant %25 10 -%27 = OpTypeBool -%28 = OpConstant %25 0 -%30 = OpConstantNull %6 -%39 = OpTypePointer StorageBuffer %13 -%42 = OpConstant %25 3 -%44 = OpConstantNull %6 -%53 = OpTypePointer StorageBuffer %11 -%54 = OpTypePointer StorageBuffer %6 -%55 = OpConstant %25 4 -%57 = OpConstant %25 1 -%59 = OpConstantNull %6 -%68 = OpTypeFunction %6 %11 %4 -%71 = OpConstantNull %6 -%79 = OpTypeFunction %11 %4 -%81 = OpTypePointer StorageBuffer %12 -%82 = OpTypePointer StorageBuffer %11 -%84 = OpConstant %25 2 -%86 = OpConstantNull %11 -%95 = OpTypeFunction %6 %4 %4 -%101 = OpConstantNull %6 -%117 = OpConstantNull %6 -%124 = OpTypeFunction %6 -%126 = OpConstant %25 9 -%139 = OpTypeFunction %2 %4 %6 -%168 = OpTypeFunction %2 %4 %11 -%179 = OpTypeFunction %2 %4 %4 %6 -%204 = OpTypeFunction %2 %6 -%19 = OpFunction %6 None %20 -%18 = OpFunctionParameter %4 -%17 = OpLabel -OpBranch %21 -%21 = OpLabel -%26 = OpULessThan %27 %18 %24 -OpSelectionMerge %31 None -OpBranchConditional %26 %32 %31 -%32 = OpLabel -%29 = OpAccessChain %23 %15 %28 %18 -%33 = OpLoad %6 %29 -OpBranch %31 -%31 = OpLabel -%34 = OpPhi %6 %30 %21 %33 %32 -OpReturnValue %34 -OpFunctionEnd -%37 = OpFunction %6 None %20 -%36 = OpFunctionParameter %4 +%8 = OpTypeInt 32 1 +%7 = OpConstant %8 9 +%9 = OpConstant %8 3 +%10 = OpConstant %8 2 +%11 = OpTypeArray %6 %3 +%12 = OpTypeVector %6 4 +%13 = OpTypeMatrix %12 3 +%14 = OpTypeRuntimeArray %6 +%15 = OpTypeStruct %11 %12 %13 %14 +%16 = OpTypePointer StorageBuffer %15 +%17 = OpTypePointer StorageBuffer %11 +%18 = OpTypePointer StorageBuffer %14 +%19 = OpTypePointer StorageBuffer %12 +%20 = OpTypePointer StorageBuffer %13 +%21 = OpTypePointer StorageBuffer %12 +%22 = OpVariable %16 StorageBuffer +%26 = OpTypeFunction %6 %8 +%28 = OpTypePointer StorageBuffer %6 +%30 = OpTypeBool +%31 = OpConstant %4 0 +%33 = OpConstantNull %6 +%44 = OpConstant %4 3 +%46 = OpConstantNull %6 +%55 = OpTypePointer StorageBuffer %6 +%56 = OpConstant %4 4 +%58 = OpConstant %4 1 +%60 = OpConstantNull %6 +%69 = OpTypeFunction %6 %12 %8 +%72 = OpConstantNull %6 +%80 = OpTypeFunction %12 %8 +%83 = OpConstant %4 2 +%85 = OpConstantNull %12 +%94 = OpTypeFunction %6 %8 %8 +%100 = OpConstantNull %6 +%116 = OpConstantNull %6 +%123 = OpTypeFunction %6 +%125 = OpConstant %4 9 +%138 = OpTypeFunction %2 %8 %6 +%167 = OpTypeFunction %2 %8 %12 +%178 = OpTypeFunction %2 %8 %8 %6 +%203 = OpTypeFunction %2 %6 +%25 = OpFunction %6 None %26 +%24 = OpFunctionParameter %8 +%23 = OpLabel +OpBranch %27 +%27 = OpLabel +%29 = OpULessThan %30 %24 %3 +OpSelectionMerge %34 None +OpBranchConditional %29 %35 %34 %35 = OpLabel -OpBranch %38 +%32 = OpAccessChain %28 %22 %31 %24 +%36 = OpLoad %6 %32 +OpBranch %34 +%34 = OpLabel +%37 = OpPhi %6 %33 %27 %36 %35 +OpReturnValue %37 +OpFunctionEnd +%40 = OpFunction %6 None %26 +%39 = OpFunctionParameter %8 %38 = OpLabel -%40 = OpArrayLength %25 %15 3 -%41 = OpULessThan %27 %36 %40 -OpSelectionMerge %45 None -OpBranchConditional %41 %46 %45 -%46 = OpLabel -%43 = OpAccessChain %23 %15 %42 %36 -%47 = OpLoad %6 %43 -OpBranch %45 -%45 = OpLabel -%48 = OpPhi %6 %44 %38 %47 %46 -OpReturnValue %48 +OpBranch %41 +%41 = OpLabel +%42 = OpArrayLength %4 %22 3 +%43 = OpULessThan %30 %39 %42 +OpSelectionMerge %47 None +OpBranchConditional %43 %48 %47 +%48 = OpLabel +%45 = OpAccessChain %28 %22 %44 %39 +%49 = OpLoad %6 %45 +OpBranch %47 +%47 = OpLabel +%50 = OpPhi %6 %46 %41 %49 %48 +OpReturnValue %50 OpFunctionEnd -%51 = OpFunction %6 None %20 -%50 = OpFunctionParameter %4 -%49 = OpLabel -OpBranch %52 -%52 = OpLabel -%56 = OpULessThan %27 %50 %55 -OpSelectionMerge %60 None -OpBranchConditional %56 %61 %60 +%53 = OpFunction %6 None %26 +%52 = OpFunctionParameter %8 +%51 = OpLabel +OpBranch %54 +%54 = OpLabel +%57 = OpULessThan %30 %52 %56 +OpSelectionMerge %61 None +OpBranchConditional %57 %62 %61 +%62 = OpLabel +%59 = OpAccessChain %55 %22 %58 %52 +%63 = OpLoad %6 %59 +OpBranch %61 %61 = OpLabel -%58 = OpAccessChain %54 %15 %57 %50 -%62 = OpLoad %6 %58 -OpBranch %60 -%60 = OpLabel -%63 = OpPhi %6 %59 %52 %62 %61 -OpReturnValue %63 +%64 = OpPhi %6 %60 %54 %63 %62 +OpReturnValue %64 OpFunctionEnd -%67 = OpFunction %6 None %68 -%65 = OpFunctionParameter %11 -%66 = OpFunctionParameter %4 -%64 = OpLabel -OpBranch %69 -%69 = OpLabel -%70 = OpULessThan %27 %66 %55 -OpSelectionMerge %72 None -OpBranchConditional %70 %73 %72 +%68 = OpFunction %6 None %69 +%66 = OpFunctionParameter %12 +%67 = OpFunctionParameter %8 +%65 = OpLabel +OpBranch %70 +%70 = OpLabel +%71 = OpULessThan %30 %67 %56 +OpSelectionMerge %73 None +OpBranchConditional %71 %74 %73 +%74 = OpLabel +%75 = OpVectorExtractDynamic %6 %66 %67 +OpBranch %73 %73 = OpLabel -%74 = OpVectorExtractDynamic %6 %65 %66 -OpBranch %72 -%72 = OpLabel -%75 = OpPhi %6 %71 %69 %74 %73 -OpReturnValue %75 +%76 = OpPhi %6 %72 %70 %75 %74 +OpReturnValue %76 OpFunctionEnd -%78 = OpFunction %11 None %79 -%77 = OpFunctionParameter %4 -%76 = OpLabel -OpBranch %80 -%80 = OpLabel -%83 = OpULessThan %27 %77 %42 -OpSelectionMerge %87 None -OpBranchConditional %83 %88 %87 -%88 = OpLabel -%85 = OpAccessChain %82 %15 %84 %77 -%89 = OpLoad %11 %85 -OpBranch %87 +%79 = OpFunction %12 None %80 +%78 = OpFunctionParameter %8 +%77 = OpLabel +OpBranch %81 +%81 = OpLabel +%82 = OpULessThan %30 %78 %44 +OpSelectionMerge %86 None +OpBranchConditional %82 %87 %86 %87 = OpLabel -%90 = OpPhi %11 %86 %80 %89 %88 -OpReturnValue %90 +%84 = OpAccessChain %21 %22 %83 %78 +%88 = OpLoad %12 %84 +OpBranch %86 +%86 = OpLabel +%89 = OpPhi %12 %85 %81 %88 %87 +OpReturnValue %89 OpFunctionEnd -%94 = OpFunction %6 None %95 -%92 = OpFunctionParameter %4 -%93 = OpFunctionParameter %4 -%91 = OpLabel -OpBranch %96 -%96 = OpLabel -%97 = OpULessThan %27 %93 %55 -%98 = OpULessThan %27 %92 %42 -%99 = OpLogicalAnd %27 %97 %98 -OpSelectionMerge %102 None -OpBranchConditional %99 %103 %102 -%103 = OpLabel -%100 = OpAccessChain %54 %15 %84 %92 %93 -%104 = OpLoad %6 %100 -OpBranch %102 +%93 = OpFunction %6 None %94 +%91 = OpFunctionParameter %8 +%92 = OpFunctionParameter %8 +%90 = OpLabel +OpBranch %95 +%95 = OpLabel +%96 = OpULessThan %30 %92 %56 +%97 = OpULessThan %30 %91 %44 +%98 = OpLogicalAnd %30 %96 %97 +OpSelectionMerge %101 None +OpBranchConditional %98 %102 %101 %102 = OpLabel -%105 = OpPhi %6 %101 %96 %104 %103 -OpReturnValue %105 +%99 = OpAccessChain %55 %22 %83 %91 %92 +%103 = OpLoad %6 %99 +OpBranch %101 +%101 = OpLabel +%104 = OpPhi %6 %100 %95 %103 %102 +OpReturnValue %104 OpFunctionEnd -%108 = OpFunction %6 None %20 -%107 = OpFunctionParameter %4 -%106 = OpLabel -OpBranch %109 -%109 = OpLabel -%110 = OpConvertSToF %6 %107 -%111 = OpFDiv %6 %110 %5 -%112 = OpExtInst %6 %1 Sin %111 -%113 = OpFMul %6 %112 %5 -%114 = OpConvertFToS %4 %113 -%115 = OpULessThan %27 %114 %24 -OpSelectionMerge %118 None -OpBranchConditional %115 %119 %118 -%119 = OpLabel -%116 = OpAccessChain %23 %15 %28 %114 -%120 = OpLoad %6 %116 -OpBranch %118 +%107 = OpFunction %6 None %26 +%106 = OpFunctionParameter %8 +%105 = OpLabel +OpBranch %108 +%108 = OpLabel +%109 = OpConvertSToF %6 %106 +%110 = OpFDiv %6 %109 %5 +%111 = OpExtInst %6 %1 Sin %110 +%112 = OpFMul %6 %111 %5 +%113 = OpConvertFToS %8 %112 +%114 = OpULessThan %30 %113 %3 +OpSelectionMerge %117 None +OpBranchConditional %114 %118 %117 %118 = OpLabel -%121 = OpPhi %6 %117 %109 %120 %119 -OpReturnValue %121 +%115 = OpAccessChain %28 %22 %31 %113 +%119 = OpLoad %6 %115 +OpBranch %117 +%117 = OpLabel +%120 = OpPhi %6 %116 %108 %119 %118 +OpReturnValue %120 OpFunctionEnd -%123 = OpFunction %6 None %124 -%122 = OpLabel -OpBranch %125 -%125 = OpLabel -%127 = OpAccessChain %23 %15 %28 %126 -%128 = OpLoad %6 %127 -%129 = OpAccessChain %54 %15 %57 %42 -%130 = OpLoad %6 %129 -%131 = OpFAdd %6 %128 %130 -%132 = OpAccessChain %54 %15 %84 %84 %42 -%133 = OpLoad %6 %132 -%134 = OpFAdd %6 %131 %133 -OpReturnValue %134 +%122 = OpFunction %6 None %123 +%121 = OpLabel +OpBranch %124 +%124 = OpLabel +%126 = OpAccessChain %28 %22 %31 %125 +%127 = OpLoad %6 %126 +%128 = OpAccessChain %55 %22 %58 %44 +%129 = OpLoad %6 %128 +%130 = OpFAdd %6 %127 %129 +%131 = OpAccessChain %55 %22 %83 %83 %44 +%132 = OpLoad %6 %131 +%133 = OpFAdd %6 %130 %132 +OpReturnValue %133 OpFunctionEnd -%138 = OpFunction %2 None %139 -%136 = OpFunctionParameter %4 -%137 = OpFunctionParameter %6 -%135 = OpLabel -OpBranch %140 -%140 = OpLabel -%141 = OpULessThan %27 %136 %24 -OpSelectionMerge %143 None -OpBranchConditional %141 %144 %143 -%144 = OpLabel -%142 = OpAccessChain %23 %15 %28 %136 -OpStore %142 %137 -OpBranch %143 +%137 = OpFunction %2 None %138 +%135 = OpFunctionParameter %8 +%136 = OpFunctionParameter %6 +%134 = OpLabel +OpBranch %139 +%139 = OpLabel +%140 = OpULessThan %30 %135 %3 +OpSelectionMerge %142 None +OpBranchConditional %140 %143 %142 %143 = OpLabel +%141 = OpAccessChain %28 %22 %31 %135 +OpStore %141 %136 +OpBranch %142 +%142 = OpLabel OpReturn OpFunctionEnd -%148 = OpFunction %2 None %139 -%146 = OpFunctionParameter %4 -%147 = OpFunctionParameter %6 -%145 = OpLabel -OpBranch %149 -%149 = OpLabel -%150 = OpArrayLength %25 %15 3 -%151 = OpULessThan %27 %146 %150 -OpSelectionMerge %153 None -OpBranchConditional %151 %154 %153 -%154 = OpLabel -%152 = OpAccessChain %23 %15 %42 %146 -OpStore %152 %147 -OpBranch %153 +%147 = OpFunction %2 None %138 +%145 = OpFunctionParameter %8 +%146 = OpFunctionParameter %6 +%144 = OpLabel +OpBranch %148 +%148 = OpLabel +%149 = OpArrayLength %4 %22 3 +%150 = OpULessThan %30 %145 %149 +OpSelectionMerge %152 None +OpBranchConditional %150 %153 %152 %153 = OpLabel +%151 = OpAccessChain %28 %22 %44 %145 +OpStore %151 %146 +OpBranch %152 +%152 = OpLabel OpReturn OpFunctionEnd -%158 = OpFunction %2 None %139 -%156 = OpFunctionParameter %4 -%157 = OpFunctionParameter %6 -%155 = OpLabel -OpBranch %159 -%159 = OpLabel -%160 = OpULessThan %27 %156 %55 -OpSelectionMerge %162 None -OpBranchConditional %160 %163 %162 -%163 = OpLabel -%161 = OpAccessChain %54 %15 %57 %156 -OpStore %161 %157 -OpBranch %162 +%157 = OpFunction %2 None %138 +%155 = OpFunctionParameter %8 +%156 = OpFunctionParameter %6 +%154 = OpLabel +OpBranch %158 +%158 = OpLabel +%159 = OpULessThan %30 %155 %56 +OpSelectionMerge %161 None +OpBranchConditional %159 %162 %161 %162 = OpLabel +%160 = OpAccessChain %55 %22 %58 %155 +OpStore %160 %156 +OpBranch %161 +%161 = OpLabel OpReturn OpFunctionEnd -%167 = OpFunction %2 None %168 -%165 = OpFunctionParameter %4 -%166 = OpFunctionParameter %11 -%164 = OpLabel -OpBranch %169 -%169 = OpLabel -%170 = OpULessThan %27 %165 %42 -OpSelectionMerge %172 None -OpBranchConditional %170 %173 %172 -%173 = OpLabel -%171 = OpAccessChain %82 %15 %84 %165 -OpStore %171 %166 -OpBranch %172 +%166 = OpFunction %2 None %167 +%164 = OpFunctionParameter %8 +%165 = OpFunctionParameter %12 +%163 = OpLabel +OpBranch %168 +%168 = OpLabel +%169 = OpULessThan %30 %164 %44 +OpSelectionMerge %171 None +OpBranchConditional %169 %172 %171 %172 = OpLabel +%170 = OpAccessChain %21 %22 %83 %164 +OpStore %170 %165 +OpBranch %171 +%171 = OpLabel OpReturn OpFunctionEnd -%178 = OpFunction %2 None %179 -%175 = OpFunctionParameter %4 -%176 = OpFunctionParameter %4 -%177 = OpFunctionParameter %6 -%174 = OpLabel -OpBranch %180 -%180 = OpLabel -%181 = OpULessThan %27 %176 %55 -%182 = OpULessThan %27 %175 %42 -%183 = OpLogicalAnd %27 %181 %182 -OpSelectionMerge %185 None -OpBranchConditional %183 %186 %185 -%186 = OpLabel -%184 = OpAccessChain %54 %15 %84 %175 %176 -OpStore %184 %177 -OpBranch %185 +%177 = OpFunction %2 None %178 +%174 = OpFunctionParameter %8 +%175 = OpFunctionParameter %8 +%176 = OpFunctionParameter %6 +%173 = OpLabel +OpBranch %179 +%179 = OpLabel +%180 = OpULessThan %30 %175 %56 +%181 = OpULessThan %30 %174 %44 +%182 = OpLogicalAnd %30 %180 %181 +OpSelectionMerge %184 None +OpBranchConditional %182 %185 %184 %185 = OpLabel +%183 = OpAccessChain %55 %22 %83 %174 %175 +OpStore %183 %176 +OpBranch %184 +%184 = OpLabel OpReturn OpFunctionEnd -%190 = OpFunction %2 None %139 -%188 = OpFunctionParameter %4 -%189 = OpFunctionParameter %6 -%187 = OpLabel -OpBranch %191 -%191 = OpLabel -%192 = OpConvertSToF %6 %188 -%193 = OpFDiv %6 %192 %5 -%194 = OpExtInst %6 %1 Sin %193 -%195 = OpFMul %6 %194 %5 -%196 = OpConvertFToS %4 %195 -%197 = OpULessThan %27 %196 %24 -OpSelectionMerge %199 None -OpBranchConditional %197 %200 %199 -%200 = OpLabel -%198 = OpAccessChain %23 %15 %28 %196 -OpStore %198 %189 -OpBranch %199 +%189 = OpFunction %2 None %138 +%187 = OpFunctionParameter %8 +%188 = OpFunctionParameter %6 +%186 = OpLabel +OpBranch %190 +%190 = OpLabel +%191 = OpConvertSToF %6 %187 +%192 = OpFDiv %6 %191 %5 +%193 = OpExtInst %6 %1 Sin %192 +%194 = OpFMul %6 %193 %5 +%195 = OpConvertFToS %8 %194 +%196 = OpULessThan %30 %195 %3 +OpSelectionMerge %198 None +OpBranchConditional %196 %199 %198 %199 = OpLabel +%197 = OpAccessChain %28 %22 %31 %195 +OpStore %197 %188 +OpBranch %198 +%198 = OpLabel OpReturn OpFunctionEnd -%203 = OpFunction %2 None %204 -%202 = OpFunctionParameter %6 -%201 = OpLabel -OpBranch %205 -%205 = OpLabel -%206 = OpAccessChain %23 %15 %28 %126 -OpStore %206 %202 -%207 = OpAccessChain %54 %15 %57 %42 -OpStore %207 %202 -%208 = OpAccessChain %54 %15 %84 %84 %42 -OpStore %208 %202 +%202 = OpFunction %2 None %203 +%201 = OpFunctionParameter %6 +%200 = OpLabel +OpBranch %204 +%204 = OpLabel +%205 = OpAccessChain %28 %22 %31 %125 +OpStore %205 %201 +%206 = OpAccessChain %55 %22 %58 %44 +OpStore %206 %201 +%207 = OpAccessChain %55 %22 %83 %83 %44 +OpStore %207 %201 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/break-if.spvasm b/tests/out/spv/break-if.spvasm index 138fb0b610..7f3c55d006 100644 --- a/tests/out/spv/break-if.spvasm +++ b/tests/out/spv/break-if.spvasm @@ -39,21 +39,21 @@ OpFunctionEnd %16 = OpVariable %14 Function %17 OpBranch %22 %22 = OpLabel -OpBranch %23 -%23 = OpLabel -OpLoopMerge %24 %26 None +%23 = OpLoad %4 %16 +%24 = OpLogicalEqual %4 %19 %23 OpBranch %25 %25 = OpLabel -OpBranch %26 -%26 = OpLabel +OpLoopMerge %26 %28 None +OpBranch %27 +%27 = OpLabel +OpBranch %28 +%28 = OpLabel OpStore %13 %19 -%27 = OpLoad %4 %13 -%28 = OpLogicalNotEqual %4 %19 %27 -OpStore %16 %28 -%29 = OpLoad %4 %16 -%30 = OpLogicalEqual %4 %19 %29 -OpBranchConditional %30 %24 %23 -%24 = OpLabel +%29 = OpLoad %4 %13 +%30 = OpLogicalNotEqual %4 %19 %29 +OpStore %16 %30 +OpBranchConditional %24 %26 %25 +%26 = OpLabel OpReturn OpFunctionEnd %37 = OpFunction %2 None %21 @@ -63,21 +63,21 @@ OpFunctionEnd %33 = OpVariable %14 Function %34 OpBranch %38 %38 = OpLabel -OpBranch %39 -%39 = OpLabel -OpLoopMerge %40 %42 None +%39 = OpLoad %4 %33 +%40 = OpLogicalEqual %4 %36 %39 OpBranch %41 %41 = OpLabel +OpLoopMerge %42 %44 None +OpBranch %43 +%43 = OpLabel OpStore %31 %36 -%43 = OpLoad %4 %31 -%44 = OpLogicalNotEqual %4 %36 %43 -OpStore %33 %44 -OpBranch %42 +%45 = OpLoad %4 %31 +%46 = OpLogicalNotEqual %4 %36 %45 +OpStore %33 %46 +OpBranch %44 +%44 = OpLabel +OpBranchConditional %40 %42 %41 %42 = OpLabel -%45 = OpLoad %4 %33 -%46 = OpLogicalEqual %4 %36 %45 -OpBranchConditional %46 %40 %39 -%40 = OpLabel OpReturn OpFunctionEnd %48 = OpFunction %2 None %7 diff --git a/tests/out/spv/collatz.spvasm b/tests/out/spv/collatz.spvasm index 6e6483da10..381698f983 100644 --- a/tests/out/spv/collatz.spvasm +++ b/tests/out/spv/collatz.spvasm @@ -1,29 +1,34 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 60 +; Bound: 65 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 %55 "main" %52 +OpExecutionMode %55 LocalSize 1 1 1 OpSource GLSL 450 +OpName %4 "u32" +OpName %8 "array" 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 %10 "vec3" +OpName %11 "ptr" +OpName %12 "ptr>" +OpName %13 "v_indices" +OpName %14 "n" +OpName %17 "i" +OpName %20 "n_base" +OpName %21 "collatz_iterations" +OpName %52 "global_id" +OpName %55 "main" OpDecorate %8 ArrayStride 4 OpMemberDecorate %9 0 Offset 0 -OpDecorate %11 DescriptorSet 0 -OpDecorate %11 Binding 0 +OpDecorate %13 DescriptorSet 0 +OpDecorate %13 Binding 0 OpDecorate %9 Block -OpDecorate %46 BuiltIn GlobalInvocationId +OpDecorate %52 BuiltIn GlobalInvocationId %2 = OpTypeVoid %4 = OpTypeInt 32 0 %3 = OpConstant %4 0 @@ -33,75 +38,85 @@ OpDecorate %46 BuiltIn GlobalInvocationId %8 = OpTypeRuntimeArray %4 %9 = OpTypeStruct %8 %10 = OpTypeVector %4 3 -%12 = OpTypePointer StorageBuffer %9 -%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 -%13 = OpVariable %14 Function %15 -%16 = OpVariable %14 Function %3 -OpBranch %21 -%21 = OpLabel -OpStore %13 %18 -OpBranch %22 -%22 = OpLabel -OpLoopMerge %23 %25 None +%11 = OpTypePointer StorageBuffer %9 +%12 = OpTypePointer StorageBuffer %8 +%13 = OpVariable %11 StorageBuffer +%15 = OpTypePointer Function %4 +%16 = OpConstantNull %4 +%18 = OpConstantNull %4 +%22 = OpTypeFunction %4 %4 +%29 = OpTypeBool +%53 = OpTypePointer Input %10 +%52 = OpVariable %53 Input +%56 = OpTypeFunction %2 +%59 = OpTypePointer StorageBuffer %4 +%21 = OpFunction %4 None %22 +%20 = OpFunctionParameter %4 +%19 = OpLabel +%14 = OpVariable %15 Function %16 +%17 = OpVariable %15 Function %18 +OpBranch %23 +%23 = OpLabel +OpStore %14 %20 +OpStore %17 %3 OpBranch %24 %24 = OpLabel -%26 = OpLoad %4 %13 -%28 = OpUGreaterThan %27 %26 %5 -OpSelectionMerge %29 None -OpBranchConditional %28 %29 %30 -%30 = OpLabel -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 +OpLoopMerge %25 %27 None +OpBranch %26 +%26 = OpLabel +%28 = OpLoad %4 %14 +%30 = OpUGreaterThan %29 %28 %5 +OpSelectionMerge %31 None +OpBranchConditional %30 %31 %32 +%32 = OpLabel +OpBranch %25 +%31 = OpLabel +OpBranch %33 +%33 = OpLabel +%35 = OpLoad %4 %14 +%36 = OpUMod %4 %35 %6 +%37 = OpIEqual %29 %36 %3 +OpSelectionMerge %38 None +OpBranchConditional %37 %39 %40 +%39 = OpLabel +%41 = OpLoad %4 %14 +%42 = OpUDiv %4 %41 %6 +OpStore %14 %42 +OpBranch %38 +%40 = OpLabel +OpBranch %43 +%43 = OpLabel +%45 = OpLoad %4 %14 +%46 = OpIMul %4 %7 %45 +%47 = OpIAdd %4 %46 %5 +OpStore %14 %47 +OpBranch %44 +%44 = OpLabel +OpBranch %38 +%38 = OpLabel +%48 = OpLoad %4 %17 +%49 = OpIAdd %4 %48 %5 +OpStore %17 %49 OpBranch %34 %34 = OpLabel -%42 = OpLoad %4 %16 -%43 = OpIAdd %4 %42 %5 -OpStore %16 %43 -OpBranch %25 +OpBranch %27 +%27 = OpLabel +OpBranch %24 %25 = OpLabel -OpBranch %22 -%23 = OpLabel -%44 = OpLoad %4 %16 -OpReturnValue %44 +%50 = OpLoad %4 %17 +OpReturnValue %50 OpFunctionEnd -%49 = OpFunction %2 None %50 -%45 = OpLabel -%48 = OpLoad %10 %46 -OpBranch %51 +%55 = OpFunction %2 None %56 %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 +%54 = OpLoad %10 %52 +OpBranch %57 +%57 = OpLabel +%58 = OpCompositeExtract %4 %54 0 +%60 = OpAccessChain %59 %13 %3 %58 +%61 = OpLoad %4 %60 +%62 = OpFunctionCall %4 %21 %61 +%63 = OpCompositeExtract %4 %54 0 +%64 = OpAccessChain %59 %13 %3 %63 +OpStore %64 %62 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/control-flow.spvasm b/tests/out/spv/control-flow.spvasm index dfd1b145a2..ddc12692be 100644 --- a/tests/out/spv/control-flow.spvasm +++ b/tests/out/spv/control-flow.spvasm @@ -101,10 +101,10 @@ OpStore %37 %3 OpBranch %53 %57 = OpLabel OpStore %37 %6 -OpBranch %58 +OpBranch %53 %58 = OpLabel OpStore %37 %7 -OpBranch %54 +OpBranch %53 %54 = OpLabel OpStore %37 %8 OpBranch %53 @@ -127,7 +127,7 @@ OpStore %37 %3 OpReturn %67 = OpLabel OpStore %37 %6 -OpBranch %68 +OpReturn %68 = OpLabel OpReturn %64 = OpLabel diff --git a/tests/out/spv/extra.spvasm b/tests/out/spv/extra.spvasm index 99a367c64e..06a3124d62 100644 --- a/tests/out/spv/extra.spvasm +++ b/tests/out/spv/extra.spvasm @@ -1,24 +1,24 @@ ; SPIR-V ; Version: 1.2 ; Generator: rspirv -; Bound: 48 +; Bound: 50 OpCapability Shader OpCapability Float64 OpCapability Geometry %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Fragment %24 "main" %16 %19 %22 -OpExecutionMode %24 OriginUpperLeft +OpEntryPoint Fragment %26 "main" %18 %21 %24 +OpExecutionMode %26 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 %14 Block +OpMemberDecorate %14 0 Offset 0 +OpDecorate %18 Location 0 +OpDecorate %21 BuiltIn PrimitiveId +OpDecorate %21 Flat +OpDecorate %24 Location 0 %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -28,49 +28,53 @@ 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 = OpTypePointer PushConstant %8 +%12 = OpTypeVector %4 3 +%14 = OpTypeStruct %8 +%15 = OpTypePointer PushConstant %14 +%13 = OpVariable %15 PushConstant +%19 = OpTypePointer Input %9 +%18 = OpVariable %19 Input +%22 = OpTypePointer Input %5 +%21 = OpVariable %22 Input +%25 = OpTypePointer Output %9 +%24 = OpVariable %25 Output +%27 = OpTypeFunction %2 +%28 = OpConstant %5 0 +%32 = OpTypePointer PushConstant %5 +%35 = OpTypeBool +%26 = OpFunction %2 None %27 +%16 = OpLabel +%20 = OpLoad %9 %18 +%23 = OpLoad %5 %21 +%17 = OpCompositeConstruct %10 %20 %23 +%29 = OpAccessChain %11 %13 %28 +OpBranch %30 +%30 = OpLabel +%31 = OpCompositeExtract %5 %17 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 -%46 = OpCompositeExtract %4 %45 3 -%47 = OpCompositeConstruct %9 %44 %46 -OpStore %22 %47 +%40 = OpCompositeExtract %9 %17 0 +OpStore %24 %40 OpReturn -%36 = OpLabel +%39 = OpLabel +OpBranch %41 +%41 = OpLabel +%43 = OpCompositeConstruct %12 %3 %3 %3 +%44 = OpCompositeExtract %9 %17 0 +%45 = OpVectorShuffle %12 %44 %44 0 1 2 +%46 = OpFSub %12 %43 %45 +%47 = OpCompositeExtract %9 %17 0 +%48 = OpCompositeExtract %4 %47 3 +%49 = OpCompositeConstruct %9 %46 %48 +OpStore %24 %49 +OpReturn +%42 = OpLabel +OpBranch %37 +%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..26ed98a1e5 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 %120 "main" +OpExecutionMode %120 LocalSize 1 1 1 OpDecorate %25 ArrayStride 4 OpMemberDecorate %27 0 Offset 0 OpMemberDecorate %27 1 Offset 12 @@ -17,223 +17,229 @@ OpDecorate %34 ArrayStride 32 OpDecorate %35 ArrayStride 64 OpDecorate %37 ArrayStride 32 OpDecorate %38 ArrayStride 64 -OpDecorate %46 DescriptorSet 0 -OpDecorate %46 Binding 1 -OpDecorate %47 Block -OpMemberDecorate %47 0 Offset 0 -OpDecorate %49 NonWritable -OpDecorate %49 DescriptorSet 0 -OpDecorate %49 Binding 2 -OpDecorate %50 Block -OpMemberDecorate %50 0 Offset 0 -OpDecorate %52 DescriptorSet 0 -OpDecorate %52 Binding 3 -OpDecorate %53 Block -OpMemberDecorate %53 0 Offset 0 -OpDecorate %55 DescriptorSet 0 -OpDecorate %55 Binding 4 -OpDecorate %56 Block -OpMemberDecorate %56 0 Offset 0 -OpDecorate %58 DescriptorSet 0 -OpDecorate %58 Binding 5 -OpDecorate %59 Block -OpMemberDecorate %59 0 Offset 0 -OpMemberDecorate %59 0 ColMajor -OpMemberDecorate %59 0 MatrixStride 8 -OpDecorate %61 DescriptorSet 0 -OpDecorate %61 Binding 6 -OpDecorate %62 Block -OpMemberDecorate %62 0 Offset 0 -OpDecorate %64 DescriptorSet 0 -OpDecorate %64 Binding 7 -OpDecorate %65 Block -OpMemberDecorate %65 0 Offset 0 +OpDecorate %57 DescriptorSet 0 +OpDecorate %57 Binding 1 +OpDecorate %58 Block +OpMemberDecorate %58 0 Offset 0 +OpDecorate %60 NonWritable +OpDecorate %60 DescriptorSet 0 +OpDecorate %60 Binding 2 +OpDecorate %61 Block +OpMemberDecorate %61 0 Offset 0 +OpDecorate %63 DescriptorSet 0 +OpDecorate %63 Binding 3 +OpDecorate %64 Block +OpMemberDecorate %64 0 Offset 0 +OpDecorate %66 DescriptorSet 0 +OpDecorate %66 Binding 4 +OpDecorate %67 Block +OpMemberDecorate %67 0 Offset 0 +OpDecorate %69 DescriptorSet 0 +OpDecorate %69 Binding 5 +OpDecorate %70 Block +OpMemberDecorate %70 0 Offset 0 +OpMemberDecorate %70 0 ColMajor +OpMemberDecorate %70 0 MatrixStride 8 +OpDecorate %72 DescriptorSet 0 +OpDecorate %72 Binding 6 +OpDecorate %73 Block +OpMemberDecorate %73 0 Offset 0 +OpDecorate %75 DescriptorSet 0 +OpDecorate %75 Binding 7 +OpDecorate %76 Block +OpMemberDecorate %76 0 Offset 0 %2 = OpTypeVoid %4 = OpTypeBool %3 = OpConstantTrue %4 %6 = OpTypeInt 32 0 %5 = OpConstant %6 10 -%8 = OpTypeInt 32 1 -%7 = OpConstant %8 20 -%9 = OpConstant %8 2 -%11 = OpTypeFloat 32 -%10 = OpConstant %11 1.0 -%12 = OpConstant %8 1 -%13 = OpConstant %8 0 -%14 = OpConstant %11 2.0 -%15 = OpConstant %11 3.0 -%16 = OpConstant %11 0.0 -%17 = OpConstant %8 7 -%18 = OpConstant %8 6 -%19 = OpConstant %8 5 -%20 = OpConstant %8 4 -%21 = OpConstant %8 3 -%22 = OpConstant %11 4.0 -%23 = OpConstant %6 2 +%7 = OpConstant %6 20 +%8 = OpConstant %6 2 +%10 = OpTypeFloat 32 +%9 = OpConstant %10 1.0 +%12 = OpTypeInt 32 1 +%11 = OpConstant %12 1 +%13 = OpConstant %12 0 +%14 = OpConstant %10 2.0 +%15 = OpConstant %10 3.0 +%16 = OpConstant %10 0.0 +%17 = OpConstant %12 7 +%18 = OpConstant %12 6 +%19 = OpConstant %12 5 +%20 = OpConstant %12 4 +%21 = OpConstant %12 3 +%22 = OpConstant %12 2 +%23 = OpConstant %10 4.0 %24 = OpConstantTrue %4 -%25 = OpTypeArray %11 %5 -%26 = OpTypeVector %11 3 -%27 = OpTypeStruct %26 %11 -%28 = OpTypeVector %11 2 +%25 = OpTypeArray %10 %5 +%26 = OpTypeVector %10 3 +%27 = OpTypeStruct %26 %10 +%28 = OpTypeVector %10 2 %29 = OpTypeRuntimeArray %28 -%30 = OpTypeVector %11 4 +%30 = OpTypeVector %10 4 %31 = OpTypeArray %30 %7 %32 = OpTypeMatrix %28 3 %33 = OpTypeMatrix %30 2 -%34 = OpTypeArray %33 %9 -%35 = OpTypeArray %34 %9 +%34 = OpTypeArray %33 %8 +%35 = OpTypeArray %34 %8 %36 = OpTypeMatrix %28 4 -%37 = OpTypeArray %36 %9 -%38 = OpTypeArray %37 %9 -%39 = OpTypeMatrix %26 3 -%40 = OpConstantComposite %26 %16 %16 %16 -%41 = OpConstantComposite %39 %40 %40 %40 -%43 = OpTypePointer Workgroup %25 -%42 = OpVariable %43 Workgroup -%45 = OpTypePointer Workgroup %6 -%44 = OpVariable %45 Workgroup -%47 = OpTypeStruct %27 -%48 = OpTypePointer StorageBuffer %47 -%46 = OpVariable %48 StorageBuffer -%50 = OpTypeStruct %29 -%51 = OpTypePointer StorageBuffer %50 -%49 = OpVariable %51 StorageBuffer -%53 = OpTypeStruct %31 -%54 = OpTypePointer Uniform %53 -%52 = OpVariable %54 Uniform -%56 = OpTypeStruct %26 -%57 = OpTypePointer Uniform %56 -%55 = OpVariable %57 Uniform -%59 = OpTypeStruct %32 -%60 = OpTypePointer Uniform %59 -%58 = OpVariable %60 Uniform -%62 = OpTypeStruct %35 -%63 = OpTypePointer Uniform %62 -%61 = OpVariable %63 Uniform -%65 = OpTypeStruct %38 -%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 -%69 = OpFunction %2 None %70 -%68 = OpFunctionParameter %26 -%67 = OpLabel -OpBranch %78 +%37 = OpTypeArray %36 %8 +%38 = OpTypeArray %37 %8 +%39 = OpTypePointer StorageBuffer %27 +%40 = OpTypePointer StorageBuffer %26 +%41 = OpTypeMatrix %26 3 +%42 = OpTypePointer Uniform %38 +%43 = OpTypePointer Uniform %37 +%44 = OpTypePointer Uniform %35 +%45 = OpTypePointer Uniform %34 +%46 = OpTypePointer Uniform %33 +%47 = OpTypePointer Workgroup %25 +%48 = OpTypePointer StorageBuffer %29 +%49 = OpTypePointer StorageBuffer %28 +%50 = OpTypePointer Uniform %31 +%51 = OpTypePointer Uniform %30 +%52 = OpTypePointer Workgroup %6 +%53 = OpConstantComposite %26 %16 %16 %16 +%54 = OpConstantComposite %41 %53 %53 %53 +%55 = OpVariable %47 Workgroup +%56 = OpVariable %52 Workgroup +%58 = OpTypeStruct %27 +%59 = OpTypePointer StorageBuffer %58 +%57 = OpVariable %59 StorageBuffer +%61 = OpTypeStruct %29 +%62 = OpTypePointer StorageBuffer %61 +%60 = OpVariable %62 StorageBuffer +%64 = OpTypeStruct %31 +%65 = OpTypePointer Uniform %64 +%63 = OpVariable %65 Uniform +%67 = OpTypeStruct %26 +%68 = OpTypePointer Uniform %67 +%66 = OpVariable %68 Uniform +%70 = OpTypeStruct %32 +%71 = OpTypePointer Uniform %70 +%69 = OpVariable %71 Uniform +%73 = OpTypeStruct %35 +%74 = OpTypePointer Uniform %73 +%72 = OpVariable %74 Uniform +%76 = OpTypeStruct %38 +%77 = OpTypePointer Uniform %76 +%75 = OpVariable %77 Uniform +%81 = OpTypeFunction %2 %26 +%84 = OpTypePointer Function %12 +%85 = OpConstantNull %12 +%88 = OpTypeFunction %2 +%89 = OpConstant %6 0 +%94 = OpTypePointer StorageBuffer %10 +%114 = OpTypePointer Function %10 +%115 = OpConstantNull %10 +%117 = OpTypePointer Function %4 +%118 = OpConstantNull %4 +%124 = OpTypePointer Uniform %26 +%126 = OpTypePointer Uniform %32 +%132 = OpTypePointer Uniform %36 +%135 = OpTypePointer Uniform %30 +%140 = OpTypePointer Workgroup %10 +%141 = OpConstant %6 7 +%147 = OpConstant %6 6 +%149 = OpConstant %6 1 +%152 = OpConstant %6 5 +%154 = OpTypePointer Uniform %10 +%155 = OpConstant %6 3 +%158 = OpConstant %6 4 +%160 = OpTypePointer StorageBuffer %10 +%171 = OpConstant %6 256 +%80 = OpFunction %2 None %81 +%79 = OpFunctionParameter %26 %78 = OpLabel +OpBranch %82 +%82 = OpLabel OpReturn OpFunctionEnd -%82 = OpFunction %2 None %83 -%81 = OpLabel -%79 = OpVariable %80 Function %12 -%85 = OpAccessChain %73 %46 %84 -OpBranch %86 +%87 = OpFunction %2 None %88 %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 = OpVariable %84 Function %85 +%90 = OpAccessChain %39 %57 %89 +OpBranch %91 +%91 = OpLabel +%92 = OpCompositeConstruct %26 %9 %9 %9 +%93 = OpAccessChain %40 %90 %89 +OpStore %93 %92 +OpStore %83 %11 +%95 = OpAccessChain %94 %90 %89 %89 +OpStore %95 %9 +%96 = OpAccessChain %94 %90 %89 %89 +OpStore %96 %14 +%97 = OpLoad %12 %83 +%98 = OpAccessChain %94 %90 %89 %97 +OpStore %98 %15 +%99 = OpLoad %27 %90 +%100 = OpCompositeExtract %26 %99 0 +%101 = OpCompositeExtract %26 %99 0 +%102 = OpVectorShuffle %28 %101 %101 2 0 +%103 = OpCompositeExtract %26 %99 0 +%104 = OpFunctionCall %2 %80 %103 +%105 = OpCompositeExtract %26 %99 0 +%106 = OpVectorTimesMatrix %26 %105 %54 +%107 = OpCompositeExtract %26 %99 0 +%108 = OpMatrixTimesVector %26 %54 %107 +%109 = OpCompositeExtract %26 %99 0 +%110 = OpVectorTimesScalar %26 %109 %14 +%111 = OpCompositeExtract %26 %99 0 +%112 = OpVectorTimesScalar %26 %111 %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 -%162 = OpLoad %11 %161 -%163 = OpAccessChain %124 %42 %23 +%120 = OpFunction %2 None %88 +%119 = OpLabel +%113 = OpVariable %114 Function %115 +%116 = OpVariable %117 Function %118 +%121 = OpAccessChain %39 %57 %89 +%122 = OpAccessChain %48 %60 %89 +%123 = OpAccessChain %50 %63 %89 +%125 = OpAccessChain %124 %66 %89 +%127 = OpAccessChain %126 %69 %89 +%128 = OpAccessChain %44 %72 %89 +%129 = OpAccessChain %42 %75 %89 +OpBranch %130 +%130 = OpLabel +%131 = OpFunctionCall %2 %87 +%133 = OpAccessChain %132 %129 %89 %89 +%134 = OpLoad %36 %133 +%136 = OpAccessChain %135 %128 %89 %89 %89 +%137 = OpLoad %30 %136 +%138 = OpMatrixTimesVector %28 %134 %137 +%139 = OpCompositeExtract %10 %138 0 +%142 = OpAccessChain %140 %55 %141 +OpStore %142 %139 +%143 = OpLoad %32 %127 +%144 = OpLoad %26 %125 +%145 = OpMatrixTimesVector %28 %143 %144 +%146 = OpCompositeExtract %10 %145 0 +%148 = OpAccessChain %140 %55 %147 +OpStore %148 %146 +%150 = OpAccessChain %94 %122 %149 %149 +%151 = OpLoad %10 %150 +%153 = OpAccessChain %140 %55 %152 +OpStore %153 %151 +%156 = OpAccessChain %154 %123 %89 %155 +%157 = OpLoad %10 %156 +%159 = OpAccessChain %140 %55 %158 +OpStore %159 %157 +%161 = OpAccessChain %160 %121 %149 +%162 = OpLoad %10 %161 +%163 = OpAccessChain %140 %55 %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 %94 %121 %89 %89 +%165 = OpLoad %10 %164 +%166 = OpAccessChain %140 %55 %8 +OpStore %166 %165 +%167 = OpAccessChain %160 %121 %149 +OpStore %167 %23 +%168 = OpArrayLength %6 %60 0 +%169 = OpConvertUToF %10 %168 +%170 = OpAccessChain %140 %55 %149 +OpStore %170 %169 +OpAtomicStore %56 %22 %171 %8 +OpStore %113 %9 +OpStore %116 %24 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/image.spvasm b/tests/out/spv/image.spvasm index f0556d35d4..b51fe9edd4 100644 --- a/tests/out/spv/image.spvasm +++ b/tests/out/spv/image.spvasm @@ -9,97 +9,127 @@ OpCapability Shader OpCapability Sampled1D %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %76 "main" %73 -OpEntryPoint GLCompute %121 "depth_load" %119 -OpEntryPoint Vertex %142 "queries" %140 -OpEntryPoint Vertex %194 "levels_queries" %193 -OpEntryPoint Fragment %223 "texture_sample" %222 -OpEntryPoint Fragment %252 "texture_sample_comparison" %250 +OpEntryPoint GLCompute %81 "main" %78 +OpEntryPoint GLCompute %123 "depth_load" %121 +OpEntryPoint Vertex %144 "queries" %142 +OpEntryPoint Vertex %196 "levels_queries" %195 +OpEntryPoint Fragment %225 "texture_sample" %224 +OpEntryPoint Fragment %253 "texture_sample_comparison" %251 OpEntryPoint Fragment %272 "gather" %271 OpEntryPoint Fragment %294 "depth_no_comparison" %293 -OpExecutionMode %76 LocalSize 16 1 1 -OpExecutionMode %121 LocalSize 16 1 1 -OpExecutionMode %223 OriginUpperLeft -OpExecutionMode %252 OriginUpperLeft +OpExecutionMode %81 LocalSize 16 1 1 +OpExecutionMode %123 LocalSize 16 1 1 +OpExecutionMode %225 OriginUpperLeft +OpExecutionMode %253 OriginUpperLeft OpExecutionMode %272 OriginUpperLeft OpExecutionMode %294 OriginUpperLeft OpSource GLSL 450 -OpName %34 "image_mipmapped_src" -OpName %36 "image_multisampled_src" -OpName %38 "image_depth_multisampled_src" -OpName %40 "image_storage_src" -OpName %42 "image_array_src" -OpName %44 "image_dup_src" -OpName %46 "image_1d_src" -OpName %48 "image_dst" -OpName %50 "image_1d" -OpName %52 "image_2d" -OpName %54 "image_2d_array" -OpName %56 "image_cube" -OpName %58 "image_cube_array" -OpName %60 "image_3d" -OpName %62 "image_aa" -OpName %64 "sampler_reg" -OpName %66 "sampler_cmp" -OpName %68 "image_2d_depth" -OpName %70 "image_cube_depth" -OpName %73 "local_id" -OpName %76 "main" -OpName %119 "local_id" -OpName %121 "depth_load" -OpName %142 "queries" -OpName %194 "levels_queries" -OpName %223 "texture_sample" -OpName %252 "texture_sample_comparison" +OpName %12 "texture_2d" +OpName %14 "texture_multisampled_2d" +OpName %15 "texture_depth_multisampled_2d" +OpName %16 "texture_storage_2d" +OpName %17 "texture_2d_array" +OpName %18 "texture_storage_1d" +OpName %19 "texture_1d" +OpName %18 "texture_storage_1d" +OpName %20 "vec3" +OpName %21 "vec2" +OpName %22 "vec2" +OpName %4 "i32" +OpName %13 "u32" +OpName %23 "vec4" +OpName %8 "f32" +OpName %24 "texture_1d" +OpName %25 "texture_2d" +OpName %26 "texture_2d_array" +OpName %27 "texture_cube" +OpName %28 "texture_cube_array" +OpName %29 "texture_3d" +OpName %30 "texture_multisampled_2d" +OpName %31 "vec4" +OpName %32 "vec3" +OpName %33 "sampler" +OpName %34 "vec2" +OpName %33 "sampler_comparison" +OpName %35 "texture_depth_2d" +OpName %36 "texture_depth_cube" +OpName %37 "vec3" +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_array" +OpName %61 "image_cube" +OpName %63 "image_cube_array" +OpName %65 "image_3d" +OpName %67 "image_aa" +OpName %69 "sampler_reg" +OpName %71 "sampler_cmp" +OpName %73 "image_2d_depth" +OpName %75 "image_cube_depth" +OpName %78 "local_id" +OpName %81 "main" +OpName %121 "local_id" +OpName %123 "depth_load" +OpName %144 "queries" +OpName %196 "levels_queries" +OpName %225 "texture_sample" +OpName %253 "texture_sample_comparison" OpName %272 "gather" OpName %294 "depth_no_comparison" -OpDecorate %34 DescriptorSet 0 -OpDecorate %34 Binding 0 -OpDecorate %36 DescriptorSet 0 -OpDecorate %36 Binding 3 -OpDecorate %38 DescriptorSet 0 -OpDecorate %38 Binding 4 -OpDecorate %40 NonWritable -OpDecorate %40 DescriptorSet 0 -OpDecorate %40 Binding 1 -OpDecorate %42 DescriptorSet 0 -OpDecorate %42 Binding 5 -OpDecorate %44 NonWritable -OpDecorate %44 DescriptorSet 0 -OpDecorate %44 Binding 6 -OpDecorate %46 DescriptorSet 0 -OpDecorate %46 Binding 7 -OpDecorate %48 NonReadable -OpDecorate %48 DescriptorSet 0 -OpDecorate %48 Binding 2 -OpDecorate %50 DescriptorSet 0 -OpDecorate %50 Binding 0 -OpDecorate %52 DescriptorSet 0 -OpDecorate %52 Binding 1 -OpDecorate %54 DescriptorSet 0 -OpDecorate %54 Binding 2 -OpDecorate %56 DescriptorSet 0 -OpDecorate %56 Binding 3 -OpDecorate %58 DescriptorSet 0 -OpDecorate %58 Binding 4 -OpDecorate %60 DescriptorSet 0 -OpDecorate %60 Binding 5 -OpDecorate %62 DescriptorSet 0 -OpDecorate %62 Binding 6 -OpDecorate %64 DescriptorSet 1 -OpDecorate %64 Binding 0 -OpDecorate %66 DescriptorSet 1 -OpDecorate %66 Binding 1 -OpDecorate %68 DescriptorSet 1 -OpDecorate %68 Binding 2 -OpDecorate %70 DescriptorSet 1 -OpDecorate %70 Binding 3 -OpDecorate %73 BuiltIn LocalInvocationId -OpDecorate %119 BuiltIn LocalInvocationId -OpDecorate %140 BuiltIn Position -OpDecorate %193 BuiltIn Position -OpDecorate %222 Location 0 -OpDecorate %250 Location 0 +OpDecorate %39 DescriptorSet 0 +OpDecorate %39 Binding 0 +OpDecorate %41 DescriptorSet 0 +OpDecorate %41 Binding 3 +OpDecorate %43 DescriptorSet 0 +OpDecorate %43 Binding 4 +OpDecorate %45 NonWritable +OpDecorate %45 DescriptorSet 0 +OpDecorate %45 Binding 1 +OpDecorate %47 DescriptorSet 0 +OpDecorate %47 Binding 5 +OpDecorate %49 NonWritable +OpDecorate %49 DescriptorSet 0 +OpDecorate %49 Binding 6 +OpDecorate %51 DescriptorSet 0 +OpDecorate %51 Binding 7 +OpDecorate %53 NonReadable +OpDecorate %53 DescriptorSet 0 +OpDecorate %53 Binding 2 +OpDecorate %55 DescriptorSet 0 +OpDecorate %55 Binding 0 +OpDecorate %57 DescriptorSet 0 +OpDecorate %57 Binding 1 +OpDecorate %59 DescriptorSet 0 +OpDecorate %59 Binding 2 +OpDecorate %61 DescriptorSet 0 +OpDecorate %61 Binding 3 +OpDecorate %63 DescriptorSet 0 +OpDecorate %63 Binding 4 +OpDecorate %65 DescriptorSet 0 +OpDecorate %65 Binding 5 +OpDecorate %67 DescriptorSet 0 +OpDecorate %67 Binding 6 +OpDecorate %69 DescriptorSet 1 +OpDecorate %69 Binding 0 +OpDecorate %71 DescriptorSet 1 +OpDecorate %71 Binding 1 +OpDecorate %73 DescriptorSet 1 +OpDecorate %73 Binding 2 +OpDecorate %75 DescriptorSet 1 +OpDecorate %75 Binding 3 +OpDecorate %78 BuiltIn LocalInvocationId +OpDecorate %121 BuiltIn LocalInvocationId +OpDecorate %142 BuiltIn Position +OpDecorate %195 BuiltIn Position +OpDecorate %224 Location 0 +OpDecorate %251 Location 0 OpDecorate %271 Location 0 OpDecorate %293 Location 0 %2 = OpTypeVoid @@ -121,319 +151,319 @@ OpDecorate %293 Location 0 %18 = OpTypeImage %13 1D 0 0 0 2 R32ui %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 %8 2D 0 1 0 1 Unknown -%25 = OpTypeImage %8 Cube 0 0 0 1 Unknown -%26 = OpTypeImage %8 Cube 0 1 0 1 Unknown -%27 = OpTypeImage %8 3D 0 0 0 1 Unknown -%28 = OpTypeImage %8 2D 0 0 1 1 Unknown -%29 = OpTypeVector %8 4 -%30 = OpTypeSampler -%31 = OpTypeImage %8 2D 1 0 0 1 Unknown -%32 = OpTypeImage %8 Cube 1 0 0 1 Unknown -%33 = OpConstantComposite %21 %10 %6 -%35 = OpTypePointer UniformConstant %12 -%34 = OpVariable %35 UniformConstant -%37 = OpTypePointer UniformConstant %14 -%36 = OpVariable %37 UniformConstant -%39 = OpTypePointer UniformConstant %15 -%38 = OpVariable %39 UniformConstant -%41 = OpTypePointer UniformConstant %16 -%40 = OpVariable %41 UniformConstant -%43 = OpTypePointer UniformConstant %17 -%42 = OpVariable %43 UniformConstant -%45 = OpTypePointer UniformConstant %18 -%44 = OpVariable %45 UniformConstant -%47 = OpTypePointer UniformConstant %19 -%46 = OpVariable %47 UniformConstant -%49 = OpTypePointer UniformConstant %18 -%48 = OpVariable %49 UniformConstant -%51 = OpTypePointer UniformConstant %22 -%50 = OpVariable %51 UniformConstant -%53 = OpTypePointer UniformConstant %23 -%52 = OpVariable %53 UniformConstant -%55 = OpTypePointer UniformConstant %24 -%54 = OpVariable %55 UniformConstant -%57 = OpTypePointer UniformConstant %25 -%56 = OpVariable %57 UniformConstant -%59 = OpTypePointer UniformConstant %26 -%58 = OpVariable %59 UniformConstant -%61 = OpTypePointer UniformConstant %27 -%60 = OpVariable %61 UniformConstant -%63 = OpTypePointer UniformConstant %28 -%62 = OpVariable %63 UniformConstant -%65 = OpTypePointer UniformConstant %30 -%64 = OpVariable %65 UniformConstant -%67 = OpTypePointer UniformConstant %30 -%66 = OpVariable %67 UniformConstant -%69 = OpTypePointer UniformConstant %31 -%68 = OpVariable %69 UniformConstant -%71 = OpTypePointer UniformConstant %32 -%70 = OpVariable %71 UniformConstant -%74 = OpTypePointer Input %20 -%73 = OpVariable %74 Input -%77 = OpTypeFunction %2 -%86 = OpTypeVector %13 2 -%94 = OpTypeVector %13 4 -%105 = OpTypeVector %4 3 -%119 = OpVariable %74 Input -%141 = OpTypePointer Output %29 -%140 = OpVariable %141 Output -%151 = OpConstant %13 0 -%193 = OpVariable %141 Output -%222 = OpVariable %141 Output -%228 = OpTypeVector %8 2 -%231 = OpTypeSampledImage %22 -%234 = OpTypeSampledImage %23 -%251 = OpTypePointer Output %8 -%250 = OpVariable %251 Output -%258 = OpTypeSampledImage %31 -%263 = OpConstant %8 0.0 -%264 = OpTypeVector %8 3 -%266 = OpTypeSampledImage %32 -%271 = OpVariable %141 Output +%21 = OpTypeVector %13 2 +%22 = OpTypeVector %4 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 %8 2D 0 1 0 1 Unknown +%27 = OpTypeImage %8 Cube 0 0 0 1 Unknown +%28 = OpTypeImage %8 Cube 0 1 0 1 Unknown +%29 = OpTypeImage %8 3D 0 0 0 1 Unknown +%30 = OpTypeImage %8 2D 0 0 1 1 Unknown +%31 = OpTypeVector %8 4 +%32 = OpTypeVector %4 3 +%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 %22 %10 %6 +%40 = OpTypePointer UniformConstant %12 +%39 = OpVariable %40 UniformConstant +%42 = OpTypePointer UniformConstant %14 +%41 = OpVariable %42 UniformConstant +%44 = OpTypePointer UniformConstant %15 +%43 = OpVariable %44 UniformConstant +%46 = OpTypePointer UniformConstant %16 +%45 = OpVariable %46 UniformConstant +%48 = OpTypePointer UniformConstant %17 +%47 = OpVariable %48 UniformConstant +%50 = OpTypePointer UniformConstant %18 +%49 = OpVariable %50 UniformConstant +%52 = OpTypePointer UniformConstant %19 +%51 = OpVariable %52 UniformConstant +%54 = OpTypePointer UniformConstant %18 +%53 = OpVariable %54 UniformConstant +%56 = OpTypePointer UniformConstant %24 +%55 = OpVariable %56 UniformConstant +%58 = OpTypePointer UniformConstant %25 +%57 = OpVariable %58 UniformConstant +%60 = OpTypePointer UniformConstant %26 +%59 = OpVariable %60 UniformConstant +%62 = OpTypePointer UniformConstant %27 +%61 = OpVariable %62 UniformConstant +%64 = OpTypePointer UniformConstant %28 +%63 = OpVariable %64 UniformConstant +%66 = OpTypePointer UniformConstant %29 +%65 = OpVariable %66 UniformConstant +%68 = OpTypePointer UniformConstant %30 +%67 = OpVariable %68 UniformConstant +%70 = OpTypePointer UniformConstant %33 +%69 = OpVariable %70 UniformConstant +%72 = OpTypePointer UniformConstant %33 +%71 = OpVariable %72 UniformConstant +%74 = OpTypePointer UniformConstant %35 +%73 = OpVariable %74 UniformConstant +%76 = OpTypePointer UniformConstant %36 +%75 = OpVariable %76 UniformConstant +%79 = OpTypePointer Input %20 +%78 = OpVariable %79 Input +%82 = OpTypeFunction %2 +%121 = OpVariable %79 Input +%143 = OpTypePointer Output %31 +%142 = OpVariable %143 Output +%153 = OpConstant %13 0 +%195 = OpVariable %143 Output +%224 = OpVariable %143 Output +%232 = OpTypeSampledImage %24 +%235 = OpTypeSampledImage %25 +%252 = OpTypePointer Output %8 +%251 = OpVariable %252 Output +%259 = OpTypeSampledImage %35 +%264 = OpConstant %8 0.0 +%266 = OpTypeSampledImage %36 +%271 = OpVariable %143 Output %281 = OpConstant %13 1 %284 = OpConstant %13 3 -%293 = OpVariable %141 Output -%76 = OpFunction %2 None %77 -%72 = OpLabel -%75 = OpLoad %20 %73 -%78 = OpLoad %12 %34 -%79 = OpLoad %14 %36 -%80 = OpLoad %16 %40 -%81 = OpLoad %17 %42 -%82 = OpLoad %19 %46 -%83 = OpLoad %18 %48 -OpBranch %84 -%84 = OpLabel -%85 = OpImageQuerySize %21 %80 -%87 = OpVectorShuffle %86 %75 %75 0 1 -%88 = OpBitcast %21 %87 -%89 = OpIMul %21 %85 %88 -%90 = OpCompositeConstruct %21 %3 %5 -%91 = OpSRem %21 %89 %90 -%92 = OpCompositeExtract %13 %75 2 -%93 = OpBitcast %4 %92 -%95 = OpImageFetch %94 %78 %91 Lod %93 -%96 = OpCompositeExtract %13 %75 2 +%293 = OpVariable %143 Output +%81 = OpFunction %2 None %82 +%77 = OpLabel +%80 = OpLoad %20 %78 +%83 = OpLoad %12 %39 +%84 = OpLoad %14 %41 +%85 = OpLoad %16 %45 +%86 = OpLoad %17 %47 +%87 = OpLoad %19 %51 +%88 = OpLoad %18 %53 +OpBranch %89 +%89 = OpLabel +%90 = OpImageQuerySize %22 %85 +%91 = OpVectorShuffle %21 %80 %80 0 1 +%92 = OpBitcast %22 %91 +%93 = OpIMul %22 %90 %92 +%94 = OpCompositeConstruct %22 %3 %5 +%95 = OpSRem %22 %93 %94 +%96 = OpCompositeExtract %13 %80 2 %97 = OpBitcast %4 %96 -%98 = OpImageFetch %94 %79 %91 Sample %97 -%99 = OpImageRead %94 %80 %91 -%100 = OpCompositeExtract %13 %75 2 -%101 = OpBitcast %4 %100 -%102 = OpCompositeExtract %13 %75 2 -%103 = OpBitcast %4 %102 -%104 = OpIAdd %4 %103 %6 -%106 = OpCompositeConstruct %105 %91 %101 -%107 = OpImageFetch %94 %81 %106 Lod %104 -%108 = OpCompositeExtract %13 %75 0 -%109 = OpBitcast %4 %108 -%110 = OpCompositeExtract %13 %75 2 +%98 = OpImageFetch %23 %83 %95 Lod %97 +%99 = OpCompositeExtract %13 %80 2 +%100 = OpBitcast %4 %99 +%101 = OpImageFetch %23 %84 %95 Sample %100 +%102 = OpImageRead %23 %85 %95 +%103 = OpCompositeExtract %13 %80 2 +%104 = OpBitcast %4 %103 +%105 = OpCompositeExtract %13 %80 2 +%106 = OpBitcast %4 %105 +%107 = OpIAdd %4 %106 %6 +%108 = OpCompositeConstruct %32 %95 %104 +%109 = OpImageFetch %23 %86 %108 Lod %107 +%110 = OpCompositeExtract %13 %80 0 %111 = OpBitcast %4 %110 -%112 = OpImageFetch %94 %82 %109 Lod %111 -%113 = OpCompositeExtract %4 %91 0 -%114 = OpIAdd %94 %95 %98 -%115 = OpIAdd %94 %114 %99 -%116 = OpIAdd %94 %115 %107 -%117 = OpIAdd %94 %116 %112 -OpImageWrite %83 %113 %117 +%112 = OpCompositeExtract %13 %80 2 +%113 = OpBitcast %4 %112 +%114 = OpImageFetch %23 %87 %111 Lod %113 +%115 = OpCompositeExtract %4 %95 0 +%116 = OpIAdd %23 %98 %101 +%117 = OpIAdd %23 %116 %102 +%118 = OpIAdd %23 %117 %109 +%119 = OpIAdd %23 %118 %114 +OpImageWrite %88 %115 %119 OpReturn OpFunctionEnd -%121 = OpFunction %2 None %77 -%118 = OpLabel -%120 = OpLoad %20 %119 -%122 = OpLoad %15 %38 -%123 = OpLoad %16 %40 -%124 = OpLoad %18 %48 -OpBranch %125 -%125 = OpLabel -%126 = OpImageQuerySize %21 %123 -%127 = OpVectorShuffle %86 %120 %120 0 1 -%128 = OpBitcast %21 %127 -%129 = OpIMul %21 %126 %128 -%130 = OpCompositeConstruct %21 %3 %5 -%131 = OpSRem %21 %129 %130 -%132 = OpCompositeExtract %13 %120 2 -%133 = OpBitcast %4 %132 -%134 = OpImageFetch %29 %122 %131 Sample %133 -%135 = OpCompositeExtract %8 %134 0 -%136 = OpCompositeExtract %4 %131 0 -%137 = OpConvertFToU %13 %135 -%138 = OpCompositeConstruct %94 %137 %137 %137 %137 -OpImageWrite %124 %136 %138 +%123 = OpFunction %2 None %82 +%120 = OpLabel +%122 = OpLoad %20 %121 +%124 = OpLoad %15 %43 +%125 = OpLoad %16 %45 +%126 = OpLoad %18 %53 +OpBranch %127 +%127 = OpLabel +%128 = OpImageQuerySize %22 %125 +%129 = OpVectorShuffle %21 %122 %122 0 1 +%130 = OpBitcast %22 %129 +%131 = OpIMul %22 %128 %130 +%132 = OpCompositeConstruct %22 %3 %5 +%133 = OpSRem %22 %131 %132 +%134 = OpCompositeExtract %13 %122 2 +%135 = OpBitcast %4 %134 +%136 = OpImageFetch %31 %124 %133 Sample %135 +%137 = OpCompositeExtract %8 %136 0 +%138 = OpCompositeExtract %4 %133 0 +%139 = OpConvertFToU %13 %137 +%140 = OpCompositeConstruct %23 %139 %139 %139 %139 +OpImageWrite %126 %138 %140 OpReturn OpFunctionEnd -%142 = OpFunction %2 None %77 -%139 = OpLabel -%143 = OpLoad %22 %50 -%144 = OpLoad %23 %52 -%145 = OpLoad %24 %54 -%146 = OpLoad %25 %56 -%147 = OpLoad %26 %58 -%148 = OpLoad %27 %60 -%149 = OpLoad %28 %62 -OpBranch %150 -%150 = OpLabel -%152 = OpImageQuerySizeLod %4 %143 %151 -%154 = OpImageQuerySizeLod %4 %143 %152 -%155 = OpImageQuerySizeLod %21 %144 %151 -%156 = OpImageQuerySizeLod %21 %144 %6 -%157 = OpImageQuerySizeLod %105 %145 %151 -%158 = OpVectorShuffle %21 %157 %157 0 1 -%159 = OpImageQuerySizeLod %105 %145 %6 -%160 = OpVectorShuffle %21 %159 %159 0 1 -%161 = OpImageQuerySizeLod %21 %146 %151 -%162 = OpImageQuerySizeLod %21 %146 %6 -%163 = OpImageQuerySizeLod %105 %147 %151 -%164 = OpVectorShuffle %21 %163 %163 0 0 -%165 = OpImageQuerySizeLod %105 %147 %6 -%166 = OpVectorShuffle %21 %165 %165 0 0 -%167 = OpImageQuerySizeLod %105 %148 %151 -%168 = OpImageQuerySizeLod %105 %148 %6 -%169 = OpImageQuerySize %21 %149 -%170 = OpCompositeExtract %4 %155 1 -%171 = OpIAdd %4 %152 %170 -%172 = OpCompositeExtract %4 %156 1 -%173 = OpIAdd %4 %171 %172 +%144 = OpFunction %2 None %82 +%141 = OpLabel +%145 = OpLoad %24 %55 +%146 = OpLoad %25 %57 +%147 = OpLoad %26 %59 +%148 = OpLoad %27 %61 +%149 = OpLoad %28 %63 +%150 = OpLoad %29 %65 +%151 = OpLoad %30 %67 +OpBranch %152 +%152 = OpLabel +%154 = OpImageQuerySizeLod %4 %145 %153 +%156 = OpImageQuerySizeLod %4 %145 %154 +%157 = OpImageQuerySizeLod %22 %146 %153 +%158 = OpImageQuerySizeLod %22 %146 %6 +%159 = OpImageQuerySizeLod %32 %147 %153 +%160 = OpVectorShuffle %22 %159 %159 0 1 +%161 = OpImageQuerySizeLod %32 %147 %6 +%162 = OpVectorShuffle %22 %161 %161 0 1 +%163 = OpImageQuerySizeLod %22 %148 %153 +%164 = OpImageQuerySizeLod %22 %148 %6 +%165 = OpImageQuerySizeLod %32 %149 %153 +%166 = OpVectorShuffle %22 %165 %165 0 0 +%167 = OpImageQuerySizeLod %32 %149 %6 +%168 = OpVectorShuffle %22 %167 %167 0 0 +%169 = OpImageQuerySizeLod %32 %150 %153 +%170 = OpImageQuerySizeLod %32 %150 %6 +%171 = OpImageQuerySize %22 %151 +%172 = OpCompositeExtract %4 %157 1 +%173 = OpIAdd %4 %154 %172 %174 = OpCompositeExtract %4 %158 1 %175 = OpIAdd %4 %173 %174 %176 = OpCompositeExtract %4 %160 1 %177 = OpIAdd %4 %175 %176 -%178 = OpCompositeExtract %4 %161 1 +%178 = OpCompositeExtract %4 %162 1 %179 = OpIAdd %4 %177 %178 -%180 = OpCompositeExtract %4 %162 1 +%180 = OpCompositeExtract %4 %163 1 %181 = OpIAdd %4 %179 %180 %182 = OpCompositeExtract %4 %164 1 %183 = OpIAdd %4 %181 %182 %184 = OpCompositeExtract %4 %166 1 %185 = OpIAdd %4 %183 %184 -%186 = OpCompositeExtract %4 %167 2 +%186 = OpCompositeExtract %4 %168 1 %187 = OpIAdd %4 %185 %186 -%188 = OpCompositeExtract %4 %168 2 +%188 = OpCompositeExtract %4 %169 2 %189 = OpIAdd %4 %187 %188 -%190 = OpConvertSToF %8 %189 -%191 = OpCompositeConstruct %29 %190 %190 %190 %190 -OpStore %140 %191 +%190 = OpCompositeExtract %4 %170 2 +%191 = OpIAdd %4 %189 %190 +%192 = OpConvertSToF %8 %191 +%193 = OpCompositeConstruct %31 %192 %192 %192 %192 +OpStore %142 %193 OpReturn OpFunctionEnd -%194 = OpFunction %2 None %77 -%192 = OpLabel -%195 = OpLoad %23 %52 -%196 = OpLoad %24 %54 -%197 = OpLoad %25 %56 -%198 = OpLoad %26 %58 -%199 = OpLoad %27 %60 -%200 = OpLoad %28 %62 -OpBranch %201 -%201 = OpLabel -%202 = OpImageQueryLevels %4 %195 -%203 = OpImageQueryLevels %4 %196 -%204 = OpImageQuerySizeLod %105 %196 %151 -%205 = OpCompositeExtract %4 %204 2 -%206 = OpImageQueryLevels %4 %197 -%207 = OpImageQueryLevels %4 %198 -%208 = OpImageQuerySizeLod %105 %198 %151 -%209 = OpCompositeExtract %4 %208 2 -%210 = OpImageQueryLevels %4 %199 -%211 = OpImageQuerySamples %4 %200 -%212 = OpIAdd %4 %205 %209 -%213 = OpIAdd %4 %212 %211 -%214 = OpIAdd %4 %213 %202 -%215 = OpIAdd %4 %214 %203 -%216 = OpIAdd %4 %215 %210 -%217 = OpIAdd %4 %216 %206 -%218 = OpIAdd %4 %217 %207 -%219 = OpConvertSToF %8 %218 -%220 = OpCompositeConstruct %29 %219 %219 %219 %219 -OpStore %193 %220 +%196 = OpFunction %2 None %82 +%194 = OpLabel +%197 = OpLoad %25 %57 +%198 = OpLoad %26 %59 +%199 = OpLoad %27 %61 +%200 = OpLoad %28 %63 +%201 = OpLoad %29 %65 +%202 = OpLoad %30 %67 +OpBranch %203 +%203 = OpLabel +%204 = OpImageQueryLevels %4 %197 +%205 = OpImageQueryLevels %4 %198 +%206 = OpImageQuerySizeLod %32 %198 %153 +%207 = OpCompositeExtract %4 %206 2 +%208 = OpImageQueryLevels %4 %199 +%209 = OpImageQueryLevels %4 %200 +%210 = OpImageQuerySizeLod %32 %200 %153 +%211 = OpCompositeExtract %4 %210 2 +%212 = OpImageQueryLevels %4 %201 +%213 = OpImageQuerySamples %4 %202 +%214 = OpIAdd %4 %207 %211 +%215 = OpIAdd %4 %214 %213 +%216 = OpIAdd %4 %215 %204 +%217 = OpIAdd %4 %216 %205 +%218 = OpIAdd %4 %217 %212 +%219 = OpIAdd %4 %218 %208 +%220 = OpIAdd %4 %219 %209 +%221 = OpConvertSToF %8 %220 +%222 = OpCompositeConstruct %31 %221 %221 %221 %221 +OpStore %195 %222 OpReturn OpFunctionEnd -%223 = OpFunction %2 None %77 -%221 = OpLabel -%224 = OpLoad %22 %50 -%225 = OpLoad %23 %52 -%226 = OpLoad %30 %64 -OpBranch %227 -%227 = OpLabel -%229 = OpCompositeConstruct %228 %7 %7 -%230 = OpCompositeExtract %8 %229 0 -%232 = OpSampledImage %231 %224 %226 -%233 = OpImageSampleImplicitLod %29 %232 %230 -%235 = OpSampledImage %234 %225 %226 -%236 = OpImageSampleImplicitLod %29 %235 %229 -%237 = OpSampledImage %234 %225 %226 -%238 = OpImageSampleImplicitLod %29 %237 %229 ConstOffset %33 -%239 = OpSampledImage %234 %225 %226 -%240 = OpImageSampleExplicitLod %29 %239 %229 Lod %9 -%241 = OpSampledImage %234 %225 %226 -%242 = OpImageSampleExplicitLod %29 %241 %229 Lod|ConstOffset %9 %33 -%243 = OpSampledImage %234 %225 %226 -%244 = OpImageSampleImplicitLod %29 %243 %229 Bias|ConstOffset %11 %33 -%245 = OpFAdd %29 %233 %236 -%246 = OpFAdd %29 %245 %238 -%247 = OpFAdd %29 %246 %240 -%248 = OpFAdd %29 %247 %242 -OpStore %222 %248 +%225 = OpFunction %2 None %82 +%223 = OpLabel +%226 = OpLoad %24 %55 +%227 = OpLoad %25 %57 +%228 = OpLoad %33 %69 +OpBranch %229 +%229 = OpLabel +%230 = OpCompositeConstruct %34 %7 %7 +%231 = OpCompositeExtract %8 %230 0 +%233 = OpSampledImage %232 %226 %228 +%234 = OpImageSampleImplicitLod %31 %233 %231 +%236 = OpSampledImage %235 %227 %228 +%237 = OpImageSampleImplicitLod %31 %236 %230 +%238 = OpSampledImage %235 %227 %228 +%239 = OpImageSampleImplicitLod %31 %238 %230 ConstOffset %38 +%240 = OpSampledImage %235 %227 %228 +%241 = OpImageSampleExplicitLod %31 %240 %230 Lod %9 +%242 = OpSampledImage %235 %227 %228 +%243 = OpImageSampleExplicitLod %31 %242 %230 Lod|ConstOffset %9 %38 +%244 = OpSampledImage %235 %227 %228 +%245 = OpImageSampleImplicitLod %31 %244 %230 Bias|ConstOffset %11 %38 +%246 = OpFAdd %31 %234 %237 +%247 = OpFAdd %31 %246 %239 +%248 = OpFAdd %31 %247 %241 +%249 = OpFAdd %31 %248 %243 +OpStore %224 %249 OpReturn OpFunctionEnd -%252 = OpFunction %2 None %77 -%249 = OpLabel -%253 = OpLoad %30 %66 -%254 = OpLoad %31 %68 -%255 = OpLoad %32 %70 -OpBranch %256 -%256 = OpLabel -%257 = OpCompositeConstruct %228 %7 %7 -%259 = OpSampledImage %258 %254 %253 -%260 = OpImageSampleDrefImplicitLod %8 %259 %257 %7 -%261 = OpSampledImage %258 %254 %253 -%262 = OpImageSampleDrefExplicitLod %8 %261 %257 %7 Lod %263 -%265 = OpCompositeConstruct %264 %7 %7 %7 -%267 = OpSampledImage %266 %255 %253 -%268 = OpImageSampleDrefExplicitLod %8 %267 %265 %7 Lod %263 -%269 = OpFAdd %8 %260 %262 -OpStore %250 %269 +%253 = OpFunction %2 None %82 +%250 = OpLabel +%254 = OpLoad %33 %71 +%255 = OpLoad %35 %73 +%256 = OpLoad %36 %75 +OpBranch %257 +%257 = OpLabel +%258 = OpCompositeConstruct %34 %7 %7 +%260 = OpSampledImage %259 %255 %254 +%261 = OpImageSampleDrefImplicitLod %8 %260 %258 %7 +%262 = OpSampledImage %259 %255 %254 +%263 = OpImageSampleDrefExplicitLod %8 %262 %258 %7 Lod %264 +%265 = OpCompositeConstruct %37 %7 %7 %7 +%267 = OpSampledImage %266 %256 %254 +%268 = OpImageSampleDrefExplicitLod %8 %267 %265 %7 Lod %264 +%269 = OpFAdd %8 %261 %263 +OpStore %251 %269 OpReturn OpFunctionEnd -%272 = OpFunction %2 None %77 +%272 = OpFunction %2 None %82 %270 = OpLabel -%273 = OpLoad %23 %52 -%274 = OpLoad %30 %64 -%275 = OpLoad %30 %66 -%276 = OpLoad %31 %68 +%273 = OpLoad %25 %57 +%274 = OpLoad %33 %69 +%275 = OpLoad %33 %71 +%276 = OpLoad %35 %73 OpBranch %277 %277 = OpLabel -%278 = OpCompositeConstruct %228 %7 %7 -%279 = OpSampledImage %234 %273 %274 -%280 = OpImageGather %29 %279 %278 %281 -%282 = OpSampledImage %234 %273 %274 -%283 = OpImageGather %29 %282 %278 %284 ConstOffset %33 -%285 = OpSampledImage %258 %276 %275 -%286 = OpImageDrefGather %29 %285 %278 %7 -%287 = OpSampledImage %258 %276 %275 -%288 = OpImageDrefGather %29 %287 %278 %7 ConstOffset %33 -%289 = OpFAdd %29 %280 %283 -%290 = OpFAdd %29 %289 %286 -%291 = OpFAdd %29 %290 %288 +%278 = OpCompositeConstruct %34 %7 %7 +%279 = OpSampledImage %235 %273 %274 +%280 = OpImageGather %31 %279 %278 %281 +%282 = OpSampledImage %235 %273 %274 +%283 = OpImageGather %31 %282 %278 %284 ConstOffset %38 +%285 = OpSampledImage %259 %276 %275 +%286 = OpImageDrefGather %31 %285 %278 %7 +%287 = OpSampledImage %259 %276 %275 +%288 = OpImageDrefGather %31 %287 %278 %7 ConstOffset %38 +%289 = OpFAdd %31 %280 %283 +%290 = OpFAdd %31 %289 %286 +%291 = OpFAdd %31 %290 %288 OpStore %271 %291 OpReturn OpFunctionEnd -%294 = OpFunction %2 None %77 +%294 = OpFunction %2 None %82 %292 = OpLabel -%295 = OpLoad %30 %64 -%296 = OpLoad %31 %68 +%295 = OpLoad %33 %69 +%296 = OpLoad %35 %73 OpBranch %297 %297 = OpLabel -%298 = OpCompositeConstruct %228 %7 %7 -%299 = OpSampledImage %258 %296 %295 -%300 = OpImageSampleImplicitLod %29 %299 %298 +%298 = OpCompositeConstruct %34 %7 %7 +%299 = OpSampledImage %259 %296 %295 +%300 = OpImageSampleImplicitLod %31 %299 %298 %301 = OpCompositeExtract %8 %300 0 -%302 = OpSampledImage %258 %296 %295 -%303 = OpImageGather %29 %302 %298 %151 -%304 = OpCompositeConstruct %29 %301 %301 %301 %301 -%305 = OpFAdd %29 %304 %303 +%302 = OpSampledImage %259 %296 %295 +%303 = OpImageGather %31 %302 %298 %153 +%304 = OpCompositeConstruct %31 %301 %301 %301 %301 +%305 = OpFAdd %31 %304 %303 OpStore %293 %305 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/interface.compute.spvasm b/tests/out/spv/interface.compute.spvasm index 6c1dac372d..fda41875e3 100644 --- a/tests/out/spv/interface.compute.spvasm +++ b/tests/out/spv/interface.compute.spvasm @@ -1,25 +1,25 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 49 +; Bound: 48 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %35 "compute" %23 %26 %28 %31 %33 -OpExecutionMode %35 LocalSize 1 1 1 +OpEntryPoint GLCompute %34 "compute" %22 %25 %27 %30 %32 +OpExecutionMode %34 LocalSize 1 1 1 +OpMemberDecorate %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 16 OpMemberDecorate %13 0 Offset 0 -OpMemberDecorate %13 1 Offset 16 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 4 -OpMemberDecorate %14 2 Offset 8 -OpDecorate %16 ArrayStride 4 +OpMemberDecorate %13 1 Offset 4 +OpMemberDecorate %13 2 Offset 8 +OpDecorate %15 ArrayStride 4 OpMemberDecorate %18 0 Offset 0 OpMemberDecorate %19 0 Offset 0 -OpDecorate %23 BuiltIn GlobalInvocationId -OpDecorate %26 BuiltIn LocalInvocationId -OpDecorate %28 BuiltIn LocalInvocationIndex -OpDecorate %31 BuiltIn WorkgroupId -OpDecorate %33 BuiltIn NumWorkgroups +OpDecorate %22 BuiltIn GlobalInvocationId +OpDecorate %25 BuiltIn LocalInvocationId +OpDecorate %27 BuiltIn LocalInvocationIndex +OpDecorate %30 BuiltIn WorkgroupId +OpDecorate %32 BuiltIn NumWorkgroups %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -27,47 +27,46 @@ OpDecorate %33 BuiltIn NumWorkgroups %5 = OpConstant %6 1 %7 = OpConstant %4 0.0 %9 = OpTypeInt 32 1 -%8 = OpConstant %9 1 -%10 = OpConstant %9 0 -%11 = OpConstant %6 2 -%12 = OpTypeVector %4 4 -%13 = OpTypeStruct %12 %4 -%14 = OpTypeStruct %4 %6 %4 -%15 = OpTypeBool -%16 = OpTypeArray %6 %8 -%17 = OpTypeVector %6 3 +%8 = OpConstant %9 0 +%10 = OpConstant %6 2 +%11 = OpTypeVector %4 4 +%12 = OpTypeStruct %11 %4 +%13 = OpTypeStruct %4 %6 %4 +%14 = OpTypeBool +%15 = OpTypeArray %6 %5 +%16 = OpTypeVector %6 3 +%17 = OpTypePointer Workgroup %15 %18 = OpTypeStruct %6 %19 = OpTypeStruct %6 -%21 = OpTypePointer Workgroup %16 -%20 = OpVariable %21 Workgroup -%24 = OpTypePointer Input %17 -%23 = OpVariable %24 Input -%26 = OpVariable %24 Input -%29 = OpTypePointer Input %6 -%28 = OpVariable %29 Input -%31 = OpVariable %24 Input -%33 = OpVariable %24 Input -%36 = OpTypeFunction %2 -%38 = OpTypePointer Workgroup %6 -%47 = OpConstant %6 0 -%35 = OpFunction %2 None %36 -%22 = OpLabel -%25 = OpLoad %17 %23 -%27 = OpLoad %17 %26 -%30 = OpLoad %6 %28 -%32 = OpLoad %17 %31 -%34 = OpLoad %17 %33 -OpBranch %37 -%37 = OpLabel -%39 = OpCompositeExtract %6 %25 0 -%40 = OpCompositeExtract %6 %27 0 -%41 = OpIAdd %6 %39 %40 -%42 = OpIAdd %6 %41 %30 -%43 = OpCompositeExtract %6 %32 0 +%20 = OpVariable %17 Workgroup +%23 = OpTypePointer Input %16 +%22 = OpVariable %23 Input +%25 = OpVariable %23 Input +%28 = OpTypePointer Input %6 +%27 = OpVariable %28 Input +%30 = OpVariable %23 Input +%32 = OpVariable %23 Input +%35 = OpTypeFunction %2 +%45 = OpTypePointer Workgroup %6 +%46 = OpConstant %6 0 +%34 = OpFunction %2 None %35 +%21 = OpLabel +%24 = OpLoad %16 %22 +%26 = OpLoad %16 %25 +%29 = OpLoad %6 %27 +%31 = OpLoad %16 %30 +%33 = OpLoad %16 %32 +OpBranch %36 +%36 = OpLabel +%37 = OpCompositeExtract %6 %24 0 +%38 = OpCompositeExtract %6 %26 0 +%39 = OpIAdd %6 %37 %38 +%40 = OpIAdd %6 %39 %29 +%41 = OpCompositeExtract %6 %31 0 +%42 = OpIAdd %6 %40 %41 +%43 = OpCompositeExtract %6 %33 0 %44 = OpIAdd %6 %42 %43 -%45 = OpCompositeExtract %6 %34 0 -%46 = OpIAdd %6 %44 %45 -%48 = OpAccessChain %38 %20 %47 -OpStore %48 %46 +%47 = OpAccessChain %45 %20 %46 +OpStore %47 %44 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/interface.fragment.spvasm b/tests/out/spv/interface.fragment.spvasm index 424208def3..e0a625ff6f 100644 --- a/tests/out/spv/interface.fragment.spvasm +++ b/tests/out/spv/interface.fragment.spvasm @@ -9,12 +9,12 @@ OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %41 "fragment" %22 %25 %28 %31 %34 %36 %38 %40 OpExecutionMode %41 OriginUpperLeft OpExecutionMode %41 DepthReplacing +OpMemberDecorate %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 16 OpMemberDecorate %13 0 Offset 0 -OpMemberDecorate %13 1 Offset 16 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 4 -OpMemberDecorate %14 2 Offset 8 -OpDecorate %16 ArrayStride 4 +OpMemberDecorate %13 1 Offset 4 +OpMemberDecorate %13 2 Offset 8 +OpDecorate %15 ArrayStride 4 OpMemberDecorate %18 0 Offset 0 OpMemberDecorate %19 0 Offset 0 OpDecorate %22 Invariant @@ -36,22 +36,22 @@ OpDecorate %40 Location 0 %5 = OpConstant %6 1 %7 = OpConstant %4 0.0 %9 = OpTypeInt 32 1 -%8 = OpConstant %9 1 -%10 = OpConstant %9 0 -%11 = OpConstant %6 2 -%12 = OpTypeVector %4 4 -%13 = OpTypeStruct %12 %4 -%14 = OpTypeStruct %4 %6 %4 -%15 = OpTypeBool -%16 = OpTypeArray %6 %8 -%17 = OpTypeVector %6 3 +%8 = OpConstant %9 0 +%10 = OpConstant %6 2 +%11 = OpTypeVector %4 4 +%12 = OpTypeStruct %11 %4 +%13 = OpTypeStruct %4 %6 %4 +%14 = OpTypeBool +%15 = OpTypeArray %6 %5 +%16 = OpTypeVector %6 3 +%17 = OpTypePointer Workgroup %15 %18 = OpTypeStruct %6 %19 = OpTypeStruct %6 -%23 = OpTypePointer Input %12 +%23 = OpTypePointer Input %11 %22 = OpVariable %23 Input %26 = OpTypePointer Input %4 %25 = OpVariable %26 Input -%29 = OpTypePointer Input %15 +%29 = OpTypePointer Input %14 %28 = OpVariable %29 Input %32 = OpTypePointer Input %6 %31 = OpVariable %32 Input @@ -64,10 +64,10 @@ OpDecorate %40 Location 0 %42 = OpTypeFunction %2 %41 = OpFunction %2 None %42 %20 = OpLabel -%24 = OpLoad %12 %22 +%24 = OpLoad %11 %22 %27 = OpLoad %4 %25 -%21 = OpCompositeConstruct %13 %24 %27 -%30 = OpLoad %15 %28 +%21 = OpCompositeConstruct %12 %24 %27 +%30 = OpLoad %14 %28 %33 = OpLoad %6 %31 %35 = OpLoad %6 %34 OpBranch %43 @@ -76,7 +76,7 @@ OpBranch %43 %45 = OpBitwiseAnd %6 %35 %44 %46 = OpSelect %4 %30 %3 %7 %47 = OpCompositeExtract %4 %21 1 -%48 = OpCompositeConstruct %14 %47 %45 %46 +%48 = OpCompositeConstruct %13 %47 %45 %46 %49 = OpCompositeExtract %4 %48 0 OpStore %36 %49 %50 = OpLoad %4 %36 diff --git a/tests/out/spv/interface.vertex.spvasm b/tests/out/spv/interface.vertex.spvasm index 62e4acb1b6..a3db0baadf 100644 --- a/tests/out/spv/interface.vertex.spvasm +++ b/tests/out/spv/interface.vertex.spvasm @@ -6,12 +6,12 @@ OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpEntryPoint Vertex %34 "vertex" %21 %24 %26 %28 %30 %32 +OpMemberDecorate %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 16 OpMemberDecorate %13 0 Offset 0 -OpMemberDecorate %13 1 Offset 16 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 4 -OpMemberDecorate %14 2 Offset 8 -OpDecorate %16 ArrayStride 4 +OpMemberDecorate %13 1 Offset 4 +OpMemberDecorate %13 2 Offset 8 +OpDecorate %15 ArrayStride 4 OpMemberDecorate %18 0 Offset 0 OpMemberDecorate %19 0 Offset 0 OpDecorate %21 BuiltIn VertexIndex @@ -28,22 +28,22 @@ OpDecorate %32 BuiltIn PointSize %5 = OpConstant %6 1 %7 = OpConstant %4 0.0 %9 = OpTypeInt 32 1 -%8 = OpConstant %9 1 -%10 = OpConstant %9 0 -%11 = OpConstant %6 2 -%12 = OpTypeVector %4 4 -%13 = OpTypeStruct %12 %4 -%14 = OpTypeStruct %4 %6 %4 -%15 = OpTypeBool -%16 = OpTypeArray %6 %8 -%17 = OpTypeVector %6 3 +%8 = OpConstant %9 0 +%10 = OpConstant %6 2 +%11 = OpTypeVector %4 4 +%12 = OpTypeStruct %11 %4 +%13 = OpTypeStruct %4 %6 %4 +%14 = OpTypeBool +%15 = OpTypeArray %6 %5 +%16 = OpTypeVector %6 3 +%17 = OpTypePointer Workgroup %15 %18 = OpTypeStruct %6 %19 = OpTypeStruct %6 %22 = OpTypePointer Input %6 %21 = OpVariable %22 Input %24 = OpVariable %22 Input %26 = OpVariable %22 Input -%29 = OpTypePointer Output %12 +%29 = OpTypePointer Output %11 %28 = OpVariable %29 Output %31 = OpTypePointer Output %4 %30 = OpVariable %31 Output @@ -60,10 +60,10 @@ OpBranch %36 %36 = OpLabel %37 = OpIAdd %6 %23 %25 %38 = OpIAdd %6 %37 %27 -%39 = OpCompositeConstruct %12 %3 %3 %3 %3 +%39 = OpCompositeConstruct %11 %3 %3 %3 %3 %40 = OpConvertUToF %4 %38 -%41 = OpCompositeConstruct %13 %39 %40 -%42 = OpCompositeExtract %12 %41 0 +%41 = OpCompositeConstruct %12 %39 %40 +%42 = OpCompositeExtract %11 %41 0 OpStore %28 %42 %43 = OpCompositeExtract %4 %41 1 OpStore %30 %43 diff --git a/tests/out/spv/interface.vertex_two_structs.spvasm b/tests/out/spv/interface.vertex_two_structs.spvasm index 190f391c39..2136308ae0 100644 --- a/tests/out/spv/interface.vertex_two_structs.spvasm +++ b/tests/out/spv/interface.vertex_two_structs.spvasm @@ -5,20 +5,20 @@ 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 %12 0 Offset 0 +OpMemberDecorate %12 1 Offset 16 OpMemberDecorate %13 0 Offset 0 -OpMemberDecorate %13 1 Offset 16 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 1 Offset 4 -OpMemberDecorate %14 2 Offset 8 -OpDecorate %16 ArrayStride 4 +OpMemberDecorate %13 1 Offset 4 +OpMemberDecorate %13 2 Offset 8 +OpDecorate %15 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 @@ -26,44 +26,45 @@ OpDecorate %32 BuiltIn PointSize %5 = OpConstant %6 1 %7 = OpConstant %4 0.0 %9 = OpTypeInt 32 1 -%8 = OpConstant %9 1 -%10 = OpConstant %9 0 -%11 = OpConstant %6 2 -%12 = OpTypeVector %4 4 -%13 = OpTypeStruct %12 %4 -%14 = OpTypeStruct %4 %6 %4 -%15 = OpTypeBool -%16 = OpTypeArray %6 %8 -%17 = OpTypeVector %6 3 +%8 = OpConstant %9 0 +%10 = OpConstant %6 2 +%11 = OpTypeVector %4 4 +%12 = OpTypeStruct %11 %4 +%13 = OpTypeStruct %4 %6 %4 +%14 = OpTypeBool +%15 = OpTypeArray %6 %5 +%16 = OpTypeVector %6 3 +%17 = OpTypePointer Workgroup %15 %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 %11 +%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 %10 +%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 +%44 = OpCompositeConstruct %11 %39 %41 %43 %7 +OpStore %31 %44 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/interpolate.spvasm b/tests/out/spv/interpolate.spvasm index a6fae2b2d0..63bf6e38c9 100644 --- a/tests/out/spv/interpolate.spvasm +++ b/tests/out/spv/interpolate.spvasm @@ -10,6 +10,11 @@ OpEntryPoint Vertex %46 "vert_main" %30 %32 %34 %36 %38 %40 %41 %42 %43 OpEntryPoint Fragment %109 "frag_main" %88 %91 %94 %97 %100 %103 %105 %107 OpExecutionMode %109 OriginUpperLeft OpSource GLSL 450 +OpName %22 "vec4" +OpName %9 "u32" +OpName %4 "f32" +OpName %23 "vec2" +OpName %24 "vec3" OpMemberName %25 0 "position" OpMemberName %25 1 "_flat" OpMemberName %25 2 "_linear" @@ -19,7 +24,8 @@ OpMemberName %25 5 "perspective" OpMemberName %25 6 "perspective_centroid" OpMemberName %25 7 "perspective_sample" OpName %25 "FragmentInput" -OpName %26 "out" +OpName %26 "ptr" +OpName %27 "out" OpName %30 "position" OpName %32 "_flat" OpName %34 "_linear" @@ -103,7 +109,7 @@ OpDecorate %107 Sample %23 = OpTypeVector %4 2 %24 = OpTypeVector %4 3 %25 = OpTypeStruct %22 %9 %4 %23 %24 %22 %4 %4 -%27 = OpTypePointer Function %25 +%26 = OpTypePointer Function %25 %28 = OpConstantNull %25 %31 = OpTypePointer Output %22 %30 = OpVariable %31 Output @@ -122,15 +128,15 @@ OpDecorate %107 Sample %43 = OpVariable %44 Output %45 = OpConstant %4 1.0 %47 = OpTypeFunction %2 -%49 = OpTypePointer Function %22 +%50 = OpTypePointer Function %22 %51 = OpConstant %9 0 %53 = OpTypePointer Function %9 %54 = OpConstant %9 1 %56 = OpTypePointer Function %4 %57 = OpConstant %9 2 -%59 = OpTypePointer Function %23 +%60 = OpTypePointer Function %23 %61 = OpConstant %9 3 -%63 = OpTypePointer Function %24 +%64 = OpTypePointer Function %24 %65 = OpConstant %9 4 %68 = OpConstant %9 5 %70 = OpConstant %9 6 @@ -150,31 +156,31 @@ OpDecorate %107 Sample %107 = OpVariable %95 Input %46 = OpFunction %2 None %47 %29 = OpLabel -%26 = OpVariable %27 Function %28 +%27 = OpVariable %26 Function %28 OpStore %43 %45 OpBranch %48 %48 = OpLabel -%50 = OpCompositeConstruct %22 %3 %5 %6 %7 -%52 = OpAccessChain %49 %26 %51 -OpStore %52 %50 -%55 = OpAccessChain %53 %26 %54 +%49 = OpCompositeConstruct %22 %3 %5 %6 %7 +%52 = OpAccessChain %50 %27 %51 +OpStore %52 %49 +%55 = OpAccessChain %53 %27 %54 OpStore %55 %8 -%58 = OpAccessChain %56 %26 %57 +%58 = OpAccessChain %56 %27 %57 OpStore %58 %10 -%60 = OpCompositeConstruct %23 %11 %12 -%62 = OpAccessChain %59 %26 %61 -OpStore %62 %60 -%64 = OpCompositeConstruct %24 %13 %14 %15 -%66 = OpAccessChain %63 %26 %65 -OpStore %66 %64 +%59 = OpCompositeConstruct %23 %11 %12 +%62 = OpAccessChain %60 %27 %61 +OpStore %62 %59 +%63 = OpCompositeConstruct %24 %13 %14 %15 +%66 = OpAccessChain %64 %27 %65 +OpStore %66 %63 %67 = OpCompositeConstruct %22 %16 %17 %18 %19 -%69 = OpAccessChain %49 %26 %68 +%69 = OpAccessChain %50 %27 %68 OpStore %69 %67 -%71 = OpAccessChain %56 %26 %70 +%71 = OpAccessChain %56 %27 %70 OpStore %71 %20 -%73 = OpAccessChain %56 %26 %72 +%73 = OpAccessChain %56 %27 %72 OpStore %73 %21 -%74 = OpLoad %25 %26 +%74 = OpLoad %25 %27 %75 = OpCompositeExtract %22 %74 0 OpStore %30 %75 %76 = OpAccessChain %44 %30 %54 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 0fde0a7072..3e769db5fe 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: 543 +; Bound: 546 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint GLCompute %531 "main" -OpExecutionMode %531 LocalSize 1 1 1 -OpMemberDecorate %31 0 Offset 0 -OpMemberDecorate %31 1 Offset 16 -OpDecorate %35 ArrayStride 32 -OpDecorate %36 ArrayStride 4 +OpEntryPoint GLCompute %534 "main" +OpExecutionMode %534 LocalSize 1 1 1 +OpMemberDecorate %32 0 Offset 0 +OpMemberDecorate %32 1 Offset 16 +OpDecorate %36 ArrayStride 32 +OpDecorate %37 ArrayStride 4 %2 = OpTypeVoid %4 = OpTypeFloat 32 %3 = OpConstant %4 1.0 @@ -30,9 +30,9 @@ OpDecorate %36 ArrayStride 4 %18 = OpConstant %8 2 %20 = OpTypeInt 32 0 %19 = OpConstant %20 0 -%21 = OpConstant %8 3 -%22 = OpConstant %20 4 -%23 = OpConstant %4 -1.0 +%21 = OpConstant %20 3 +%22 = OpConstant %8 3 +%23 = OpConstant %20 4 %24 = OpConstant %20 2 %25 = OpConstant %20 1 %26 = OpTypeVector %4 4 @@ -40,561 +40,566 @@ OpDecorate %36 ArrayStride 4 %28 = OpTypeVector %10 4 %29 = OpTypeVector %4 2 %30 = OpTypeVector %4 3 -%31 = OpTypeStruct %26 %8 -%32 = OpTypeMatrix %29 2 -%33 = OpTypeMatrix %26 4 -%34 = OpTypeVector %20 2 -%35 = OpTypeArray %31 %21 -%36 = OpTypeArray %8 %22 -%37 = OpTypeMatrix %30 2 -%38 = OpTypeMatrix %30 3 -%39 = OpTypeMatrix %30 4 -%40 = OpTypeMatrix %26 3 -%41 = OpTypeVector %8 3 -%42 = OpConstantComposite %26 %3 %3 %3 %3 -%43 = OpConstantComposite %26 %5 %5 %5 %5 -%44 = OpConstantComposite %26 %6 %6 %6 %6 -%45 = OpConstantComposite %27 %7 %7 %7 %7 -%46 = OpConstantComposite %34 %19 %19 -%47 = OpConstantComposite %29 %5 %5 -%48 = OpConstantComposite %32 %47 %47 -%49 = OpConstantComposite %26 %5 %5 %5 %5 -%50 = OpConstantComposite %31 %49 %11 -%51 = OpConstantComposite %35 %50 %50 %50 -%52 = OpConstantComposite %30 %5 %5 %5 -%53 = OpConstantComposite %37 %52 %52 -%54 = OpConstantComposite %38 %52 %52 %52 -%55 = OpConstantComposite %39 %52 %52 %52 %52 -%56 = OpConstantComposite %40 %49 %49 %49 -%57 = OpConstantComposite %41 %11 %11 %11 -%60 = OpTypeFunction %26 -%100 = OpTypePointer Function %29 -%101 = OpConstantNull %29 -%104 = OpTypeFunction %29 -%120 = OpTypeFunction %30 %30 -%122 = OpTypeVector %10 3 -%129 = OpTypePointer Function %31 -%130 = OpConstantNull %31 -%133 = OpTypeFunction %4 -%158 = OpTypePointer Function %26 -%159 = OpTypePointer Function %4 -%164 = OpTypeFunction %2 -%167 = OpTypeVector %10 2 -%183 = OpTypeVector %8 2 -%194 = OpTypeVector %20 3 -%489 = OpTypePointer Function %8 -%491 = OpTypePointer Function %41 -%521 = OpTypePointer Function %8 -%59 = OpFunction %26 None %60 -%58 = OpLabel -OpBranch %61 -%61 = OpLabel -%62 = OpSelect %8 %9 %7 %11 -%64 = OpCompositeConstruct %28 %9 %9 %9 %9 -%63 = OpSelect %26 %64 %42 %43 -%65 = OpCompositeConstruct %28 %12 %12 %12 %12 -%66 = OpSelect %26 %65 %43 %42 -%67 = OpExtInst %26 %1 FMix %43 %42 %44 -%69 = OpCompositeConstruct %26 %13 %13 %13 %13 -%68 = OpExtInst %26 %1 FMix %43 %42 %69 -%70 = OpCompositeExtract %8 %45 0 -%71 = OpBitcast %4 %70 -%72 = OpBitcast %26 %45 -%73 = OpConvertFToS %27 %43 -%74 = OpCompositeConstruct %27 %62 %62 %62 %62 -%75 = OpIAdd %27 %74 %73 -%76 = OpConvertSToF %26 %75 -%77 = OpFAdd %26 %76 %63 -%78 = OpFAdd %26 %77 %67 -%79 = OpFAdd %26 %78 %68 -%80 = OpCompositeConstruct %26 %71 %71 %71 %71 -%81 = OpFAdd %26 %79 %80 -%82 = OpFAdd %26 %81 %72 -OpReturnValue %82 +%31 = OpTypeVector %10 3 +%32 = OpTypeStruct %26 %8 +%33 = OpTypeMatrix %29 2 +%34 = OpTypeMatrix %26 4 +%35 = OpTypeVector %20 2 +%36 = OpTypeArray %32 %21 +%37 = OpTypeArray %8 %23 +%38 = OpTypeMatrix %30 2 +%39 = OpTypePointer Function %32 +%40 = OpTypePointer Function %26 +%41 = OpTypeVector %10 2 +%42 = OpTypeVector %8 2 +%43 = OpTypeVector %20 3 +%44 = OpTypeMatrix %30 3 +%45 = OpTypeMatrix %30 4 +%46 = OpTypeMatrix %26 3 +%47 = OpTypeVector %8 3 +%48 = OpTypePointer Function %47 +%49 = OpConstantComposite %26 %3 %3 %3 %3 +%50 = OpConstantComposite %26 %5 %5 %5 %5 +%51 = OpConstantComposite %26 %6 %6 %6 %6 +%52 = OpConstantComposite %27 %7 %7 %7 %7 +%53 = OpConstantComposite %35 %19 %19 +%54 = OpConstantComposite %29 %5 %5 +%55 = OpConstantComposite %33 %54 %54 +%56 = OpConstantComposite %26 %5 %5 %5 %5 +%57 = OpConstantComposite %32 %56 %11 +%58 = OpConstantComposite %36 %57 %57 %57 +%59 = OpConstantComposite %30 %5 %5 %5 +%60 = OpConstantComposite %38 %59 %59 +%61 = OpConstantComposite %44 %59 %59 %59 +%62 = OpConstantComposite %45 %59 %59 %59 %59 +%63 = OpConstantComposite %46 %56 %56 %56 +%64 = OpConstantComposite %47 %11 %11 %11 +%67 = OpTypeFunction %26 +%107 = OpTypePointer Function %29 +%108 = OpConstantNull %29 +%111 = OpTypeFunction %29 +%127 = OpTypeFunction %30 %30 +%135 = OpConstantNull %32 +%138 = OpTypeFunction %4 +%163 = OpTypePointer Function %4 +%168 = OpTypeFunction %2 +%491 = OpTypePointer Function %8 +%492 = OpConstantNull %8 +%494 = OpConstantNull %47 +%524 = OpTypePointer Function %8 +%66 = OpFunction %26 None %67 +%65 = OpLabel +OpBranch %68 +%68 = OpLabel +%69 = OpSelect %8 %9 %7 %11 +%71 = OpCompositeConstruct %28 %9 %9 %9 %9 +%70 = OpSelect %26 %71 %49 %50 +%72 = OpCompositeConstruct %28 %12 %12 %12 %12 +%73 = OpSelect %26 %72 %50 %49 +%74 = OpExtInst %26 %1 FMix %50 %49 %51 +%76 = OpCompositeConstruct %26 %13 %13 %13 %13 +%75 = OpExtInst %26 %1 FMix %50 %49 %76 +%77 = OpCompositeExtract %8 %52 0 +%78 = OpBitcast %4 %77 +%79 = OpBitcast %26 %52 +%80 = OpConvertFToS %27 %50 +%81 = OpCompositeConstruct %27 %69 %69 %69 %69 +%82 = OpIAdd %27 %81 %80 +%83 = OpConvertSToF %26 %82 +%84 = OpFAdd %26 %83 %70 +%85 = OpFAdd %26 %84 %74 +%86 = OpFAdd %26 %85 %75 +%87 = OpCompositeConstruct %26 %78 %78 %78 %78 +%88 = OpFAdd %26 %86 %87 +%89 = OpFAdd %26 %88 %79 +OpReturnValue %89 OpFunctionEnd -%84 = OpFunction %26 None %60 -%83 = OpLabel -OpBranch %85 -%85 = OpLabel -%86 = OpCompositeConstruct %29 %14 %14 -%87 = OpCompositeConstruct %29 %3 %3 -%88 = OpFAdd %29 %87 %86 -%89 = OpCompositeConstruct %29 %15 %15 -%90 = OpFSub %29 %88 %89 -%91 = OpCompositeConstruct %29 %16 %16 -%92 = OpFDiv %29 %90 %91 -%93 = OpCompositeConstruct %27 %17 %17 %17 %17 -%94 = OpCompositeConstruct %27 %18 %18 %18 %18 -%95 = OpSRem %27 %93 %94 -%96 = OpVectorShuffle %26 %92 %92 0 1 0 1 -%97 = OpConvertSToF %26 %95 -%98 = OpFAdd %26 %96 %97 -OpReturnValue %98 +%91 = OpFunction %26 None %67 +%90 = OpLabel +OpBranch %92 +%92 = OpLabel +%93 = OpCompositeConstruct %29 %14 %14 +%94 = OpCompositeConstruct %29 %3 %3 +%95 = OpFAdd %29 %94 %93 +%96 = OpCompositeConstruct %29 %15 %15 +%97 = OpFSub %29 %95 %96 +%98 = OpCompositeConstruct %29 %16 %16 +%99 = OpFDiv %29 %97 %98 +%100 = OpCompositeConstruct %27 %17 %17 %17 %17 +%101 = OpCompositeConstruct %27 %18 %18 %18 %18 +%102 = OpSRem %27 %100 %101 +%103 = OpVectorShuffle %26 %99 %99 0 1 0 1 +%104 = OpConvertSToF %26 %102 +%105 = OpFAdd %26 %103 %104 +OpReturnValue %105 OpFunctionEnd -%103 = OpFunction %29 None %104 -%102 = OpLabel -%99 = OpVariable %100 Function %101 -OpBranch %105 -%105 = OpLabel -%106 = OpCompositeConstruct %29 %14 %14 -OpStore %99 %106 -%107 = OpLoad %29 %99 -%108 = OpCompositeConstruct %29 %3 %3 -%109 = OpFAdd %29 %107 %108 -OpStore %99 %109 -%110 = OpLoad %29 %99 -%111 = OpCompositeConstruct %29 %15 %15 -%112 = OpFSub %29 %110 %111 -OpStore %99 %112 -%113 = OpLoad %29 %99 -%114 = OpCompositeConstruct %29 %16 %16 -%115 = OpFDiv %29 %113 %114 -OpStore %99 %115 -%116 = OpLoad %29 %99 -OpReturnValue %116 +%110 = OpFunction %29 None %111 +%109 = OpLabel +%106 = OpVariable %107 Function %108 +OpBranch %112 +%112 = OpLabel +%113 = OpCompositeConstruct %29 %14 %14 +OpStore %106 %113 +%114 = OpLoad %29 %106 +%115 = OpCompositeConstruct %29 %3 %3 +%116 = OpFAdd %29 %114 %115 +OpStore %106 %116 +%117 = OpLoad %29 %106 +%118 = OpCompositeConstruct %29 %15 %15 +%119 = OpFSub %29 %117 %118 +OpStore %106 %119 +%120 = OpLoad %29 %106 +%121 = OpCompositeConstruct %29 %16 %16 +%122 = OpFDiv %29 %120 %121 +OpStore %106 %122 +%123 = OpLoad %29 %106 +OpReturnValue %123 OpFunctionEnd -%119 = OpFunction %30 None %120 -%118 = OpFunctionParameter %30 -%117 = OpLabel -OpBranch %121 -%121 = OpLabel -%123 = OpCompositeConstruct %30 %5 %5 %5 -%124 = OpFUnordNotEqual %122 %118 %123 -%125 = OpCompositeConstruct %30 %5 %5 %5 -%126 = OpCompositeConstruct %30 %3 %3 %3 -%127 = OpSelect %30 %124 %126 %125 -OpReturnValue %127 +%126 = OpFunction %30 None %127 +%125 = OpFunctionParameter %30 +%124 = OpLabel +OpBranch %128 +%128 = OpLabel +%129 = OpCompositeConstruct %30 %5 %5 %5 +%130 = OpFUnordNotEqual %31 %125 %129 +%131 = OpCompositeConstruct %30 %5 %5 %5 +%132 = OpCompositeConstruct %30 %3 %3 %3 +%133 = OpSelect %30 %130 %132 %131 +OpReturnValue %133 OpFunctionEnd -%132 = OpFunction %4 None %133 -%131 = OpLabel -%128 = OpVariable %129 Function %130 -OpBranch %134 -%134 = OpLabel -%135 = OpCompositeConstruct %26 %3 %3 %3 %3 -%136 = OpCompositeConstruct %31 %135 %7 -OpStore %128 %136 -%137 = OpCompositeConstruct %29 %3 %5 -%138 = OpCompositeConstruct %29 %5 %3 -%139 = OpCompositeConstruct %32 %137 %138 -%140 = OpCompositeConstruct %26 %3 %5 %5 %5 -%141 = OpCompositeConstruct %26 %5 %3 %5 %5 -%142 = OpCompositeConstruct %26 %5 %5 %3 %5 -%143 = OpCompositeConstruct %26 %5 %5 %5 %3 -%144 = OpCompositeConstruct %33 %140 %141 %142 %143 -%145 = OpCompositeConstruct %34 %19 %19 -%146 = OpCompositeConstruct %29 %5 %5 -%147 = OpCompositeConstruct %29 %5 %5 -%148 = OpCompositeConstruct %32 %146 %147 -%149 = OpCompositeConstruct %36 %11 %7 %18 %21 -%155 = OpCopyObject %37 %53 -%157 = OpCopyObject %37 %53 -%160 = OpAccessChain %159 %128 %19 %19 -%161 = OpLoad %4 %160 -OpReturnValue %161 +%137 = OpFunction %4 None %138 +%136 = OpLabel +%134 = OpVariable %39 Function %135 +OpBranch %139 +%139 = OpLabel +%140 = OpCompositeConstruct %26 %3 %3 %3 %3 +%141 = OpCompositeConstruct %32 %140 %7 +OpStore %134 %141 +%142 = OpCompositeConstruct %29 %3 %5 +%143 = OpCompositeConstruct %29 %5 %3 +%144 = OpCompositeConstruct %33 %142 %143 +%145 = OpCompositeConstruct %26 %3 %5 %5 %5 +%146 = OpCompositeConstruct %26 %5 %3 %5 %5 +%147 = OpCompositeConstruct %26 %5 %5 %3 %5 +%148 = OpCompositeConstruct %26 %5 %5 %5 %3 +%149 = OpCompositeConstruct %34 %145 %146 %147 %148 +%150 = OpCompositeConstruct %35 %19 %19 +%151 = OpCompositeConstruct %29 %5 %5 +%152 = OpCompositeConstruct %29 %5 %5 +%153 = OpCompositeConstruct %33 %151 %152 +%154 = OpCompositeConstruct %37 %11 %7 %18 %22 +%160 = OpCopyObject %38 %60 +%162 = OpCopyObject %38 %60 +%164 = OpAccessChain %163 %134 %19 %19 +%165 = OpLoad %4 %164 +OpReturnValue %165 OpFunctionEnd -%163 = OpFunction %2 None %164 -%162 = OpLabel -OpBranch %165 -%165 = OpLabel -%166 = OpLogicalNot %10 %9 -%168 = OpCompositeConstruct %167 %9 %9 -%169 = OpLogicalNot %167 %168 -%170 = OpLogicalOr %10 %9 %12 -%171 = OpLogicalAnd %10 %9 %12 -%172 = OpLogicalOr %10 %9 %12 -%173 = OpCompositeConstruct %122 %9 %9 %9 -%174 = OpCompositeConstruct %122 %12 %12 %12 -%175 = OpLogicalOr %122 %173 %174 -%176 = OpLogicalAnd %10 %9 %12 -%177 = OpCompositeConstruct %28 %9 %9 %9 %9 -%178 = OpCompositeConstruct %28 %12 %12 %12 %12 -%179 = OpLogicalAnd %28 %177 %178 +%167 = OpFunction %2 None %168 +%166 = OpLabel +OpBranch %169 +%169 = OpLabel +%170 = OpLogicalNot %10 %9 +%171 = OpCompositeConstruct %41 %9 %9 +%172 = OpLogicalNot %41 %171 +%173 = OpLogicalOr %10 %9 %12 +%174 = OpLogicalAnd %10 %9 %12 +%175 = OpLogicalOr %10 %9 %12 +%176 = OpCompositeConstruct %31 %9 %9 %9 +%177 = OpCompositeConstruct %31 %12 %12 %12 +%178 = OpLogicalOr %31 %176 %177 +%179 = OpLogicalAnd %10 %9 %12 +%180 = OpCompositeConstruct %28 %9 %9 %9 %9 +%181 = OpCompositeConstruct %28 %12 %12 %12 %12 +%182 = OpLogicalAnd %28 %180 %181 OpReturn OpFunctionEnd -%181 = OpFunction %2 None %164 -%180 = OpLabel -OpBranch %182 -%182 = OpLabel -%184 = OpCompositeConstruct %183 %7 %7 -%185 = OpSNegate %183 %184 -%186 = OpCompositeConstruct %29 %3 %3 -%187 = OpFNegate %29 %186 -%188 = OpIAdd %8 %18 %7 -%189 = OpIAdd %20 %24 %25 -%190 = OpFAdd %4 %14 %3 -%191 = OpCompositeConstruct %183 %18 %18 -%192 = OpCompositeConstruct %183 %7 %7 -%193 = OpIAdd %183 %191 %192 -%195 = OpCompositeConstruct %194 %24 %24 %24 -%196 = OpCompositeConstruct %194 %25 %25 %25 -%197 = OpIAdd %194 %195 %196 -%198 = OpCompositeConstruct %26 %14 %14 %14 %14 -%199 = OpCompositeConstruct %26 %3 %3 %3 %3 -%200 = OpFAdd %26 %198 %199 -%201 = OpISub %8 %18 %7 -%202 = OpISub %20 %24 %25 -%203 = OpFSub %4 %14 %3 -%204 = OpCompositeConstruct %183 %18 %18 -%205 = OpCompositeConstruct %183 %7 %7 -%206 = OpISub %183 %204 %205 -%207 = OpCompositeConstruct %194 %24 %24 %24 -%208 = OpCompositeConstruct %194 %25 %25 %25 -%209 = OpISub %194 %207 %208 -%210 = OpCompositeConstruct %26 %14 %14 %14 %14 -%211 = OpCompositeConstruct %26 %3 %3 %3 %3 -%212 = OpFSub %26 %210 %211 -%213 = OpIMul %8 %18 %7 -%214 = OpIMul %20 %24 %25 -%215 = OpFMul %4 %14 %3 -%216 = OpCompositeConstruct %183 %18 %18 -%217 = OpCompositeConstruct %183 %7 %7 -%218 = OpIMul %183 %216 %217 -%219 = OpCompositeConstruct %194 %24 %24 %24 -%220 = OpCompositeConstruct %194 %25 %25 %25 -%221 = OpIMul %194 %219 %220 -%222 = OpCompositeConstruct %26 %14 %14 %14 %14 -%223 = OpCompositeConstruct %26 %3 %3 %3 %3 -%224 = OpFMul %26 %222 %223 -%225 = OpSDiv %8 %18 %7 -%226 = OpUDiv %20 %24 %25 -%227 = OpFDiv %4 %14 %3 -%228 = OpCompositeConstruct %183 %18 %18 -%229 = OpCompositeConstruct %183 %7 %7 -%230 = OpSDiv %183 %228 %229 -%231 = OpCompositeConstruct %194 %24 %24 %24 -%232 = OpCompositeConstruct %194 %25 %25 %25 -%233 = OpUDiv %194 %231 %232 -%234 = OpCompositeConstruct %26 %14 %14 %14 %14 -%235 = OpCompositeConstruct %26 %3 %3 %3 %3 -%236 = OpFDiv %26 %234 %235 -%237 = OpSRem %8 %18 %7 -%238 = OpUMod %20 %24 %25 -%239 = OpFRem %4 %14 %3 -%240 = OpCompositeConstruct %183 %18 %18 -%241 = OpCompositeConstruct %183 %7 %7 -%242 = OpSRem %183 %240 %241 -%243 = OpCompositeConstruct %194 %24 %24 %24 -%244 = OpCompositeConstruct %194 %25 %25 %25 -%245 = OpUMod %194 %243 %244 -%246 = OpCompositeConstruct %26 %14 %14 %14 %14 -%247 = OpCompositeConstruct %26 %3 %3 %3 %3 -%248 = OpFRem %26 %246 %247 -%249 = OpCompositeConstruct %183 %18 %18 -%250 = OpCompositeConstruct %183 %7 %7 -%251 = OpIAdd %183 %249 %250 -%252 = OpCompositeConstruct %183 %7 %7 -%253 = OpCompositeConstruct %183 %18 %18 -%254 = OpIAdd %183 %253 %252 -%255 = OpCompositeConstruct %34 %24 %24 -%256 = OpCompositeConstruct %34 %25 %25 -%257 = OpIAdd %34 %255 %256 -%258 = OpCompositeConstruct %34 %25 %25 -%259 = OpCompositeConstruct %34 %24 %24 -%260 = OpIAdd %34 %259 %258 -%261 = OpCompositeConstruct %29 %14 %14 -%262 = OpCompositeConstruct %29 %3 %3 -%263 = OpFAdd %29 %261 %262 +%184 = OpFunction %2 None %168 +%183 = OpLabel +OpBranch %185 +%185 = OpLabel +%186 = OpFNegate %4 %3 +%187 = OpCompositeConstruct %42 %7 %7 +%188 = OpSNegate %42 %187 +%189 = OpCompositeConstruct %29 %3 %3 +%190 = OpFNegate %29 %189 +%191 = OpIAdd %8 %18 %7 +%192 = OpIAdd %20 %24 %25 +%193 = OpFAdd %4 %14 %3 +%194 = OpCompositeConstruct %42 %18 %18 +%195 = OpCompositeConstruct %42 %7 %7 +%196 = OpIAdd %42 %194 %195 +%197 = OpCompositeConstruct %43 %24 %24 %24 +%198 = OpCompositeConstruct %43 %25 %25 %25 +%199 = OpIAdd %43 %197 %198 +%200 = OpCompositeConstruct %26 %14 %14 %14 %14 +%201 = OpCompositeConstruct %26 %3 %3 %3 %3 +%202 = OpFAdd %26 %200 %201 +%203 = OpISub %8 %18 %7 +%204 = OpISub %20 %24 %25 +%205 = OpFSub %4 %14 %3 +%206 = OpCompositeConstruct %42 %18 %18 +%207 = OpCompositeConstruct %42 %7 %7 +%208 = OpISub %42 %206 %207 +%209 = OpCompositeConstruct %43 %24 %24 %24 +%210 = OpCompositeConstruct %43 %25 %25 %25 +%211 = OpISub %43 %209 %210 +%212 = OpCompositeConstruct %26 %14 %14 %14 %14 +%213 = OpCompositeConstruct %26 %3 %3 %3 %3 +%214 = OpFSub %26 %212 %213 +%215 = OpIMul %8 %18 %7 +%216 = OpIMul %20 %24 %25 +%217 = OpFMul %4 %14 %3 +%218 = OpCompositeConstruct %42 %18 %18 +%219 = OpCompositeConstruct %42 %7 %7 +%220 = OpIMul %42 %218 %219 +%221 = OpCompositeConstruct %43 %24 %24 %24 +%222 = OpCompositeConstruct %43 %25 %25 %25 +%223 = OpIMul %43 %221 %222 +%224 = OpCompositeConstruct %26 %14 %14 %14 %14 +%225 = OpCompositeConstruct %26 %3 %3 %3 %3 +%226 = OpFMul %26 %224 %225 +%227 = OpSDiv %8 %18 %7 +%228 = OpUDiv %20 %24 %25 +%229 = OpFDiv %4 %14 %3 +%230 = OpCompositeConstruct %42 %18 %18 +%231 = OpCompositeConstruct %42 %7 %7 +%232 = OpSDiv %42 %230 %231 +%233 = OpCompositeConstruct %43 %24 %24 %24 +%234 = OpCompositeConstruct %43 %25 %25 %25 +%235 = OpUDiv %43 %233 %234 +%236 = OpCompositeConstruct %26 %14 %14 %14 %14 +%237 = OpCompositeConstruct %26 %3 %3 %3 %3 +%238 = OpFDiv %26 %236 %237 +%239 = OpSRem %8 %18 %7 +%240 = OpUMod %20 %24 %25 +%241 = OpFRem %4 %14 %3 +%242 = OpCompositeConstruct %42 %18 %18 +%243 = OpCompositeConstruct %42 %7 %7 +%244 = OpSRem %42 %242 %243 +%245 = OpCompositeConstruct %43 %24 %24 %24 +%246 = OpCompositeConstruct %43 %25 %25 %25 +%247 = OpUMod %43 %245 %246 +%248 = OpCompositeConstruct %26 %14 %14 %14 %14 +%249 = OpCompositeConstruct %26 %3 %3 %3 %3 +%250 = OpFRem %26 %248 %249 +%251 = OpCompositeConstruct %42 %18 %18 +%252 = OpCompositeConstruct %42 %7 %7 +%253 = OpIAdd %42 %251 %252 +%254 = OpCompositeConstruct %42 %7 %7 +%255 = OpCompositeConstruct %42 %18 %18 +%256 = OpIAdd %42 %255 %254 +%257 = OpCompositeConstruct %35 %24 %24 +%258 = OpCompositeConstruct %35 %25 %25 +%259 = OpIAdd %35 %257 %258 +%260 = OpCompositeConstruct %35 %25 %25 +%261 = OpCompositeConstruct %35 %24 %24 +%262 = OpIAdd %35 %261 %260 +%263 = OpCompositeConstruct %29 %14 %14 %264 = OpCompositeConstruct %29 %3 %3 -%265 = OpCompositeConstruct %29 %14 %14 -%266 = OpFAdd %29 %265 %264 -%267 = OpCompositeConstruct %183 %18 %18 -%268 = OpCompositeConstruct %183 %7 %7 -%269 = OpISub %183 %267 %268 -%270 = OpCompositeConstruct %183 %7 %7 -%271 = OpCompositeConstruct %183 %18 %18 -%272 = OpISub %183 %271 %270 -%273 = OpCompositeConstruct %34 %24 %24 -%274 = OpCompositeConstruct %34 %25 %25 -%275 = OpISub %34 %273 %274 -%276 = OpCompositeConstruct %34 %25 %25 -%277 = OpCompositeConstruct %34 %24 %24 -%278 = OpISub %34 %277 %276 -%279 = OpCompositeConstruct %29 %14 %14 -%280 = OpCompositeConstruct %29 %3 %3 -%281 = OpFSub %29 %279 %280 +%265 = OpFAdd %29 %263 %264 +%266 = OpCompositeConstruct %29 %3 %3 +%267 = OpCompositeConstruct %29 %14 %14 +%268 = OpFAdd %29 %267 %266 +%269 = OpCompositeConstruct %42 %18 %18 +%270 = OpCompositeConstruct %42 %7 %7 +%271 = OpISub %42 %269 %270 +%272 = OpCompositeConstruct %42 %7 %7 +%273 = OpCompositeConstruct %42 %18 %18 +%274 = OpISub %42 %273 %272 +%275 = OpCompositeConstruct %35 %24 %24 +%276 = OpCompositeConstruct %35 %25 %25 +%277 = OpISub %35 %275 %276 +%278 = OpCompositeConstruct %35 %25 %25 +%279 = OpCompositeConstruct %35 %24 %24 +%280 = OpISub %35 %279 %278 +%281 = OpCompositeConstruct %29 %14 %14 %282 = OpCompositeConstruct %29 %3 %3 -%283 = OpCompositeConstruct %29 %14 %14 -%284 = OpFSub %29 %283 %282 -%285 = OpCompositeConstruct %183 %18 %18 -%287 = OpCompositeConstruct %183 %7 %7 -%286 = OpIMul %183 %285 %287 -%288 = OpCompositeConstruct %183 %7 %7 -%290 = OpCompositeConstruct %183 %18 %18 -%289 = OpIMul %183 %288 %290 -%291 = OpCompositeConstruct %34 %24 %24 -%293 = OpCompositeConstruct %34 %25 %25 -%292 = OpIMul %34 %291 %293 -%294 = OpCompositeConstruct %34 %25 %25 -%296 = OpCompositeConstruct %34 %24 %24 -%295 = OpIMul %34 %294 %296 -%297 = OpCompositeConstruct %29 %14 %14 -%298 = OpVectorTimesScalar %29 %297 %3 -%299 = OpCompositeConstruct %29 %3 %3 -%300 = OpVectorTimesScalar %29 %299 %14 -%301 = OpCompositeConstruct %183 %18 %18 -%302 = OpCompositeConstruct %183 %7 %7 -%303 = OpSDiv %183 %301 %302 -%304 = OpCompositeConstruct %183 %7 %7 -%305 = OpCompositeConstruct %183 %18 %18 -%306 = OpSDiv %183 %305 %304 -%307 = OpCompositeConstruct %34 %24 %24 -%308 = OpCompositeConstruct %34 %25 %25 -%309 = OpUDiv %34 %307 %308 -%310 = OpCompositeConstruct %34 %25 %25 -%311 = OpCompositeConstruct %34 %24 %24 -%312 = OpUDiv %34 %311 %310 -%313 = OpCompositeConstruct %29 %14 %14 -%314 = OpCompositeConstruct %29 %3 %3 -%315 = OpFDiv %29 %313 %314 +%283 = OpFSub %29 %281 %282 +%284 = OpCompositeConstruct %29 %3 %3 +%285 = OpCompositeConstruct %29 %14 %14 +%286 = OpFSub %29 %285 %284 +%287 = OpCompositeConstruct %42 %18 %18 +%289 = OpCompositeConstruct %42 %7 %7 +%288 = OpIMul %42 %287 %289 +%290 = OpCompositeConstruct %42 %7 %7 +%292 = OpCompositeConstruct %42 %18 %18 +%291 = OpIMul %42 %290 %292 +%293 = OpCompositeConstruct %35 %24 %24 +%295 = OpCompositeConstruct %35 %25 %25 +%294 = OpIMul %35 %293 %295 +%296 = OpCompositeConstruct %35 %25 %25 +%298 = OpCompositeConstruct %35 %24 %24 +%297 = OpIMul %35 %296 %298 +%299 = OpCompositeConstruct %29 %14 %14 +%300 = OpVectorTimesScalar %29 %299 %3 +%301 = OpCompositeConstruct %29 %3 %3 +%302 = OpVectorTimesScalar %29 %301 %14 +%303 = OpCompositeConstruct %42 %18 %18 +%304 = OpCompositeConstruct %42 %7 %7 +%305 = OpSDiv %42 %303 %304 +%306 = OpCompositeConstruct %42 %7 %7 +%307 = OpCompositeConstruct %42 %18 %18 +%308 = OpSDiv %42 %307 %306 +%309 = OpCompositeConstruct %35 %24 %24 +%310 = OpCompositeConstruct %35 %25 %25 +%311 = OpUDiv %35 %309 %310 +%312 = OpCompositeConstruct %35 %25 %25 +%313 = OpCompositeConstruct %35 %24 %24 +%314 = OpUDiv %35 %313 %312 +%315 = OpCompositeConstruct %29 %14 %14 %316 = OpCompositeConstruct %29 %3 %3 -%317 = OpCompositeConstruct %29 %14 %14 -%318 = OpFDiv %29 %317 %316 -%319 = OpCompositeConstruct %183 %18 %18 -%320 = OpCompositeConstruct %183 %7 %7 -%321 = OpSRem %183 %319 %320 -%322 = OpCompositeConstruct %183 %7 %7 -%323 = OpCompositeConstruct %183 %18 %18 -%324 = OpSRem %183 %323 %322 -%325 = OpCompositeConstruct %34 %24 %24 -%326 = OpCompositeConstruct %34 %25 %25 -%327 = OpUMod %34 %325 %326 -%328 = OpCompositeConstruct %34 %25 %25 -%329 = OpCompositeConstruct %34 %24 %24 -%330 = OpUMod %34 %329 %328 -%331 = OpCompositeConstruct %29 %14 %14 -%332 = OpCompositeConstruct %29 %3 %3 -%333 = OpFRem %29 %331 %332 +%317 = OpFDiv %29 %315 %316 +%318 = OpCompositeConstruct %29 %3 %3 +%319 = OpCompositeConstruct %29 %14 %14 +%320 = OpFDiv %29 %319 %318 +%321 = OpCompositeConstruct %42 %18 %18 +%322 = OpCompositeConstruct %42 %7 %7 +%323 = OpSRem %42 %321 %322 +%324 = OpCompositeConstruct %42 %7 %7 +%325 = OpCompositeConstruct %42 %18 %18 +%326 = OpSRem %42 %325 %324 +%327 = OpCompositeConstruct %35 %24 %24 +%328 = OpCompositeConstruct %35 %25 %25 +%329 = OpUMod %35 %327 %328 +%330 = OpCompositeConstruct %35 %25 %25 +%331 = OpCompositeConstruct %35 %24 %24 +%332 = OpUMod %35 %331 %330 +%333 = OpCompositeConstruct %29 %14 %14 %334 = OpCompositeConstruct %29 %3 %3 -%335 = OpCompositeConstruct %29 %14 %14 -%336 = OpFRem %29 %335 %334 -%338 = OpCompositeExtract %30 %54 0 -%339 = OpCompositeExtract %30 %54 0 -%340 = OpFAdd %30 %338 %339 -%341 = OpCompositeExtract %30 %54 1 -%342 = OpCompositeExtract %30 %54 1 -%343 = OpFAdd %30 %341 %342 -%344 = OpCompositeExtract %30 %54 2 -%345 = OpCompositeExtract %30 %54 2 -%346 = OpFAdd %30 %344 %345 -%337 = OpCompositeConstruct %38 %340 %343 %346 -%348 = OpCompositeExtract %30 %54 0 -%349 = OpCompositeExtract %30 %54 0 -%350 = OpFSub %30 %348 %349 -%351 = OpCompositeExtract %30 %54 1 -%352 = OpCompositeExtract %30 %54 1 -%353 = OpFSub %30 %351 %352 -%354 = OpCompositeExtract %30 %54 2 -%355 = OpCompositeExtract %30 %54 2 -%356 = OpFSub %30 %354 %355 -%347 = OpCompositeConstruct %38 %350 %353 %356 -%357 = OpMatrixTimesScalar %38 %54 %3 -%358 = OpMatrixTimesScalar %38 %54 %14 -%359 = OpCompositeConstruct %26 %3 %3 %3 %3 -%360 = OpMatrixTimesVector %30 %55 %359 -%361 = OpCompositeConstruct %30 %14 %14 %14 -%362 = OpVectorTimesMatrix %26 %361 %55 -%363 = OpMatrixTimesMatrix %38 %55 %56 +%335 = OpFRem %29 %333 %334 +%336 = OpCompositeConstruct %29 %3 %3 +%337 = OpCompositeConstruct %29 %14 %14 +%338 = OpFRem %29 %337 %336 +%340 = OpCompositeExtract %30 %61 0 +%341 = OpCompositeExtract %30 %61 0 +%342 = OpFAdd %30 %340 %341 +%343 = OpCompositeExtract %30 %61 1 +%344 = OpCompositeExtract %30 %61 1 +%345 = OpFAdd %30 %343 %344 +%346 = OpCompositeExtract %30 %61 2 +%347 = OpCompositeExtract %30 %61 2 +%348 = OpFAdd %30 %346 %347 +%339 = OpCompositeConstruct %44 %342 %345 %348 +%350 = OpCompositeExtract %30 %61 0 +%351 = OpCompositeExtract %30 %61 0 +%352 = OpFSub %30 %350 %351 +%353 = OpCompositeExtract %30 %61 1 +%354 = OpCompositeExtract %30 %61 1 +%355 = OpFSub %30 %353 %354 +%356 = OpCompositeExtract %30 %61 2 +%357 = OpCompositeExtract %30 %61 2 +%358 = OpFSub %30 %356 %357 +%349 = OpCompositeConstruct %44 %352 %355 %358 +%359 = OpMatrixTimesScalar %44 %61 %3 +%360 = OpMatrixTimesScalar %44 %61 %14 +%361 = OpCompositeConstruct %26 %3 %3 %3 %3 +%362 = OpMatrixTimesVector %30 %62 %361 +%363 = OpCompositeConstruct %30 %14 %14 %14 +%364 = OpVectorTimesMatrix %26 %363 %62 +%365 = OpMatrixTimesMatrix %44 %62 %63 OpReturn OpFunctionEnd -%365 = OpFunction %2 None %164 -%364 = OpLabel -OpBranch %366 +%367 = OpFunction %2 None %168 %366 = OpLabel -%367 = OpNot %8 %7 -%368 = OpNot %20 %25 -%369 = OpCompositeConstruct %183 %7 %7 -%370 = OpNot %183 %369 -%371 = OpCompositeConstruct %194 %25 %25 %25 -%372 = OpNot %194 %371 -%373 = OpBitwiseOr %8 %18 %7 -%374 = OpBitwiseOr %20 %24 %25 -%375 = OpCompositeConstruct %183 %18 %18 -%376 = OpCompositeConstruct %183 %7 %7 -%377 = OpBitwiseOr %183 %375 %376 -%378 = OpCompositeConstruct %194 %24 %24 %24 -%379 = OpCompositeConstruct %194 %25 %25 %25 -%380 = OpBitwiseOr %194 %378 %379 -%381 = OpBitwiseAnd %8 %18 %7 -%382 = OpBitwiseAnd %20 %24 %25 -%383 = OpCompositeConstruct %183 %18 %18 -%384 = OpCompositeConstruct %183 %7 %7 -%385 = OpBitwiseAnd %183 %383 %384 -%386 = OpCompositeConstruct %194 %24 %24 %24 -%387 = OpCompositeConstruct %194 %25 %25 %25 -%388 = OpBitwiseAnd %194 %386 %387 -%389 = OpBitwiseXor %8 %18 %7 -%390 = OpBitwiseXor %20 %24 %25 -%391 = OpCompositeConstruct %183 %18 %18 -%392 = OpCompositeConstruct %183 %7 %7 -%393 = OpBitwiseXor %183 %391 %392 -%394 = OpCompositeConstruct %194 %24 %24 %24 -%395 = OpCompositeConstruct %194 %25 %25 %25 -%396 = OpBitwiseXor %194 %394 %395 -%397 = OpShiftLeftLogical %8 %18 %25 -%398 = OpShiftLeftLogical %20 %24 %25 -%399 = OpCompositeConstruct %183 %18 %18 -%400 = OpCompositeConstruct %34 %25 %25 -%401 = OpShiftLeftLogical %183 %399 %400 -%402 = OpCompositeConstruct %194 %24 %24 %24 -%403 = OpCompositeConstruct %194 %25 %25 %25 -%404 = OpShiftLeftLogical %194 %402 %403 -%405 = OpShiftRightArithmetic %8 %18 %25 -%406 = OpShiftRightLogical %20 %24 %25 -%407 = OpCompositeConstruct %183 %18 %18 -%408 = OpCompositeConstruct %34 %25 %25 -%409 = OpShiftRightArithmetic %183 %407 %408 -%410 = OpCompositeConstruct %194 %24 %24 %24 -%411 = OpCompositeConstruct %194 %25 %25 %25 -%412 = OpShiftRightLogical %194 %410 %411 +OpBranch %368 +%368 = OpLabel +%369 = OpNot %8 %7 +%370 = OpNot %20 %25 +%371 = OpCompositeConstruct %42 %7 %7 +%372 = OpNot %42 %371 +%373 = OpCompositeConstruct %43 %25 %25 %25 +%374 = OpNot %43 %373 +%375 = OpBitwiseOr %8 %18 %7 +%376 = OpBitwiseOr %20 %24 %25 +%377 = OpCompositeConstruct %42 %18 %18 +%378 = OpCompositeConstruct %42 %7 %7 +%379 = OpBitwiseOr %42 %377 %378 +%380 = OpCompositeConstruct %43 %24 %24 %24 +%381 = OpCompositeConstruct %43 %25 %25 %25 +%382 = OpBitwiseOr %43 %380 %381 +%383 = OpBitwiseAnd %8 %18 %7 +%384 = OpBitwiseAnd %20 %24 %25 +%385 = OpCompositeConstruct %42 %18 %18 +%386 = OpCompositeConstruct %42 %7 %7 +%387 = OpBitwiseAnd %42 %385 %386 +%388 = OpCompositeConstruct %43 %24 %24 %24 +%389 = OpCompositeConstruct %43 %25 %25 %25 +%390 = OpBitwiseAnd %43 %388 %389 +%391 = OpBitwiseXor %8 %18 %7 +%392 = OpBitwiseXor %20 %24 %25 +%393 = OpCompositeConstruct %42 %18 %18 +%394 = OpCompositeConstruct %42 %7 %7 +%395 = OpBitwiseXor %42 %393 %394 +%396 = OpCompositeConstruct %43 %24 %24 %24 +%397 = OpCompositeConstruct %43 %25 %25 %25 +%398 = OpBitwiseXor %43 %396 %397 +%399 = OpShiftLeftLogical %8 %18 %25 +%400 = OpShiftLeftLogical %20 %24 %25 +%401 = OpCompositeConstruct %42 %18 %18 +%402 = OpCompositeConstruct %35 %25 %25 +%403 = OpShiftLeftLogical %42 %401 %402 +%404 = OpCompositeConstruct %43 %24 %24 %24 +%405 = OpCompositeConstruct %43 %25 %25 %25 +%406 = OpShiftLeftLogical %43 %404 %405 +%407 = OpShiftRightArithmetic %8 %18 %25 +%408 = OpShiftRightLogical %20 %24 %25 +%409 = OpCompositeConstruct %42 %18 %18 +%410 = OpCompositeConstruct %35 %25 %25 +%411 = OpShiftRightArithmetic %42 %409 %410 +%412 = OpCompositeConstruct %43 %24 %24 %24 +%413 = OpCompositeConstruct %43 %25 %25 %25 +%414 = OpShiftRightLogical %43 %412 %413 OpReturn OpFunctionEnd -%414 = OpFunction %2 None %164 -%413 = OpLabel -OpBranch %415 +%416 = OpFunction %2 None %168 %415 = OpLabel -%416 = OpIEqual %10 %18 %7 -%417 = OpIEqual %10 %24 %25 -%418 = OpFOrdEqual %10 %14 %3 -%419 = OpCompositeConstruct %183 %18 %18 -%420 = OpCompositeConstruct %183 %7 %7 -%421 = OpIEqual %167 %419 %420 -%422 = OpCompositeConstruct %194 %24 %24 %24 -%423 = OpCompositeConstruct %194 %25 %25 %25 -%424 = OpIEqual %122 %422 %423 -%425 = OpCompositeConstruct %26 %14 %14 %14 %14 -%426 = OpCompositeConstruct %26 %3 %3 %3 %3 -%427 = OpFOrdEqual %28 %425 %426 -%428 = OpINotEqual %10 %18 %7 -%429 = OpINotEqual %10 %24 %25 -%430 = OpFOrdNotEqual %10 %14 %3 -%431 = OpCompositeConstruct %183 %18 %18 -%432 = OpCompositeConstruct %183 %7 %7 -%433 = OpINotEqual %167 %431 %432 -%434 = OpCompositeConstruct %194 %24 %24 %24 -%435 = OpCompositeConstruct %194 %25 %25 %25 -%436 = OpINotEqual %122 %434 %435 -%437 = OpCompositeConstruct %26 %14 %14 %14 %14 -%438 = OpCompositeConstruct %26 %3 %3 %3 %3 -%439 = OpFOrdNotEqual %28 %437 %438 -%440 = OpSLessThan %10 %18 %7 -%441 = OpULessThan %10 %24 %25 -%442 = OpFOrdLessThan %10 %14 %3 -%443 = OpCompositeConstruct %183 %18 %18 -%444 = OpCompositeConstruct %183 %7 %7 -%445 = OpSLessThan %167 %443 %444 -%446 = OpCompositeConstruct %194 %24 %24 %24 -%447 = OpCompositeConstruct %194 %25 %25 %25 -%448 = OpULessThan %122 %446 %447 -%449 = OpCompositeConstruct %26 %14 %14 %14 %14 -%450 = OpCompositeConstruct %26 %3 %3 %3 %3 -%451 = OpFOrdLessThan %28 %449 %450 -%452 = OpSLessThanEqual %10 %18 %7 -%453 = OpULessThanEqual %10 %24 %25 -%454 = OpFOrdLessThanEqual %10 %14 %3 -%455 = OpCompositeConstruct %183 %18 %18 -%456 = OpCompositeConstruct %183 %7 %7 -%457 = OpSLessThanEqual %167 %455 %456 -%458 = OpCompositeConstruct %194 %24 %24 %24 -%459 = OpCompositeConstruct %194 %25 %25 %25 -%460 = OpULessThanEqual %122 %458 %459 -%461 = OpCompositeConstruct %26 %14 %14 %14 %14 -%462 = OpCompositeConstruct %26 %3 %3 %3 %3 -%463 = OpFOrdLessThanEqual %28 %461 %462 -%464 = OpSGreaterThan %10 %18 %7 -%465 = OpUGreaterThan %10 %24 %25 -%466 = OpFOrdGreaterThan %10 %14 %3 -%467 = OpCompositeConstruct %183 %18 %18 -%468 = OpCompositeConstruct %183 %7 %7 -%469 = OpSGreaterThan %167 %467 %468 -%470 = OpCompositeConstruct %194 %24 %24 %24 -%471 = OpCompositeConstruct %194 %25 %25 %25 -%472 = OpUGreaterThan %122 %470 %471 -%473 = OpCompositeConstruct %26 %14 %14 %14 %14 -%474 = OpCompositeConstruct %26 %3 %3 %3 %3 -%475 = OpFOrdGreaterThan %28 %473 %474 -%476 = OpSGreaterThanEqual %10 %18 %7 -%477 = OpUGreaterThanEqual %10 %24 %25 -%478 = OpFOrdGreaterThanEqual %10 %14 %3 -%479 = OpCompositeConstruct %183 %18 %18 -%480 = OpCompositeConstruct %183 %7 %7 -%481 = OpSGreaterThanEqual %167 %479 %480 -%482 = OpCompositeConstruct %194 %24 %24 %24 -%483 = OpCompositeConstruct %194 %25 %25 %25 -%484 = OpUGreaterThanEqual %122 %482 %483 -%485 = OpCompositeConstruct %26 %14 %14 %14 %14 -%486 = OpCompositeConstruct %26 %3 %3 %3 %3 -%487 = OpFOrdGreaterThanEqual %28 %485 %486 +OpBranch %417 +%417 = OpLabel +%418 = OpIEqual %10 %18 %7 +%419 = OpIEqual %10 %24 %25 +%420 = OpFOrdEqual %10 %14 %3 +%421 = OpCompositeConstruct %42 %18 %18 +%422 = OpCompositeConstruct %42 %7 %7 +%423 = OpIEqual %41 %421 %422 +%424 = OpCompositeConstruct %43 %24 %24 %24 +%425 = OpCompositeConstruct %43 %25 %25 %25 +%426 = OpIEqual %31 %424 %425 +%427 = OpCompositeConstruct %26 %14 %14 %14 %14 +%428 = OpCompositeConstruct %26 %3 %3 %3 %3 +%429 = OpFOrdEqual %28 %427 %428 +%430 = OpINotEqual %10 %18 %7 +%431 = OpINotEqual %10 %24 %25 +%432 = OpFOrdNotEqual %10 %14 %3 +%433 = OpCompositeConstruct %42 %18 %18 +%434 = OpCompositeConstruct %42 %7 %7 +%435 = OpINotEqual %41 %433 %434 +%436 = OpCompositeConstruct %43 %24 %24 %24 +%437 = OpCompositeConstruct %43 %25 %25 %25 +%438 = OpINotEqual %31 %436 %437 +%439 = OpCompositeConstruct %26 %14 %14 %14 %14 +%440 = OpCompositeConstruct %26 %3 %3 %3 %3 +%441 = OpFOrdNotEqual %28 %439 %440 +%442 = OpSLessThan %10 %18 %7 +%443 = OpULessThan %10 %24 %25 +%444 = OpFOrdLessThan %10 %14 %3 +%445 = OpCompositeConstruct %42 %18 %18 +%446 = OpCompositeConstruct %42 %7 %7 +%447 = OpSLessThan %41 %445 %446 +%448 = OpCompositeConstruct %43 %24 %24 %24 +%449 = OpCompositeConstruct %43 %25 %25 %25 +%450 = OpULessThan %31 %448 %449 +%451 = OpCompositeConstruct %26 %14 %14 %14 %14 +%452 = OpCompositeConstruct %26 %3 %3 %3 %3 +%453 = OpFOrdLessThan %28 %451 %452 +%454 = OpSLessThanEqual %10 %18 %7 +%455 = OpULessThanEqual %10 %24 %25 +%456 = OpFOrdLessThanEqual %10 %14 %3 +%457 = OpCompositeConstruct %42 %18 %18 +%458 = OpCompositeConstruct %42 %7 %7 +%459 = OpSLessThanEqual %41 %457 %458 +%460 = OpCompositeConstruct %43 %24 %24 %24 +%461 = OpCompositeConstruct %43 %25 %25 %25 +%462 = OpULessThanEqual %31 %460 %461 +%463 = OpCompositeConstruct %26 %14 %14 %14 %14 +%464 = OpCompositeConstruct %26 %3 %3 %3 %3 +%465 = OpFOrdLessThanEqual %28 %463 %464 +%466 = OpSGreaterThan %10 %18 %7 +%467 = OpUGreaterThan %10 %24 %25 +%468 = OpFOrdGreaterThan %10 %14 %3 +%469 = OpCompositeConstruct %42 %18 %18 +%470 = OpCompositeConstruct %42 %7 %7 +%471 = OpSGreaterThan %41 %469 %470 +%472 = OpCompositeConstruct %43 %24 %24 %24 +%473 = OpCompositeConstruct %43 %25 %25 %25 +%474 = OpUGreaterThan %31 %472 %473 +%475 = OpCompositeConstruct %26 %14 %14 %14 %14 +%476 = OpCompositeConstruct %26 %3 %3 %3 %3 +%477 = OpFOrdGreaterThan %28 %475 %476 +%478 = OpSGreaterThanEqual %10 %18 %7 +%479 = OpUGreaterThanEqual %10 %24 %25 +%480 = OpFOrdGreaterThanEqual %10 %14 %3 +%481 = OpCompositeConstruct %42 %18 %18 +%482 = OpCompositeConstruct %42 %7 %7 +%483 = OpSGreaterThanEqual %41 %481 %482 +%484 = OpCompositeConstruct %43 %24 %24 %24 +%485 = OpCompositeConstruct %43 %25 %25 %25 +%486 = OpUGreaterThanEqual %31 %484 %485 +%487 = OpCompositeConstruct %26 %14 %14 %14 %14 +%488 = OpCompositeConstruct %26 %3 %3 %3 %3 +%489 = OpFOrdGreaterThanEqual %28 %487 %488 OpReturn OpFunctionEnd -%493 = OpFunction %2 None %164 -%492 = OpLabel -%488 = OpVariable %489 Function %7 -%490 = OpVariable %491 Function %57 -OpBranch %494 -%494 = OpLabel -%495 = OpLoad %8 %488 -%496 = OpIAdd %8 %495 %7 -OpStore %488 %496 -%497 = OpLoad %8 %488 -%498 = OpISub %8 %497 %7 -OpStore %488 %498 -%499 = OpLoad %8 %488 -%500 = OpLoad %8 %488 -%501 = OpIMul %8 %499 %500 -OpStore %488 %501 -%502 = OpLoad %8 %488 -%503 = OpLoad %8 %488 -%504 = OpSDiv %8 %502 %503 -OpStore %488 %504 -%505 = OpLoad %8 %488 -%506 = OpSRem %8 %505 %7 -OpStore %488 %506 -%507 = OpLoad %8 %488 -%508 = OpBitwiseAnd %8 %507 %11 -OpStore %488 %508 -%509 = OpLoad %8 %488 -%510 = OpBitwiseOr %8 %509 %11 -OpStore %488 %510 -%511 = OpLoad %8 %488 -%512 = OpBitwiseXor %8 %511 %11 -OpStore %488 %512 -%513 = OpLoad %8 %488 -%514 = OpShiftLeftLogical %8 %513 %24 -OpStore %488 %514 -%515 = OpLoad %8 %488 -%516 = OpShiftRightArithmetic %8 %515 %25 -OpStore %488 %516 -%517 = OpLoad %8 %488 -%518 = OpIAdd %8 %517 %7 -OpStore %488 %518 -%519 = OpLoad %8 %488 -%520 = OpISub %8 %519 %7 -OpStore %488 %520 -%522 = OpAccessChain %521 %490 %25 -%523 = OpLoad %8 %522 -%524 = OpIAdd %8 %523 %7 -%525 = OpAccessChain %521 %490 %25 -OpStore %525 %524 -%526 = OpAccessChain %521 %490 %25 -%527 = OpLoad %8 %526 -%528 = OpISub %8 %527 %7 -%529 = OpAccessChain %521 %490 %25 -OpStore %529 %528 +%496 = OpFunction %2 None %168 +%495 = OpLabel +%490 = OpVariable %491 Function %492 +%493 = OpVariable %48 Function %494 +OpBranch %497 +%497 = OpLabel +OpStore %490 %7 +%498 = OpLoad %8 %490 +%499 = OpIAdd %8 %498 %7 +OpStore %490 %499 +%500 = OpLoad %8 %490 +%501 = OpISub %8 %500 %7 +OpStore %490 %501 +%502 = OpLoad %8 %490 +%503 = OpLoad %8 %490 +%504 = OpIMul %8 %503 %502 +OpStore %490 %504 +%505 = OpLoad %8 %490 +%506 = OpLoad %8 %490 +%507 = OpSDiv %8 %506 %505 +OpStore %490 %507 +%508 = OpLoad %8 %490 +%509 = OpSRem %8 %508 %7 +OpStore %490 %509 +%510 = OpLoad %8 %490 +%511 = OpBitwiseAnd %8 %510 %11 +OpStore %490 %511 +%512 = OpLoad %8 %490 +%513 = OpBitwiseOr %8 %512 %11 +OpStore %490 %513 +%514 = OpLoad %8 %490 +%515 = OpBitwiseXor %8 %514 %11 +OpStore %490 %515 +%516 = OpLoad %8 %490 +%517 = OpShiftLeftLogical %8 %516 %24 +OpStore %490 %517 +%518 = OpLoad %8 %490 +%519 = OpShiftRightArithmetic %8 %518 %25 +OpStore %490 %519 +%520 = OpLoad %8 %490 +%521 = OpIAdd %8 %520 %7 +OpStore %490 %521 +%522 = OpLoad %8 %490 +%523 = OpISub %8 %522 %7 +OpStore %490 %523 +OpStore %493 %64 +%525 = OpAccessChain %524 %493 %25 +%526 = OpLoad %8 %525 +%527 = OpIAdd %8 %526 %7 +%528 = OpAccessChain %524 %493 %25 +OpStore %528 %527 +%529 = OpAccessChain %524 %493 %25 +%530 = OpLoad %8 %529 +%531 = OpISub %8 %530 %7 +%532 = OpAccessChain %524 %493 %25 +OpStore %532 %531 OpReturn OpFunctionEnd -%531 = OpFunction %2 None %164 -%530 = OpLabel -OpBranch %532 -%532 = OpLabel -%533 = OpFunctionCall %26 %59 -%534 = OpFunctionCall %26 %84 -%535 = OpVectorShuffle %30 %42 %42 0 1 2 -%536 = OpFunctionCall %30 %119 %535 -%537 = OpFunctionCall %4 %132 -%538 = OpFunctionCall %2 %163 -%539 = OpFunctionCall %2 %181 -%540 = OpFunctionCall %2 %365 -%541 = OpFunctionCall %2 %414 -%542 = OpFunctionCall %2 %493 +%534 = OpFunction %2 None %168 +%533 = OpLabel +OpBranch %535 +%535 = OpLabel +%536 = OpFunctionCall %26 %66 +%537 = OpFunctionCall %26 %91 +%538 = OpVectorShuffle %30 %49 %49 0 1 2 +%539 = OpFunctionCall %30 %126 %538 +%540 = OpFunctionCall %4 %137 +%541 = OpFunctionCall %2 %167 +%542 = OpFunctionCall %2 %184 +%543 = OpFunctionCall %2 %367 +%544 = OpFunctionCall %2 %416 +%545 = OpFunctionCall %2 %496 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/padding.spvasm b/tests/out/spv/padding.spvasm index 44ec6a4d19..acaf63374e 100644 --- a/tests/out/spv/padding.spvasm +++ b/tests/out/spv/padding.spvasm @@ -1,27 +1,35 @@ ; SPIR-V ; Version: 1.1 ; Generator: rspirv -; Bound: 50 +; Bound: 49 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %27 "vertex" %25 +OpEntryPoint Vertex %30 "vertex" %28 OpSource GLSL 450 +OpName %7 "vec3" OpMemberName %8 0 "a" OpName %8 "S" +OpName %6 "f32" OpMemberName %9 0 "a" OpMemberName %9 1 "b" OpName %9 "Test" +OpName %10 "array, 2>" OpMemberName %11 0 "a" OpMemberName %11 1 "b" OpName %11 "Test2" +OpName %12 "mat4x3" OpMemberName %13 0 "a" OpMemberName %13 1 "b" OpName %13 "Test3" -OpName %15 "input1" -OpName %18 "input2" -OpName %21 "input3" -OpName %27 "vertex" +OpName %14 "vec4" +OpName %15 "ptr" +OpName %16 "ptr" +OpName %17 "ptr" +OpName %18 "input1" +OpName %21 "input2" +OpName %24 "input3" +OpName %30 "vertex" OpMemberDecorate %8 0 Offset 0 OpMemberDecorate %9 0 Offset 0 OpMemberDecorate %9 1 Offset 16 @@ -32,21 +40,21 @@ OpMemberDecorate %13 0 Offset 0 OpMemberDecorate %13 0 ColMajor OpMemberDecorate %13 0 MatrixStride 16 OpMemberDecorate %13 1 Offset 64 -OpDecorate %15 DescriptorSet 0 -OpDecorate %15 Binding 0 -OpDecorate %16 Block -OpMemberDecorate %16 0 Offset 0 OpDecorate %18 DescriptorSet 0 -OpDecorate %18 Binding 1 +OpDecorate %18 Binding 0 OpDecorate %19 Block OpMemberDecorate %19 0 Offset 0 OpDecorate %21 DescriptorSet 0 -OpDecorate %21 Binding 2 +OpDecorate %21 Binding 1 OpDecorate %22 Block OpMemberDecorate %22 0 Offset 0 -OpDecorate %25 BuiltIn Position +OpDecorate %24 DescriptorSet 0 +OpDecorate %24 Binding 2 +OpDecorate %25 Block +OpMemberDecorate %25 0 Offset 0 +OpDecorate %28 BuiltIn Position %2 = OpTypeVoid -%4 = OpTypeInt 32 1 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 2 %6 = OpTypeFloat 32 %5 = OpConstant %6 1.0 @@ -58,42 +66,41 @@ OpDecorate %25 BuiltIn Position %12 = OpTypeMatrix %7 4 %13 = OpTypeStruct %12 %6 %14 = OpTypeVector %6 4 -%16 = OpTypeStruct %9 -%17 = OpTypePointer Uniform %16 -%15 = OpVariable %17 Uniform -%19 = OpTypeStruct %11 +%15 = OpTypePointer Uniform %9 +%16 = OpTypePointer Uniform %11 +%17 = OpTypePointer Uniform %13 +%19 = OpTypeStruct %9 %20 = OpTypePointer Uniform %19 %18 = OpVariable %20 Uniform -%22 = OpTypeStruct %13 +%22 = OpTypeStruct %11 %23 = OpTypePointer Uniform %22 %21 = OpVariable %23 Uniform -%26 = OpTypePointer Output %14 -%25 = OpVariable %26 Output -%28 = OpTypeFunction %2 -%29 = OpTypePointer Uniform %9 -%31 = OpTypeInt 32 0 -%30 = OpConstant %31 0 -%33 = OpTypePointer Uniform %11 -%35 = OpTypePointer Uniform %13 -%39 = OpTypePointer Uniform %6 -%40 = OpConstant %31 1 -%27 = OpFunction %2 None %28 -%24 = OpLabel -%32 = OpAccessChain %29 %15 %30 -%34 = OpAccessChain %33 %18 %30 -%36 = OpAccessChain %35 %21 %30 -OpBranch %37 -%37 = OpLabel -%38 = OpCompositeConstruct %14 %5 %5 %5 %5 -%41 = OpAccessChain %39 %32 %40 -%42 = OpLoad %6 %41 -%43 = OpVectorTimesScalar %14 %38 %42 -%44 = OpAccessChain %39 %34 %40 -%45 = OpLoad %6 %44 -%46 = OpVectorTimesScalar %14 %43 %45 -%47 = OpAccessChain %39 %36 %40 -%48 = OpLoad %6 %47 -%49 = OpVectorTimesScalar %14 %46 %48 -OpStore %25 %49 +%25 = OpTypeStruct %13 +%26 = OpTypePointer Uniform %25 +%24 = OpVariable %26 Uniform +%29 = OpTypePointer Output %14 +%28 = OpVariable %29 Output +%31 = OpTypeFunction %2 +%32 = OpConstant %4 0 +%38 = OpTypePointer Uniform %6 +%39 = OpConstant %4 1 +%30 = OpFunction %2 None %31 +%27 = OpLabel +%33 = OpAccessChain %15 %18 %32 +%34 = OpAccessChain %16 %21 %32 +%35 = OpAccessChain %17 %24 %32 +OpBranch %36 +%36 = OpLabel +%37 = OpCompositeConstruct %14 %5 %5 %5 %5 +%40 = OpAccessChain %38 %33 %39 +%41 = OpLoad %6 %40 +%42 = OpVectorTimesScalar %14 %37 %41 +%43 = OpAccessChain %38 %34 %39 +%44 = OpLoad %6 %43 +%45 = OpVectorTimesScalar %14 %42 %44 +%46 = OpAccessChain %38 %35 %39 +%47 = OpLoad %6 %46 +%48 = OpVectorTimesScalar %14 %45 %47 +OpStore %28 %48 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/pointers.spvasm b/tests/out/spv/pointers.spvasm index 81a17b558c..63c8faa450 100644 --- a/tests/out/spv/pointers.spvasm +++ b/tests/out/spv/pointers.spvasm @@ -8,71 +8,79 @@ OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpSource GLSL 450 -OpMemberName %8 0 "arr" -OpName %8 "DynamicArray" -OpName %11 "dynamic_array" -OpName %12 "v" -OpName %16 "f" +OpName %5 "vec2" +OpName %6 "ptr>" +OpName %7 "ptr" +OpName %8 "u32" +OpName %9 "array" +OpMemberName %10 0 "arr" +OpName %10 "DynamicArray" +OpName %4 "i32" +OpName %11 "ptr" +OpName %12 "ptr>" +OpName %13 "dynamic_array" +OpName %14 "v" +OpName %17 "f" OpName %23 "i" OpName %24 "v" OpName %25 "index_unsized" OpName %34 "i" OpName %35 "v" OpName %36 "index_dynamic_array" -OpDecorate %7 ArrayStride 4 -OpMemberDecorate %8 0 Offset 0 -OpDecorate %11 DescriptorSet 0 -OpDecorate %11 Binding 0 -OpDecorate %8 Block +OpDecorate %9 ArrayStride 4 +OpMemberDecorate %10 0 Offset 0 +OpDecorate %13 DescriptorSet 0 +OpDecorate %13 Binding 0 +OpDecorate %10 Block %2 = OpTypeVoid %4 = OpTypeInt 32 1 %3 = OpConstant %4 10 %5 = OpTypeVector %4 2 -%6 = OpTypeInt 32 0 -%7 = OpTypeRuntimeArray %6 -%8 = OpTypeStruct %7 -%9 = OpTypePointer StorageBuffer %8 -%10 = OpTypePointer StorageBuffer %7 -%11 = OpVariable %9 StorageBuffer -%13 = OpTypePointer Function %5 -%14 = OpConstantNull %5 -%17 = OpTypeFunction %2 -%19 = OpTypePointer Function %4 -%20 = OpConstant %6 0 -%26 = OpTypeFunction %2 %4 %6 -%28 = OpTypePointer StorageBuffer %6 -%16 = OpFunction %2 None %17 -%15 = OpLabel -%12 = OpVariable %13 Function %14 -OpBranch %18 -%18 = OpLabel -%21 = OpAccessChain %19 %12 %20 +%6 = OpTypePointer Function %5 +%7 = OpTypePointer Function %4 +%8 = OpTypeInt 32 0 +%9 = OpTypeRuntimeArray %8 +%10 = OpTypeStruct %9 +%11 = OpTypePointer StorageBuffer %10 +%12 = OpTypePointer StorageBuffer %9 +%13 = OpVariable %11 StorageBuffer +%15 = OpConstantNull %5 +%18 = OpTypeFunction %2 +%20 = OpConstant %8 0 +%26 = OpTypeFunction %2 %4 %8 +%28 = OpTypePointer StorageBuffer %8 +%17 = OpFunction %2 None %18 +%16 = OpLabel +%14 = OpVariable %6 Function %15 +OpBranch %19 +%19 = OpLabel +%21 = OpAccessChain %7 %14 %20 OpStore %21 %3 OpReturn OpFunctionEnd %25 = OpFunction %2 None %26 %23 = OpFunctionParameter %4 -%24 = OpFunctionParameter %6 +%24 = OpFunctionParameter %8 %22 = OpLabel OpBranch %27 %27 = OpLabel -%29 = OpAccessChain %28 %11 %20 %23 -%30 = OpLoad %6 %29 -%31 = OpIAdd %6 %30 %24 -%32 = OpAccessChain %28 %11 %20 %23 +%29 = OpAccessChain %28 %13 %20 %23 +%30 = OpLoad %8 %29 +%31 = OpIAdd %8 %30 %24 +%32 = OpAccessChain %28 %13 %20 %23 OpStore %32 %31 OpReturn OpFunctionEnd %36 = OpFunction %2 None %26 %34 = OpFunctionParameter %4 -%35 = OpFunctionParameter %6 +%35 = OpFunctionParameter %8 %33 = OpLabel OpBranch %37 %37 = OpLabel -%38 = OpAccessChain %28 %11 %20 %34 -%39 = OpLoad %6 %38 -%40 = OpIAdd %6 %39 %35 -%41 = OpAccessChain %28 %11 %20 %34 +%38 = OpAccessChain %28 %13 %20 %34 +%39 = OpLoad %8 %38 +%40 = OpIAdd %8 %39 %35 +%41 = OpAccessChain %28 %13 %20 %34 OpStore %41 %40 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/policy-mix.spvasm b/tests/out/spv/policy-mix.spvasm index c082d3d469..ce4ec805c0 100644 --- a/tests/out/spv/policy-mix.spvasm +++ b/tests/out/spv/policy-mix.spvasm @@ -9,141 +9,158 @@ OpExtension "SPV_KHR_storage_buffer_storage_class" %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 OpSource GLSL 450 +OpName %13 "vec4" +OpName %14 "array, 10>" OpMemberName %15 0 "a" OpName %15 "InStorage" +OpName %16 "array, 20>" OpMemberName %17 0 "a" OpName %17 "InUniform" -OpName %23 "in_storage" -OpName %26 "in_uniform" -OpName %29 "image_2d_array" -OpName %31 "in_workgroup" -OpName %33 "in_private" -OpName %36 "in_function" -OpName %40 "c" -OpName %41 "i" -OpName %42 "l" -OpName %43 "mock_function" +OpName %18 "texture_2d_array" +OpName %9 "f32" +OpName %19 "array" +OpName %20 "array" +OpName %21 "vec2" +OpName %22 "i32" +OpName %23 "array, 2>" +OpName %24 "ptr" +OpName %25 "ptr, 10>>" +OpName %26 "ptr" +OpName %27 "ptr, 20>>" +OpName %28 "ptr>" +OpName %29 "ptr>" +OpName %30 "ptr, 2>>" +OpName %31 "in_storage" +OpName %34 "in_uniform" +OpName %37 "image_2d_array" +OpName %39 "in_workgroup" +OpName %40 "in_private" +OpName %42 "in_function" +OpName %45 "c" +OpName %46 "i" +OpName %47 "l" +OpName %48 "mock_function" OpDecorate %14 ArrayStride 16 OpMemberDecorate %15 0 Offset 0 OpDecorate %16 ArrayStride 16 OpMemberDecorate %17 0 Offset 0 OpDecorate %19 ArrayStride 4 OpDecorate %20 ArrayStride 4 -OpDecorate %22 ArrayStride 16 -OpDecorate %23 NonWritable -OpDecorate %23 DescriptorSet 0 -OpDecorate %23 Binding 0 -OpDecorate %24 Block -OpMemberDecorate %24 0 Offset 0 -OpDecorate %26 DescriptorSet 0 -OpDecorate %26 Binding 1 -OpDecorate %27 Block -OpMemberDecorate %27 0 Offset 0 -OpDecorate %29 DescriptorSet 0 -OpDecorate %29 Binding 2 +OpDecorate %23 ArrayStride 16 +OpDecorate %31 NonWritable +OpDecorate %31 DescriptorSet 0 +OpDecorate %31 Binding 0 +OpDecorate %32 Block +OpMemberDecorate %32 0 Offset 0 +OpDecorate %34 DescriptorSet 0 +OpDecorate %34 Binding 1 +OpDecorate %35 Block +OpMemberDecorate %35 0 Offset 0 +OpDecorate %37 DescriptorSet 0 +OpDecorate %37 Binding 2 %2 = OpTypeVoid -%4 = OpTypeInt 32 1 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 10 %5 = OpConstant %4 20 %6 = OpConstant %4 30 %7 = OpConstant %4 40 -%8 = OpConstant %4 2 -%10 = OpTypeFloat 32 -%9 = OpConstant %10 0.707 -%11 = OpConstant %10 0.0 -%12 = OpConstant %10 1.0 -%13 = OpTypeVector %10 4 +%9 = OpTypeFloat 32 +%8 = OpConstant %9 0.707 +%10 = OpConstant %9 0.0 +%11 = OpConstant %9 1.0 +%12 = OpConstant %4 2 +%13 = OpTypeVector %9 4 %14 = OpTypeArray %13 %3 %15 = OpTypeStruct %14 %16 = OpTypeArray %13 %5 %17 = OpTypeStruct %16 -%18 = OpTypeImage %10 2D 0 1 0 1 Unknown -%19 = OpTypeArray %10 %6 -%20 = OpTypeArray %10 %7 -%21 = OpTypeVector %4 2 -%22 = OpTypeArray %13 %8 -%24 = OpTypeStruct %15 -%25 = OpTypePointer StorageBuffer %24 -%23 = OpVariable %25 StorageBuffer -%27 = OpTypeStruct %17 -%28 = OpTypePointer Uniform %27 -%26 = OpVariable %28 Uniform -%30 = OpTypePointer UniformConstant %18 -%29 = OpVariable %30 UniformConstant -%32 = OpTypePointer Workgroup %19 -%31 = OpVariable %32 Workgroup -%34 = OpTypePointer Private %20 -%35 = OpConstantNull %20 -%33 = OpVariable %34 Private %35 -%37 = OpTypePointer Function %22 -%38 = OpConstantNull %22 -%44 = OpTypeFunction %13 %21 %4 %4 -%45 = OpTypePointer StorageBuffer %15 -%47 = OpTypeInt 32 0 -%46 = OpConstant %47 0 -%49 = OpTypePointer Uniform %17 -%56 = OpTypePointer StorageBuffer %14 -%57 = OpTypePointer StorageBuffer %13 -%60 = OpTypePointer Uniform %16 +%18 = OpTypeImage %9 2D 0 1 0 1 Unknown +%19 = OpTypeArray %9 %6 +%20 = OpTypeArray %9 %7 +%22 = OpTypeInt 32 1 +%21 = OpTypeVector %22 2 +%23 = OpTypeArray %13 %12 +%24 = OpTypePointer StorageBuffer %15 +%25 = OpTypePointer StorageBuffer %14 +%26 = OpTypePointer Uniform %17 +%27 = OpTypePointer Uniform %16 +%28 = OpTypePointer Workgroup %19 +%29 = OpTypePointer Private %20 +%30 = OpTypePointer Function %23 +%32 = OpTypeStruct %15 +%33 = OpTypePointer StorageBuffer %32 +%31 = OpVariable %33 StorageBuffer +%35 = OpTypeStruct %17 +%36 = OpTypePointer Uniform %35 +%34 = OpVariable %36 Uniform +%38 = OpTypePointer UniformConstant %18 +%37 = OpVariable %38 UniformConstant +%39 = OpVariable %28 Workgroup +%41 = OpConstantNull %20 +%40 = OpVariable %29 Private %41 +%43 = OpConstantNull %23 +%49 = OpTypeFunction %13 %21 %22 %22 +%50 = OpConstant %4 0 +%58 = OpTypePointer StorageBuffer %13 %61 = OpTypePointer Uniform %13 -%65 = OpTypeVector %4 3 +%65 = OpTypeVector %22 3 %67 = OpTypeBool %68 = OpConstantNull %13 %74 = OpTypeVector %67 3 -%81 = OpTypePointer Workgroup %10 -%82 = OpConstant %47 29 -%88 = OpTypePointer Private %10 -%89 = OpConstant %47 39 +%81 = OpTypePointer Workgroup %9 +%82 = OpConstant %4 29 +%88 = OpTypePointer Private %9 +%89 = OpConstant %4 39 %95 = OpTypePointer Function %13 -%96 = OpConstant %47 1 -%43 = OpFunction %13 None %44 -%40 = OpFunctionParameter %21 -%41 = OpFunctionParameter %4 -%42 = OpFunctionParameter %4 -%39 = OpLabel -%36 = OpVariable %37 Function %38 -%48 = OpAccessChain %45 %23 %46 -%50 = OpAccessChain %49 %26 %46 -%51 = OpLoad %18 %29 -OpBranch %52 -%52 = OpLabel -%53 = OpCompositeConstruct %13 %9 %11 %11 %12 -%54 = OpCompositeConstruct %13 %11 %9 %11 %12 -%55 = OpCompositeConstruct %22 %53 %54 -OpStore %36 %55 -%58 = OpAccessChain %57 %48 %46 %41 -%59 = OpLoad %13 %58 -%62 = OpAccessChain %61 %50 %46 %41 +%96 = OpConstant %4 1 +%48 = OpFunction %13 None %49 +%45 = OpFunctionParameter %21 +%46 = OpFunctionParameter %22 +%47 = OpFunctionParameter %22 +%44 = OpLabel +%42 = OpVariable %30 Function %43 +%51 = OpAccessChain %24 %31 %50 +%52 = OpAccessChain %26 %34 %50 +%53 = OpLoad %18 %37 +OpBranch %54 +%54 = OpLabel +%55 = OpCompositeConstruct %13 %8 %10 %10 %11 +%56 = OpCompositeConstruct %13 %10 %8 %10 %11 +%57 = OpCompositeConstruct %23 %55 %56 +OpStore %42 %57 +%59 = OpAccessChain %58 %51 %50 %46 +%60 = OpLoad %13 %59 +%62 = OpAccessChain %61 %52 %50 %46 %63 = OpLoad %13 %62 -%64 = OpFAdd %13 %59 %63 -%66 = OpCompositeConstruct %65 %40 %41 -%69 = OpImageQueryLevels %4 %51 -%70 = OpULessThan %67 %42 %69 +%64 = OpFAdd %13 %60 %63 +%66 = OpCompositeConstruct %65 %45 %46 +%69 = OpImageQueryLevels %22 %53 +%70 = OpULessThan %67 %47 %69 OpSelectionMerge %71 None OpBranchConditional %70 %72 %71 %72 = OpLabel -%73 = OpImageQuerySizeLod %65 %51 %42 +%73 = OpImageQuerySizeLod %65 %53 %47 %75 = OpULessThan %74 %66 %73 %76 = OpAll %67 %75 OpBranchConditional %76 %77 %71 %77 = OpLabel -%78 = OpImageFetch %13 %51 %66 Lod %42 +%78 = OpImageFetch %13 %53 %66 Lod %47 OpBranch %71 %71 = OpLabel -%79 = OpPhi %13 %68 %52 %68 %72 %78 %77 +%79 = OpPhi %13 %68 %54 %68 %72 %78 %77 %80 = OpFAdd %13 %64 %79 -%83 = OpExtInst %47 %1 UMin %41 %82 -%84 = OpAccessChain %81 %31 %83 -%85 = OpLoad %10 %84 +%83 = OpExtInst %4 %1 UMin %46 %82 +%84 = OpAccessChain %81 %39 %83 +%85 = OpLoad %9 %84 %86 = OpCompositeConstruct %13 %85 %85 %85 %85 %87 = OpFAdd %13 %80 %86 -%90 = OpExtInst %47 %1 UMin %41 %89 -%91 = OpAccessChain %88 %33 %90 -%92 = OpLoad %10 %91 +%90 = OpExtInst %4 %1 UMin %46 %89 +%91 = OpAccessChain %88 %40 %90 +%92 = OpLoad %9 %91 %93 = OpCompositeConstruct %13 %92 %92 %92 %92 %94 = OpFAdd %13 %87 %93 -%97 = OpExtInst %47 %1 UMin %41 %96 -%98 = OpAccessChain %95 %36 %97 +%97 = OpExtInst %4 %1 UMin %46 %96 +%98 = OpAccessChain %95 %42 %97 %99 = OpLoad %13 %98 %100 = OpFAdd %13 %94 %99 OpReturnValue %100 diff --git a/tests/out/spv/quad.spvasm b/tests/out/spv/quad.spvasm index bb0409d141..6ed4bbfd76 100644 --- a/tests/out/spv/quad.spvasm +++ b/tests/out/spv/quad.spvasm @@ -12,9 +12,14 @@ OpExecutionMode %45 OriginUpperLeft OpExecutionMode %61 OriginUpperLeft OpSource GLSL 450 OpName %3 "c_scale" +OpName %4 "f32" +OpName %8 "vec2" +OpName %9 "vec4" OpMemberName %10 0 "uv" OpMemberName %10 1 "position" OpName %10 "VertexOutput" +OpName %11 "texture_2d" +OpName %12 "sampler" OpName %13 "u_texture" OpName %15 "u_sampler" OpName %18 "pos" diff --git a/tests/out/spv/shadow.spvasm b/tests/out/spv/shadow.spvasm index e20fcebc5e..fc097455cf 100644 --- a/tests/out/spv/shadow.spvasm +++ b/tests/out/spv/shadow.spvasm @@ -1,414 +1,459 @@ ; SPIR-V ; Version: 1.2 ; Generator: rspirv -; Bound: 262 +; Bound: 274 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 Fragment %148 "fs_main" %139 %142 %145 %147 -OpEntryPoint Fragment %212 "fs_main_without_storage" %205 %207 %209 %211 -OpExecutionMode %148 OriginUpperLeft -OpExecutionMode %212 OriginUpperLeft +OpEntryPoint Vertex %96 "vs_main" %86 %89 %91 %93 %95 +OpEntryPoint Fragment %151 "fs_main" %142 %145 %148 %150 +OpEntryPoint Fragment %220 "fs_main_without_storage" %213 %215 %217 %219 +OpExecutionMode %151 OriginUpperLeft +OpExecutionMode %220 OriginUpperLeft OpSource GLSL 450 -OpName %11 "c_max_lights" -OpMemberName %18 0 "view_proj" -OpMemberName %18 1 "num_lights" -OpName %18 "Globals" -OpMemberName %19 0 "world" -OpMemberName %19 1 "color" -OpName %19 "Entity" -OpMemberName %21 0 "proj_position" -OpMemberName %21 1 "world_normal" -OpMemberName %21 2 "world_position" -OpName %21 "VertexOutput" -OpMemberName %24 0 "proj" -OpMemberName %24 1 "pos" -OpMemberName %24 2 "color" -OpName %24 "Light" -OpName %30 "c_ambient" -OpName %31 "u_globals" -OpName %34 "u_entity" -OpName %37 "s_lights" -OpName %40 "u_lights" -OpName %43 "t_shadow" -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 %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" -OpMemberDecorate %18 0 Offset 0 -OpMemberDecorate %18 0 ColMajor -OpMemberDecorate %18 0 MatrixStride 16 -OpMemberDecorate %18 1 Offset 64 +OpName %10 "c_max_lights" +OpName %13 "mat4x4" +OpName %15 "vec4" +OpMemberName %16 0 "view_proj" +OpMemberName %16 1 "num_lights" +OpName %16 "Globals" +OpName %14 "vec4" +OpMemberName %17 0 "world" +OpMemberName %17 1 "color" +OpName %17 "Entity" +OpName %18 "vec3" +OpMemberName %19 0 "proj_position" +OpMemberName %19 1 "world_normal" +OpMemberName %19 2 "world_position" +OpName %19 "VertexOutput" +OpName %20 "vec4" +OpName %22 "ptr" +OpName %23 "mat3x3" +OpName %24 "vec3" +OpName %25 "ptr" +OpName %26 "ptr" +OpMemberName %27 0 "proj" +OpMemberName %27 1 "pos" +OpMemberName %27 2 "color" +OpName %27 "Light" +OpName %28 "array" +OpName %29 "array" +OpName %30 "texture_depth_2d_array" +OpName %31 "sampler_comparison" +OpName %4 "u32" +OpName %6 "f32" +OpName %32 "vec2" +OpName %21 "i32" +OpName %33 "ptr>" +OpName %34 "ptr>" +OpName %35 "ptr>" +OpName %36 "c_ambient" +OpName %37 "u_globals" +OpName %40 "u_entity" +OpName %43 "s_lights" +OpName %46 "u_lights" +OpName %49 "t_shadow" +OpName %51 "sampler_shadow" +OpName %54 "light_id" +OpName %55 "homogeneous_coords" +OpName %56 "fetch_shadow" +OpName %83 "out" +OpName %86 "position" +OpName %89 "normal" +OpName %91 "proj_position" +OpName %93 "world_normal" +OpName %95 "world_position" +OpName %96 "vs_main" +OpName %135 "color" +OpName %137 "i" +OpName %142 "proj_position" +OpName %145 "world_normal" +OpName %148 "world_position" +OpName %151 "fs_main" +OpName %207 "color" +OpName %209 "i" +OpName %213 "proj_position" +OpName %215 "world_normal" +OpName %217 "world_position" +OpName %220 "fs_main_without_storage" +OpMemberDecorate %16 0 Offset 0 +OpMemberDecorate %16 0 ColMajor +OpMemberDecorate %16 0 MatrixStride 16 +OpMemberDecorate %16 1 Offset 64 +OpMemberDecorate %17 0 Offset 0 +OpMemberDecorate %17 0 ColMajor +OpMemberDecorate %17 0 MatrixStride 16 +OpMemberDecorate %17 1 Offset 64 OpMemberDecorate %19 0 Offset 0 -OpMemberDecorate %19 0 ColMajor -OpMemberDecorate %19 0 MatrixStride 16 -OpMemberDecorate %19 1 Offset 64 -OpMemberDecorate %21 0 Offset 0 -OpMemberDecorate %21 1 Offset 16 -OpMemberDecorate %21 2 Offset 32 -OpMemberDecorate %24 0 Offset 0 -OpMemberDecorate %24 0 ColMajor -OpMemberDecorate %24 0 MatrixStride 16 -OpMemberDecorate %24 1 Offset 64 -OpMemberDecorate %24 2 Offset 80 -OpDecorate %25 ArrayStride 96 -OpDecorate %26 ArrayStride 96 -OpDecorate %31 DescriptorSet 0 -OpDecorate %31 Binding 0 -OpDecorate %32 Block -OpMemberDecorate %32 0 Offset 0 -OpDecorate %34 DescriptorSet 1 -OpDecorate %34 Binding 0 -OpDecorate %35 Block -OpMemberDecorate %35 0 Offset 0 -OpDecorate %37 NonWritable +OpMemberDecorate %19 1 Offset 16 +OpMemberDecorate %19 2 Offset 32 +OpMemberDecorate %27 0 Offset 0 +OpMemberDecorate %27 0 ColMajor +OpMemberDecorate %27 0 MatrixStride 16 +OpMemberDecorate %27 1 Offset 64 +OpMemberDecorate %27 2 Offset 80 +OpDecorate %28 ArrayStride 96 +OpDecorate %29 ArrayStride 96 OpDecorate %37 DescriptorSet 0 -OpDecorate %37 Binding 1 +OpDecorate %37 Binding 0 OpDecorate %38 Block OpMemberDecorate %38 0 Offset 0 -OpDecorate %40 DescriptorSet 0 -OpDecorate %40 Binding 1 +OpDecorate %40 DescriptorSet 1 +OpDecorate %40 Binding 0 OpDecorate %41 Block OpMemberDecorate %41 0 Offset 0 +OpDecorate %43 NonWritable 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 %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 %43 Binding 1 +OpDecorate %44 Block +OpMemberDecorate %44 0 Offset 0 +OpDecorate %46 DescriptorSet 0 +OpDecorate %46 Binding 1 +OpDecorate %47 Block +OpMemberDecorate %47 0 Offset 0 +OpDecorate %49 DescriptorSet 0 +OpDecorate %49 Binding 2 +OpDecorate %51 DescriptorSet 0 +OpDecorate %51 Binding 3 +OpDecorate %86 Location 0 +OpDecorate %89 Location 1 +OpDecorate %91 BuiltIn Position +OpDecorate %93 Location 0 +OpDecorate %95 Location 1 +OpDecorate %142 BuiltIn FragCoord +OpDecorate %145 Location 0 +OpDecorate %148 Location 1 +OpDecorate %150 Location 0 +OpDecorate %213 BuiltIn FragCoord +OpDecorate %215 Location 0 +OpDecorate %217 Location 1 +OpDecorate %219 Location 0 %2 = OpTypeVoid -%4 = OpTypeInt 32 1 +%4 = OpTypeInt 32 0 %3 = OpConstant %4 10 %6 = OpTypeFloat 32 %5 = OpConstant %6 0.0 %7 = OpConstant %6 1.0 %8 = OpConstant %6 0.5 -%9 = OpConstant %6 -0.5 -%10 = OpConstant %6 0.05 -%12 = OpTypeInt 32 0 -%11 = OpConstant %12 10 -%13 = OpConstant %12 0 -%14 = OpConstant %12 1 -%16 = OpTypeVector %6 4 -%15 = OpTypeMatrix %16 4 -%17 = OpTypeVector %12 4 -%18 = OpTypeStruct %15 %17 -%19 = OpTypeStruct %15 %16 -%20 = OpTypeVector %6 3 -%21 = OpTypeStruct %16 %20 %16 -%22 = OpTypeVector %4 4 -%23 = OpTypeMatrix %20 3 -%24 = OpTypeStruct %15 %16 %16 -%25 = OpTypeRuntimeArray %24 -%26 = OpTypeArray %24 %3 -%27 = OpTypeImage %6 2D 1 1 0 1 Unknown -%28 = OpTypeSampler -%29 = OpTypeVector %6 2 -%30 = OpConstantComposite %20 %10 %10 %10 -%32 = OpTypeStruct %18 -%33 = OpTypePointer Uniform %32 -%31 = OpVariable %33 Uniform -%35 = OpTypeStruct %19 -%36 = OpTypePointer Uniform %35 -%34 = OpVariable %36 Uniform -%38 = OpTypeStruct %25 -%39 = OpTypePointer StorageBuffer %38 -%37 = OpVariable %39 StorageBuffer -%41 = OpTypeStruct %26 +%9 = OpConstant %6 0.05 +%10 = OpConstant %4 10 +%11 = OpConstant %4 0 +%12 = OpConstant %4 1 +%14 = OpTypeVector %6 4 +%13 = OpTypeMatrix %14 4 +%15 = OpTypeVector %4 4 +%16 = OpTypeStruct %13 %15 +%17 = OpTypeStruct %13 %14 +%18 = OpTypeVector %6 3 +%19 = OpTypeStruct %14 %18 %14 +%21 = OpTypeInt 32 1 +%20 = OpTypeVector %21 4 +%22 = OpTypePointer Uniform %17 +%23 = OpTypeMatrix %18 3 +%24 = OpTypeVector %21 3 +%25 = OpTypePointer Function %19 +%26 = OpTypePointer Uniform %16 +%27 = OpTypeStruct %13 %14 %14 +%28 = OpTypeRuntimeArray %27 +%29 = OpTypeArray %27 %3 +%30 = OpTypeImage %6 2D 1 1 0 1 Unknown +%31 = OpTypeSampler +%32 = OpTypeVector %6 2 +%33 = OpTypePointer Uniform %15 +%34 = OpTypePointer StorageBuffer %28 +%35 = OpTypePointer Uniform %29 +%36 = OpConstantComposite %18 %9 %9 %9 +%38 = OpTypeStruct %16 +%39 = OpTypePointer Uniform %38 +%37 = OpVariable %39 Uniform +%41 = OpTypeStruct %17 %42 = OpTypePointer Uniform %41 %40 = OpVariable %42 Uniform -%44 = OpTypePointer UniformConstant %27 -%43 = OpVariable %44 UniformConstant -%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 +%44 = OpTypeStruct %28 +%45 = OpTypePointer StorageBuffer %44 +%43 = OpVariable %45 StorageBuffer +%47 = OpTypeStruct %29 +%48 = OpTypePointer Uniform %47 +%46 = OpVariable %48 Uniform +%50 = OpTypePointer UniformConstant %30 +%49 = OpVariable %50 UniformConstant +%52 = OpTypePointer UniformConstant %31 +%51 = OpVariable %52 UniformConstant +%57 = OpTypeFunction %6 %4 %14 +%62 = OpTypeBool +%78 = OpTypeSampledImage %30 +%84 = OpConstantNull %19 +%87 = OpTypePointer Input %20 +%86 = OpVariable %87 Input +%89 = OpVariable %87 Input +%92 = OpTypePointer Output %14 %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 -%140 = OpTypePointer Input %16 -%139 = OpVariable %140 Input -%143 = OpTypePointer Input %20 +%94 = OpTypePointer Output %18 +%93 = OpVariable %94 Output +%95 = OpVariable %92 Output +%97 = OpTypeFunction %2 +%101 = OpTypePointer Uniform %13 +%118 = OpTypePointer Function %18 +%120 = OpTypePointer Function %14 +%121 = OpConstant %4 2 +%129 = OpTypePointer Output %6 +%136 = OpConstantNull %18 +%138 = OpTypePointer Function %4 +%139 = OpConstantNull %4 +%143 = OpTypePointer Input %14 %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 -%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 +%146 = OpTypePointer Input %18 +%145 = OpVariable %146 Input +%148 = OpVariable %143 Input +%150 = OpVariable %92 Output +%167 = OpTypePointer Uniform %4 +%177 = OpTypePointer StorageBuffer %27 +%203 = OpTypePointer Uniform %14 +%208 = OpConstantNull %18 +%210 = OpConstantNull %4 +%213 = OpVariable %143 Input +%215 = OpVariable %146 Input +%217 = OpVariable %143 Input +%219 = OpVariable %92 Output +%245 = OpTypePointer Uniform %27 +%56 = OpFunction %6 None %57 +%54 = OpFunctionParameter %4 +%55 = OpFunctionParameter %14 +%53 = OpLabel +%58 = OpLoad %30 %49 +%59 = OpLoad %31 %51 +OpBranch %60 +%60 = OpLabel +%61 = OpCompositeExtract %6 %55 3 +%63 = OpFOrdLessThanEqual %62 %61 %5 +OpSelectionMerge %64 None +OpBranchConditional %63 %65 %64 +%65 = 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 +%64 = OpLabel +%66 = OpFNegate %6 %8 +%67 = OpCompositeConstruct %32 %8 %66 +%68 = OpCompositeExtract %6 %55 3 +%69 = OpFDiv %6 %7 %68 +%70 = OpVectorShuffle %32 %55 %55 0 1 +%71 = OpFMul %32 %70 %67 +%72 = OpVectorTimesScalar %32 %71 %69 +%73 = OpCompositeConstruct %32 %8 %8 +%74 = OpFAdd %32 %72 %73 +%75 = OpBitcast %21 %54 +%76 = OpCompositeExtract %6 %55 2 +%77 = OpFMul %6 %76 %69 +%79 = OpConvertUToF %6 %75 +%80 = OpCompositeConstruct %18 %74 %79 +%81 = OpSampledImage %78 %58 %59 +%82 = OpImageSampleDrefExplicitLod %6 %81 %80 %77 Lod %5 +OpReturnValue %82 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 -%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 -%108 = OpVectorShuffle %20 %107 %107 0 1 2 -%109 = OpCompositeExtract %16 %101 1 -%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 +%96 = OpFunction %2 None %97 +%85 = OpLabel +%83 = OpVariable %25 Function %84 +%88 = OpLoad %20 %86 +%90 = OpLoad %20 %89 +%98 = OpAccessChain %26 %37 %11 +%99 = OpAccessChain %22 %40 %11 +OpBranch %100 +%100 = OpLabel +%102 = OpAccessChain %101 %99 %11 +%103 = OpLoad %13 %102 +%104 = OpAccessChain %101 %99 %11 +%105 = OpLoad %13 %104 +%106 = OpConvertSToF %14 %88 +%107 = OpMatrixTimesVector %14 %105 %106 +%108 = OpCompositeExtract %14 %103 0 +%109 = OpVectorShuffle %18 %108 %108 0 1 2 +%110 = OpCompositeExtract %14 %103 1 +%111 = OpVectorShuffle %18 %110 %110 0 1 2 +%112 = OpCompositeExtract %14 %103 2 +%113 = OpVectorShuffle %18 %112 %112 0 1 2 +%114 = OpCompositeConstruct %23 %109 %111 %113 +%115 = OpVectorShuffle %24 %90 %90 0 1 2 +%116 = OpConvertSToF %18 %115 +%117 = OpMatrixTimesVector %18 %114 %116 +%119 = OpAccessChain %118 %83 %12 +OpStore %119 %117 +%122 = OpAccessChain %120 %83 %121 +OpStore %122 %107 +%123 = OpAccessChain %101 %98 %11 +%124 = OpLoad %13 %123 +%125 = OpMatrixTimesVector %14 %124 %107 +%126 = OpAccessChain %120 %83 %11 +OpStore %126 %125 +%127 = OpLoad %19 %83 +%128 = OpCompositeExtract %14 %127 0 +OpStore %91 %128 +%130 = OpAccessChain %129 %91 %12 +%131 = OpLoad %6 %130 +%132 = OpFNegate %6 %131 +OpStore %130 %132 +%133 = OpCompositeExtract %18 %127 1 OpStore %93 %133 +%134 = OpCompositeExtract %14 %127 2 +OpStore %95 %134 OpReturn OpFunctionEnd -%148 = OpFunction %2 None %95 -%137 = OpLabel -%134 = OpVariable %106 Function %30 -%135 = OpVariable %136 Function %13 -%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 +%151 = OpFunction %2 None %97 +%140 = OpLabel +%135 = OpVariable %118 Function %136 +%137 = OpVariable %138 Function %139 +%144 = OpLoad %14 %142 +%147 = OpLoad %18 %145 +%149 = OpLoad %14 %148 +%141 = OpCompositeConstruct %19 %144 %147 %149 +%152 = OpAccessChain %26 %37 %11 +%153 = OpAccessChain %22 %40 %11 +%154 = OpAccessChain %34 %43 %11 +%155 = OpLoad %30 %49 +%156 = OpLoad %31 %51 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 -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 = OpCompositeExtract %18 %141 1 +%159 = OpExtInst %18 %1 Normalize %158 +OpStore %135 %36 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 +OpStore %137 %11 +OpBranch %162 +%162 = OpLabel +OpLoopMerge %163 %165 None +OpBranch %164 +%164 = OpLabel +%166 = OpLoad %4 %137 +%168 = OpAccessChain %167 %152 %12 %11 +%169 = OpLoad %4 %168 +%170 = OpExtInst %4 %1 UMin %169 %10 +%171 = OpULessThan %62 %166 %170 +OpSelectionMerge %172 None +OpBranchConditional %171 %172 %173 +%173 = OpLabel +OpBranch %163 +%172 = OpLabel +OpBranch %174 +%174 = OpLabel +%176 = OpLoad %4 %137 +%178 = OpAccessChain %177 %154 %176 +%179 = OpLoad %27 %178 +%180 = OpLoad %4 %137 +%181 = OpCompositeExtract %13 %179 0 +%182 = OpCompositeExtract %14 %141 2 +%183 = OpMatrixTimesVector %14 %181 %182 +%184 = OpFunctionCall %6 %56 %180 %183 +%185 = OpCompositeExtract %14 %179 1 +%186 = OpVectorShuffle %18 %185 %185 0 1 2 +%187 = OpCompositeExtract %14 %141 2 +%188 = OpVectorShuffle %18 %187 %187 0 1 2 +%189 = OpFSub %18 %186 %188 +%190 = OpExtInst %18 %1 Normalize %189 +%191 = OpDot %6 %159 %190 +%192 = OpExtInst %6 %1 FMax %5 %191 +%193 = OpFMul %6 %184 %192 +%194 = OpCompositeExtract %14 %179 2 +%195 = OpVectorShuffle %18 %194 %194 0 1 2 +%196 = OpVectorTimesScalar %18 %195 %193 +%197 = OpLoad %18 %135 +%198 = OpFAdd %18 %197 %196 +OpStore %135 %198 +OpBranch %175 +%175 = OpLabel +OpBranch %165 +%165 = OpLabel +%199 = OpLoad %4 %137 +%200 = OpIAdd %4 %199 %12 +OpStore %137 %200 +OpBranch %162 +%163 = OpLabel +OpBranch %161 +%161 = OpLabel +%201 = OpLoad %18 %135 +%202 = OpCompositeConstruct %14 %201 %7 +%204 = OpAccessChain %203 %153 %12 +%205 = OpLoad %14 %204 +%206 = OpFMul %14 %202 %205 +OpStore %150 %206 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 +%220 = OpFunction %2 None %97 +%211 = OpLabel +%207 = OpVariable %118 Function %208 +%209 = OpVariable %138 Function %210 +%214 = OpLoad %14 %213 +%216 = OpLoad %18 %215 +%218 = OpLoad %14 %217 +%212 = OpCompositeConstruct %19 %214 %216 %218 +%221 = OpAccessChain %26 %37 %11 +%222 = OpAccessChain %22 %40 %11 +%223 = OpAccessChain %35 %46 %11 +%224 = OpLoad %30 %49 +%225 = OpLoad %31 %51 +OpBranch %226 +%226 = OpLabel +%227 = OpCompositeExtract %18 %212 1 +%228 = OpExtInst %18 %1 Normalize %227 +OpStore %207 %36 +OpBranch %229 +%229 = OpLabel +OpStore %209 %11 +OpBranch %231 %231 = OpLabel -OpBranch %222 +OpLoopMerge %232 %234 None +OpBranch %233 +%233 = OpLabel +%235 = OpLoad %4 %209 +%236 = OpAccessChain %167 %221 %12 %11 +%237 = OpLoad %4 %236 +%238 = OpExtInst %4 %1 UMin %237 %10 +%239 = OpULessThan %62 %235 %238 +OpSelectionMerge %240 None +OpBranchConditional %239 %240 %241 +%241 = OpLabel +OpBranch %232 +%240 = OpLabel +OpBranch %242 +%242 = OpLabel +%244 = OpLoad %4 %209 +%246 = OpAccessChain %245 %223 %244 +%247 = OpLoad %27 %246 +%248 = OpLoad %4 %209 +%249 = OpCompositeExtract %13 %247 0 +%250 = OpCompositeExtract %14 %212 2 +%251 = OpMatrixTimesVector %14 %249 %250 +%252 = OpFunctionCall %6 %56 %248 %251 +%253 = OpCompositeExtract %14 %247 1 +%254 = OpVectorShuffle %18 %253 %253 0 1 2 +%255 = OpCompositeExtract %14 %212 2 +%256 = OpVectorShuffle %18 %255 %255 0 1 2 +%257 = OpFSub %18 %254 %256 +%258 = OpExtInst %18 %1 Normalize %257 +%259 = OpDot %6 %228 %258 +%260 = OpExtInst %6 %1 FMax %5 %259 +%261 = OpFMul %6 %252 %260 +%262 = OpCompositeExtract %14 %247 2 +%263 = OpVectorShuffle %18 %262 %262 0 1 2 +%264 = OpVectorTimesScalar %18 %263 %261 +%265 = OpLoad %18 %207 +%266 = OpFAdd %18 %265 %264 +OpStore %207 %266 +OpBranch %243 +%243 = OpLabel +OpBranch %234 +%234 = OpLabel +%267 = OpLoad %4 %209 +%268 = OpIAdd %4 %267 %12 +OpStore %209 %268 +OpBranch %231 +%232 = OpLabel +OpBranch %230 %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 -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 +%269 = OpLoad %18 %207 +%270 = OpCompositeConstruct %14 %269 %7 +%271 = OpAccessChain %203 %222 %12 +%272 = OpLoad %14 %271 +%273 = OpFMul %14 %270 %272 +OpStore %219 %273 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/skybox.spvasm b/tests/out/spv/skybox.spvasm index ca51a06dd8..499b67510f 100644 --- a/tests/out/spv/skybox.spvasm +++ b/tests/out/spv/skybox.spvasm @@ -1,35 +1,35 @@ ; SPIR-V ; Version: 1.0 ; Generator: rspirv -; Bound: 98 +; Bound: 99 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" OpMemoryModel Logical GLSL450 -OpEntryPoint Vertex %39 "vs_main" %32 %35 %37 -OpEntryPoint Fragment %90 "fs_main" %83 %86 %89 -OpExecutionMode %90 OriginUpperLeft -OpMemberDecorate %12 0 Offset 0 -OpMemberDecorate %12 1 Offset 16 -OpMemberDecorate %14 0 Offset 0 -OpMemberDecorate %14 0 ColMajor -OpMemberDecorate %14 0 MatrixStride 16 -OpMemberDecorate %14 1 Offset 64 -OpMemberDecorate %14 1 ColMajor -OpMemberDecorate %14 1 MatrixStride 16 -OpDecorate %19 DescriptorSet 0 -OpDecorate %19 Binding 0 -OpDecorate %20 Block -OpMemberDecorate %20 0 Offset 0 -OpDecorate %22 DescriptorSet 0 -OpDecorate %22 Binding 1 -OpDecorate %24 DescriptorSet 0 -OpDecorate %24 Binding 2 -OpDecorate %32 BuiltIn VertexIndex -OpDecorate %35 BuiltIn Position -OpDecorate %37 Location 0 -OpDecorate %83 BuiltIn FragCoord -OpDecorate %86 Location 0 -OpDecorate %89 Location 0 +OpEntryPoint Vertex %43 "vs_main" %36 %39 %41 +OpEntryPoint Fragment %91 "fs_main" %84 %87 %90 +OpExecutionMode %91 OriginUpperLeft +OpMemberDecorate %13 0 Offset 0 +OpMemberDecorate %13 1 Offset 16 +OpMemberDecorate %15 0 Offset 0 +OpMemberDecorate %15 0 ColMajor +OpMemberDecorate %15 0 MatrixStride 16 +OpMemberDecorate %15 1 Offset 64 +OpMemberDecorate %15 1 ColMajor +OpMemberDecorate %15 1 MatrixStride 16 +OpDecorate %23 DescriptorSet 0 +OpDecorate %23 Binding 0 +OpDecorate %24 Block +OpMemberDecorate %24 0 Offset 0 +OpDecorate %26 DescriptorSet 0 +OpDecorate %26 Binding 1 +OpDecorate %28 DescriptorSet 0 +OpDecorate %28 Binding 2 +OpDecorate %36 BuiltIn VertexIndex +OpDecorate %39 BuiltIn Position +OpDecorate %41 Location 0 +OpDecorate %84 BuiltIn FragCoord +OpDecorate %87 Location 0 +OpDecorate %90 Location 0 %2 = OpTypeVoid %4 = OpTypeInt 32 1 %3 = OpConstant %4 2 @@ -38,102 +38,103 @@ OpDecorate %89 Location 0 %6 = OpConstant %7 4.0 %8 = OpConstant %7 1.0 %9 = OpConstant %7 0.0 -%10 = OpTypeVector %7 4 -%11 = OpTypeVector %7 3 -%12 = OpTypeStruct %10 %11 -%13 = OpTypeMatrix %10 4 -%14 = OpTypeStruct %13 %13 -%15 = OpTypeInt 32 0 -%16 = OpTypeMatrix %11 3 -%17 = OpTypeImage %7 Cube 0 0 0 1 Unknown -%18 = OpTypeSampler -%20 = OpTypeStruct %14 -%21 = OpTypePointer Uniform %20 -%19 = OpVariable %21 Uniform -%23 = OpTypePointer UniformConstant %17 -%22 = OpVariable %23 UniformConstant -%25 = OpTypePointer UniformConstant %18 -%24 = OpVariable %25 UniformConstant -%27 = OpTypePointer Function %4 -%28 = OpConstantNull %4 -%30 = OpConstantNull %4 -%33 = OpTypePointer Input %15 -%32 = OpVariable %33 Input -%36 = OpTypePointer Output %10 -%35 = OpVariable %36 Output -%38 = OpTypePointer Output %11 -%37 = OpVariable %38 Output -%40 = OpTypeFunction %2 -%41 = OpTypePointer Uniform %14 -%42 = OpConstant %15 0 -%58 = OpTypePointer Uniform %13 -%59 = OpTypePointer Uniform %10 -%60 = OpConstant %15 1 -%67 = OpConstant %15 2 -%84 = OpTypePointer Input %10 -%83 = OpVariable %84 Input -%87 = OpTypePointer Input %11 -%86 = OpVariable %87 Input -%89 = OpVariable %36 Output -%95 = OpTypeSampledImage %17 -%39 = OpFunction %2 None %40 -%31 = OpLabel -%26 = OpVariable %27 Function %28 -%29 = OpVariable %27 Function %30 -%34 = OpLoad %15 %32 -%43 = OpAccessChain %41 %19 %42 -OpBranch %44 -%44 = OpLabel -%45 = OpBitcast %4 %34 -%46 = OpSDiv %4 %45 %3 -OpStore %26 %46 -%47 = OpBitcast %4 %34 -%48 = OpBitwiseAnd %4 %47 %5 -OpStore %29 %48 -%49 = OpLoad %4 %26 -%50 = OpConvertSToF %7 %49 -%51 = OpFMul %7 %50 %6 -%52 = OpFSub %7 %51 %8 -%53 = OpLoad %4 %29 -%54 = OpConvertSToF %7 %53 -%55 = OpFMul %7 %54 %6 -%56 = OpFSub %7 %55 %8 -%57 = OpCompositeConstruct %10 %52 %56 %9 %8 -%61 = OpAccessChain %59 %43 %60 %42 -%62 = OpLoad %10 %61 -%63 = OpVectorShuffle %11 %62 %62 0 1 2 -%64 = OpAccessChain %59 %43 %60 %60 -%65 = OpLoad %10 %64 -%66 = OpVectorShuffle %11 %65 %65 0 1 2 -%68 = OpAccessChain %59 %43 %60 %67 -%69 = OpLoad %10 %68 -%70 = OpVectorShuffle %11 %69 %69 0 1 2 -%71 = OpCompositeConstruct %16 %63 %66 %70 -%72 = OpTranspose %16 %71 -%73 = OpAccessChain %58 %43 %42 -%74 = OpLoad %13 %73 -%75 = OpMatrixTimesVector %10 %74 %57 -%76 = OpVectorShuffle %11 %75 %75 0 1 2 -%77 = OpMatrixTimesVector %11 %72 %76 -%78 = OpCompositeConstruct %12 %57 %77 -%79 = OpCompositeExtract %10 %78 0 -OpStore %35 %79 -%80 = OpCompositeExtract %11 %78 1 -OpStore %37 %80 +%10 = OpConstant %4 0 +%11 = OpTypeVector %7 4 +%12 = OpTypeVector %7 3 +%13 = OpTypeStruct %11 %12 +%14 = OpTypeMatrix %11 4 +%15 = OpTypeStruct %14 %14 +%16 = OpTypeInt 32 0 +%17 = OpTypePointer Uniform %15 +%18 = OpTypePointer Uniform %14 +%19 = OpTypePointer Uniform %11 +%20 = OpTypeMatrix %12 3 +%21 = OpTypeImage %7 Cube 0 0 0 1 Unknown +%22 = OpTypeSampler +%24 = OpTypeStruct %15 +%25 = OpTypePointer Uniform %24 +%23 = OpVariable %25 Uniform +%27 = OpTypePointer UniformConstant %21 +%26 = OpVariable %27 UniformConstant +%29 = OpTypePointer UniformConstant %22 +%28 = OpVariable %29 UniformConstant +%31 = OpTypePointer Function %4 +%32 = OpConstantNull %4 +%34 = OpConstantNull %4 +%37 = OpTypePointer Input %16 +%36 = OpVariable %37 Input +%40 = OpTypePointer Output %11 +%39 = OpVariable %40 Output +%42 = OpTypePointer Output %12 +%41 = OpVariable %42 Output +%44 = OpTypeFunction %2 +%45 = OpConstant %16 0 +%61 = OpConstant %16 1 +%68 = OpConstant %16 2 +%85 = OpTypePointer Input %11 +%84 = OpVariable %85 Input +%88 = OpTypePointer Input %12 +%87 = OpVariable %88 Input +%90 = OpVariable %40 Output +%96 = OpTypeSampledImage %21 +%43 = OpFunction %2 None %44 +%35 = OpLabel +%30 = OpVariable %31 Function %32 +%33 = OpVariable %31 Function %34 +%38 = OpLoad %16 %36 +%46 = OpAccessChain %17 %23 %45 +OpBranch %47 +%47 = OpLabel +%48 = OpBitcast %4 %38 +%49 = OpSDiv %4 %48 %3 +OpStore %30 %49 +%50 = OpBitcast %4 %38 +%51 = OpBitwiseAnd %4 %50 %5 +OpStore %33 %51 +%52 = OpLoad %4 %30 +%53 = OpConvertSToF %7 %52 +%54 = OpFMul %7 %53 %6 +%55 = OpFSub %7 %54 %8 +%56 = OpLoad %4 %33 +%57 = OpConvertSToF %7 %56 +%58 = OpFMul %7 %57 %6 +%59 = OpFSub %7 %58 %8 +%60 = OpCompositeConstruct %11 %55 %59 %9 %8 +%62 = OpAccessChain %19 %46 %61 %45 +%63 = OpLoad %11 %62 +%64 = OpVectorShuffle %12 %63 %63 0 1 2 +%65 = OpAccessChain %19 %46 %61 %61 +%66 = OpLoad %11 %65 +%67 = OpVectorShuffle %12 %66 %66 0 1 2 +%69 = OpAccessChain %19 %46 %61 %68 +%70 = OpLoad %11 %69 +%71 = OpVectorShuffle %12 %70 %70 0 1 2 +%72 = OpCompositeConstruct %20 %64 %67 %71 +%73 = OpTranspose %20 %72 +%74 = OpAccessChain %18 %46 %45 +%75 = OpLoad %14 %74 +%76 = OpMatrixTimesVector %11 %75 %60 +%77 = OpVectorShuffle %12 %76 %76 0 1 2 +%78 = OpMatrixTimesVector %12 %73 %77 +%79 = OpCompositeConstruct %13 %60 %78 +%80 = OpCompositeExtract %11 %79 0 +OpStore %39 %80 +%81 = OpCompositeExtract %12 %79 1 +OpStore %41 %81 OpReturn OpFunctionEnd -%90 = OpFunction %2 None %40 -%81 = OpLabel -%85 = OpLoad %10 %83 -%88 = OpLoad %11 %86 -%82 = OpCompositeConstruct %12 %85 %88 -%91 = OpLoad %17 %22 -%92 = OpLoad %18 %24 -OpBranch %93 -%93 = OpLabel -%94 = OpCompositeExtract %11 %82 1 -%96 = OpSampledImage %95 %91 %92 -%97 = OpImageSampleImplicitLod %10 %96 %94 -OpStore %89 %97 +%91 = OpFunction %2 None %44 +%82 = OpLabel +%86 = OpLoad %11 %84 +%89 = OpLoad %12 %87 +%83 = OpCompositeConstruct %13 %86 %89 +%92 = OpLoad %21 %26 +%93 = OpLoad %22 %28 +OpBranch %94 +%94 = OpLabel +%95 = OpCompositeExtract %12 %83 1 +%97 = OpSampledImage %96 %92 %93 +%98 = OpImageSampleImplicitLod %11 %97 %95 +OpStore %90 %98 OpReturn OpFunctionEnd \ No newline at end of file diff --git a/tests/out/spv/texture-arg.spvasm b/tests/out/spv/texture-arg.spvasm index eca3f80c61..70a67b76e9 100644 --- a/tests/out/spv/texture-arg.spvasm +++ b/tests/out/spv/texture-arg.spvasm @@ -8,6 +8,11 @@ OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %28 "main" %26 OpExecutionMode %28 OriginUpperLeft OpSource GLSL 450 +OpName %5 "texture_2d" +OpName %6 "sampler" +OpName %7 "vec4" +OpName %4 "f32" +OpName %8 "vec2" OpName %9 "Texture" OpName %11 "Sampler" OpName %14 "Passed_Texture" diff --git a/tests/out/wgsl/access.wgsl b/tests/out/wgsl/access.wgsl index 2a25704545..f73286deda 100644 --- a/tests/out/wgsl/access.wgsl +++ b/tests/out/wgsl/access.wgsl @@ -10,9 +10,9 @@ struct AlignedWrapper { struct Bar { _matrix: mat4x3, - matrix_array: array,2>, + matrix_array: array,2u>, atom: atomic, - arr: array,2>, + arr: array,2u>, data: array, } @@ -21,7 +21,7 @@ struct Baz { } struct MatCx2InArray { - am: array,2>, + am: array,2u>, } var global_const: GlobalConst = GlobalConst(0u, vec3(0u, 0u, 0u), 0); @@ -36,85 +36,89 @@ 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 _e3 = idx; + idx = (_e3 - 1); _ = baz.m; _ = baz.m[0]; - let _e16 = idx; - _ = baz.m[_e16]; + let _e17 = idx; + _ = baz.m[_e17]; _ = baz.m[0][1]; - let _e28 = idx; - _ = baz.m[0][_e28]; let _e32 = idx; - _ = baz.m[_e32][1]; + _ = baz.m[0][_e32]; let _e38 = idx; - let _e40 = idx; - _ = baz.m[_e38][_e40]; - t = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); - let _e52 = idx; - idx = (_e52 + 1); + _ = baz.m[_e38][1]; + let _e46 = idx; + let _e49 = idx; + _ = baz.m[_e46][_e49]; + let t_2 = Baz(mat3x2(vec2(1.0), vec2(2.0), vec2(3.0))); + t = t_2; + let _e62 = idx; + idx = (_e62 + 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 _e85 = idx; + t.m[_e85] = 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 _e99 = idx; + t.m[0][_e99] = 20.0; + let _e105 = idx; + t.m[_e105][1] = 30.0; + let _e113 = idx; + let _e116 = idx; + t.m[_e113][_e116] = 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 _e3 = idx_1; + idx_1 = (_e3 - 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 _e26 = idx_1; + _ = nested_mat_cx2_.am[0][_e26]; _ = 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]; - 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 _e45 = idx_1; + _ = nested_mat_cx2_.am[0][0][_e45]; + let _e53 = idx_1; + _ = nested_mat_cx2_.am[0][_e53][1]; let _e63 = idx_1; - idx_1 = (_e63 + 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))); + let _e66 = idx_1; + _ = nested_mat_cx2_.am[0][_e63][_e66]; + let t_3 = MatCx2InArray(array,2u>(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 = t_3; + let _e73 = idx_1; + idx_1 = (_e73 + 1); + t_1.am = array,2u>(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); - 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; + t_1.am[0][_e107] = vec2(90.0); + t_1.am[0][0][1] = 10.0; + let _e125 = idx_1; + t_1.am[0][0][_e125] = 20.0; + let _e133 = idx_1; + t_1.am[0][_e133][1] = 30.0; + let _e143 = idx_1; + let _e146 = idx_1; + t_1.am[0][_e143][_e146] = 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 { +fn test_arr_as_arg(a: array,5u>) -> f32 { return a[4][9]; } @@ -125,9 +129,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 d: array; + foo = 0.0; let baz_1 = foo; foo = 1.0; test_matrix_within_struct_accesses(); @@ -136,13 +141,14 @@ 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 _e35 = read_from_private((&foo)); + let d_1 = array(a_1, i32(b), 3, 4, 5); + d = d_1; + d[(vi + 1u)] = 42; + let value = d[vi]; + let _e53 = test_arr_as_arg(array,5u>(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); } @@ -150,7 +156,7 @@ fn foo_vert(@builtin(vertex_index) vi: u32) -> @builtin(position) vec4 { fn foo_frag() -> @location(0) vec4 { bar._matrix[1][2] = 1.0; bar._matrix = mat4x3(vec3(0.0), vec3(1.0), vec3(2.0), vec3(3.0)); - bar.arr = array,2>(vec2(0u), vec2(1u)); + bar.arr = array,2u>(vec2(0u), vec2(1u)); bar.data[1].value = 1; qux = vec2(0, 0); return vec4(0.0); @@ -161,22 +167,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 _e6 = atomicAdd((&bar.atom), 5); + tmp = _e6; + let _e11 = atomicSub((&bar.atom), 5); + tmp = _e11; let _e16 = atomicAnd((&bar.atom), 5); tmp = _e16; - 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 _e21 = atomicOr((&bar.atom), 5); + tmp = _e21; + let _e26 = atomicXor((&bar.atom), 5); + tmp = _e26; + let _e31 = atomicMin((&bar.atom), 5); tmp = _e31; + let _e36 = atomicMax((&bar.atom), 5); + tmp = _e36; + let _e41 = atomicExchange((&bar.atom), 5); + tmp = _e41; atomicStore((&bar.atom), value_1); return; } diff --git a/tests/out/wgsl/binding-arrays.wgsl b/tests/out/wgsl/binding-arrays.wgsl index 0760aef72b..f07c6a37d9 100644 --- a/tests/out/wgsl/binding-arrays.wgsl +++ b/tests/out/wgsl/binding-arrays.wgsl @@ -9,162 +9,166 @@ struct FragmentIn { @group(0) @binding(0) var texture_array_unbounded: binding_array>; @group(0) @binding(1) -var texture_array_bounded: binding_array,5>; +var texture_array_bounded: binding_array,5u>; @group(0) @binding(2) -var texture_array_2darray: binding_array,5>; +var texture_array_2darray: binding_array,5u>; @group(0) @binding(3) -var texture_array_multisampled: binding_array,5>; +var texture_array_multisampled: binding_array,5u>; @group(0) @binding(4) -var texture_array_depth: binding_array; +var texture_array_depth: binding_array; @group(0) @binding(5) -var texture_array_storage: binding_array,5>; +var texture_array_storage: binding_array,5u>; @group(0) @binding(6) -var samp: binding_array; +var samp: binding_array; @group(0) @binding(7) -var samp_comp: binding_array; +var samp_comp: binding_array; @group(0) @binding(8) 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; - i2_ = vec2(0); - v4_ = vec4(0.0); + i1_ = 0; + let i2_1 = vec2(0); + i2_ = i2_1; + v1_ = 0.0; + let v4_1 = vec4(0.0); + v4_ = v4_1; 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 _e22 = textureDimensions(texture_array_unbounded[0]); + let _e24 = i2_; + i2_ = (_e24 + _e22); + let _e28 = textureDimensions(texture_array_unbounded[uniform_index]); + let _e30 = i2_; + i2_ = (_e30 + _e28); + let _e34 = textureDimensions(texture_array_unbounded[non_uniform_index]); 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 _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 _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); + i2_ = (_e36 + _e34); + let _e44 = textureGather(0, texture_array_bounded[0], samp[0], uv); + let _e46 = v4_; + v4_ = (_e46 + _e44); + let _e52 = textureGather(0, texture_array_bounded[uniform_index], samp[uniform_index], uv); + let _e54 = v4_; + v4_ = (_e54 + _e52); + let _e60 = textureGather(0, texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); + let _e62 = v4_; + v4_ = (_e62 + _e60); + let _e71 = textureGatherCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); + let _e73 = v4_; + v4_ = (_e73 + _e71); + let _e80 = textureGatherCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e82 = v4_; + v4_ = (_e82 + _e80); + let _e89 = textureGatherCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e91 = v4_; + v4_ = (_e91 + _e89); + let _e97 = textureLoad(texture_array_unbounded[0], pix, 0); + let _e99 = v4_; + v4_ = (_e99 + _e97); + let _e104 = textureLoad(texture_array_unbounded[uniform_index], pix, 0); + let _e106 = v4_; + v4_ = (_e106 + _e104); + let _e111 = textureLoad(texture_array_unbounded[non_uniform_index], pix, 0); + let _e113 = v4_; + v4_ = (_e113 + _e111); + let _e118 = textureNumLayers(texture_array_2darray[0]); + let _e120 = i1_; + i1_ = (_e120 + _e118); + let _e124 = textureNumLayers(texture_array_2darray[uniform_index]); + let _e126 = i1_; + i1_ = (_e126 + _e124); + let _e130 = textureNumLayers(texture_array_2darray[non_uniform_index]); + let _e132 = i1_; + i1_ = (_e132 + _e130); + let _e137 = textureNumLevels(texture_array_bounded[0]); + let _e139 = i1_; + i1_ = (_e139 + _e137); + let _e143 = textureNumLevels(texture_array_bounded[uniform_index]); + let _e145 = i1_; + i1_ = (_e145 + _e143); + let _e149 = textureNumLevels(texture_array_bounded[non_uniform_index]); + let _e151 = i1_; + i1_ = (_e151 + _e149); + let _e156 = textureNumSamples(texture_array_multisampled[0]); + let _e158 = i1_; + i1_ = (_e158 + _e156); + let _e162 = textureNumSamples(texture_array_multisampled[uniform_index]); + let _e164 = i1_; + i1_ = (_e164 + _e162); + let _e168 = textureNumSamples(texture_array_multisampled[non_uniform_index]); + let _e170 = i1_; + i1_ = (_e170 + _e168); + let _e178 = textureSample(texture_array_bounded[0], samp[0], uv); + let _e180 = v4_; + v4_ = (_e180 + _e178); + let _e186 = textureSample(texture_array_bounded[uniform_index], samp[uniform_index], uv); + let _e188 = v4_; + v4_ = (_e188 + _e186); + let _e194 = textureSample(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv); + let _e196 = v4_; + v4_ = (_e196 + _e194); + let _e205 = textureSampleBias(texture_array_bounded[0], samp[0], uv, 0.0); + let _e207 = v4_; + v4_ = (_e207 + _e205); + let _e214 = textureSampleBias(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); 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_; + v4_ = (_e216 + _e214); + let _e223 = textureSampleBias(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); + let _e225 = v4_; + v4_ = (_e225 + _e223); + let _e234 = textureSampleCompare(texture_array_depth[0], samp_comp[0], uv, 0.0); + let _e236 = v1_; + v1_ = (_e236 + _e234); + let _e243 = textureSampleCompare(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e245 = v1_; + v1_ = (_e245 + _e243); + let _e252 = textureSampleCompare(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e254 = v1_; + v1_ = (_e254 + _e252); + let _e263 = textureSampleCompareLevel(texture_array_depth[0], samp_comp[0], uv, 0.0); let _e265 = v1_; - return ((_e258 + vec4(v2_.x, v2_.y, v2_.x, v2_.y)) + vec4(_e265)); + v1_ = (_e265 + _e263); + let _e272 = textureSampleCompareLevel(texture_array_depth[uniform_index], samp_comp[uniform_index], uv, 0.0); + let _e274 = v1_; + v1_ = (_e274 + _e272); + let _e281 = textureSampleCompareLevel(texture_array_depth[non_uniform_index], samp_comp[non_uniform_index], uv, 0.0); + let _e283 = v1_; + v1_ = (_e283 + _e281); + let _e291 = textureSampleGrad(texture_array_bounded[0], samp[0], uv, uv, uv); + let _e293 = v4_; + v4_ = (_e293 + _e291); + let _e299 = textureSampleGrad(texture_array_bounded[uniform_index], samp[uniform_index], uv, uv, uv); + let _e301 = v4_; + v4_ = (_e301 + _e299); + let _e307 = textureSampleGrad(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, uv, uv); + let _e309 = v4_; + v4_ = (_e309 + _e307); + let _e318 = textureSampleLevel(texture_array_bounded[0], samp[0], uv, 0.0); + let _e320 = v4_; + v4_ = (_e320 + _e318); + let _e327 = textureSampleLevel(texture_array_bounded[uniform_index], samp[uniform_index], uv, 0.0); + let _e329 = v4_; + v4_ = (_e329 + _e327); + let _e336 = textureSampleLevel(texture_array_bounded[non_uniform_index], samp[non_uniform_index], uv, 0.0); + let _e338 = v4_; + v4_ = (_e338 + _e336); + let _e344 = v4_; + textureStore(texture_array_storage[0], pix, _e344); + let _e348 = v4_; + textureStore(texture_array_storage[uniform_index], pix, _e348); + let _e352 = v4_; + textureStore(texture_array_storage[non_uniform_index], pix, _e352); + let _e354 = i2_; + let _e356 = i1_; + let v2_ = vec2((_e354 + vec2(_e356))); + let _e361 = v4_; + let _e369 = v1_; + return ((_e361 + vec4(v2_.x, v2_.y, v2_.x, v2_.y)) + vec4(_e369)); } diff --git a/tests/out/wgsl/bitcast.wgsl b/tests/out/wgsl/bitcast.wgsl index 298c5fc21d..f0ca24750d 100644 --- a/tests/out/wgsl/bitcast.wgsl +++ b/tests/out/wgsl/bitcast.wgsl @@ -10,32 +10,41 @@ fn main() { var f3_: vec3; var f4_: vec4; - i2_ = vec2(0); - i3_ = vec3(0); - i4_ = vec4(0); - u2_ = vec2(0u); - u3_ = vec3(0u); - u4_ = vec4(0u); - f2_ = vec2(0.0); - f3_ = vec3(0.0); - f4_ = vec4(0.0); - let _e27 = i2_; - u2_ = bitcast>(_e27); - let _e29 = i3_; - u3_ = bitcast>(_e29); - let _e31 = i4_; - u4_ = bitcast>(_e31); - let _e33 = u2_; - i2_ = bitcast>(_e33); - let _e35 = u3_; - i3_ = bitcast>(_e35); - let _e37 = u4_; - i4_ = bitcast>(_e37); - let _e39 = i2_; - f2_ = bitcast>(_e39); - let _e41 = i3_; - f3_ = bitcast>(_e41); - let _e43 = i4_; - f4_ = bitcast>(_e43); + let i2_1 = vec2(0); + i2_ = i2_1; + let i3_1 = vec3(0); + i3_ = i3_1; + let i4_1 = vec4(0); + i4_ = i4_1; + let u2_1 = vec2(0u); + u2_ = u2_1; + let u3_1 = vec3(0u); + u3_ = u3_1; + let u4_1 = vec4(0u); + u4_ = u4_1; + let f2_1 = vec2(0.0); + f2_ = f2_1; + let f3_1 = vec3(0.0); + f3_ = f3_1; + let f4_1 = vec4(0.0); + f4_ = f4_1; + let _e28 = i2_; + u2_ = bitcast>(_e28); + let _e32 = i3_; + u3_ = bitcast>(_e32); + let _e36 = i4_; + u4_ = bitcast>(_e36); + let _e40 = u2_; + i2_ = bitcast>(_e40); + let _e44 = u3_; + i3_ = bitcast>(_e44); + let _e48 = u4_; + i4_ = bitcast>(_e48); + let _e52 = i2_; + f2_ = bitcast>(_e52); + let _e56 = i3_; + f3_ = bitcast>(_e56); + let _e60 = i4_; + f4_ = bitcast>(_e60); return; } diff --git a/tests/out/wgsl/bits.wgsl b/tests/out/wgsl/bits.wgsl index ccaebff41e..0df55159bd 100644 --- a/tests/out/wgsl/bits.wgsl +++ b/tests/out/wgsl/bits.wgsl @@ -1,123 +1,133 @@ @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; - i2_ = vec2(0); - i3_ = vec3(0); - i4_ = vec4(0); - u2_ = vec2(0u); - u3_ = vec3(0u); - u4_ = vec4(0u); - f2_ = vec2(0.0); - f4_ = vec4(0.0); - let _e28 = f4_; - u = pack4x8snorm(_e28); - let _e30 = f4_; - u = pack4x8unorm(_e30); - let _e32 = f2_; - u = pack2x16snorm(_e32); - let _e34 = f2_; - u = pack2x16unorm(_e34); - let _e36 = f2_; - u = pack2x16float(_e36); - let _e38 = u; - f4_ = unpack4x8snorm(_e38); - let _e40 = u; - f4_ = unpack4x8unorm(_e40); - let _e42 = u; - f2_ = unpack2x16snorm(_e42); - let _e44 = u; - f2_ = unpack2x16unorm(_e44); - let _e46 = u; - f2_ = unpack2x16float(_e46); - let _e48 = i; - let _e49 = i; - i = insertBits(_e48, _e49, 5u, 10u); - let _e53 = i2_; - let _e54 = i2_; - i2_ = insertBits(_e53, _e54, 5u, 10u); - let _e58 = i3_; - let _e59 = i3_; - i3_ = insertBits(_e58, _e59, 5u, 10u); - let _e63 = i4_; - let _e64 = i4_; - i4_ = insertBits(_e63, _e64, 5u, 10u); - let _e68 = u; - let _e69 = u; - u = insertBits(_e68, _e69, 5u, 10u); - let _e73 = u2_; - let _e74 = u2_; - u2_ = insertBits(_e73, _e74, 5u, 10u); - let _e78 = u3_; - let _e79 = u3_; - u3_ = insertBits(_e78, _e79, 5u, 10u); - let _e83 = u4_; - let _e84 = u4_; - u4_ = insertBits(_e83, _e84, 5u, 10u); - let _e88 = i; - i = extractBits(_e88, 5u, 10u); - let _e92 = i2_; - i2_ = extractBits(_e92, 5u, 10u); - let _e96 = i3_; - i3_ = extractBits(_e96, 5u, 10u); - let _e100 = i4_; - i4_ = extractBits(_e100, 5u, 10u); - let _e104 = u; - u = extractBits(_e104, 5u, 10u); - let _e108 = u2_; - u2_ = extractBits(_e108, 5u, 10u); - let _e112 = u3_; - u3_ = extractBits(_e112, 5u, 10u); - let _e116 = u4_; - u4_ = extractBits(_e116, 5u, 10u); - let _e120 = i; - i = firstTrailingBit(_e120); - let _e122 = u2_; - u2_ = firstTrailingBit(_e122); - let _e124 = i3_; - i3_ = firstLeadingBit(_e124); - let _e126 = u; - u = firstLeadingBit(_e126); - let _e128 = i; - i = countOneBits(_e128); - let _e130 = i2_; - i2_ = countOneBits(_e130); - let _e132 = i3_; - i3_ = countOneBits(_e132); - let _e134 = i4_; - i4_ = countOneBits(_e134); - let _e136 = u; - u = countOneBits(_e136); - let _e138 = u2_; - u2_ = countOneBits(_e138); - let _e140 = u3_; - u3_ = countOneBits(_e140); - let _e142 = u4_; - u4_ = countOneBits(_e142); - let _e144 = i; - i = reverseBits(_e144); - let _e146 = i2_; - i2_ = reverseBits(_e146); - let _e148 = i3_; - i3_ = reverseBits(_e148); - let _e150 = i4_; - i4_ = reverseBits(_e150); - let _e152 = u; - u = reverseBits(_e152); - let _e154 = u2_; - u2_ = reverseBits(_e154); - let _e156 = u3_; - u3_ = reverseBits(_e156); - let _e158 = u4_; - u4_ = reverseBits(_e158); + i = 0; + let i2_1 = vec2(0); + i2_ = i2_1; + let i3_1 = vec3(0); + i3_ = i3_1; + let i4_1 = vec4(0); + i4_ = i4_1; + u = 0u; + let u2_1 = vec2(0u); + u2_ = u2_1; + let u3_1 = vec3(0u); + u3_ = u3_1; + let u4_1 = vec4(0u); + u4_ = u4_1; + let f2_1 = vec2(0.0); + f2_ = f2_1; + let f4_1 = vec4(0.0); + f4_ = f4_1; + let _e29 = f4_; + u = pack4x8snorm(_e29); + let _e33 = f4_; + u = pack4x8unorm(_e33); + let _e37 = f2_; + u = pack2x16snorm(_e37); + let _e41 = f2_; + u = pack2x16unorm(_e41); + let _e45 = f2_; + u = pack2x16float(_e45); + let _e49 = u; + f4_ = unpack4x8snorm(_e49); + let _e53 = u; + f4_ = unpack4x8unorm(_e53); + let _e57 = u; + f2_ = unpack2x16snorm(_e57); + let _e61 = u; + f2_ = unpack2x16unorm(_e61); + let _e65 = u; + f2_ = unpack2x16float(_e65); + let _e69 = i; + let _e71 = i; + i = insertBits(_e69, _e71, 5u, 10u); + let _e77 = i2_; + let _e79 = i2_; + i2_ = insertBits(_e77, _e79, 5u, 10u); + let _e85 = i3_; + let _e87 = i3_; + i3_ = insertBits(_e85, _e87, 5u, 10u); + let _e93 = i4_; + let _e95 = i4_; + i4_ = insertBits(_e93, _e95, 5u, 10u); + let _e101 = u; + let _e103 = u; + u = insertBits(_e101, _e103, 5u, 10u); + let _e109 = u2_; + let _e111 = u2_; + u2_ = insertBits(_e109, _e111, 5u, 10u); + let _e117 = u3_; + let _e119 = u3_; + u3_ = insertBits(_e117, _e119, 5u, 10u); + let _e125 = u4_; + let _e127 = u4_; + u4_ = insertBits(_e125, _e127, 5u, 10u); + let _e133 = i; + i = extractBits(_e133, 5u, 10u); + let _e139 = i2_; + i2_ = extractBits(_e139, 5u, 10u); + let _e145 = i3_; + i3_ = extractBits(_e145, 5u, 10u); + let _e151 = i4_; + i4_ = extractBits(_e151, 5u, 10u); + let _e157 = u; + u = extractBits(_e157, 5u, 10u); + let _e163 = u2_; + u2_ = extractBits(_e163, 5u, 10u); + let _e169 = u3_; + u3_ = extractBits(_e169, 5u, 10u); + let _e175 = u4_; + u4_ = extractBits(_e175, 5u, 10u); + let _e181 = i; + i = firstTrailingBit(_e181); + let _e185 = u2_; + u2_ = firstTrailingBit(_e185); + let _e189 = i3_; + i3_ = firstLeadingBit(_e189); + let _e193 = u; + u = firstLeadingBit(_e193); + let _e197 = i; + i = countOneBits(_e197); + let _e201 = i2_; + i2_ = countOneBits(_e201); + let _e205 = i3_; + i3_ = countOneBits(_e205); + let _e209 = i4_; + i4_ = countOneBits(_e209); + let _e213 = u; + u = countOneBits(_e213); + let _e217 = u2_; + u2_ = countOneBits(_e217); + let _e221 = u3_; + u3_ = countOneBits(_e221); + let _e225 = u4_; + u4_ = countOneBits(_e225); + let _e229 = i; + i = reverseBits(_e229); + let _e233 = i2_; + i2_ = reverseBits(_e233); + let _e237 = i3_; + i3_ = reverseBits(_e237); + let _e241 = i4_; + i4_ = reverseBits(_e241); + let _e245 = u; + u = reverseBits(_e245); + let _e249 = u2_; + u2_ = reverseBits(_e249); + let _e253 = u3_; + u3_ = reverseBits(_e253); + let _e257 = u4_; + u4_ = reverseBits(_e257); return; } diff --git a/tests/out/wgsl/boids.wgsl b/tests/out/wgsl/boids.wgsl index fd143f79fb..e9004a809e 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,125 @@ 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; - cMass = vec2(0.0, 0.0); - cVel = vec2(0.0, 0.0); - colVel = vec2(0.0, 0.0); + let vPos_1 = particlesSrc.particles[index].pos; + vPos = vPos_1; + let vVel_1 = particlesSrc.particles[index].vel; + vVel = vVel_1; + let cMass_1 = vec2(0.0, 0.0); + cMass = cMass_1; + let cVel_1 = vec2(0.0, 0.0); + cVel = cVel_1; + let colVel_1 = vec2(0.0, 0.0); + colVel = colVel_1; + cMassCount = 0; + cVelCount = 0; + i = 0u; loop { - let _e37 = i; - if (_e37 >= NUM_PARTICLES) { + let _e35 = i; + if (_e35 >= 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 _e44 = i; + let _e47 = particlesSrc.particles[_e44].pos; + pos = _e47; + let _e52 = i; + let _e55 = particlesSrc.particles[_e52].vel; + vel = _e55; + let _e58 = pos; + let _e60 = vPos; + let _e64 = params.rule1Distance; + if (distance(_e58, _e60) < _e64) { + let _e67 = cMass; + let _e69 = pos; + cMass = (_e67 + _e69); + let _e73 = cMassCount; + cMassCount = (_e73 + 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 _e78 = pos; + let _e80 = vPos; + let _e84 = params.rule2Distance; + if (distance(_e78, _e80) < _e84) { + let _e87 = colVel; + let _e89 = pos; + let _e91 = vPos; + colVel = (_e87 - (_e89 - _e91)); } - 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 _e96 = pos; + let _e98 = vPos; + let _e102 = params.rule3Distance; + if (distance(_e96, _e98) < _e102) { + let _e105 = cVel; + let _e107 = vel; + cVel = (_e105 + _e107); + let _e111 = cVelCount; + cVelCount = (_e111 + 1); } continuing { - let _e86 = i; - i = (_e86 + 1u); + let _e116 = i; + i = (_e116 + 1u); } } - let _e89 = cMassCount; - if (_e89 > 0) { - let _e92 = cMass; - let _e93 = cMassCount; - let _e97 = vPos; - cMass = ((_e92 / vec2(f32(_e93))) - _e97); + let _e121 = cMassCount; + if (_e121 > 0) { + let _e125 = cMass; + let _e127 = cMassCount; + let _e132 = vPos; + cMass = ((_e125 / vec2(f32(_e127))) - _e132); } - let _e99 = cVelCount; - if (_e99 > 0) { - let _e102 = cVel; - let _e103 = cVelCount; - cVel = (_e102 / vec2(f32(_e103))); + let _e136 = cVelCount; + if (_e136 > 0) { + let _e140 = cVel; + let _e142 = cVelCount; + cVel = (_e140 / vec2(f32(_e142))); } - 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 _e148 = vVel; + let _e150 = cMass; + let _e153 = params.rule1Scale; + let _e157 = colVel; + let _e160 = params.rule2Scale; + let _e164 = cVel; + let _e167 = params.rule3Scale; + vVel = (((_e148 + (_e150 * _e153)) + (_e157 * _e160)) + (_e164 * _e167)); + let _e172 = vVel; + let _e175 = vVel; + vVel = (normalize(_e172) * clamp(length(_e175), 0.0, 0.1)); + let _e183 = vPos; + let _e185 = vVel; + let _e188 = params.deltaT; + vPos = (_e183 + (_e185 * _e188)); + let _e194 = vPos.x; + if (_e194 < -(1.0)) { vPos.x = 1.0; } - let _e144 = vPos.x; - if (_e144 > 1.0) { - vPos.x = -1.0; + let _e203 = vPos.x; + if (_e203 > 1.0) { + vPos.x = -(1.0); } - let _e150 = vPos.y; - if (_e150 < -1.0) { + let _e212 = vPos.y; + if (_e212 < -(1.0)) { vPos.y = 1.0; } - let _e156 = vPos.y; - if (_e156 > 1.0) { - vPos.y = -1.0; + let _e221 = vPos.y; + if (_e221 > 1.0) { + vPos.y = -(1.0); } - let _e164 = vPos; - particlesDst.particles[index].pos = _e164; - let _e168 = vVel; - particlesDst.particles[index].vel = _e168; + let _e229 = vPos; + particlesDst.particles[index].pos = _e229; + let _e235 = vVel; + particlesDst.particles[index].vel = _e235; return; } diff --git a/tests/out/wgsl/break-if.wgsl b/tests/out/wgsl/break-if.wgsl index 04b232905b..c88b649ed5 100644 --- a/tests/out/wgsl/break-if.wgsl +++ b/tests/out/wgsl/break-if.wgsl @@ -11,14 +11,15 @@ fn breakIfEmptyBody(a: bool) { var b: bool; var c: bool; + let _e9 = c; + _ = (a == _e9); loop { continuing { b = a; - let _e2 = b; - c = (a != _e2); - let _e5 = c; - _ = (a == _e5); - break if (a == _e5); + let _e4 = b; + let c_1 = (a != _e4); + c = c_1; + break if (a == _e9); } } return; @@ -28,14 +29,15 @@ fn breakIf(a_1: bool) { var d: bool; var e: bool; + let _e9 = e; + _ = (a_1 == _e9); loop { d = a_1; - let _e2 = d; - e = (a_1 != _e2); + let _e4 = d; + let e_1 = (a_1 != _e4); + e = e_1; continuing { - let _e5 = e; - _ = (a_1 == _e5); - break if (a_1 == _e5); + break if (a_1 == _e9); } } return; diff --git a/tests/out/wgsl/collatz.wgsl b/tests/out/wgsl/collatz.wgsl index ea16c79618..aeda3267b5 100644 --- a/tests/out/wgsl/collatz.wgsl +++ b/tests/out/wgsl/collatz.wgsl @@ -7,34 +7,39 @@ 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) { } else { break; } - let _e8 = n; - if ((_e8 % 2u) == 0u) { - let _e13 = n; - n = (_e13 / 2u); - } else { - let _e17 = n; - n = ((3u * _e17) + 1u); + { + let _e9 = n; + if ((_e9 % 2u) == 0u) { + let _e15 = n; + n = (_e15 / 2u); + } else { + { + let _e21 = n; + n = ((3u * _e21) + 1u); + } + } + let _e27 = i; + i = (_e27 + 1u); } - let _e21 = i; - i = (_e21 + 1u); } - let _e24 = i; - return _e24; + let _e32 = i; + return _e32; } @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 _e6 = v_indices.data[global_id.x]; + let _e0 = collatz_iterations(_e6); + v_indices.data[global_id.x] = _e0; return; } diff --git a/tests/out/wgsl/control-flow.wgsl b/tests/out/wgsl/control-flow.wgsl index ce3911f2b1..9423020f45 100644 --- a/tests/out/wgsl/control-flow.wgsl +++ b/tests/out/wgsl/control-flow.wgsl @@ -52,11 +52,9 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { } case 3: { pos = 2; - fallthrough; } case 4: { pos = 3; - fallthrough; } default: { pos = 4; @@ -68,8 +66,8 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { default: { } } - let _e11 = pos; - switch _e11 { + let _e17 = pos; + switch _e17 { case 1: { pos = 0; break; @@ -80,7 +78,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { } case 3: { pos = 2; - fallthrough; + return; } case 4: { return; diff --git a/tests/out/wgsl/extra.wgsl b/tests/out/wgsl/extra.wgsl index 34a2e176c5..c9d47d9d03 100644 --- a/tests/out/wgsl/extra.wgsl +++ b/tests/out/wgsl/extra.wgsl @@ -16,6 +16,8 @@ fn main(in: FragmentIn) -> @location(0) vec4 { if (in.primitive_index == _e4) { return in.color; } else { - return vec4((vec3(1.0) - in.color.xyz), in.color.w); + { + return vec4((vec3(1.0) - in.color.xyz), in.color.w); + } } } diff --git a/tests/out/wgsl/globals.wgsl b/tests/out/wgsl/globals.wgsl index 147f6ec322..72fd1cde2b 100644 --- a/tests/out/wgsl/globals.wgsl +++ b/tests/out/wgsl/globals.wgsl @@ -3,7 +3,7 @@ struct Foo { v1_: f32, } -let Foo_2: bool = true; +const FooConst: bool = true; var wg: array; var at_1: atomic; @@ -12,28 +12,29 @@ var alignment: Foo; @group(0) @binding(2) var dummy: array>; @group(0) @binding(3) -var float_vecs: array,20>; +var float_vecs: array,20u>; @group(0) @binding(4) var global_vec: vec3; @group(0) @binding(5) var global_mat: mat3x2; @group(0) @binding(6) -var global_nested_arrays_of_matrices_2x4_: array,2>,2>; +var global_nested_arrays_of_matrices_2x4_: array,2u>,2u>; @group(0) @binding(7) -var global_nested_arrays_of_matrices_4x2_: array,2>,2>; +var global_nested_arrays_of_matrices_4x2_: array,2u>,2u>; fn test_msl_packed_vec3_as_arg(arg: vec3) { return; } 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 _e18 = idx; + alignment.v3_[_e18] = 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_1: 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 _e43 = float_vecs[0].w; - wg[4] = _e43; - let _e47 = alignment.v1_; - wg[3] = _e47; - let _e52 = alignment.v3_.x; - wg[2] = _e52; + let _e5 = global_nested_arrays_of_matrices_4x2_[0][0]; + let _e13 = global_nested_arrays_of_matrices_2x4_[0][0][0]; + wg[7] = (_e5 * _e13).x; + let _e20 = global_mat; + let _e22 = global_vec; + wg[6] = (_e20 * _e22).x; + let _e32 = dummy[1].y; + wg[5] = _e32; + let _e40 = float_vecs[0].w; + wg[4] = _e40; + let _e46 = alignment.v1_; + wg[3] = _e46; + let _e53 = alignment.v3_.x; + wg[2] = _e53; alignment.v1_ = 4.0; wg[1] = f32(arrayLength((&dummy))); atomicStore((&at_1), 2u); + Foo_1 = 1.0; + at = true; return; } diff --git a/tests/out/wgsl/image.wgsl b/tests/out/wgsl/image.wgsl index 062876f224..0a84b8fba0 100644 --- a/tests/out/wgsl/image.wgsl +++ b/tests/out/wgsl/image.wgsl @@ -98,8 +98,8 @@ fn texture_sample() -> @location(0) vec4 { let s1d = textureSample(image_1d, sampler_reg, tc.x); let s2d = textureSample(image_2d, sampler_reg, tc); let s2d_offset = textureSample(image_2d, sampler_reg, tc, vec2(3, 1)); - let s2d_level = textureSampleLevel(image_2d, sampler_reg, tc, 2.299999952316284); - let s2d_level_offset = textureSampleLevel(image_2d, sampler_reg, tc, 2.299999952316284, vec2(3, 1)); + let s2d_level = textureSampleLevel(image_2d, sampler_reg, tc, 2.3); + let s2d_level_offset = textureSampleLevel(image_2d, sampler_reg, tc, 2.3, vec2(3, 1)); let s2d_bias_offset = textureSampleBias(image_2d, sampler_reg, tc, 2.0, vec2(3, 1)); return ((((s1d + s2d) + s2d_offset) + s2d_level) + s2d_level_offset); } diff --git a/tests/out/wgsl/interface.wgsl b/tests/out/wgsl/interface.wgsl index a17865c5a8..bd2926e29b 100644 --- a/tests/out/wgsl/interface.wgsl +++ b/tests/out/wgsl/interface.wgsl @@ -17,7 +17,7 @@ struct Input2_ { @builtin(instance_index) index: u32, } -var output: array; +var output: array; @vertex fn vertex(@builtin(vertex_index) vertex_index: u32, @builtin(instance_index) instance_index: u32, @location(10) color: u32) -> VertexOutput { @@ -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; + index = 2u; let _e9: u32 = index; return vec4(f32(in1_.index), f32(in2_.index), f32(_e9), 0.0); } diff --git a/tests/out/wgsl/interpolate.wgsl b/tests/out/wgsl/interpolate.wgsl index d566aae80c..6de1596b96 100644 --- a/tests/out/wgsl/interpolate.wgsl +++ b/tests/out/wgsl/interpolate.wgsl @@ -21,8 +21,8 @@ fn vert_main() -> FragmentInput { out.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0); out.perspective_centroid = 2197.0; out.perspective_sample = 2744.0; - let _e30 = out; - return _e30; + let _e38 = out; + return _e38; } @fragment diff --git a/tests/out/wgsl/lexical-scopes.wgsl b/tests/out/wgsl/lexical-scopes.wgsl index 39f033cb1e..68ea58c16a 100644 --- a/tests/out/wgsl/lexical-scopes.wgsl +++ b/tests/out/wgsl/lexical-scopes.wgsl @@ -20,17 +20,22 @@ fn loopLexicalScope(a_2: bool) { } fn forLexicalScope(a_3: f32) { - var a_4: i32 = 0; + var a_4: i32; - loop { - let _e4 = a_4; - if (_e4 < 1) { - } else { - break; - } - continuing { - let _e7 = a_4; - a_4 = (_e7 + 1); + { + a_4 = 0; + loop { + let _e4 = a_4; + if (_e4 < 1) { + } else { + break; + } + { + } + continuing { + let _e9 = a_4; + a_4 = (_e9 + 1); + } } } let test_4 = (false == true); @@ -42,6 +47,8 @@ fn whileLexicalScope(a_5: i32) { } else { break; } + { + } } let test_5 = (a_5 == 1); } diff --git a/tests/out/wgsl/operators.wgsl b/tests/out/wgsl/operators.wgsl index a8a488dff6..51892b9ee3 100644 --- a/tests/out/wgsl/operators.wgsl +++ b/tests/out/wgsl/operators.wgsl @@ -3,16 +3,16 @@ 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); let s3_ = select(vec4(1.0, 1.0, 1.0, 1.0), vec4(0.0, 0.0, 0.0, 0.0), vec4(false, false, false, false)); let m1_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), vec4(0.5, 0.5, 0.5, 0.5)); - let m2_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), 0.10000000149011612); + let m2_ = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0), 0.1); let b1_ = bitcast(vec4(1, 1, 1, 1).x); let b2_ = bitcast>(vec4(1, 1, 1, 1)); let v_i32_zero = vec4(vec4(0.0, 0.0, 0.0, 0.0)); @@ -28,13 +28,14 @@ fn splat() -> vec4 { 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 _e15 = a; - a = (_e15 / vec2(4.0)); + let a_3 = vec2(2.0); + a = a_3; + let _e4 = a; + a = (_e4 + vec2(1.0)); + let _e9 = a; + a = (_e9 - vec2(3.0)); + let _e14 = a; + a = (_e14 / vec2(4.0)); let _e19 = a; return _e19; } @@ -59,17 +60,17 @@ fn constructors() -> f32 { _ = f32(0.0); _ = vec2(vec2(0u, 0u)); _ = mat2x3(mat2x3(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0))); - _ = bitcast>(vec2(0u, 0u)); + _ = vec2(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 _e72 = foo.a.x; + return _e72; } fn logical() { _ = !(true); _ = !(vec2(true)); - _ = (true || false); - _ = (true && false); + _ = (true | false); + _ = (true & false); _ = (true | false); _ = (vec3(true) | vec3(false)); _ = (true & false); @@ -77,6 +78,7 @@ fn logical() { } fn arithmetic() { + _ = -(1.0); _ = -(vec2(1)); _ = -(vec2(1.0)); _ = (2 + 1); @@ -215,48 +217,50 @@ fn comparison() { } fn assignment() { - var a_1: i32 = 1; - var vec0_: vec3 = vec3(0, 0, 0); + var a_1: i32; + var vec0_: vec3; - let _e6 = a_1; - a_1 = (_e6 + 1); - let _e9 = a_1; - a_1 = (_e9 - 1); - let _e12 = a_1; + a_1 = 1; + let _e3 = a_1; + a_1 = (_e3 + 1); + let _e7 = a_1; + a_1 = (_e7 - 1); + let _e11 = a_1; let _e13 = a_1; - a_1 = (_e12 * _e13); - let _e15 = a_1; + a_1 = (_e13 * _e11); let _e16 = a_1; - a_1 = (_e15 / _e16); let _e18 = a_1; - a_1 = (_e18 % 1); + a_1 = (_e18 / _e16); let _e21 = a_1; - a_1 = (_e21 & 0); - let _e24 = a_1; - a_1 = (_e24 | 0); - let _e27 = a_1; - a_1 = (_e27 ^ 0); - let _e30 = a_1; - a_1 = (_e30 << 2u); + a_1 = (_e21 % 1); + let _e25 = a_1; + a_1 = (_e25 & 0); + let _e29 = a_1; + a_1 = (_e29 | 0); 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 = (_e33 ^ 0); + let _e38 = a_1; + a_1 = (_e38 << 2u); + let _e42 = a_1; + a_1 = (_e42 >> 1u); + let _e45 = a_1; + a_1 = (_e45 + 1); + let _e49 = a_1; + a_1 = (_e49 - 1); + vec0_ = vec3(0, 0, 0); + let _e57 = vec0_.y; + vec0_.y = (_e57 + 1); + let _e63 = vec0_.y; + vec0_.y = (_e63 - 1); return; } @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 _e2 = 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..5801a5177e 100644 --- a/tests/out/wgsl/padding.wgsl +++ b/tests/out/wgsl/padding.wgsl @@ -8,7 +8,7 @@ struct Test { } struct Test2_ { - a: array,2>, + a: array,2u>, b: f32, } @@ -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..3a92981d95 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.2; @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..bb1dfbc643 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.05, 0.05, 0.05); +const c_max_lights: u32 = 10u; @group(0) @binding(0) var u_globals: Globals; @@ -30,7 +30,7 @@ var u_entity: Entity; @group(0) @binding(1) var s_lights: array; @group(0) @binding(1) -var u_lights: array; +var u_lights: array; @group(0) @binding(2) var t_shadow: texture_depth_2d_array; @group(0) @binding(3) @@ -40,7 +40,7 @@ fn fetch_shadow(light_id: u32, homogeneous_coords: vec4) -> f32 { if (homogeneous_coords.w <= 0.0) { return 1.0; } - let flip_correction = vec2(0.5, -0.5); + 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)); @@ -52,74 +52,86 @@ fn vs_main(@location(0) position: vec4, @location(1) normal: vec4) -> var out: VertexOutput; let w = u_entity.world; - let _e7 = u_entity.world; - let world_pos = (_e7 * vec4(position)); + let _e5 = u_entity.world; + let world_pos = (_e5 * 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 _e31 = out; + return _e31; } @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); - loop { - let _e14 = i; - let _e17 = u_globals.num_lights.x; - if (_e14 < min(_e17, 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)); - continuing { - let _e20 = i; - i = (_e20 + 1u); + color = vec3(0.05, 0.05, 0.05); + { + i = 0u; + loop { + let _e8 = i; + let _e12 = u_globals.num_lights.x; + if (_e8 < min(_e12, c_max_lights)) { + } else { + break; + } + { + let _e18 = i; + let light = s_lights[_e18]; + let _e23 = i; + let _e21 = fetch_shadow(_e23, (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 _e43 = color; + color = (_e43 + ((_e21 * diffuse) * light.color.xyz)); + } + continuing { + let _e46 = i; + i = (_e46 + 1u); + } } } - let _e46 = color; - let _e50 = u_entity.color; - return (vec4(_e46, 1.0) * _e50); + let _e50 = color; + let _e55 = u_entity.color; + return (vec4(_e50, 1.0) * _e55); } @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); - loop { - let _e14 = i_1; - let _e17 = u_globals.num_lights.x; - if (_e14 < min(_e17, 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)); - continuing { - let _e20 = i_1; - i_1 = (_e20 + 1u); + color_1 = vec3(0.05, 0.05, 0.05); + { + i_1 = 0u; + loop { + let _e8 = i_1; + let _e12 = u_globals.num_lights.x; + if (_e8 < min(_e12, c_max_lights)) { + } else { + break; + } + { + let _e18 = i_1; + let light_1 = u_lights[_e18]; + let _e23 = i_1; + let _e21 = fetch_shadow(_e23, (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 _e43 = color_1; + color_1 = (_e43 + ((_e21 * diffuse_1) * light_1.color.xyz)); + } + continuing { + let _e46 = i_1; + i_1 = (_e46 + 1u); + } } } - let _e46 = color_1; - let _e50 = u_entity.color; - return (vec4(_e46, 1.0) * _e50); + let _e50 = color_1; + let _e55 = u_entity.color; + return (vec4(_e50, 1.0) * _e55); } diff --git a/tests/out/wgsl/skybox.wgsl b/tests/out/wgsl/skybox.wgsl index c9be90196e..57cc7446a3 100644 --- a/tests/out/wgsl/skybox.wgsl +++ b/tests/out/wgsl/skybox.wgsl @@ -20,22 +20,24 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32) -> VertexOutput { var tmp1_: i32; var tmp2_: i32; - 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 _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 tmp1_1 = (i32(vertex_index) / 2); + tmp1_ = tmp1_1; + let tmp2_1 = (i32(vertex_index) & 1); + tmp2_ = tmp2_1; + let _e11 = tmp1_; + let _e18 = tmp2_; + let pos = vec4(((f32(_e11) * 4.0) - 1.0), ((f32(_e18) * 4.0) - 1.0), 0.0, 1.0); + let _e31 = r_data.view[0]; + let _e37 = r_data.view[1]; + let _e43 = r_data.view[2]; + let inv_model_view = transpose(mat3x3(_e31.xyz, _e37.xyz, _e43.xyz)); + let _e49 = r_data.proj_inv; + let unprojected = (_e49 * 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..210ed792de 100644 --- a/tests/out/wgsl/texture-arg.wgsl +++ b/tests/out/wgsl/texture-arg.wgsl @@ -4,12 +4,12 @@ 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 fn main() -> @location(0) vec4 { - let _e2 = test(Texture, Sampler); - return _e2; + let _e0 = test(Texture, Sampler); + return _e0; } diff --git a/tests/snapshots.rs b/tests/snapshots.rs index 59a3e314bd..dd28173478 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -532,7 +532,6 @@ fn convert_wgsl() { "math-functions", Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL, ), - ("cubeArrayShadow", Targets::GLSL), ( "binding-arrays", Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV, @@ -553,7 +552,13 @@ fn convert_wgsl() { .expect("Couldn't find wgsl file"); match naga::front::wgsl::parse_str(&file) { Ok(module) => check_targets(&module, name, targets), - Err(e) => panic!("{}", e.emit_to_string(&file)), + Err(e) => panic!( + "{}", + e.into_iter() + .map(|x| x.emit_to_string(&file)) + .collect::>() + .join("\n") + ), } } } diff --git a/tests/spirv-capabilities.rs b/tests/spirv-capabilities.rs index 409768910b..1972ff968d 100644 --- a/tests/spirv-capabilities.rs +++ b/tests/spirv-capabilities.rs @@ -13,7 +13,10 @@ fn capabilities_used(source: &str) -> naga::FastHashSet { let module = naga::front::wgsl::parse_str(source).unwrap_or_else(|e| { panic!( "expected WGSL to parse successfully:\n{}", - e.emit_to_string(source) + e.into_iter() + .map(|x| x.emit_to_string(source)) + .collect::>() + .join("\n"), ); }); @@ -167,6 +170,7 @@ fn storage_image_formats() { &[Ca::Shader], &[Ca::StorageImageExtendedFormats], r#" + enable storage_image_read; @group(0) @binding(0) var image_rg32f: texture_storage_2d; "#, @@ -175,6 +179,7 @@ fn storage_image_formats() { require( &[Ca::StorageImageExtendedFormats], r#" + enable storage_image_read; @group(0) @binding(0) var image_rg32f: texture_storage_2d; "#, diff --git a/tests/wgsl-errors.rs b/tests/wgsl-errors.rs index 445459f3b2..f9a0c2eab7 100644 --- a/tests/wgsl-errors.rs +++ b/tests/wgsl-errors.rs @@ -6,7 +6,10 @@ Tests for the WGSL front end. fn check(input: &str, snapshot: &str) { let output = naga::front::wgsl::parse_str(input) .expect_err("expected parser error") - .emit_to_string(input); + .into_iter() + .map(|x| x.emit_to_string(input)) + .collect::>() + .join("\n"); if output != snapshot { for diff in diff::lines(&output, snapshot) { match diff { @@ -19,43 +22,15 @@ fn check(input: &str, snapshot: &str) { } } -#[test] -fn reserved_identifier_prefix() { - check( - "var __bad;", - r###"error: Identifier starts with a reserved prefix: '__bad' - ┌─ wgsl:1:5 - │ -1 │ var __bad; - │ ^^^^^ invalid identifier - -"###, - ); -} - #[test] fn function_without_identifier() { check( "fn () {}", - r###"error: expected identifier, found '(' + r###"error: unexpected `(` ┌─ wgsl:1:4 │ 1 │ fn () {} - │ ^ expected identifier - -"###, - ); -} - -#[test] -fn invalid_integer() { - check( - "fn foo([location(1.)] x: i32) {}", - r###"error: expected identifier, found '[' - ┌─ wgsl:1:8 - │ -1 │ fn foo([location(1.)] x: i32) {} - │ ^ expected identifier + │ ^ expected one of `` "###, ); @@ -64,12 +39,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: unexpected `;` + ┌─ wgsl:1:24 │ -1 │ let scale: f32 = 1.1.; - │ ^ expected ';' +1 │ const scale: f32 = 1.1.; + │ ^ expected one of `` "###, ); @@ -78,54 +53,35 @@ fn invalid_float() { #[test] fn invalid_texture_sample_type() { check( - "let x: texture_2d;", - r###"error: texture sample type must be one of f32, i32 or u32, but found f16 + "var x: texture_2d;", + r###"error: invalid sample type for `texture_2d` ┌─ wgsl:1:19 │ -1 │ let x: texture_2d; - │ ^^^ must be one of f32, i32 or u32 +1 │ var x: texture_2d; + │ ^^^ must be `u32`, `f32`, or `i32` "###, ); } #[test] -fn unknown_identifier() { +fn undefined_identifier() { check( r###" fn f(x: f32) -> f32 { return x * schmoo; } "###, - r###"error: no definition in scope for identifier: 'schmoo' + r###"error: undefined identifier ┌─ wgsl:3:30 │ 3 │ return x * schmoo; - │ ^^^^^^ unknown identifier + │ ^^^^^^ "###, ); } -#[test] -fn negative_index() { - check( - r#" - fn main() -> f32 { - let a = array(0., 1., 2.); - return a[-1]; - } - "#, - r#"error: expected unsigned integer constant expression, found `-1` - ┌─ wgsl:4:26 - │ -4 │ return a[-1]; - │ ^^ expected unsigned integer - -"#, - ); -} - #[test] fn bad_texture() { check( @@ -138,11 +94,11 @@ fn bad_texture() { return textureSample(a, sampler1, vec2(0.0)); } "#, - r#"error: expected an image, but found 'a' which is not an image + r#"error: expected a texture ┌─ wgsl:7:38 │ 7 │ return textureSample(a, sampler1, vec2(0.0)); - │ ^ not an image + │ ^ found `i32` "#, ); @@ -156,11 +112,11 @@ fn bad_type_cast() { return i32(vec2(0.0)); } "#, - r#"error: cannot cast a vec2 to a i32 + r#"error: cannot cast to `i32` ┌─ wgsl:3:28 │ 3 │ return i32(vec2(0.0)); - │ ^^^^^^^^^^^^^^ cannot cast a vec2 to a i32 + │ ^^^^^^^^^^^^^^ has type `vec2` "#, ); @@ -174,11 +130,18 @@ fn type_not_constructible() { _ = atomic(0); } "#, - r#"error: type `atomic` is not constructible + r#"error: cannot construct this type + ┌─ wgsl:3:21 + │ +3 │ _ = atomic(0); + │ ^^^^^^^^^^^ + + +error: undefined function ┌─ wgsl:3:21 │ 3 │ _ = atomic(0); - │ ^^^^^^ type is not constructible + │ ^^^^^^ "#, ); @@ -192,11 +155,13 @@ fn type_not_inferrable() { _ = vec2(); } "#, - r#"error: type can't be inferred + r#"error: cannot infer generics ┌─ wgsl:3:21 │ 3 │ _ = vec2(); - │ ^^^^ type can't be inferred + │ ^^^^ + │ + = note: consider annotating the generics with `<...>` "#, ); @@ -210,11 +175,13 @@ fn unexpected_constructor_parameters() { _ = i32(0, 1); } "#, - r#"error: unexpected components - ┌─ wgsl:3:27 + r#"error: expected 1 argument + ┌─ wgsl:3:28 │ 3 │ _ = i32(0, 1); - │ ^^ unexpected components + │ ^ extra argument + │ + = note: consider removing the 1 extra argument "#, ); @@ -228,11 +195,11 @@ fn constructor_parameter_type_mismatch() { _ = mat2x2(array(0, 1), vec2(2, 3)); } "#, - r#"error: invalid type for constructor component at index [0] + r#"error: expected scalar or vector to construct matrix ┌─ wgsl:3:33 │ 3 │ _ = mat2x2(array(0, 1), vec2(2, 3)); - │ ^^^^^^^^^^^ invalid component type + │ ^^^^^^^^^^^ found `array` "#, ); @@ -250,11 +217,11 @@ fn bad_texture_sample_type() { return textureSample(texture, sampler1, vec2(0.0)); } "#, - r#"error: texture sample type must be one of f32, i32 or u32, but found bool + r#"error: invalid sample type for `texture_2d` ┌─ wgsl:3:60 │ 3 │ @group(0) @binding(1) var texture : texture_2d; - │ ^^^^ must be one of f32, i32 or u32 + │ ^^^^ must be `u32`, `f32`, or `i32` "#, ); @@ -265,14 +232,14 @@ fn bad_for_initializer() { check( r#" fn x() { - for ({};;) {} + for (25;;) {} } "#, - r#"error: for(;;) initializer is not an assignment or a function call: '{}' + r#"error: this expression is not allowed here ┌─ wgsl:3:22 │ -3 │ for ({};;) {} - │ ^^ not an assignment or function call +3 │ for (25;;) {} + │ ^^ "#, ); @@ -284,11 +251,11 @@ fn unknown_storage_class() { r#" @group(0) @binding(0) var texture: texture_2d; "#, - r#"error: unknown address space: 'bad' + r#"error: unknown address space ┌─ wgsl:2:39 │ 2 │ @group(0) @binding(0) var texture: texture_2d; - │ ^^^ unknown address space + │ ^^^ "#, ); @@ -301,11 +268,11 @@ fn unknown_attribute() { @a fn x() {} "#, - r#"error: unknown attribute: 'a' + r#"error: unknown attribute ┌─ wgsl:2:14 │ 2 │ @a - │ ^ unknown attribute + │ ^ "#, ); @@ -317,11 +284,11 @@ fn unknown_built_in() { r#" fn x(@builtin(unknown_built_in) y: u32) {} "#, - r#"error: unknown builtin: 'unknown_built_in' + r#"error: unknown builtin ┌─ wgsl:2:27 │ 2 │ fn x(@builtin(unknown_built_in) y: u32) {} - │ ^^^^^^^^^^^^^^^^ unknown builtin + │ ^^^^^^^^^^^^^^^^ "#, ); @@ -333,79 +300,34 @@ fn unknown_access() { r#" var x: array; "#, - r#"error: unknown access: 'unknown_access' + r#"error: unknown access mode ┌─ wgsl:2:25 │ 2 │ var x: array; - │ ^^^^^^^^^^^^^^ unknown access - -"#, - ); -} - -#[test] -fn unknown_ident() { - check( - r#" - fn main() { - let a = b; - } - "#, - r#"error: no definition in scope for identifier: 'b' - ┌─ wgsl:3:25 - │ -3 │ let a = b; - │ ^ unknown identifier + │ ^^^^^^^^^^^^^^ "#, ); } #[test] -fn unknown_scalar_type() { - check( - r#" - let a: vec2; - "#, - r#"error: unknown scalar type: 'something' - ┌─ wgsl:2:25 - │ -2 │ let a: vec2; - │ ^^^^^^^^^ unknown scalar type - │ - = note: Valid scalar types are f16, f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, bool - -"#, - ); -} - -#[test] -fn unknown_type() { +fn unknown_storage_format() { check( r#" - let a: Vec; + var storage1: texture_storage_1d; "#, - r#"error: unknown type: 'Vec' - ┌─ wgsl:2:20 + r#"error: `texture_storage_1d` must have exactly 2 generic parameters + ┌─ wgsl:2:27 │ -2 │ let a: Vec; - │ ^^^ unknown type +2 │ var storage1: texture_storage_1d; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ -"#, - ); -} -#[test] -fn unknown_storage_format() { - check( - r#" - let storage1: texture_storage_1d; - "#, - r#"error: unknown storage format: 'rgba' +error: unknown texel format ┌─ wgsl:2:46 │ -2 │ let storage1: texture_storage_1d; - │ ^^^^ unknown storage format +2 │ var storage1: texture_storage_1d; + │ ^^^^ "#, ); @@ -415,13 +337,13 @@ fn unknown_storage_format() { fn unknown_conservative_depth() { check( r#" - @early_depth_test(abc) fn main() {} + @fragment @early_depth_test(abc) fn main() {} "#, - r#"error: unknown conservative depth: 'abc' - ┌─ wgsl:2:31 + r#"error: unknown conservative depth + ┌─ wgsl:2:41 │ -2 │ @early_depth_test(abc) fn main() {} - │ ^^^ unknown conservative depth +2 │ @fragment @early_depth_test(abc) fn main() {} + │ ^^^ "#, ); @@ -435,13 +357,15 @@ fn struct_member_size_too_low() { @size(0) data: array } "#, - r#"error: struct member size must be at least 4 - ┌─ wgsl:3:23 + "error: size attribute is too small + ┌─ wgsl:3:26 │ 3 │ @size(0) data: array - │ ^ must be at least 4 + │ ^^^^ ^^^^^^^^^^ type size is `4` + │ │\x20\x20\x20\x20\x20\x20 + │ set size is `0` -"#, +", ); } @@ -453,13 +377,15 @@ fn struct_member_align_too_low() { @align(8) data: vec3 } "#, - r#"error: struct member alignment must be at least 16 - ┌─ wgsl:3:24 + "error: alignment attribute is too small + ┌─ wgsl:3:27 │ 3 │ @align(8) data: vec3 - │ ^ must be at least 16 + │ ^^^^ ^^^^^^^^^ type alignment is `16` + │ │\x20\x20\x20\x20\x20\x20 + │ set alignment is `8` -"#, +", ); } @@ -471,11 +397,11 @@ fn struct_member_non_po2_align() { @align(7) data: array } "#, - r#"error: struct member alignment must be a power of 2 - ┌─ wgsl:3:24 + r#"error: alignment must be a power of two + ┌─ wgsl:3:27 │ 3 │ @align(7) data: array - │ ^ must be a power of 2 + │ ^^^^ set to `7` "#, ); @@ -487,29 +413,11 @@ fn inconsistent_binding() { r#" fn foo(@builtin(vertex_index) @location(0) x: u32) {} "#, - r#"error: input/output binding is not consistent - ┌─ wgsl:2:16 + r#"error: this attribute is not allowed here + ┌─ wgsl:2:39 │ 2 │ fn foo(@builtin(vertex_index) @location(0) x: u32) {} - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ input/output binding is not consistent - -"#, - ); -} - -#[test] -fn unknown_local_function() { - check( - r#" - fn x() { - for (a();;) {} - } - "#, - r#"error: unknown local function `a` - ┌─ wgsl:3:22 - │ -3 │ for (a();;) {} - │ ^ unknown local function + │ ^^^^^^^^^^^^ "#, ); @@ -519,15 +427,17 @@ 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 + "error: mismatched types + ┌─ wgsl:2:22 │ -2 │ let x: i32 = 1.0; - │ ^ definition of `x` +2 │ const x: i32 = 1.0; + │ ^^^ ^^^ found f32 + │ │\x20\x20\x20\x20\x20\x20 + │ expected i32 -"#, +", ); check( @@ -536,44 +446,35 @@ fn let_type_mismatch() { let x: f32 = true; } "#, - r#"error: the type of `x` is expected to be `bool` - ┌─ wgsl:3:21 + "error: mismatched types + ┌─ wgsl:3:24 │ 3 │ let x: f32 = true; - │ ^ definition of `x` + │ ^^^ ^^^^ found bool + │ │\x20\x20\x20\x20\x20\x20 + │ expected f32 -"#, +", ); } #[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` - ┌─ wgsl:3:21 + "error: mismatched types + ┌─ wgsl:3:24 │ -3 │ var x: f32 = 1u32; - │ ^ definition of `x` +3 │ var x: f32 = 1u; + │ ^^^ ^^ found u32 + │ │\x20\x20\x20\x20\x20\x20 + │ expected f32 -"#, +", ); } @@ -585,11 +486,11 @@ fn local_var_missing_type() { var x; } "#, - r#"error: variable `x` needs a type - ┌─ wgsl:3:21 + r#"error: variable declaration must have either initializer or type + ┌─ wgsl:3:17 │ 3 │ var x; - │ ^ definition of `x` + │ ^^^^^^ "#, ); @@ -605,46 +506,65 @@ fn postfix_pointers() { let a = *pv[3]; // Problematic line } "#, - r#"error: the value indexed by a `[]` subscripting expression must not be a pointer + r#"error: cannot index a pointer ┌─ wgsl:5:26 │ 5 │ let a = *pv[3]; // Problematic line - │ ^^ expression is a pointer + │ ^^ found type `ptr>` + │ + = note: consider dereferencing first "#, ); check( r#" - struct S { m: i32 }; + struct S { m: i32 } fn main() { var s: S = S(42); let ps = &s; let a = *ps.m; // Problematic line } "#, - r#"error: the value accessed by a `.member` expression must not be a pointer - ┌─ wgsl:6:26 + r#"error: unknown field of type `ptr` + ┌─ wgsl:6:29 │ 6 │ let a = *ps.m; // Problematic line - │ ^^ expression is a pointer + │ ^ + │ + = note: consider dereferencing first "#, ); } #[test] -fn reserved_keyword() { +fn reserved_identifier() { + check( + "var async;", + r###"error: usage of reserved identifier + ┌─ wgsl:1:5 + │ +1 │ var async; + │ ^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier + +"###, + ); + // global var check( r#" var bool: bool = true; "#, - r###"error: name `bool: bool = true;` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:2:17 │ 2 │ var bool: bool = true; - │ ^^^^^^^^^^^^^^^^^^ definition of `bool: bool = true;` + │ ^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -652,16 +572,27 @@ 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 + r###"error: usage of reserved identifier + ┌─ wgsl:2:19 + │ +2 │ const break: bool = true; + │ ^^^^^ │ -2 │ let break: bool = true; - │ ^^^^^ definition of `break` + = note: this is reserved by the WGSL spec, consider renaming the identifier + + +error: usage of reserved identifier + ┌─ wgsl:4:27 + │ +4 │ var foo = break; + │ ^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -673,11 +604,13 @@ fn reserved_keyword() { let atomic: f32 = 1.0; } "#, - r###"error: name `atomic` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:3:21 │ 3 │ let atomic: f32 = 1.0; - │ ^^^^^^ definition of `atomic` + │ ^^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -689,11 +622,13 @@ fn reserved_keyword() { var sampler: f32 = 1.0; } "#, - r###"error: name `sampler` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:3:21 │ 3 │ var sampler: f32 = 1.0; - │ ^^^^^^^ definition of `sampler` + │ ^^^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -703,11 +638,13 @@ fn reserved_keyword() { r#" fn break() {} "#, - r###"error: name `break` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:2:16 │ 2 │ fn break() {} - │ ^^^^^ definition of `break` + │ ^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -717,11 +654,13 @@ fn reserved_keyword() { r#" struct array {} "#, - r###"error: name `array` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:2:20 │ 2 │ struct array {} - │ ^^^^^ definition of `array` + │ ^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -731,11 +670,13 @@ fn reserved_keyword() { r#" struct Foo { sampler: f32 } "#, - r###"error: name `sampler` is a reserved keyword + r###"error: usage of reserved identifier ┌─ wgsl:2:26 │ 2 │ struct Foo { sampler: f32 } - │ ^^^^^^^ definition of `sampler` + │ ^^^^^^^ + │ + = note: this is reserved by the WGSL spec, consider renaming the identifier "###, ); @@ -743,19 +684,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 + r###"error: duplicate declaration + ┌─ 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; + │ ^^^ previously declared here +3 │ const foo: bool = true; + │ ^^^ redeclared here "###, ); @@ -765,30 +706,30 @@ fn module_scope_identifier_redefinition() { var foo: bool = true; var foo: bool = true; "#, - r###"error: redefinition of `foo: bool = true;` + r###"error: duplicate declaration ┌─ wgsl:2:17 │ 2 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ previous definition of `foo: bool = true;` + │ ^^^ previously declared here 3 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ redefinition of `foo: bool = true;` + │ ^^^ redeclared here "###, ); - // let and var + // const and var check( r#" var foo: bool = true; - let foo: bool = true; + const foo: bool = true; "#, - r###"error: redefinition of `foo` + r###"error: duplicate declaration ┌─ wgsl:2:17 │ 2 │ var foo: bool = true; - │ ^^^^^^^^^^^^^^^^^ previous definition of `foo: bool = true;` -3 │ let foo: bool = true; - │ ^^^ redefinition of `foo` + │ ^^^ previously declared here +3 │ const foo: bool = true; + │ ^^^ redeclared here "###, ); @@ -798,14 +739,14 @@ fn module_scope_identifier_redefinition() { r#"fn foo() {} fn bar() {} fn foo() {}"#, - r###"error: redefinition of `foo` + r###"error: duplicate declaration ┌─ wgsl:1:4 │ 1 │ fn foo() {} - │ ^^^ previous definition of `foo` + │ ^^^ previously declared here 2 │ fn bar() {} 3 │ fn foo() {} - │ ^^^ redefinition of `foo` + │ ^^^ redeclared here "###, ); @@ -813,16 +754,16 @@ 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 + r###"error: duplicate declaration + ┌─ wgsl:2:19 │ -2 │ let foo: bool = true; - │ ^^^ previous definition of `foo` +2 │ const foo: bool = true; + │ ^^^ previously declared here 3 │ fn foo() {} - │ ^^^ redefinition of `foo` + │ ^^^ redeclared here "###, ); @@ -836,11 +777,11 @@ fn matrix_with_bad_type() { let m = mat2x2(); } "#, - r#"error: matrix scalar type must be floating-point, but found `i32` - ┌─ wgsl:3:32 + r#"error: `mat2x2` must have a floating-point type as its generic parameter + ┌─ wgsl:3:25 │ 3 │ let m = mat2x2(); - │ ^^^ must be floating-point (e.g. `f32`) + │ ^^^^^^^^^^^ eg. `f32` "#, ); @@ -848,14 +789,14 @@ fn matrix_with_bad_type() { check( r#" fn main() { - let m: mat3x3; + var m: mat3x3; } "#, - r#"error: matrix scalar type must be floating-point, but found `i32` - ┌─ wgsl:3:31 + r#"error: `mat3x3` must have a floating-point type as its generic parameter + ┌─ wgsl:3:24 │ -3 │ let m: mat3x3; - │ ^^^ must be floating-point (e.g. `f32`) +3 │ var m: mat3x3; + │ ^^^^^^^^^^^ eg. `f32` "#, ); @@ -911,7 +852,13 @@ fn validation_error(source: &str) -> Result module, Err(err) => { eprintln!("WGSL parse failed:"); - panic!("{}", err.emit_to_string(source)); + panic!( + "{}", + err.into_iter() + .map(|x| x.emit_to_string(source)) + .collect::>() + .join("\n") + ); } }; naga::valid::Validator::new( @@ -933,27 +880,42 @@ fn invalid_arrays() { .. }) } +} - check_validation! { +#[test] +fn frontend_invalid_arrays() { + check( "type Bad = array;", - r#" - let length: f32 = 2.718; - type Bad = array; - "#: - Err(naga::valid::ValidationError::Type { - error: naga::valid::TypeError::InvalidArraySizeConstant(_), - .. - }) - } + "error: expected a positive integer + ┌─ wgsl:1:23 + │ +1 │ type Bad = array; + │ ^^^^ has type bool - check_validation! { +", + ); + + check( "type Bad = array;", - "type Bad = array;": - Err(naga::valid::ValidationError::Type { - error: naga::valid::TypeError::NonPositiveArrayLength(_), - .. - }) - } + "error: expected a positive integer + ┌─ wgsl:1:23 + │ +1 │ type Bad = array; + │ ^ has value `0` + +", + ); + + check( + "type Bad = array;", + "error: expected a positive integer + ┌─ wgsl:1:23 + │ +1 │ type Bad = array; + │ ^^ has value `-1` + +", + ); } #[test] @@ -1052,7 +1014,7 @@ fn invalid_functions() { " struct AFloat { said_float: f32 - }; + } @group(0) @binding(0) var float: AFloat; @@ -1370,28 +1332,6 @@ fn select() { } } -#[test] -fn last_case_falltrough() { - check_validation! { - " - fn test_falltrough() { - switch(0) { - default: {} - case 0: { - fallthrough; - } - } - } - ": - Err( - naga::valid::ValidationError::Function { - error: naga::valid::FunctionError::LastCaseFallTrough, - .. - }, - ) - } -} - #[test] fn missing_default_case() { check_validation! { @@ -1508,7 +1448,7 @@ fn host_shareable_types() { AStruct"; for ty in types.split_whitespace() { check_one_validation! { - &format!("struct AStruct {{ member: array, 8> }}; + &format!("struct AStruct {{ member: array, 8> }} @group(0) @binding(0) var ubuf: {}; @group(0) @binding(1) var sbuf: {};", ty, ty), @@ -1523,7 +1463,7 @@ fn host_shareable_types() { AStruct"; for ty in types.split_whitespace() { check_one_validation! { - &format!("struct AStruct {{ member: array, 8> }}; + &format!("struct AStruct {{ member: array, 8> }} @group(0) @binding(1) var sbuf: {};", ty), Ok(_module) @@ -1567,11 +1507,11 @@ fn misplaced_break_if() { } } ", - r###"error: A break if is only allowed in a continuing block + r###"error: `break if` must be the last statement in `continuing` ┌─ wgsl:4:17 │ 4 │ break if true; - │ ^^^^^^^^ not in a continuing block + │ ^^^^^^^^^^^^^^ "###, ); @@ -1607,14 +1547,14 @@ fn swizzle_assignment() { v.xy = vec2(1); } ", - r###"error: invalid left-hand side of assignment + r###"error: cannot assign to value ┌─ wgsl:4:13 │ 4 │ v.xy = vec2(1); - │ ^^^^ cannot assign to this expression + │ ^^^^ │ - = note: WGSL does not support assignments to swizzles - = note: consider assigning each component individually + = note: cannot assign to a swizzle + = note: consider assigning to each component separately "###, ); @@ -1628,11 +1568,11 @@ fn binary_statement() { 3 + 5; } ", - r###"error: expected assignment or increment/decrement, found '3 + 5' + r###"error: this expression is not allowed here ┌─ wgsl:3:13 │ 3 │ 3 + 5; - │ ^^^^^ expected assignment or increment/decrement + │ ^^^^^ "###, ); @@ -1646,11 +1586,11 @@ fn assign_to_expr() { 3 + 5 = 10; } ", - r###"error: invalid left-hand side of assignment + r###"error: cannot assign to value ┌─ wgsl:3:13 │ 3 │ 3 + 5 = 10; - │ ^^^^^ cannot assign to this expression + │ ^^^^^ "###, ); @@ -1665,14 +1605,14 @@ fn assign_to_let() { a = 20; } ", - r###"error: invalid left-hand side of assignment + r###"error: cannot assign to value ┌─ wgsl:4:10 │ 4 │ a = 20; - │ ^ cannot assign to this expression + │ ^ │ - = note: 'a' is an immutable binding - = note: consider declaring it with `var` instead of `let` + = note: cannot assign to a `let` binding + = note: consider using `var` instead "###, );