Add support for array stride to wgsl frontend (#137)

* Add support for array stride to wgsl frontend

* rename
This commit is contained in:
Lachlan Sneff
2020-08-19 14:09:28 -04:00
committed by GitHub
parent b0f1f6285a
commit d6b172ddcb
2 changed files with 45 additions and 5 deletions

View File

@@ -170,6 +170,8 @@ pub enum Error<'a> {
UnknownFunction(&'a str),
#[error("missing offset for structure member `{0}`")]
MissingMemberOffset(&'a str),
#[error("array stride must not be 0")]
ZeroStride,
//MutabilityViolation(&'a str),
// TODO: these could be replaced with more detailed errors
#[error("other error")]
@@ -256,6 +258,22 @@ impl<'a> Lexer<'a> {
self.expect(Token::Paren('>'))?;
Ok(pair)
}
fn take_until(&mut self, what: Token<'a>) -> Result<Lexer<'a>, Error<'a>> {
let original_input = self.input;
let initial_len = self.input.len();
let mut used_len = 0;
loop {
if self.next() == what {
break;
}
used_len = initial_len - self.input.len();
}
Ok(Lexer {
input: &original_input[..used_len],
})
}
}
trait StringValueLookup<'a> {
@@ -1000,6 +1018,12 @@ impl Parser {
type_arena: &mut Arena<crate::Type>,
) -> Result<Handle<crate::Type>, Error<'a>> {
self.scopes.push(Scope::TypeDecl);
let decoration_lexer = if lexer.skip(Token::DoubleParen('[')) {
Some(lexer.take_until(Token::DoubleParen(']'))?)
} else {
None
};
let inner = match lexer.next() {
Token::Word("f32") => crate::TypeInner::Scalar {
kind: crate::ScalarKind::Float,
@@ -1138,11 +1162,27 @@ impl Parser {
Token::Separator('>') => crate::ArraySize::Dynamic,
other => return Err(Error::Unexpected(other)),
};
crate::TypeInner::Array {
base,
size,
stride: None,
let mut stride = None;
if let Some(mut lexer) = decoration_lexer {
self.scopes.push(Scope::Decoration);
loop {
match lexer.next() {
Token::Word("stride") => {
use std::num::NonZeroU32;
stride = Some(
NonZeroU32::new(lexer.next_uint_literal()?)
.ok_or(Error::ZeroStride)?,
);
}
Token::End => break,
other => return Err(Error::Unexpected(other)),
}
}
self.scopes.pop();
}
crate::TypeInner::Array { base, size, stride }
}
Token::Word("struct") => {
let members = self.parse_struct_body(lexer, type_arena)?;

View File

@@ -57,7 +57,7 @@ type SimParams = struct {
};
type Particles = struct {
[[offset 0]] particles : array<Particle, 5>;
[[offset 0]] particles : [[stride 16]] array<Particle, 5>;
};
[[binding 0, set 0]] var<uniform> params : SimParams;