Skip to content

Commit

Permalink
glsl-in: Support arrays as input/output types
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JCapucho authored and kvark committed Mar 4, 2022
1 parent a2bcdda commit f054aa9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
53 changes: 53 additions & 0 deletions src/front/glsl/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions tests/in/glsl/declarations.vert
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
21 changes: 17 additions & 4 deletions tests/out/wgsl/declarations-vert.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit f054aa9

Please sign in to comment.