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.
This commit is contained in:
João Capucho
2022-03-03 17:20:18 +00:00
committed by Dzmitry Malyshau
parent a2bcdda81c
commit f054aa94f4
3 changed files with 75 additions and 4 deletions

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -16,23 +16,36 @@ struct TestStruct {
struct VertexOutput {
@location(0) position: vec2<f32>;
@location(1) a: vec2<f32>;
@location(2) out_array: vec4<f32>;
@location(3) out_array_1: vec4<f32>;
};
var<private> vert: VertexData;
var<private> frag: FragmentData;
var<private> in_array_2: array<vec4<f32>,2u>;
var<private> out_array: array<vec4<f32>,2u>;
fn main_1() {
var positions: array<vec3<f32>,2u> = array<vec3<f32>,2u>(vec3<f32>(-1.0, 1.0, 0.0), vec3<f32>(-1.0, -1.0, 0.0));
var strct: TestStruct = TestStruct(1.0, 2.0);
var from_input_array: vec4<f32>;
let _e32 = in_array_2;
from_input_array = _e32[1];
out_array[0] = vec4<f32>(2.0);
return;
}
@stage(vertex)
fn main(@location(0) position: vec2<f32>, @location(1) a: vec2<f32>) -> VertexOutput {
fn main(@location(0) position: vec2<f32>, @location(1) a: vec2<f32>, @location(2) in_array: vec4<f32>, @location(3) in_array_1: vec4<f32>) -> 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);
}