Poking gpu-buffer a bit because I'm apparently afraid of writing a blur shader which I've already written once.

This commit is contained in:
Rezmason
2021-11-11 23:30:37 -08:00
parent d05cb3928d
commit 910d29e175
2 changed files with 24 additions and 26 deletions

View File

@@ -5,6 +5,14 @@ WebGPU
Update links in issues
Get rid of end pass once it's possible to copy a bgra8unorm to a canvas texture
Support looping
Write an explanation of the rain pass (and include images)
Compute
Volumetric quads
Fullscreen quad and spacial mapping
MSDFs
gpu-buffer, working title
Try and use it for the palette color buffer
Test it
@@ -13,14 +21,6 @@ gpu-buffer, working title
Capture expected requirements down the road, make roadmap
License it and put it somewhere else
Write an explanation of the rain pass (and include images)
Compute
Volumetric quads
Fullscreen quad and spacial mapping
MSDFs
Support looping
Resurrection
Modified glyph order?
New glyphs?

View File

@@ -117,14 +117,13 @@ const parseAttributes = (str) => {
const attributes = {};
for (const attr of str.split(",").filter((attr) => attr.length > 0)) {
const match = attr.match(/(\w+)(\((.*)\))?/); // foo(bar)
const [_, name, __, value] = match;
attributes[name] = value;
const [_, identifier, __, value] = match;
attributes[identifier] = value;
}
return attributes;
};
const parseStruct = (str, structLayouts) => {
const [_, block, name, body] = str;
const parseStructLayout = (identifier, body, isBlock, structLayouts) => {
const fields = [];
let byteOffset = 0;
const lines = body
@@ -132,12 +131,12 @@ const parseStruct = (str, structLayouts) => {
.split(";")
.filter((s) => s.length > 0);
for (const line of lines) {
const fieldMatch = line.match(/(\[\[(.*?)\]\])? ?(\w+) ?: (\[\[(.*?)\]\])? ?(.*)/); // [[...]] foo : [[...]] bar;
const fieldMatch = line.match(/(\[\[(.*?)\]\])? ?(\w+) ?: ?(\[\[(.*?)\]\])? ?(.*)/); // [[...]] foo : [[...]] bar;
const [_, __, leftAttributes, identifier, ___, rightAttributes, type] = fieldMatch;
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
if (typeData == null) {
console.warn(`Skipping layout for struct ${name}.`);
console.warn(`gSkipping struct ${identifier}.`);
return null;
}
@@ -155,23 +154,22 @@ const parseStruct = (str, structLayouts) => {
const minSizeInBytes = byteOffset;
const align = Math.max(...fields.map((field) => field.align));
const size = Math.ceil(minSizeInBytes / align) * align;
return { name, fields, size, align };
return { identifier, isBlock, fields, size, align };
};
const parseStructLayoutsFromShader = (wgsl) => {
wgsl = wgsl
.replace(/\/\*(.|\n)*?\*\//gm, "") // remove multi-line comments
.replace(/\s*\/\/.*$/gm, "") // remove end-of-line comments
.replace(/\n/gm, "") // remove newlines
.replace(/:/g, ": ") // add space after colons
.replace(/\s+/g, " "); // convert all whitespace to single space character
.replace(/\/\*.*?\*\//gms, "") // remove multi-line comments
.replace(/\s+/gm, " "); // convert all contiguous whitespace to single space characters
const structLayouts = {};
const structMatches = Array.from(wgsl.matchAll(/(\[\[block\]\])? ?struct (\w+) \{(.*?)\};/g)); // [[block]] struct Foo {...}
for (const struct of structMatches) {
const layout = parseStruct(struct, structLayouts);
const structMatches = Array.from(wgsl.matchAll(/(\[\[block\]\])? ?struct (\w+) ?\{(.*?)\};/g)); // [[block]] struct Foo {...}
for (const structMatch of structMatches) {
const [_, block, identifier, body] = structMatch;
const layout = parseStructLayout(identifier, body, block != null, structLayouts);
if (layout != null) {
structLayouts[layout.name] = layout;
structLayouts[layout.identifier] = layout;
}
}
return structLayouts;
@@ -211,8 +209,8 @@ const makeGenerator = (layout, structLayouts) => {
if (destination == null) {
let size = layout.size;
const lastField = layout.fields[layout.fields.length - 1];
if (lastField.isArray && lastField.name in object) {
size += lastField.stride * object[lastField.name].length;
if (lastField.isArray && lastField.identifier in object) {
size += lastField.stride * object[lastField.identifier].length;
}
destination = new ArrayBuffer(size);
}
@@ -240,7 +238,7 @@ const structs = Object.freeze({
throw new Error("Input is not a string.");
}
const structLayouts = parseStructLayoutsFromShader(wgsl);
return Object.fromEntries(Object.entries(structLayouts).map(([name, layout]) => [name, makeGenerator(layout, structLayouts)]));
return Object.fromEntries(Object.entries(structLayouts).map(([identifier, layout]) => [identifier, makeGenerator(layout, structLayouts)]));
},
});