diff --git a/lib/gpu-uniforms.js b/lib/gpu-uniforms.js index 7383546..4d07d12 100644 --- a/lib/gpu-uniforms.js +++ b/lib/gpu-uniforms.js @@ -1,16 +1,14 @@ -/** PLAN +/** * - * Note: This should go in its own repo - * - * Address every TODO item + * Meant to conform to the WGSL spec: * * https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size * https://gpuweb.github.io/gpuweb/wgsl/#structure-layout-rules * - * Create tests (maybe mocha?) - * - * Document - * - examples of the simple constructor and from WGSL + * TODO: + * - Put in own repo + * - create mocha tests + * - Document. Provide examples of the simple constructor and from WGSL * **/ @@ -157,7 +155,7 @@ const parseStruct = (str, structLayouts) => { const minSizeInBytes = byteOffset * BYTES_PER_ELEMENT; const align = Math.max(...fields.map((field) => field.align)); - const size = Math.ceil(minSizeInBytes / align) * align; // TODO: support runtime-sized arrays + const size = Math.ceil(minSizeInBytes / align) * align; return { name, fields, size, align }; }; @@ -211,7 +209,14 @@ const makeGenerator = (layout, structLayouts) => { minSize, create: () => makeDataForLayout(structLayouts, layout), write: (object, destination, warnMissingFields = false) => { - destination ??= new ArrayBuffer(layout.size); // TODO: expand to support runtime-sized arrays, via the length of the array on the data object + 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; + } + destination = new ArrayBuffer(size); + } const views = { i32: new Int32Array(destination),