From f054aa94f4b842b504c8de90cbd8e7d2a2af3922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Capucho?= Date: Thu, 3 Mar 2022 17:20:18 +0000 Subject: [PATCH] glsl-in: Support arrays as input/output types Like it was already done for structs, arrays are flattened and each element is attributed a location that is it's index + the array base location. --- src/front/glsl/functions.rs | 53 +++++++++++++++++++++++++++ tests/in/glsl/declarations.vert | 5 +++ tests/out/wgsl/declarations-vert.wgsl | 21 +++++++++-- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/front/glsl/functions.rs b/src/front/glsl/functions.rs index 9a53e50028..a6dd97e999 100644 --- a/src/front/glsl/functions.rs +++ b/src/front/glsl/functions.rs @@ -1208,6 +1208,59 @@ impl Parser { ), ) { match self.module.types[ty].inner { + TypeInner::Array { + base, + size: crate::ArraySize::Constant(constant), + .. + } => { + let mut location = match binding { + crate::Binding::Location { location, .. } => location, + _ => return, + }; + + // TODO: Better error reporting + // right now we just don't walk the array if the size isn't known at + // compile time and let validation catch it + let size = match self.module.constants[constant].to_array_length() { + Some(val) => val, + None => return f(name, pointer, ty, binding, expressions), + }; + + let interpolation = + self.module.types[base] + .inner + .scalar_kind() + .map(|kind| match kind { + ScalarKind::Float => crate::Interpolation::Perspective, + _ => crate::Interpolation::Flat, + }); + + for index in 0..size { + let member_pointer = expressions.append( + Expression::AccessIndex { + base: pointer, + index, + }, + crate::Span::default(), + ); + + let binding = crate::Binding::Location { + location, + interpolation, + sampling: None, + }; + location += 1; + + self.arg_type_walker( + name.clone(), + binding, + member_pointer, + base, + expressions, + f, + ) + } + } TypeInner::Struct { ref members, .. } => { let mut location = match binding { crate::Binding::Location { location, .. } => location, diff --git a/tests/in/glsl/declarations.vert b/tests/in/glsl/declarations.vert index c8dab77954..4d2054caa6 100644 --- a/tests/in/glsl/declarations.vert +++ b/tests/in/glsl/declarations.vert @@ -10,6 +10,9 @@ layout(location = 0) out FragmentData { vec2 a; } frag; +layout(location = 2) in vec4 in_array[2]; +layout(location = 2) out vec4 out_array[2]; + struct TestStruct { float a; float b; @@ -22,4 +25,6 @@ void main() { vec3(-1.0, -1.0, 0.0) ); const TestStruct strct = TestStruct( 1, 2 ); + const vec4 from_input_array = in_array[1]; + out_array[0] = vec4(2.0); } diff --git a/tests/out/wgsl/declarations-vert.wgsl b/tests/out/wgsl/declarations-vert.wgsl index 8673150904..cc5d9c932e 100644 --- a/tests/out/wgsl/declarations-vert.wgsl +++ b/tests/out/wgsl/declarations-vert.wgsl @@ -16,23 +16,36 @@ struct TestStruct { struct VertexOutput { @location(0) position: vec2; @location(1) a: vec2; + @location(2) out_array: vec4; + @location(3) out_array_1: vec4; }; var vert: VertexData; var frag: FragmentData; +var in_array_2: array,2u>; +var out_array: array,2u>; fn main_1() { var positions: array,2u> = array,2u>(vec3(-1.0, 1.0, 0.0), vec3(-1.0, -1.0, 0.0)); var strct: TestStruct = TestStruct(1.0, 2.0); + var from_input_array: vec4; + let _e32 = in_array_2; + from_input_array = _e32[1]; + out_array[0] = vec4(2.0); + return; } @stage(vertex) -fn main(@location(0) position: vec2, @location(1) a: vec2) -> VertexOutput { +fn main(@location(0) position: vec2, @location(1) a: vec2, @location(2) in_array: vec4, @location(3) in_array_1: vec4) -> VertexOutput { vert.position = position; vert.a = a; + in_array_2[0] = in_array; + in_array_2[1] = in_array_1; main_1(); - let _e17 = frag.position; - let _e19 = frag.a; - return VertexOutput(_e17, _e19); + let _e26 = frag.position; + let _e28 = frag.a; + let _e31 = out_array[0]; + let _e33 = out_array[1]; + return VertexOutput(_e26, _e28, _e31, _e33); }