From 1676ee0dc0b2d90e5d631c668af1b1bb258ca1ef Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 22 Nov 2023 21:34:19 -0800 Subject: [PATCH] [naga wgsl-in] Automatic conversions for global `var` initializers. --- naga/src/front/wgsl/lower/mod.rs | 28 ++++++- naga/tests/in/abstract-types-var.wgsl | 44 +++++++++++ naga/tests/out/msl/abstract-types-var.msl | 12 +++ naga/tests/out/spv/abstract-types-var.spvasm | 78 ++++++++++++++++++++ naga/tests/out/wgsl/abstract-types-var.wgsl | 25 +++++++ naga/tests/snapshots.rs | 4 + naga/tests/wgsl_errors.rs | 16 ++++ 7 files changed, 203 insertions(+), 4 deletions(-) create mode 100644 naga/tests/in/abstract-types-var.wgsl create mode 100644 naga/tests/out/msl/abstract-types-var.msl create mode 100644 naga/tests/out/spv/abstract-types-var.spvasm create mode 100644 naga/tests/out/wgsl/abstract-types-var.wgsl diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index b050ffc343..27ed142286 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -875,10 +875,30 @@ impl<'source, 'temp> Lowerer<'source, 'temp> { ast::GlobalDeclKind::Var(ref v) => { let ty = self.resolve_ast_type(v.ty, &mut ctx)?; - let init = v - .init - .map(|init| self.expression(init, &mut ctx.as_const())) - .transpose()?; + let init; + if let Some(init_ast) = v.init { + let mut ectx = ctx.as_const(); + let lowered = self.expression_for_abstract(init_ast, &mut ectx)?; + let ty_res = crate::proc::TypeResolution::Handle(ty); + let converted = ectx + .try_automatic_conversions(lowered, &ty_res, v.name.span) + .map_err(|error| match error { + Error::AutoConversion { + dest_span: _, + dest_type, + source_span: _, + source_type, + } => Error::InitializationTypeMismatch { + name: v.name.span, + expected: dest_type, + got: source_type, + }, + other => other, + })?; + init = Some(converted); + } else { + init = None; + } let binding = if let Some(ref binding) = v.binding { Some(crate::ResourceBinding { diff --git a/naga/tests/in/abstract-types-var.wgsl b/naga/tests/in/abstract-types-var.wgsl new file mode 100644 index 0000000000..7eeb69065c --- /dev/null +++ b/naga/tests/in/abstract-types-var.wgsl @@ -0,0 +1,44 @@ +// i/x: type inferred / explicit +// vX/mX/aX: vector / matrix / array of X +// where X: u/i/f: u32 / i32 / f32 +// s: vector splat +// r: vector spread (vector arg to vector constructor) +// p: "partial" constructor (type parameter inferred) +// u/i/f/ai/af: u32 / i32 / f32 / abstract float / abstract integer as parameter +// _: just for alignment + +// Ensure that: +// - the inferred type is correct. +// - all parameters' types are considered. +// - all parameters are converted to the consensus type. + +var xvipaiai: vec2 = vec2(42, 43); +var xvupaiai: vec2 = vec2(44, 45); +var xvfpaiai: vec2 = vec2(46, 47); + +var xvupuai: vec2 = vec2(42u, 43); +var xvupaiu: vec2 = vec2(42, 43u); + +var xvuuai: vec2 = vec2(42u, 43); +var xvuaiu: vec2 = vec2(42, 43u); + +var xmfpaiaiaiai: mat2x2 = mat2x2(1, 2, 3, 4); +var xmfpafaiaiai: mat2x2 = mat2x2(1.0, 2, 3, 4); +var xmfpaiafaiai: mat2x2 = mat2x2(1, 2.0, 3, 4); +var xmfpaiaiafai: mat2x2 = mat2x2(1, 2, 3.0, 4); +var xmfpaiaiaiaf: mat2x2 = mat2x2(1, 2, 3, 4.0); + +var xvispai: vec2 = vec2(1); +var xvfspaf: vec2 = vec2(1.0); +var xvis_ai: vec2 = vec2(1); +var xvus_ai: vec2 = vec2(1); +var xvfs_ai: vec2 = vec2(1); +var xvfs_af: vec2 = vec2(1.0); + +var xafafaf: array = array(1.0, 2.0); +var xafaiai: array = array(1, 2); + +var xafpaiai: array = array(1, 2); +var xafpaiaf: array = array(1, 2.0); +var xafpafai: array = array(1.0, 2); +var xafpafaf: array = array(1.0, 2.0); diff --git a/naga/tests/out/msl/abstract-types-var.msl b/naga/tests/out/msl/abstract-types-var.msl new file mode 100644 index 0000000000..63f1cdfa75 --- /dev/null +++ b/naga/tests/out/msl/abstract-types-var.msl @@ -0,0 +1,12 @@ +// language: metal1.0 +#include +#include + +using metal::uint; + +struct type_5 { + float inner[2]; +}; +struct type_7 { + int inner[2]; +}; diff --git a/naga/tests/out/spv/abstract-types-var.spvasm b/naga/tests/out/spv/abstract-types-var.spvasm new file mode 100644 index 0000000000..ee9b4c1c72 --- /dev/null +++ b/naga/tests/out/spv/abstract-types-var.spvasm @@ -0,0 +1,78 @@ +; SPIR-V +; Version: 1.1 +; Generator: rspirv +; Bound: 70 +OpCapability Shader +OpCapability Linkage +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpDecorate %10 ArrayStride 4 +OpDecorate %12 ArrayStride 4 +%2 = OpTypeVoid +%4 = OpTypeInt 32 1 +%3 = OpTypeVector %4 2 +%6 = OpTypeInt 32 0 +%5 = OpTypeVector %6 2 +%8 = OpTypeFloat 32 +%7 = OpTypeVector %8 2 +%9 = OpTypeMatrix %7 2 +%11 = OpConstant %6 2 +%10 = OpTypeArray %8 %11 +%12 = OpTypeArray %4 %11 +%13 = OpConstant %4 42 +%14 = OpConstant %4 43 +%15 = OpConstantComposite %3 %13 %14 +%16 = OpConstant %6 44 +%17 = OpConstant %6 45 +%18 = OpConstantComposite %5 %16 %17 +%19 = OpConstant %8 46.0 +%20 = OpConstant %8 47.0 +%21 = OpConstantComposite %7 %19 %20 +%22 = OpConstant %6 42 +%23 = OpConstant %6 43 +%24 = OpConstantComposite %5 %22 %23 +%25 = OpConstant %8 1.0 +%26 = OpConstant %8 2.0 +%27 = OpConstantComposite %7 %25 %26 +%28 = OpConstant %8 3.0 +%29 = OpConstant %8 4.0 +%30 = OpConstantComposite %7 %28 %29 +%31 = OpConstantComposite %9 %27 %30 +%32 = OpConstant %4 1 +%33 = OpConstantComposite %3 %32 %32 +%34 = OpConstantComposite %7 %25 %25 +%35 = OpConstant %6 1 +%36 = OpConstantComposite %5 %35 %35 +%37 = OpConstantComposite %10 %25 %26 +%38 = OpConstant %4 2 +%39 = OpConstantComposite %12 %32 %38 +%41 = OpTypePointer Private %3 +%40 = OpVariable %41 Private %15 +%43 = OpTypePointer Private %5 +%42 = OpVariable %43 Private %18 +%45 = OpTypePointer Private %7 +%44 = OpVariable %45 Private %21 +%46 = OpVariable %43 Private %24 +%47 = OpVariable %43 Private %24 +%48 = OpVariable %43 Private %24 +%49 = OpVariable %43 Private %24 +%51 = OpTypePointer Private %9 +%50 = OpVariable %51 Private %31 +%52 = OpVariable %51 Private %31 +%53 = OpVariable %51 Private %31 +%54 = OpVariable %51 Private %31 +%55 = OpVariable %51 Private %31 +%56 = OpVariable %41 Private %33 +%57 = OpVariable %45 Private %34 +%58 = OpVariable %41 Private %33 +%59 = OpVariable %43 Private %36 +%60 = OpVariable %45 Private %34 +%61 = OpVariable %45 Private %34 +%63 = OpTypePointer Private %10 +%62 = OpVariable %63 Private %37 +%64 = OpVariable %63 Private %37 +%66 = OpTypePointer Private %12 +%65 = OpVariable %66 Private %39 +%67 = OpVariable %63 Private %37 +%68 = OpVariable %63 Private %37 +%69 = OpVariable %63 Private %37 \ No newline at end of file diff --git a/naga/tests/out/wgsl/abstract-types-var.wgsl b/naga/tests/out/wgsl/abstract-types-var.wgsl new file mode 100644 index 0000000000..cf05b83cde --- /dev/null +++ b/naga/tests/out/wgsl/abstract-types-var.wgsl @@ -0,0 +1,25 @@ +var xvipaiai: vec2 = vec2(42, 43); +var xvupaiai: vec2 = vec2(44u, 45u); +var xvfpaiai: vec2 = vec2(46.0, 47.0); +var xvupuai: vec2 = vec2(42u, 43u); +var xvupaiu: vec2 = vec2(42u, 43u); +var xvuuai: vec2 = vec2(42u, 43u); +var xvuaiu: vec2 = vec2(42u, 43u); +var xmfpaiaiaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpafaiaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiafaiai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiaiafai: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xmfpaiaiaiaf: mat2x2 = mat2x2(vec2(1.0, 2.0), vec2(3.0, 4.0)); +var xvispai: vec2 = vec2(1); +var xvfspaf: vec2 = vec2(1.0); +var xvis_ai: vec2 = vec2(1); +var xvus_ai: vec2 = vec2(1u); +var xvfs_ai: vec2 = vec2(1.0); +var xvfs_af: vec2 = vec2(1.0); +var xafafaf: array = array(1.0, 2.0); +var xafaiai: array = array(1.0, 2.0); +var xafpaiai: array = array(1, 2); +var xafpaiaf: array = array(1.0, 2.0); +var xafpafai: array = array(1.0, 2.0); +var xafpafaf: array = array(1.0, 2.0); + diff --git a/naga/tests/snapshots.rs b/naga/tests/snapshots.rs index fd955be32a..c201b206a2 100644 --- a/naga/tests/snapshots.rs +++ b/naga/tests/snapshots.rs @@ -794,6 +794,10 @@ fn convert_wgsl() { "abstract-types-const", Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL, ), + ( + "abstract-types-var", + Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL, + ), ]; for &(name, targets) in inputs.iter() { diff --git a/naga/tests/wgsl_errors.rs b/naga/tests/wgsl_errors.rs index b01c94d72e..7dddf633a4 100644 --- a/naga/tests/wgsl_errors.rs +++ b/naga/tests/wgsl_errors.rs @@ -2003,6 +2003,22 @@ fn constructor_type_error_span() { ) } +#[test] +fn global_initialization_type_mismatch() { + check( + " + var a: vec2 = vec2(1i, 2i); + ", + r###"error: the type of `a` is expected to be `vec2`, but got `vec2` + ┌─ wgsl:2:22 + │ +2 │ var a: vec2 = vec2(1i, 2i); + │ ^ definition of `a` + +"###, + ) +} + #[test] fn binding_array_local() { check_validation! {