The delimiter between WGSL struct fields is now a comma, which is also the delimiter between parameters in angle brackets, so gpu-buffer needs to be a little cleverer with the lines it separates.

This commit is contained in:
Rezmason
2022-04-30 18:00:35 -07:00
parent e8458a1304
commit e39c26a95a
10 changed files with 99 additions and 81 deletions

View File

@@ -116,7 +116,7 @@ const getTypeData = (type, attributes, otherStructLayouts) => {
const parseAttributes = (str) => {
const attributes = {};
for (const attr of str.split(",").filter((attr) => attr.length > 0)) {
const match = attr.match(/@(\w+)(\((.*)\))?/); // @foo(bar)
const match = attr.match(/(\w+)(\((.*)\))?/); // foo(bar)
const [_, identifier, __, value] = match;
attributes[identifier] = value;
}
@@ -128,16 +128,33 @@ const parseStructLayout = (identifier, body, structLayouts) => {
let byteOffset = 0;
const lines = body
.trim()
.split(";")
.filter((s) => s.length > 0);
.split(",") // WGSL struct fields are currently delimited by commas...
.filter((s) => s.length > 0)
// ...but some commas separate elements between angle brackets, rather than between lines:
.reduce((existingLines, line, index) => {
if (index === 0) {
return [line];
}
const lastLine = existingLines[index - 1];
const angleBracketBalance = lastLine.split("<").length - lastLine.split(">").length;
if (angleBracketBalance !== 0) {
existingLines[index - 1] = `${lastLine},${line}`;
} else {
existingLines.push(line);
}
return existingLines;
}, []);
for (const line of lines) {
console.log(line);
const fieldMatch = line.match(/(\[\[(.*?)\]\])? ?(\w+) ?: ?(\[\[(.*?)\]\])? ?(.*)/); // @a(...) @b(...) foo : @c(...) @d(...) bar;
const fieldMatch = line.match(/(@(.*?))? ?(\w+) ?: ?(@(.*?))? ?(.*)/); // @a(...) @b(...) foo : @c(...) @d(...) bar;
const [_, __, leftAttributes, identifier, ___, rightAttributes, type] = fieldMatch;
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
if (typeData == null) {
console.warn(`gSkipping struct ${identifier}.`);
console.warn(`Skipping struct ${identifier}.`);
return null;
}
@@ -166,6 +183,7 @@ const parseStructLayoutsFromShader = (wgsl) => {
const structLayouts = {};
const structMatches = Array.from(wgsl.matchAll(/struct (\w+) ?\{(.*?)\};/g)); // struct Foo {...}
for (const structMatch of structMatches) {
const [_, identifier, body] = structMatch;
const layout = parseStructLayout(identifier, body, structLayouts);