diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index 95336a5d61..fc9a0677ee 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -756,8 +756,6 @@ impl Parser { // If the argument is to be passed as a pointer but the type of the // expression returns a vector it must mean that it was for example // swizzled and it must be spilled into a local before calling - // TODO: this part doesn't work because of #1385 once that's sorted out - // revisit this part. TypeInner::Vector { size, kind, width } => ( self.module.types.insert( Type { @@ -829,7 +827,40 @@ impl Parser { arguments.push(temp_expr); // Register the temporary local to be written back to it's original // place after the function call - proxy_writes.push((handle, temp_expr)); + if let Expression::Swizzle { + size, + mut vector, + pattern, + } = ctx.expressions[value] + { + if let Expression::Load { pointer } = ctx.expressions[vector] { + vector = pointer; + } + + for (i, component) in pattern.iter().take(size as usize).enumerate() { + let original = ctx.add_expression( + Expression::AccessIndex { + base: vector, + index: *component as u32, + }, + Span::default(), + body, + ); + + let temp = ctx.add_expression( + Expression::AccessIndex { + base: temp_expr, + index: i as u32, + }, + Span::default(), + body, + ); + + proxy_writes.push((original, temp)); + } + } else { + proxy_writes.push((handle, temp_expr)); + } continue; } diff --git a/tests/in/glsl/swizzle_write.frag b/tests/in/glsl/swizzle_write.frag index a554c94e12..c5a165590a 100644 --- a/tests/in/glsl/swizzle_write.frag +++ b/tests/in/glsl/swizzle_write.frag @@ -1,9 +1,11 @@ #version 450 +void foo(inout vec2 p) {} void main() { vec3 x = vec3(2.0); x.zxy.xy = vec2(3.0, 4.0); x.rg *= 5.0; x.zy++; + foo(x.xz); } diff --git a/tests/out/wgsl/swizzle_write-frag.wgsl b/tests/out/wgsl/swizzle_write-frag.wgsl index 48ca0a1996..04bbd7ec5b 100644 --- a/tests/out/wgsl/swizzle_write-frag.wgsl +++ b/tests/out/wgsl/swizzle_write-frag.wgsl @@ -1,5 +1,10 @@ +fn foo(p: ptr>) { + return; +} + fn main_1() { var x: vec3 = vec3(2.0, 2.0, 2.0); + var local: vec2; let _e3 = x; let _e8 = vec2(3.0, 4.0); @@ -14,6 +19,14 @@ fn main_1() { let _e27 = (_e23.zy + vec2(1.0)); x.z = _e27.x; x.y = _e27.y; + let _e32 = x; + let _e34 = x; + local = _e34.xz; + foo((&local)); + let _e41 = local.x; + x.x = _e41; + let _e42 = local.y; + x.z = _e42; return; }