Moved the WebGPU code off of "std140" and onto gpu-uniforms.

This commit is contained in:
Rezmason
2021-11-08 02:23:33 -08:00
parent 8f226be368
commit 61a3a6d783
10 changed files with 82 additions and 202 deletions

View File

@@ -166,6 +166,10 @@ const parseStructLayoutsFromShader = (wgsl) => {
const makeDataForLayout = (structLayouts, layout) => Object.fromEntries(layout.fields.map((field) => [field.identifier, field.defaultValue()]));
const writeField = (allLayouts, field, value, views, byteOffset) => {
if (value == null) {
console.warn(`Property missing: ${field.identifier}`);
return;
}
if (field.isArray) {
const count = field.isFixedSize ? field.mult : value.length;
for (let i = 0; i < field.mult; i++) {
@@ -182,46 +186,34 @@ const writeField = (allLayouts, field, value, views, byteOffset) => {
}
};
export default class Uniforms {
static fromWGSL(wgsl) {
const makeGenerator = (layout, structLayouts) => {
const minSize = layout.sizeInBytes;
return Object.freeze({
minSize,
create: () => makeDataForLayout(structLayouts, layout),
write: (object, destination) => {
destination ??= new ArrayBuffer(layout.sizeInBytes); // TODO: expand to support runtime-sized arrays, via the length of the array on the data object
const views = {
i32: new Int32Array(destination),
u32: new Uint32Array(destination),
f32: new Float32Array(destination),
};
for (const field of layout.fields) {
writeField(structLayouts, field, object[field.identifier], views, 0);
}
return destination;
},
});
};
const api = Object.freeze({
read: (wgsl) => {
const structLayouts = parseStructLayoutsFromShader(wgsl);
return Object.fromEntries(Object.entries(structLayouts).map(([name, layout]) => [name, new Uniforms(layout, structLayouts)]));
}
return Object.fromEntries(Object.entries(structLayouts).map(([name, layout]) => [name, makeGenerator(layout, structLayouts)]));
},
});
#structLayouts;
#layout;
data;
minSize;
constructor(layout, structLayouts = null) {
if (typeof layout === "string") {
structLayouts = parseStructLayoutsFromShader(layout);
layout = Object.values(structLayouts)[0];
}
structLayouts ??= {};
this.#structLayouts = structLayouts;
this.#layout = layout;
this.minSize = layout.sizeInBytes;
}
object() {
return makeDataForLayout(this.#structLayouts, this.#layout);
}
stuff(object, destination) {
destination ??= new ArrayBuffer(this.#layout.sizeInBytes); // TODO: expand to support runtime-sized arrays, via the length of the array on the data object
const views = {
i32: new Int32Array(destination),
u32: new Uint32Array(destination),
f32: new Float32Array(destination),
};
for (const field of this.#layout.fields) {
writeField(this.#structLayouts, field, object[field.identifier], views, 0);
}
return destination;
}
}
export default api;