Skip to content

Commit

Permalink
[naga wgsl-in] Automatic conversions for local var initializers.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimblandy committed Nov 25, 2023
1 parent 9e8228c commit a220510
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 59 deletions.
70 changes: 37 additions & 33 deletions naga/src/front/wgsl/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,45 1162,49 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
return Ok(());
}
ast::LocalDecl::Var(ref v) => {
let mut emitter = Emitter::default();
emitter.start(&ctx.function.expressions);

let initializer = match v.init {
Some(init) => Some(
self.expression(init, &mut ctx.as_expression(block, &mut emitter))?,
),
None => None,
};

let explicit_ty =
v.ty.map(|ty| self.resolve_ast_type(ty, &mut ctx.as_global()))
v.ty.map(|ast| self.resolve_ast_type(ast, &mut ctx.as_global()))
.transpose()?;

let ty = match (explicit_ty, initializer) {
(Some(explicit), Some(initializer)) => {
let mut ctx = ctx.as_expression(block, &mut emitter);
let initializer_ty = resolve_inner!(ctx, initializer);
if !ctx.module.types[explicit]
.inner
.equivalent(initializer_ty, &ctx.module.types)
{
let gctx = &ctx.module.to_ctx();
return Err(Error::InitializationTypeMismatch {
let mut emitter = Emitter::default();
emitter.start(&ctx.function.expressions);
let mut ectx = ctx.as_expression(block, &mut emitter);

let ty;
let initializer;
match (v.init, explicit_ty) {
(Some(init), Some(explicit_ty)) => {
let init = self.expression_for_abstract(init, &mut ectx)?;
let ty_res = crate::proc::TypeResolution::Handle(explicit_ty);
let init = ectx
.try_automatic_conversions(init, &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: explicit.to_wgsl(gctx),
got: initializer_ty.to_wgsl(gctx),
});
}
explicit
expected: dest_type,
got: source_type,
},
other => other,
})?;
ty = explicit_ty;
initializer = Some(init);
}
(Some(explicit), None) => explicit,
(None, Some(initializer)) => ctx
.as_expression(block, &mut emitter)
.register_type(initializer)?,
(None, None) => {
return Err(Error::MissingType(v.name.span));
(Some(init), None) => {
let concretized = self.expression(init, &mut ectx)?;
ty = ectx.register_type(concretized)?;
initializer = Some(concretized);
}
};
(None, Some(explicit_ty)) => {
ty = explicit_ty;
initializer = None;
}
(None, None) => return Err(Error::MissingType(v.name.span)),
}

let (const_initializer, initializer) = {
match initializer {
Expand Down
33 changes: 33 additions & 0 deletions naga/tests/in/abstract-types-var.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 42,36 @@ var<private> xafpaiai: array<i32, 2> = array(1, 2);
var<private> xafpaiaf: array<f32, 2> = array(1, 2.0);
var<private> xafpafai: array<f32, 2> = array(1.0, 2);
var<private> xafpafaf: array<f32, 2> = array(1.0, 2.0);

fn f() {
var xvipaiai: vec2<i32> = vec2(42, 43);
var xvupaiai: vec2<u32> = vec2(44, 45);
var xvfpaiai: vec2<f32> = vec2(46, 47);

var xvupuai: vec2<u32> = vec2(42u, 43);
var xvupaiu: vec2<u32> = vec2(42, 43u);

var xvuuai: vec2<u32> = vec2<u32>(42u, 43);
var xvuaiu: vec2<u32> = vec2<u32>(42, 43u);

var xmfpaiaiaiai: mat2x2<f32> = mat2x2(1, 2, 3, 4);
var xmfpafaiaiai: mat2x2<f32> = mat2x2(1.0, 2, 3, 4);
var xmfpaiafaiai: mat2x2<f32> = mat2x2(1, 2.0, 3, 4);
var xmfpaiaiafai: mat2x2<f32> = mat2x2(1, 2, 3.0, 4);
var xmfpaiaiaiaf: mat2x2<f32> = mat2x2(1, 2, 3, 4.0);

var xvispai: vec2<i32> = vec2(1);
var xvfspaf: vec2<f32> = vec2(1.0);
var xvis_ai: vec2<i32> = vec2<i32>(1);
var xvus_ai: vec2<u32> = vec2<u32>(1);
var xvfs_ai: vec2<f32> = vec2<f32>(1);
var xvfs_af: vec2<f32> = vec2<f32>(1.0);

var xafafaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var xafaiai: array<f32, 2> = array<f32, 2>(1, 2);

var xafpaiai: array<i32, 2> = array(1, 2);
var xafpaiaf: array<f32, 2> = array(1, 2.0);
var xafpafai: array<f32, 2> = array(1.0, 2);
var xafpafaf: array<f32, 2> = array(1.0, 2.0);
}
28 changes: 28 additions & 0 deletions naga/tests/out/msl/abstract-types-var.msl
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 10,31 @@ struct type_5 {
struct type_7 {
int inner[2];
};

void f(
) {
metal::int2 xvipaiai = metal::int2(42, 43);
metal::uint2 xvupaiai = metal::uint2(44u, 45u);
metal::float2 xvfpaiai = metal::float2(46.0, 47.0);
metal::uint2 xvupuai = metal::uint2(42u, 43u);
metal::uint2 xvupaiu = metal::uint2(42u, 43u);
metal::uint2 xvuuai = metal::uint2(42u, 43u);
metal::uint2 xvuaiu = metal::uint2(42u, 43u);
metal::float2x2 xmfpaiaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
metal::float2x2 xmfpafaiaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
metal::float2x2 xmfpaiafaiai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
metal::float2x2 xmfpaiaiafai = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
metal::float2x2 xmfpaiaiaiaf = metal::float2x2(metal::float2(1.0, 2.0), metal::float2(3.0, 4.0));
metal::int2 xvispai = metal::int2(1);
metal::float2 xvfspaf = metal::float2(1.0);
metal::int2 xvis_ai = metal::int2(1);
metal::uint2 xvus_ai = metal::uint2(1u);
metal::float2 xvfs_ai = metal::float2(1.0);
metal::float2 xvfs_af = metal::float2(1.0);
type_5 xafafaf = type_5 {1.0, 2.0};
type_5 xafaiai = type_5 {1.0, 2.0};
type_7 xafpaiai = type_7 {1, 2};
type_5 xafpaiaf = type_5 {1.0, 2.0};
type_5 xafpafai = type_5 {1.0, 2.0};
type_5 xafpafaf = type_5 {1.0, 2.0};
}
41 changes: 39 additions & 2 deletions naga/tests/out/spv/abstract-types-var.spvasm
Original file line number Diff line number Diff line change
@@ -1,7 1,7 @@
; SPIR-V
; Version: 1.1
; Generator: rspirv
; Bound: 70
; Bound: 104
OpCapability Shader
OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
Expand Down Expand Up @@ -75,4 75,41 @@ OpDecorate  ArrayStride 4
e = OpVariable f Private 9
g = OpVariable c Private 7
h = OpVariable c Private 7
i = OpVariable c Private 7
i = OpVariable c Private 7
r = OpTypeFunction %2
t = OpTypePointer Function %3
v = OpTypePointer Function %5
x = OpTypePointer Function %7
� = OpTypePointer Function %9
� = OpTypePointer Function 
� = OpTypePointer Function 
q = OpFunction %2 None r
p = OpLabel
1 = OpVariable � Function 7
� = OpVariable � Function 7
� = OpVariable x Function 4
� = OpVariable x Function 4
� = OpVariable � Function 1
� = OpVariable � Function 1
� = OpVariable v Function $
u = OpVariable v Function 
0 = OpVariable � Function 7
� = OpVariable � Function 7
� = OpVariable v Function 6
� = OpVariable t Function 3
� = OpVariable � Function 1
� = OpVariable v Function $
y = OpVariable v Function $
s = OpVariable t Function 
2 = OpVariable � Function 7
� = OpVariable � Function 9
� = OpVariable x Function 4
� = OpVariable t Function 3
� = OpVariable � Function 1
� = OpVariable � Function 1
� = OpVariable v Function $
w = OpVariable x Function !
OpBranch 3
3 = OpLabel
OpReturn
OpFunctionEnd
76 changes: 52 additions & 24 deletions naga/tests/out/wgsl/abstract-types-var.wgsl
Original file line number Diff line number Diff line change
@@ -1,25 1,53 @@
var<private> xvipaiai: vec2<i32> = vec2<i32>(42, 43);
var<private> xvupaiai: vec2<u32> = vec2<u32>(44u, 45u);
var<private> xvfpaiai: vec2<f32> = vec2<f32>(46.0, 47.0);
var<private> xvupuai: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvupaiu: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvuuai: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvuaiu: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xmfpaiaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpafaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiafaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiaiafai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiaiaiaf: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xvispai: vec2<i32> = vec2(1);
var<private> xvfspaf: vec2<f32> = vec2(1.0);
var<private> xvis_ai: vec2<i32> = vec2(1);
var<private> xvus_ai: vec2<u32> = vec2(1u);
var<private> xvfs_ai: vec2<f32> = vec2(1.0);
var<private> xvfs_af: vec2<f32> = vec2(1.0);
var<private> xafafaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafaiai: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpaiai: array<i32, 2> = array<i32, 2>(1, 2);
var<private> xafpaiaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpafai: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpafaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xvipaiai_1: vec2<i32> = vec2<i32>(42, 43);
var<private> xvupaiai_1: vec2<u32> = vec2<u32>(44u, 45u);
var<private> xvfpaiai_1: vec2<f32> = vec2<f32>(46.0, 47.0);
var<private> xvupuai_1: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvupaiu_1: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvuuai_1: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xvuaiu_1: vec2<u32> = vec2<u32>(42u, 43u);
var<private> xmfpaiaiaiai_1: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpafaiaiai_1: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiafaiai_1: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiaiafai_1: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xmfpaiaiaiaf_1: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var<private> xvispai_1: vec2<i32> = vec2(1);
var<private> xvfspaf_1: vec2<f32> = vec2(1.0);
var<private> xvis_ai_1: vec2<i32> = vec2(1);
var<private> xvus_ai_1: vec2<u32> = vec2(1u);
var<private> xvfs_ai_1: vec2<f32> = vec2(1.0);
var<private> xvfs_af_1: vec2<f32> = vec2(1.0);
var<private> xafafaf_1: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafaiai_1: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpaiai_1: array<i32, 2> = array<i32, 2>(1, 2);
var<private> xafpaiaf_1: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpafai_1: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var<private> xafpafaf_1: array<f32, 2> = array<f32, 2>(1.0, 2.0);

fn f() {
var xvipaiai: vec2<i32> = vec2<i32>(42, 43);
var xvupaiai: vec2<u32> = vec2<u32>(44u, 45u);
var xvfpaiai: vec2<f32> = vec2<f32>(46.0, 47.0);
var xvupuai: vec2<u32> = vec2<u32>(42u, 43u);
var xvupaiu: vec2<u32> = vec2<u32>(42u, 43u);
var xvuuai: vec2<u32> = vec2<u32>(42u, 43u);
var xvuaiu: vec2<u32> = vec2<u32>(42u, 43u);
var xmfpaiaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var xmfpafaiaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var xmfpaiafaiai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var xmfpaiaiafai: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var xmfpaiaiaiaf: mat2x2<f32> = mat2x2<f32>(vec2<f32>(1.0, 2.0), vec2<f32>(3.0, 4.0));
var xvispai: vec2<i32> = vec2(1);
var xvfspaf: vec2<f32> = vec2(1.0);
var xvis_ai: vec2<i32> = vec2(1);
var xvus_ai: vec2<u32> = vec2(1u);
var xvfs_ai: vec2<f32> = vec2(1.0);
var xvfs_af: vec2<f32> = vec2(1.0);
var xafafaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var xafaiai: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var xafpaiai: array<i32, 2> = array<i32, 2>(1, 2);
var xafpaiaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var xafpafai: array<f32, 2> = array<f32, 2>(1.0, 2.0);
var xafpafaf: array<f32, 2> = array<f32, 2>(1.0, 2.0);

}

0 comments on commit a220510

Please sign in to comment.