@luma.gl/core 9.3.0-alpha.8 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/device.d.ts +1 -1
- package/dist/adapter/device.d.ts.map +1 -1
- package/dist/adapter/device.js +3 -2
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.d.ts.map +1 -1
- package/dist/adapter/luma.js +2 -1
- package/dist/adapter/luma.js.map +1 -1
- package/dist/dist.dev.js +328 -173
- package/dist/dist.min.js +5 -5
- package/dist/factories/bind-group-factory.d.ts.map +1 -1
- package/dist/factories/bind-group-factory.js +14 -5
- package/dist/factories/bind-group-factory.js.map +1 -1
- package/dist/index.cjs +317 -173
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/portable/shader-block-writer.d.ts +51 -0
- package/dist/portable/shader-block-writer.d.ts.map +1 -0
- package/dist/portable/shader-block-writer.js +185 -0
- package/dist/portable/shader-block-writer.js.map +1 -0
- package/dist/portable/uniform-store.d.ts +52 -20
- package/dist/portable/uniform-store.d.ts.map +1 -1
- package/dist/portable/uniform-store.js +71 -26
- package/dist/portable/uniform-store.js.map +1 -1
- package/dist/shadertypes/data-types/data-type-decoder.js +2 -2
- package/dist/shadertypes/data-types/data-type-decoder.js.map +1 -1
- package/dist/shadertypes/data-types/decode-data-types.js +2 -2
- package/dist/shadertypes/data-types/decode-data-types.js.map +1 -1
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts +72 -0
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts.map +1 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js +209 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.js +1 -1
- package/dist/shadertypes/texture-types/texture-format-decoder.js.map +1 -1
- package/dist/shadertypes/texture-types/texture-format-table.js +2 -2
- package/dist/shadertypes/texture-types/texture-format-table.js.map +1 -1
- package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts.map +1 -1
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js +41 -3
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js.map +1 -1
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts +6 -6
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/adapter/device.ts +4 -2
- package/src/adapter/luma.ts +1 -0
- package/src/factories/bind-group-factory.ts +23 -5
- package/src/index.ts +7 -1
- package/src/portable/shader-block-writer.ts +254 -0
- package/src/portable/uniform-store.ts +92 -37
- package/src/shadertypes/data-types/data-type-decoder.ts +2 -2
- package/src/shadertypes/data-types/decode-data-types.ts +2 -2
- package/src/shadertypes/shader-types/shader-block-layout.ts +340 -0
- package/src/shadertypes/shader-types/shader-types.ts +5 -5
- package/src/shadertypes/texture-types/texture-format-decoder.ts +1 -1
- package/src/shadertypes/texture-types/texture-format-table.ts +2 -2
- package/src/shadertypes/vertex-types/vertex-format-decoder.ts +47 -3
- package/src/shadertypes/vertex-types/vertex-formats.ts +18 -5
- package/dist/portable/uniform-buffer-layout.d.ts +0 -42
- package/dist/portable/uniform-buffer-layout.d.ts.map +0 -1
- package/dist/portable/uniform-buffer-layout.js +0 -274
- package/dist/portable/uniform-buffer-layout.js.map +0 -1
- package/src/portable/uniform-buffer-layout.ts +0 -384
package/dist/index.cjs
CHANGED
|
@@ -47,13 +47,13 @@ __export(dist_exports, {
|
|
|
47
47
|
Resource: () => Resource,
|
|
48
48
|
Sampler: () => Sampler,
|
|
49
49
|
Shader: () => Shader,
|
|
50
|
+
ShaderBlockWriter: () => ShaderBlockWriter,
|
|
50
51
|
ShaderFactory: () => ShaderFactory,
|
|
51
52
|
SharedRenderPipeline: () => SharedRenderPipeline,
|
|
52
53
|
Texture: () => Texture,
|
|
53
54
|
TextureView: () => TextureView,
|
|
54
55
|
TransformFeedback: () => TransformFeedback,
|
|
55
56
|
UniformBlock: () => UniformBlock,
|
|
56
|
-
UniformBufferLayout: () => UniformBufferLayout,
|
|
57
57
|
UniformStore: () => UniformStore,
|
|
58
58
|
VertexArray: () => VertexArray,
|
|
59
59
|
_getDefaultBindGroupFactory: () => _getDefaultBindGroupFactory,
|
|
@@ -74,6 +74,7 @@ __export(dist_exports, {
|
|
|
74
74
|
isExternalImage: () => isExternalImage,
|
|
75
75
|
log: () => log,
|
|
76
76
|
luma: () => luma,
|
|
77
|
+
makeShaderBlockLayout: () => makeShaderBlockLayout,
|
|
77
78
|
normalizeBindingsByGroup: () => normalizeBindingsByGroup,
|
|
78
79
|
readPixel: () => readPixel,
|
|
79
80
|
setTextureImageData: () => setTextureImageData,
|
|
@@ -731,12 +732,51 @@ var VertexFormatDecoder = class {
|
|
|
731
732
|
}
|
|
732
733
|
return `${dataType}x${components}`;
|
|
733
734
|
case "snorm8":
|
|
735
|
+
if (components === 1) {
|
|
736
|
+
return "snorm8";
|
|
737
|
+
}
|
|
738
|
+
if (components === 3) {
|
|
739
|
+
return "snorm8x3-webgl";
|
|
740
|
+
}
|
|
741
|
+
return `${dataType}x${components}`;
|
|
734
742
|
case "uint8":
|
|
735
743
|
case "sint8":
|
|
744
|
+
if (components === 1 || components === 3) {
|
|
745
|
+
throw new Error(`size: ${components}`);
|
|
746
|
+
}
|
|
747
|
+
return `${dataType}x${components}`;
|
|
736
748
|
case "uint16":
|
|
749
|
+
if (components === 1) {
|
|
750
|
+
return "uint16";
|
|
751
|
+
}
|
|
752
|
+
if (components === 3) {
|
|
753
|
+
return "uint16x3-webgl";
|
|
754
|
+
}
|
|
755
|
+
return `${dataType}x${components}`;
|
|
737
756
|
case "sint16":
|
|
757
|
+
if (components === 1) {
|
|
758
|
+
return "sint16";
|
|
759
|
+
}
|
|
760
|
+
if (components === 3) {
|
|
761
|
+
return "sint16x3-webgl";
|
|
762
|
+
}
|
|
763
|
+
return `${dataType}x${components}`;
|
|
738
764
|
case "unorm16":
|
|
765
|
+
if (components === 1) {
|
|
766
|
+
return "unorm16";
|
|
767
|
+
}
|
|
768
|
+
if (components === 3) {
|
|
769
|
+
return "unorm16x3-webgl";
|
|
770
|
+
}
|
|
771
|
+
return `${dataType}x${components}`;
|
|
739
772
|
case "snorm16":
|
|
773
|
+
if (components === 1) {
|
|
774
|
+
return "snorm16";
|
|
775
|
+
}
|
|
776
|
+
if (components === 3) {
|
|
777
|
+
return "snorm16x3-webgl";
|
|
778
|
+
}
|
|
779
|
+
return `${dataType}x${components}`;
|
|
740
780
|
case "float16":
|
|
741
781
|
if (components === 1 || components === 3) {
|
|
742
782
|
throw new Error(`size: ${components}`);
|
|
@@ -1427,7 +1467,7 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1427
1467
|
throw new Error("_createBindGroupLayoutWebGPU() not implemented");
|
|
1428
1468
|
}
|
|
1429
1469
|
/** Internal WebGPU-only helper for creating a native bind group. */
|
|
1430
|
-
_createBindGroupWebGPU(_bindGroupLayout, _shaderLayout, _bindings, _group) {
|
|
1470
|
+
_createBindGroupWebGPU(_bindGroupLayout, _shaderLayout, _bindings, _group, _label) {
|
|
1431
1471
|
throw new Error("_createBindGroupWebGPU() not implemented");
|
|
1432
1472
|
}
|
|
1433
1473
|
/**
|
|
@@ -1652,7 +1692,7 @@ var _Luma = class {
|
|
|
1652
1692
|
VERSION = (
|
|
1653
1693
|
// Version detection using build plugin
|
|
1654
1694
|
// @ts-expect-error no-undef
|
|
1655
|
-
true ? "9.3.0
|
|
1695
|
+
true ? "9.3.0" : "running from source"
|
|
1656
1696
|
);
|
|
1657
1697
|
spector;
|
|
1658
1698
|
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
@@ -3608,9 +3648,10 @@ var BindGroupFactory = class {
|
|
|
3608
3648
|
for (const group of getBindGroupIndicesUpToMax(pipeline.shaderLayout.bindings)) {
|
|
3609
3649
|
const groupBindings = bindingsByGroup[group];
|
|
3610
3650
|
const bindGroupLayout = this._getBindGroupLayout(pipeline, group);
|
|
3651
|
+
const bindGroupLabel = getBindGroupLabel(pipeline, pipeline.shaderLayout, group);
|
|
3611
3652
|
if (!groupBindings || Object.keys(groupBindings).length === 0) {
|
|
3612
3653
|
if (!hasBindingsInGroup(pipeline.shaderLayout.bindings, group)) {
|
|
3613
|
-
resolvedBindGroups[group] = this._getEmptyBindGroup(bindGroupLayout, pipeline.shaderLayout, group);
|
|
3654
|
+
resolvedBindGroups[group] = this._getEmptyBindGroup(bindGroupLayout, pipeline.shaderLayout, group, bindGroupLabel);
|
|
3614
3655
|
}
|
|
3615
3656
|
continue;
|
|
3616
3657
|
}
|
|
@@ -3621,11 +3662,11 @@ var BindGroupFactory = class {
|
|
|
3621
3662
|
resolvedBindGroups[group] = layoutCache.bindGroupsBySource.get(bindGroupCacheKey) || null;
|
|
3622
3663
|
continue;
|
|
3623
3664
|
}
|
|
3624
|
-
const bindGroup = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3665
|
+
const bindGroup = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group, bindGroupLabel);
|
|
3625
3666
|
layoutCache.bindGroupsBySource.set(bindGroupCacheKey, bindGroup);
|
|
3626
3667
|
resolvedBindGroups[group] = bindGroup;
|
|
3627
3668
|
} else {
|
|
3628
|
-
resolvedBindGroups[group] = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group);
|
|
3669
|
+
resolvedBindGroups[group] = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group, bindGroupLabel);
|
|
3629
3670
|
}
|
|
3630
3671
|
}
|
|
3631
3672
|
return resolvedBindGroups;
|
|
@@ -3639,9 +3680,9 @@ var BindGroupFactory = class {
|
|
|
3639
3680
|
layoutCache[group] ||= this.device._createBindGroupLayoutWebGPU(pipeline, group);
|
|
3640
3681
|
return layoutCache[group];
|
|
3641
3682
|
}
|
|
3642
|
-
_getEmptyBindGroup(bindGroupLayout, shaderLayout, group) {
|
|
3683
|
+
_getEmptyBindGroup(bindGroupLayout, shaderLayout, group, label) {
|
|
3643
3684
|
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3644
|
-
layoutCache.emptyBindGroup ||= this.device._createBindGroupWebGPU(bindGroupLayout, shaderLayout, {}, group) || null;
|
|
3685
|
+
layoutCache.emptyBindGroup ||= this.device._createBindGroupWebGPU(bindGroupLayout, shaderLayout, {}, group, label) || null;
|
|
3645
3686
|
return layoutCache.emptyBindGroup;
|
|
3646
3687
|
}
|
|
3647
3688
|
_getLayoutBindGroupCache(bindGroupLayout) {
|
|
@@ -3664,6 +3705,11 @@ function getBindGroupIndicesUpToMax(bindings) {
|
|
|
3664
3705
|
function hasBindingsInGroup(bindings, group) {
|
|
3665
3706
|
return bindings.some((binding) => binding.group === group);
|
|
3666
3707
|
}
|
|
3708
|
+
function getBindGroupLabel(pipeline, shaderLayout, group) {
|
|
3709
|
+
const bindingNames = shaderLayout.bindings.filter((binding) => binding.group === group).sort((left, right) => left.location - right.location).map((binding) => binding.name);
|
|
3710
|
+
const bindingSuffix = bindingNames.length > 0 ? bindingNames.join(",") : "empty";
|
|
3711
|
+
return `${pipeline.id}/group${group}[${bindingSuffix}]`;
|
|
3712
|
+
}
|
|
3667
3713
|
|
|
3668
3714
|
// dist/adapter/resources/render-pass.js
|
|
3669
3715
|
var _RenderPass = class extends Resource {
|
|
@@ -4257,6 +4303,160 @@ var NORMALIZED_TYPE_MAP2 = {
|
|
|
4257
4303
|
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
4258
4304
|
};
|
|
4259
4305
|
|
|
4306
|
+
// dist/shadertypes/shader-types/shader-block-layout.js
|
|
4307
|
+
function makeShaderBlockLayout(uniformTypes, options = {}) {
|
|
4308
|
+
const copiedUniformTypes = { ...uniformTypes };
|
|
4309
|
+
const layout = options.layout ?? "std140";
|
|
4310
|
+
const fields = {};
|
|
4311
|
+
let size = 0;
|
|
4312
|
+
for (const [key, uniformType] of Object.entries(copiedUniformTypes)) {
|
|
4313
|
+
size = addToLayout(fields, key, uniformType, size, layout);
|
|
4314
|
+
}
|
|
4315
|
+
size = alignTo(size, getTypeAlignment(copiedUniformTypes, layout));
|
|
4316
|
+
return {
|
|
4317
|
+
layout,
|
|
4318
|
+
byteLength: size * 4,
|
|
4319
|
+
uniformTypes: copiedUniformTypes,
|
|
4320
|
+
fields
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
function getLeafLayoutInfo(type, layout) {
|
|
4324
|
+
const resolvedType = resolveVariableShaderTypeAlias(type);
|
|
4325
|
+
const decodedType = getVariableShaderTypeInfo(resolvedType);
|
|
4326
|
+
const matrixMatch = /^mat(\d)x(\d)<.+>$/.exec(resolvedType);
|
|
4327
|
+
if (matrixMatch) {
|
|
4328
|
+
const columns = Number(matrixMatch[1]);
|
|
4329
|
+
const rows = Number(matrixMatch[2]);
|
|
4330
|
+
const columnInfo = getVectorLayoutInfo(rows, resolvedType, decodedType.type, layout);
|
|
4331
|
+
const columnStride = getMatrixColumnStride(columnInfo.size, columnInfo.alignment, layout);
|
|
4332
|
+
return {
|
|
4333
|
+
alignment: columnInfo.alignment,
|
|
4334
|
+
size: columns * columnStride,
|
|
4335
|
+
components: columns * rows,
|
|
4336
|
+
columns,
|
|
4337
|
+
rows,
|
|
4338
|
+
columnStride,
|
|
4339
|
+
shaderType: resolvedType,
|
|
4340
|
+
type: decodedType.type
|
|
4341
|
+
};
|
|
4342
|
+
}
|
|
4343
|
+
const vectorMatch = /^vec(\d)<.+>$/.exec(resolvedType);
|
|
4344
|
+
if (vectorMatch) {
|
|
4345
|
+
return getVectorLayoutInfo(Number(vectorMatch[1]), resolvedType, decodedType.type, layout);
|
|
4346
|
+
}
|
|
4347
|
+
return {
|
|
4348
|
+
alignment: 1,
|
|
4349
|
+
size: 1,
|
|
4350
|
+
components: 1,
|
|
4351
|
+
columns: 1,
|
|
4352
|
+
rows: 1,
|
|
4353
|
+
columnStride: 1,
|
|
4354
|
+
shaderType: resolvedType,
|
|
4355
|
+
type: decodedType.type
|
|
4356
|
+
};
|
|
4357
|
+
}
|
|
4358
|
+
function isCompositeShaderTypeStruct(value) {
|
|
4359
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4360
|
+
}
|
|
4361
|
+
function addToLayout(fields, name2, type, offset, layout) {
|
|
4362
|
+
if (typeof type === "string") {
|
|
4363
|
+
const info = getLeafLayoutInfo(type, layout);
|
|
4364
|
+
const alignedOffset = alignTo(offset, info.alignment);
|
|
4365
|
+
fields[name2] = {
|
|
4366
|
+
offset: alignedOffset,
|
|
4367
|
+
...info
|
|
4368
|
+
};
|
|
4369
|
+
return alignedOffset + info.size;
|
|
4370
|
+
}
|
|
4371
|
+
if (Array.isArray(type)) {
|
|
4372
|
+
if (Array.isArray(type[0])) {
|
|
4373
|
+
throw new Error(`Nested arrays are not supported for ${name2}`);
|
|
4374
|
+
}
|
|
4375
|
+
const elementType = type[0];
|
|
4376
|
+
const length = type[1];
|
|
4377
|
+
const stride = getArrayStride(elementType, layout);
|
|
4378
|
+
const arrayOffset = alignTo(offset, getTypeAlignment(type, layout));
|
|
4379
|
+
for (let i = 0; i < length; i++) {
|
|
4380
|
+
addToLayout(fields, `${name2}[${i}]`, elementType, arrayOffset + i * stride, layout);
|
|
4381
|
+
}
|
|
4382
|
+
return arrayOffset + stride * length;
|
|
4383
|
+
}
|
|
4384
|
+
if (isCompositeShaderTypeStruct(type)) {
|
|
4385
|
+
const structAlignment = getTypeAlignment(type, layout);
|
|
4386
|
+
let structOffset = alignTo(offset, structAlignment);
|
|
4387
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
4388
|
+
structOffset = addToLayout(fields, `${name2}.${memberName}`, memberType, structOffset, layout);
|
|
4389
|
+
}
|
|
4390
|
+
return alignTo(structOffset, structAlignment);
|
|
4391
|
+
}
|
|
4392
|
+
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
4393
|
+
}
|
|
4394
|
+
function getTypeSize(type, layout) {
|
|
4395
|
+
if (typeof type === "string") {
|
|
4396
|
+
return getLeafLayoutInfo(type, layout).size;
|
|
4397
|
+
}
|
|
4398
|
+
if (Array.isArray(type)) {
|
|
4399
|
+
const elementType = type[0];
|
|
4400
|
+
const length = type[1];
|
|
4401
|
+
if (Array.isArray(elementType)) {
|
|
4402
|
+
throw new Error("Nested arrays are not supported");
|
|
4403
|
+
}
|
|
4404
|
+
return getArrayStride(elementType, layout) * length;
|
|
4405
|
+
}
|
|
4406
|
+
let size = 0;
|
|
4407
|
+
for (const memberType of Object.values(type)) {
|
|
4408
|
+
const compositeMemberType = memberType;
|
|
4409
|
+
size = alignTo(size, getTypeAlignment(compositeMemberType, layout));
|
|
4410
|
+
size += getTypeSize(compositeMemberType, layout);
|
|
4411
|
+
}
|
|
4412
|
+
return alignTo(size, getTypeAlignment(type, layout));
|
|
4413
|
+
}
|
|
4414
|
+
function getTypeAlignment(type, layout) {
|
|
4415
|
+
if (typeof type === "string") {
|
|
4416
|
+
return getLeafLayoutInfo(type, layout).alignment;
|
|
4417
|
+
}
|
|
4418
|
+
if (Array.isArray(type)) {
|
|
4419
|
+
const elementType = type[0];
|
|
4420
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4421
|
+
return uses16ByteArrayAlignment(layout) ? Math.max(elementAlignment, 4) : elementAlignment;
|
|
4422
|
+
}
|
|
4423
|
+
let maxAlignment = 1;
|
|
4424
|
+
for (const memberType of Object.values(type)) {
|
|
4425
|
+
const memberAlignment = getTypeAlignment(memberType, layout);
|
|
4426
|
+
maxAlignment = Math.max(maxAlignment, memberAlignment);
|
|
4427
|
+
}
|
|
4428
|
+
return uses16ByteStructAlignment(layout) ? Math.max(maxAlignment, 4) : maxAlignment;
|
|
4429
|
+
}
|
|
4430
|
+
function getVectorLayoutInfo(components, shaderType, type, layout) {
|
|
4431
|
+
return {
|
|
4432
|
+
alignment: components === 2 ? 2 : 4,
|
|
4433
|
+
size: components === 3 ? 3 : components,
|
|
4434
|
+
components,
|
|
4435
|
+
columns: 1,
|
|
4436
|
+
rows: components,
|
|
4437
|
+
columnStride: components === 3 ? 3 : components,
|
|
4438
|
+
shaderType,
|
|
4439
|
+
type
|
|
4440
|
+
};
|
|
4441
|
+
}
|
|
4442
|
+
function getArrayStride(elementType, layout) {
|
|
4443
|
+
const elementSize = getTypeSize(elementType, layout);
|
|
4444
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4445
|
+
return getArrayLikeStride(elementSize, elementAlignment, layout);
|
|
4446
|
+
}
|
|
4447
|
+
function getArrayLikeStride(size, alignment, layout) {
|
|
4448
|
+
return alignTo(size, uses16ByteArrayAlignment(layout) ? 4 : alignment);
|
|
4449
|
+
}
|
|
4450
|
+
function getMatrixColumnStride(size, alignment, layout) {
|
|
4451
|
+
return layout === "std140" ? 4 : alignTo(size, alignment);
|
|
4452
|
+
}
|
|
4453
|
+
function uses16ByteArrayAlignment(layout) {
|
|
4454
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4455
|
+
}
|
|
4456
|
+
function uses16ByteStructAlignment(layout) {
|
|
4457
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4458
|
+
}
|
|
4459
|
+
|
|
4260
4460
|
// dist/utils/array-utils-flat.js
|
|
4261
4461
|
var arrayBuffer;
|
|
4262
4462
|
function getScratchArrayBuffer(byteLength) {
|
|
@@ -4281,49 +4481,56 @@ function isNumberArray(value) {
|
|
|
4281
4481
|
return isTypedArray(value);
|
|
4282
4482
|
}
|
|
4283
4483
|
|
|
4284
|
-
// dist/portable/
|
|
4285
|
-
var
|
|
4286
|
-
|
|
4287
|
-
layout
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
}
|
|
4298
|
-
size = alignTo(size, 4);
|
|
4299
|
-
this.byteLength = Math.max(size * 4, minBufferSize);
|
|
4300
|
-
}
|
|
4301
|
-
/** Does this layout have a field with specified name */
|
|
4484
|
+
// dist/portable/shader-block-writer.js
|
|
4485
|
+
var ShaderBlockWriter = class {
|
|
4486
|
+
/** Layout metadata used to flatten and serialize values. */
|
|
4487
|
+
layout;
|
|
4488
|
+
/**
|
|
4489
|
+
* Creates a writer for a precomputed shader-block layout.
|
|
4490
|
+
*/
|
|
4491
|
+
constructor(layout) {
|
|
4492
|
+
this.layout = layout;
|
|
4493
|
+
}
|
|
4494
|
+
/**
|
|
4495
|
+
* Returns `true` if the flattened layout contains the given field.
|
|
4496
|
+
*/
|
|
4302
4497
|
has(name2) {
|
|
4303
|
-
return Boolean(this.layout[name2]);
|
|
4498
|
+
return Boolean(this.layout.fields[name2]);
|
|
4304
4499
|
}
|
|
4305
|
-
/**
|
|
4500
|
+
/**
|
|
4501
|
+
* Returns offset and size metadata for a flattened field.
|
|
4502
|
+
*/
|
|
4306
4503
|
get(name2) {
|
|
4307
|
-
const
|
|
4308
|
-
return
|
|
4504
|
+
const entry = this.layout.fields[name2];
|
|
4505
|
+
return entry ? { offset: entry.offset, size: entry.size } : void 0;
|
|
4309
4506
|
}
|
|
4310
|
-
/**
|
|
4507
|
+
/**
|
|
4508
|
+
* Flattens nested composite values into leaf-path values understood by {@link UniformBlock}.
|
|
4509
|
+
*
|
|
4510
|
+
* Top-level values may be supplied either in nested object form matching the
|
|
4511
|
+
* declared composite shader types or as already-flattened leaf-path values.
|
|
4512
|
+
*/
|
|
4311
4513
|
getFlatUniformValues(uniformValues) {
|
|
4312
4514
|
const flattenedUniformValues = {};
|
|
4313
4515
|
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
4314
|
-
const uniformType = this.uniformTypes[name2];
|
|
4516
|
+
const uniformType = this.layout.uniformTypes[name2];
|
|
4315
4517
|
if (uniformType) {
|
|
4316
4518
|
this._flattenCompositeValue(flattenedUniformValues, name2, uniformType, value);
|
|
4317
|
-
} else if (this.layout[name2]) {
|
|
4519
|
+
} else if (this.layout.fields[name2]) {
|
|
4318
4520
|
flattenedUniformValues[name2] = value;
|
|
4319
4521
|
}
|
|
4320
4522
|
}
|
|
4321
4523
|
return flattenedUniformValues;
|
|
4322
4524
|
}
|
|
4323
|
-
/**
|
|
4525
|
+
/**
|
|
4526
|
+
* Serializes the supplied values into buffer-backed binary data.
|
|
4527
|
+
*
|
|
4528
|
+
* The returned view length matches {@link ShaderBlockLayout.byteLength}, which
|
|
4529
|
+
* is the exact packed size of the block.
|
|
4530
|
+
*/
|
|
4324
4531
|
getData(uniformValues) {
|
|
4325
|
-
const buffer = getScratchArrayBuffer(this.byteLength);
|
|
4326
|
-
new Uint8Array(buffer, 0, this.byteLength).fill(0);
|
|
4532
|
+
const buffer = getScratchArrayBuffer(this.layout.byteLength);
|
|
4533
|
+
new Uint8Array(buffer, 0, this.layout.byteLength).fill(0);
|
|
4327
4534
|
const typedArrays = {
|
|
4328
4535
|
i32: new Int32Array(buffer),
|
|
4329
4536
|
u32: new Uint32Array(buffer),
|
|
@@ -4334,46 +4541,16 @@ var UniformBufferLayout = class {
|
|
|
4334
4541
|
for (const [name2, value] of Object.entries(flattenedUniformValues)) {
|
|
4335
4542
|
this._writeLeafValue(typedArrays, name2, value);
|
|
4336
4543
|
}
|
|
4337
|
-
return new Uint8Array(buffer, 0, this.byteLength);
|
|
4338
|
-
}
|
|
4339
|
-
// Recursively add a uniform to the layout
|
|
4340
|
-
_addToLayout(name2, type, offset) {
|
|
4341
|
-
if (typeof type === "string") {
|
|
4342
|
-
const info = getLeafLayoutInfo(type);
|
|
4343
|
-
const alignedOffset = alignTo(offset, info.alignment);
|
|
4344
|
-
this.layout[name2] = {
|
|
4345
|
-
offset: alignedOffset,
|
|
4346
|
-
...info
|
|
4347
|
-
};
|
|
4348
|
-
return alignedOffset + info.size;
|
|
4349
|
-
}
|
|
4350
|
-
if (Array.isArray(type)) {
|
|
4351
|
-
if (Array.isArray(type[0])) {
|
|
4352
|
-
throw new Error(`Nested arrays are not supported for ${name2}`);
|
|
4353
|
-
}
|
|
4354
|
-
const elementType = type[0];
|
|
4355
|
-
const length = type[1];
|
|
4356
|
-
const stride = alignTo(getTypeSize(elementType), 4);
|
|
4357
|
-
const arrayOffset = alignTo(offset, 4);
|
|
4358
|
-
for (let i = 0; i < length; i++) {
|
|
4359
|
-
this._addToLayout(`${name2}[${i}]`, elementType, arrayOffset + i * stride);
|
|
4360
|
-
}
|
|
4361
|
-
return arrayOffset + stride * length;
|
|
4362
|
-
}
|
|
4363
|
-
if (isCompositeShaderTypeStruct(type)) {
|
|
4364
|
-
let structOffset = alignTo(offset, 4);
|
|
4365
|
-
for (const [memberName, memberType] of Object.entries(type)) {
|
|
4366
|
-
structOffset = this._addToLayout(`${name2}.${memberName}`, memberType, structOffset);
|
|
4367
|
-
}
|
|
4368
|
-
return alignTo(structOffset, 4);
|
|
4369
|
-
}
|
|
4370
|
-
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
4544
|
+
return new Uint8Array(buffer, 0, this.layout.byteLength);
|
|
4371
4545
|
}
|
|
4546
|
+
/**
|
|
4547
|
+
* Recursively flattens nested values using the declared composite shader type.
|
|
4548
|
+
*/
|
|
4372
4549
|
_flattenCompositeValue(flattenedUniformValues, baseName, uniformType, value) {
|
|
4373
4550
|
if (value === void 0) {
|
|
4374
4551
|
return;
|
|
4375
4552
|
}
|
|
4376
|
-
if (typeof uniformType === "string" || this.layout[baseName]) {
|
|
4553
|
+
if (typeof uniformType === "string" || this.layout.fields[baseName]) {
|
|
4377
4554
|
flattenedUniformValues[baseName] = value;
|
|
4378
4555
|
return;
|
|
4379
4556
|
}
|
|
@@ -4412,9 +4589,12 @@ var UniformBufferLayout = class {
|
|
|
4412
4589
|
}
|
|
4413
4590
|
log.warn(`Unsupported uniform value for ${baseName}:`, value)();
|
|
4414
4591
|
}
|
|
4592
|
+
/**
|
|
4593
|
+
* Expands tightly packed numeric arrays into per-element leaf fields.
|
|
4594
|
+
*/
|
|
4415
4595
|
_flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value) {
|
|
4416
4596
|
const numericValue = value;
|
|
4417
|
-
const elementLayout = getLeafLayoutInfo(elementType);
|
|
4597
|
+
const elementLayout = getLeafLayoutInfo(elementType, this.layout.layout);
|
|
4418
4598
|
const packedElementLength = elementLayout.components;
|
|
4419
4599
|
for (let index = 0; index < length; index++) {
|
|
4420
4600
|
const start = index * packedElementLength;
|
|
@@ -4428,13 +4608,16 @@ var UniformBufferLayout = class {
|
|
|
4428
4608
|
}
|
|
4429
4609
|
}
|
|
4430
4610
|
}
|
|
4611
|
+
/**
|
|
4612
|
+
* Writes one flattened leaf value into its typed-array view.
|
|
4613
|
+
*/
|
|
4431
4614
|
_writeLeafValue(typedArrays, name2, value) {
|
|
4432
|
-
const
|
|
4433
|
-
if (!
|
|
4615
|
+
const entry = this.layout.fields[name2];
|
|
4616
|
+
if (!entry) {
|
|
4434
4617
|
log.warn(`Uniform ${name2} not found in layout`)();
|
|
4435
4618
|
return;
|
|
4436
4619
|
}
|
|
4437
|
-
const { type, components, columns, rows, offset } =
|
|
4620
|
+
const { type, components, columns, rows, offset, columnStride } = entry;
|
|
4438
4621
|
const array = typedArrays[type];
|
|
4439
4622
|
if (components === 1) {
|
|
4440
4623
|
array[offset] = Number(value);
|
|
@@ -4449,85 +4632,13 @@ var UniformBufferLayout = class {
|
|
|
4449
4632
|
}
|
|
4450
4633
|
let sourceIndex = 0;
|
|
4451
4634
|
for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
|
|
4452
|
-
const columnOffset = offset + columnIndex *
|
|
4635
|
+
const columnOffset = offset + columnIndex * columnStride;
|
|
4453
4636
|
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
4454
4637
|
array[columnOffset + rowIndex] = Number(sourceValue[sourceIndex++] ?? 0);
|
|
4455
4638
|
}
|
|
4456
4639
|
}
|
|
4457
4640
|
}
|
|
4458
4641
|
};
|
|
4459
|
-
function getTypeSize(type) {
|
|
4460
|
-
if (typeof type === "string") {
|
|
4461
|
-
return getLeafLayoutInfo(type).size;
|
|
4462
|
-
}
|
|
4463
|
-
if (Array.isArray(type)) {
|
|
4464
|
-
const elementType = type[0];
|
|
4465
|
-
const length = type[1];
|
|
4466
|
-
if (Array.isArray(elementType)) {
|
|
4467
|
-
throw new Error("Nested arrays are not supported");
|
|
4468
|
-
}
|
|
4469
|
-
return alignTo(getTypeSize(elementType), 4) * length;
|
|
4470
|
-
}
|
|
4471
|
-
let size = 0;
|
|
4472
|
-
for (const memberType of Object.values(type)) {
|
|
4473
|
-
const compositeMemberType = memberType;
|
|
4474
|
-
size = alignTo(size, getTypeAlignment(compositeMemberType));
|
|
4475
|
-
size += getTypeSize(compositeMemberType);
|
|
4476
|
-
}
|
|
4477
|
-
return alignTo(size, 4);
|
|
4478
|
-
}
|
|
4479
|
-
function getTypeAlignment(type) {
|
|
4480
|
-
if (typeof type === "string") {
|
|
4481
|
-
return getLeafLayoutInfo(type).alignment;
|
|
4482
|
-
}
|
|
4483
|
-
if (Array.isArray(type)) {
|
|
4484
|
-
return 4;
|
|
4485
|
-
}
|
|
4486
|
-
return 4;
|
|
4487
|
-
}
|
|
4488
|
-
function getLeafLayoutInfo(type) {
|
|
4489
|
-
const resolvedType = resolveVariableShaderTypeAlias(type);
|
|
4490
|
-
const decodedType = getVariableShaderTypeInfo(resolvedType);
|
|
4491
|
-
const matrixMatch = /^mat(\d)x(\d)<.+>$/.exec(resolvedType);
|
|
4492
|
-
if (matrixMatch) {
|
|
4493
|
-
const columns = Number(matrixMatch[1]);
|
|
4494
|
-
const rows = Number(matrixMatch[2]);
|
|
4495
|
-
return {
|
|
4496
|
-
alignment: 4,
|
|
4497
|
-
size: columns * 4,
|
|
4498
|
-
components: columns * rows,
|
|
4499
|
-
columns,
|
|
4500
|
-
rows,
|
|
4501
|
-
shaderType: resolvedType,
|
|
4502
|
-
type: decodedType.type
|
|
4503
|
-
};
|
|
4504
|
-
}
|
|
4505
|
-
const vectorMatch = /^vec(\d)<.+>$/.exec(resolvedType);
|
|
4506
|
-
if (vectorMatch) {
|
|
4507
|
-
const components = Number(vectorMatch[1]);
|
|
4508
|
-
return {
|
|
4509
|
-
alignment: components === 2 ? 2 : 4,
|
|
4510
|
-
size: components === 3 ? 4 : components,
|
|
4511
|
-
components,
|
|
4512
|
-
columns: 1,
|
|
4513
|
-
rows: components,
|
|
4514
|
-
shaderType: resolvedType,
|
|
4515
|
-
type: decodedType.type
|
|
4516
|
-
};
|
|
4517
|
-
}
|
|
4518
|
-
return {
|
|
4519
|
-
alignment: 1,
|
|
4520
|
-
size: 1,
|
|
4521
|
-
components: 1,
|
|
4522
|
-
columns: 1,
|
|
4523
|
-
rows: 1,
|
|
4524
|
-
shaderType: resolvedType,
|
|
4525
|
-
type: decodedType.type
|
|
4526
|
-
};
|
|
4527
|
-
}
|
|
4528
|
-
function isCompositeShaderTypeStruct(value) {
|
|
4529
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4530
|
-
}
|
|
4531
4642
|
function isCompositeUniformObject(value) {
|
|
4532
4643
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !ArrayBuffer.isView(value);
|
|
4533
4644
|
}
|
|
@@ -4619,24 +4730,33 @@ var UniformBlock = class {
|
|
|
4619
4730
|
};
|
|
4620
4731
|
|
|
4621
4732
|
// dist/portable/uniform-store.js
|
|
4733
|
+
var minUniformBufferSize = 1024;
|
|
4622
4734
|
var UniformStore = class {
|
|
4735
|
+
/** Device used to infer layout and allocate buffers. */
|
|
4736
|
+
device;
|
|
4623
4737
|
/** Stores the uniform values for each uniform block */
|
|
4624
4738
|
uniformBlocks = /* @__PURE__ */ new Map();
|
|
4625
|
-
/**
|
|
4626
|
-
|
|
4739
|
+
/** Flattened layout metadata for each block. */
|
|
4740
|
+
shaderBlockLayouts = /* @__PURE__ */ new Map();
|
|
4741
|
+
/** Serializers for block-backed uniform data. */
|
|
4742
|
+
shaderBlockWriters = /* @__PURE__ */ new Map();
|
|
4627
4743
|
/** Actual buffer for the blocks */
|
|
4628
4744
|
uniformBuffers = /* @__PURE__ */ new Map();
|
|
4629
4745
|
/**
|
|
4630
|
-
*
|
|
4631
|
-
* @param blocks
|
|
4746
|
+
* Creates a new {@link UniformStore} for the supplied device and block definitions.
|
|
4632
4747
|
*/
|
|
4633
|
-
constructor(blocks) {
|
|
4748
|
+
constructor(device, blocks) {
|
|
4749
|
+
this.device = device;
|
|
4634
4750
|
for (const [bufferName, block] of Object.entries(blocks)) {
|
|
4635
4751
|
const uniformBufferName = bufferName;
|
|
4636
|
-
const
|
|
4637
|
-
|
|
4752
|
+
const shaderBlockLayout = makeShaderBlockLayout(block.uniformTypes ?? {}, {
|
|
4753
|
+
layout: block.layout ?? getDefaultUniformBufferLayout(device)
|
|
4754
|
+
});
|
|
4755
|
+
const shaderBlockWriter = new ShaderBlockWriter(shaderBlockLayout);
|
|
4756
|
+
this.shaderBlockLayouts.set(uniformBufferName, shaderBlockLayout);
|
|
4757
|
+
this.shaderBlockWriters.set(uniformBufferName, shaderBlockWriter);
|
|
4638
4758
|
const uniformBlock = new UniformBlock({ name: bufferName });
|
|
4639
|
-
uniformBlock.setUniforms(
|
|
4759
|
+
uniformBlock.setUniforms(shaderBlockWriter.getFlatUniformValues(block.defaultUniforms || {}));
|
|
4640
4760
|
this.uniformBlocks.set(uniformBufferName, uniformBlock);
|
|
4641
4761
|
}
|
|
4642
4762
|
}
|
|
@@ -4648,39 +4768,52 @@ var UniformStore = class {
|
|
|
4648
4768
|
}
|
|
4649
4769
|
/**
|
|
4650
4770
|
* Set uniforms
|
|
4651
|
-
*
|
|
4771
|
+
*
|
|
4772
|
+
* Makes all group properties partial and eagerly propagates changes to any
|
|
4773
|
+
* managed GPU buffers.
|
|
4652
4774
|
*/
|
|
4653
4775
|
setUniforms(uniforms) {
|
|
4654
4776
|
var _a;
|
|
4655
4777
|
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
|
|
4656
4778
|
const uniformBufferName = blockName;
|
|
4657
|
-
const
|
|
4658
|
-
const flattenedUniforms =
|
|
4779
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4780
|
+
const flattenedUniforms = shaderBlockWriter == null ? void 0 : shaderBlockWriter.getFlatUniformValues(uniformValues || {});
|
|
4659
4781
|
(_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.setUniforms(flattenedUniforms || {});
|
|
4660
4782
|
}
|
|
4661
4783
|
this.updateUniformBuffers();
|
|
4662
4784
|
}
|
|
4663
|
-
/**
|
|
4785
|
+
/**
|
|
4786
|
+
* Returns the allocation size for the named uniform buffer.
|
|
4787
|
+
*
|
|
4788
|
+
* This may exceed the packed layout size because minimum buffer-size policy is
|
|
4789
|
+
* applied at the store layer.
|
|
4790
|
+
*/
|
|
4664
4791
|
getUniformBufferByteLength(uniformBufferName) {
|
|
4665
4792
|
var _a;
|
|
4666
|
-
|
|
4793
|
+
const packedByteLength = ((_a = this.shaderBlockLayouts.get(uniformBufferName)) == null ? void 0 : _a.byteLength) || 0;
|
|
4794
|
+
return Math.max(packedByteLength, minUniformBufferSize);
|
|
4667
4795
|
}
|
|
4668
|
-
/**
|
|
4796
|
+
/**
|
|
4797
|
+
* Returns packed binary data that can be uploaded to the named uniform buffer.
|
|
4798
|
+
*
|
|
4799
|
+
* The returned view length matches the packed block size and is not padded to
|
|
4800
|
+
* the store's minimum allocation size.
|
|
4801
|
+
*/
|
|
4669
4802
|
getUniformBufferData(uniformBufferName) {
|
|
4670
|
-
var _a
|
|
4803
|
+
var _a;
|
|
4671
4804
|
const uniformValues = ((_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.getAllUniforms()) || {};
|
|
4672
|
-
|
|
4805
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4806
|
+
return (shaderBlockWriter == null ? void 0 : shaderBlockWriter.getData(uniformValues)) || new Uint8Array(0);
|
|
4673
4807
|
}
|
|
4674
4808
|
/**
|
|
4675
|
-
* Creates an unmanaged uniform buffer
|
|
4676
|
-
* The new buffer is initialized with current / supplied values
|
|
4809
|
+
* Creates an unmanaged uniform buffer initialized with the current or supplied values.
|
|
4677
4810
|
*/
|
|
4678
|
-
createUniformBuffer(
|
|
4811
|
+
createUniformBuffer(uniformBufferName, uniforms) {
|
|
4679
4812
|
if (uniforms) {
|
|
4680
4813
|
this.setUniforms(uniforms);
|
|
4681
4814
|
}
|
|
4682
4815
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
4683
|
-
const uniformBuffer = device.createBuffer({
|
|
4816
|
+
const uniformBuffer = this.device.createBuffer({
|
|
4684
4817
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
4685
4818
|
byteLength
|
|
4686
4819
|
});
|
|
@@ -4688,11 +4821,11 @@ var UniformStore = class {
|
|
|
4688
4821
|
uniformBuffer.write(uniformBufferData);
|
|
4689
4822
|
return uniformBuffer;
|
|
4690
4823
|
}
|
|
4691
|
-
/**
|
|
4692
|
-
getManagedUniformBuffer(
|
|
4824
|
+
/** Returns the managed uniform buffer for the named block. */
|
|
4825
|
+
getManagedUniformBuffer(uniformBufferName) {
|
|
4693
4826
|
if (!this.uniformBuffers.get(uniformBufferName)) {
|
|
4694
4827
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
4695
|
-
const uniformBuffer = device.createBuffer({
|
|
4828
|
+
const uniformBuffer = this.device.createBuffer({
|
|
4696
4829
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
4697
4830
|
byteLength
|
|
4698
4831
|
});
|
|
@@ -4700,7 +4833,11 @@ var UniformStore = class {
|
|
|
4700
4833
|
}
|
|
4701
4834
|
return this.uniformBuffers.get(uniformBufferName);
|
|
4702
4835
|
}
|
|
4703
|
-
/**
|
|
4836
|
+
/**
|
|
4837
|
+
* Updates every managed uniform buffer whose source uniforms have changed.
|
|
4838
|
+
*
|
|
4839
|
+
* @returns The first redraw reason encountered, or `false` if nothing changed.
|
|
4840
|
+
*/
|
|
4704
4841
|
updateUniformBuffers() {
|
|
4705
4842
|
let reason = false;
|
|
4706
4843
|
for (const uniformBufferName of this.uniformBlocks.keys()) {
|
|
@@ -4712,7 +4849,11 @@ var UniformStore = class {
|
|
|
4712
4849
|
}
|
|
4713
4850
|
return reason;
|
|
4714
4851
|
}
|
|
4715
|
-
/**
|
|
4852
|
+
/**
|
|
4853
|
+
* Updates one managed uniform buffer if its corresponding block is dirty.
|
|
4854
|
+
*
|
|
4855
|
+
* @returns The redraw reason for the update, or `false` if no write occurred.
|
|
4856
|
+
*/
|
|
4716
4857
|
updateUniformBuffer(uniformBufferName) {
|
|
4717
4858
|
var _a;
|
|
4718
4859
|
const uniformBlock = this.uniformBlocks.get(uniformBufferName);
|
|
@@ -4729,6 +4870,9 @@ var UniformStore = class {
|
|
|
4729
4870
|
return reason;
|
|
4730
4871
|
}
|
|
4731
4872
|
};
|
|
4873
|
+
function getDefaultUniformBufferLayout(device) {
|
|
4874
|
+
return device.type === "webgpu" ? "wgsl-uniform" : "std140";
|
|
4875
|
+
}
|
|
4732
4876
|
|
|
4733
4877
|
// dist/shadertypes/texture-types/texture-layout.js
|
|
4734
4878
|
function getTextureImageView(arrayBuffer2, memoryLayout, format, image = 0) {
|