mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-18 22:29:28 -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
|
Update links in issues
|
||||||
Get rid of end pass once it's possible to copy a bgra8unorm to a canvas texture
|
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
|
gpu-buffer, working title
|
||||||
Try and use it for the palette color buffer
|
Try and use it for the palette color buffer
|
||||||
Test it
|
Test it
|
||||||
@@ -13,14 +21,6 @@ gpu-buffer, working title
|
|||||||
Capture expected requirements down the road, make roadmap
|
Capture expected requirements down the road, make roadmap
|
||||||
License it and put it somewhere else
|
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
|
Resurrection
|
||||||
Modified glyph order?
|
Modified glyph order?
|
||||||
New glyphs?
|
New glyphs?
|
||||||
|
|||||||
@@ -117,14 +117,13 @@ const parseAttributes = (str) => {
|
|||||||
const attributes = {};
|
const attributes = {};
|
||||||
for (const attr of str.split(",").filter((attr) => attr.length > 0)) {
|
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 [_, name, __, value] = match;
|
const [_, identifier, __, value] = match;
|
||||||
attributes[name] = value;
|
attributes[identifier] = value;
|
||||||
}
|
}
|
||||||
return attributes;
|
return attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseStruct = (str, structLayouts) => {
|
const parseStructLayout = (identifier, body, isBlock, structLayouts) => {
|
||||||
const [_, block, name, body] = str;
|
|
||||||
const fields = [];
|
const fields = [];
|
||||||
let byteOffset = 0;
|
let byteOffset = 0;
|
||||||
const lines = body
|
const lines = body
|
||||||
@@ -132,12 +131,12 @@ const parseStruct = (str, structLayouts) => {
|
|||||||
.split(";")
|
.split(";")
|
||||||
.filter((s) => s.length > 0);
|
.filter((s) => s.length > 0);
|
||||||
for (const line of lines) {
|
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 [_, __, leftAttributes, identifier, ___, rightAttributes, type] = fieldMatch;
|
||||||
|
|
||||||
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
|
const typeData = getTypeData(type, parseAttributes(rightAttributes ?? ""), structLayouts);
|
||||||
if (typeData == null) {
|
if (typeData == null) {
|
||||||
console.warn(`Skipping layout for struct ${name}.`);
|
console.warn(`gSkipping struct ${identifier}.`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,23 +154,22 @@ const parseStruct = (str, structLayouts) => {
|
|||||||
const minSizeInBytes = byteOffset;
|
const minSizeInBytes = byteOffset;
|
||||||
const align = Math.max(...fields.map((field) => field.align));
|
const align = Math.max(...fields.map((field) => field.align));
|
||||||
const size = Math.ceil(minSizeInBytes / align) * align;
|
const size = Math.ceil(minSizeInBytes / align) * align;
|
||||||
return { name, fields, size, align };
|
return { identifier, isBlock, fields, size, align };
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseStructLayoutsFromShader = (wgsl) => {
|
const parseStructLayoutsFromShader = (wgsl) => {
|
||||||
wgsl = wgsl
|
wgsl = wgsl
|
||||||
.replace(/\/\*(.|\n)*?\*\//gm, "") // remove multi-line comments
|
|
||||||
.replace(/\s*\/\/.*$/gm, "") // remove end-of-line comments
|
.replace(/\s*\/\/.*$/gm, "") // remove end-of-line comments
|
||||||
.replace(/\n/gm, "") // remove newlines
|
.replace(/\/\*.*?\*\//gms, "") // remove multi-line comments
|
||||||
.replace(/:/g, ": ") // add space after colons
|
.replace(/\s+/gm, " "); // convert all contiguous whitespace to single space characters
|
||||||
.replace(/\s+/g, " "); // convert all whitespace to single space character
|
|
||||||
|
|
||||||
const structLayouts = {};
|
const structLayouts = {};
|
||||||
const structMatches = Array.from(wgsl.matchAll(/(\[\[block\]\])? ?struct (\w+) \{(.*?)\};/g)); // [[block]] struct Foo {...}
|
const structMatches = Array.from(wgsl.matchAll(/(\[\[block\]\])? ?struct (\w+) ?\{(.*?)\};/g)); // [[block]] struct Foo {...}
|
||||||
for (const struct of structMatches) {
|
for (const structMatch of structMatches) {
|
||||||
const layout = parseStruct(struct, structLayouts);
|
const [_, block, identifier, body] = structMatch;
|
||||||
|
const layout = parseStructLayout(identifier, body, block != null, structLayouts);
|
||||||
if (layout != null) {
|
if (layout != null) {
|
||||||
structLayouts[layout.name] = layout;
|
structLayouts[layout.identifier] = layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return structLayouts;
|
return structLayouts;
|
||||||
@@ -211,8 +209,8 @@ const makeGenerator = (layout, structLayouts) => {
|
|||||||
if (destination == null) {
|
if (destination == null) {
|
||||||
let size = layout.size;
|
let size = layout.size;
|
||||||
const lastField = layout.fields[layout.fields.length - 1];
|
const lastField = layout.fields[layout.fields.length - 1];
|
||||||
if (lastField.isArray && lastField.name in object) {
|
if (lastField.isArray && lastField.identifier in object) {
|
||||||
size += lastField.stride * object[lastField.name].length;
|
size += lastField.stride * object[lastField.identifier].length;
|
||||||
}
|
}
|
||||||
destination = new ArrayBuffer(size);
|
destination = new ArrayBuffer(size);
|
||||||
}
|
}
|
||||||
@@ -240,7 +238,7 @@ const structs = Object.freeze({
|
|||||||
throw new Error("Input is not a string.");
|
throw new Error("Input is not a string.");
|
||||||
}
|
}
|
||||||
const structLayouts = parseStructLayoutsFromShader(wgsl);
|
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