mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
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:
16
TODO.txt
16
TODO.txt
@@ -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?
|
||||
|
||||
@@ -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)]));
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user