@luma.gl/webgpu 9.0.0-alpha.33 → 9.0.0-alpha.35

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.
Files changed (40) hide show
  1. package/dist/adapter/helpers/generate-mipmaps.js +18 -6
  2. package/dist/adapter/helpers/generate-mipmaps.js.map +1 -1
  3. package/dist/adapter/helpers/get-bind-group.js +1 -1
  4. package/dist/adapter/helpers/get-bind-group.js.map +1 -1
  5. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -1
  6. package/dist/adapter/helpers/get-vertex-buffer-layout.js +12 -11
  7. package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -1
  8. package/dist/adapter/helpers/webgpu-parameters.js +1 -1
  9. package/dist/adapter/helpers/webgpu-parameters.js.map +1 -1
  10. package/dist/adapter/resources/webgpu-buffer.js +3 -4
  11. package/dist/adapter/resources/webgpu-buffer.js.map +1 -1
  12. package/dist/adapter/resources/webgpu-command-encoder.js +2 -3
  13. package/dist/adapter/resources/webgpu-command-encoder.js.map +1 -1
  14. package/dist/adapter/resources/webgpu-compute-pass.js +3 -4
  15. package/dist/adapter/resources/webgpu-compute-pass.js.map +1 -1
  16. package/dist/adapter/resources/webgpu-compute-pipeline.js +2 -3
  17. package/dist/adapter/resources/webgpu-compute-pipeline.js.map +1 -1
  18. package/dist/adapter/resources/webgpu-external-texture.js +3 -4
  19. package/dist/adapter/resources/webgpu-external-texture.js.map +1 -1
  20. package/dist/adapter/resources/webgpu-framebuffer.js +1 -2
  21. package/dist/adapter/resources/webgpu-framebuffer.js.map +1 -1
  22. package/dist/adapter/resources/webgpu-render-pass.js +3 -4
  23. package/dist/adapter/resources/webgpu-render-pass.js.map +1 -1
  24. package/dist/adapter/resources/webgpu-render-pipeline.js +13 -14
  25. package/dist/adapter/resources/webgpu-render-pipeline.js.map +1 -1
  26. package/dist/adapter/resources/webgpu-sampler.js +2 -3
  27. package/dist/adapter/resources/webgpu-sampler.js.map +1 -1
  28. package/dist/adapter/resources/webgpu-shader.js +4 -5
  29. package/dist/adapter/resources/webgpu-shader.js.map +1 -1
  30. package/dist/adapter/resources/webgpu-texture.js +6 -7
  31. package/dist/adapter/resources/webgpu-texture.js.map +1 -1
  32. package/dist/adapter/webgpu-canvas-context.js +8 -9
  33. package/dist/adapter/webgpu-canvas-context.js.map +1 -1
  34. package/dist/adapter/webgpu-device.js +10 -11
  35. package/dist/adapter/webgpu-device.js.map +1 -1
  36. package/dist/dist.dev.js +213 -44
  37. package/dist/index.cjs +9 -7
  38. package/dist.min.js +5 -4
  39. package/package.json +3 -3
  40. package/src/adapter/helpers/get-vertex-buffer-layout.ts +12 -9
package/dist/dist.dev.js CHANGED
@@ -11,8 +11,8 @@ var __exports__ = (() => {
11
11
  var __hasOwnProp = Object.prototype.hasOwnProperty;
12
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
13
  var __export = (target, all) => {
14
- for (var name in all)
15
- __defProp(target, name, { get: all[name], enumerable: true });
14
+ for (var name2 in all)
15
+ __defProp(target, name2, { get: all[name2], enumerable: true });
16
16
  };
17
17
  var __copyProps = (to, from, except, desc) => {
18
18
  if (from && typeof from === "object" || typeof from === "function") {
@@ -198,7 +198,7 @@ var __exports__ = (() => {
198
198
  for (const key of propNames) {
199
199
  const value = object[key];
200
200
  if (typeof value === "function") {
201
- if (!predefined.find((name) => key === name)) {
201
+ if (!predefined.find((name2) => key === name2)) {
202
202
  object[key] = value.bind(obj);
203
203
  }
204
204
  }
@@ -587,7 +587,7 @@ var __exports__ = (() => {
587
587
 
588
588
  // ../../node_modules/@probe.gl/stats/dist/lib/stat.js
589
589
  var Stat = class {
590
- constructor(name, type) {
590
+ constructor(name2, type) {
591
591
  this.name = void 0;
592
592
  this.type = void 0;
593
593
  this.sampleSize = 1;
@@ -602,7 +602,7 @@ var __exports__ = (() => {
602
602
  this._samples = 0;
603
603
  this._startTime = 0;
604
604
  this._timerPending = false;
605
- this.name = name;
605
+ this.name = name2;
606
606
  this.type = type;
607
607
  this.reset();
608
608
  }
@@ -707,10 +707,10 @@ var __exports__ = (() => {
707
707
  this._initializeStats(options.stats);
708
708
  Object.seal(this);
709
709
  }
710
- get(name) {
710
+ get(name2) {
711
711
  let type = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "count";
712
712
  return this._getOrCreate({
713
- name,
713
+ name: name2,
714
714
  type
715
715
  });
716
716
  }
@@ -746,17 +746,17 @@ var __exports__ = (() => {
746
746
  }
747
747
  _getOrCreate(stat) {
748
748
  const {
749
- name,
749
+ name: name2,
750
750
  type
751
751
  } = stat;
752
- let result = this.stats[name];
752
+ let result = this.stats[name2];
753
753
  if (!result) {
754
754
  if (stat instanceof Stat) {
755
755
  result = stat;
756
756
  } else {
757
- result = new Stat(name, type);
757
+ result = new Stat(name2, type);
758
758
  }
759
- this.stats[name] = result;
759
+ this.stats[name2] = result;
760
760
  }
761
761
  return result;
762
762
  }
@@ -765,16 +765,16 @@ var __exports__ = (() => {
765
765
  // ../core/src/lib/utils/stats-manager.ts
766
766
  var StatsManager = class {
767
767
  stats = /* @__PURE__ */ new Map();
768
- getStats(name) {
769
- return this.get(name);
768
+ getStats(name2) {
769
+ return this.get(name2);
770
770
  }
771
- get(name) {
772
- if (!this.stats.has(name)) {
773
- this.stats.set(name, new Stats({
774
- id: name
771
+ get(name2) {
772
+ if (!this.stats.has(name2)) {
773
+ this.stats.set(name2, new Stats({
774
+ id: name2
775
775
  }));
776
776
  }
777
- return this.stats.get(name);
777
+ return this.stats.get(name2);
778
778
  }
779
779
  };
780
780
  var lumaStats = new StatsManager();
@@ -904,30 +904,30 @@ var __exports__ = (() => {
904
904
  /** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
905
905
  removeStats() {
906
906
  const stats = this._device.statsManager.getStats("Resource Counts");
907
- const name = this[Symbol.toStringTag];
908
- stats.get(`${name}s Active`).decrementCount();
907
+ const name2 = this[Symbol.toStringTag];
908
+ stats.get(`${name2}s Active`).decrementCount();
909
909
  }
910
910
  /** Called by subclass to track memory allocations */
911
- trackAllocatedMemory(bytes, name = this[Symbol.toStringTag]) {
911
+ trackAllocatedMemory(bytes, name2 = this[Symbol.toStringTag]) {
912
912
  const stats = this._device.statsManager.getStats("Resource Counts");
913
913
  stats.get("GPU Memory").addCount(bytes);
914
- stats.get(`${name} Memory`).addCount(bytes);
914
+ stats.get(`${name2} Memory`).addCount(bytes);
915
915
  this.allocatedBytes = bytes;
916
916
  }
917
917
  /** Called by subclass to track memory deallocations */
918
- trackDeallocatedMemory(name = this[Symbol.toStringTag]) {
918
+ trackDeallocatedMemory(name2 = this[Symbol.toStringTag]) {
919
919
  const stats = this._device.statsManager.getStats("Resource Counts");
920
920
  stats.get("GPU Memory").subtractCount(this.allocatedBytes);
921
- stats.get(`${name} Memory`).subtractCount(this.allocatedBytes);
921
+ stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
922
922
  this.allocatedBytes = 0;
923
923
  }
924
924
  /** Called by resource constructor to track object creation */
925
925
  addStats() {
926
926
  const stats = this._device.statsManager.getStats("Resource Counts");
927
- const name = this[Symbol.toStringTag];
927
+ const name2 = this[Symbol.toStringTag];
928
928
  stats.get("Resources Created").incrementCount();
929
- stats.get(`${name}s Created`).incrementCount();
930
- stats.get(`${name}s Active`).incrementCount();
929
+ stats.get(`${name2}s Created`).incrementCount();
930
+ stats.get(`${name2}s Active`).incrementCount();
931
931
  }
932
932
  };
933
933
  /** Default properties for resource */
@@ -1141,7 +1141,7 @@ var __exports__ = (() => {
1141
1141
  // Resource creation helpers
1142
1142
  _getBufferProps(props) {
1143
1143
  if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
1144
- return {
1144
+ props = {
1145
1145
  data: props
1146
1146
  };
1147
1147
  }
@@ -1153,6 +1153,8 @@ var __exports__ = (() => {
1153
1153
  newProps.indexType = "uint32";
1154
1154
  } else if (props.data instanceof Uint16Array) {
1155
1155
  newProps.indexType = "uint16";
1156
+ } else {
1157
+ log.warn("indices buffer content must be of integer type")();
1156
1158
  }
1157
1159
  }
1158
1160
  return newProps;
@@ -1954,6 +1956,171 @@ var __exports__ = (() => {
1954
1956
  return result;
1955
1957
  }
1956
1958
 
1959
+ // ../core/src/adapter/type-utils/decode-attribute-type.ts
1960
+ function decodeShaderAttributeType(attributeType) {
1961
+ const [dataType, components] = TYPE_INFO[attributeType];
1962
+ const integer = dataType === "i32" || dataType === "u32";
1963
+ const signed = dataType !== "u32";
1964
+ const byteLength = TYPE_SIZES2[dataType] * components;
1965
+ const defaultVertexFormat = getCompatibleVertexFormat(dataType, components);
1966
+ return {
1967
+ dataType,
1968
+ components,
1969
+ defaultVertexFormat,
1970
+ byteLength,
1971
+ integer,
1972
+ signed
1973
+ };
1974
+ }
1975
+ function getCompatibleVertexFormat(dataType, components) {
1976
+ let vertexType;
1977
+ switch (dataType) {
1978
+ case "f32":
1979
+ vertexType = "float32";
1980
+ break;
1981
+ case "i32":
1982
+ vertexType = "sint32";
1983
+ break;
1984
+ case "u32":
1985
+ vertexType = "uint32";
1986
+ break;
1987
+ case "f16":
1988
+ return components <= 2 ? "float16x2" : "float16x4";
1989
+ }
1990
+ if (components === 1) {
1991
+ return vertexType;
1992
+ }
1993
+ return `${vertexType}x${components}`;
1994
+ }
1995
+ var TYPE_INFO = {
1996
+ f32: ["f32", 1],
1997
+ "vec2<f32>": ["f32", 2],
1998
+ "vec3<f32>": ["f32", 3],
1999
+ "vec4<f32>": ["f32", 4],
2000
+ f16: ["f16", 1],
2001
+ "vec2<f16>": ["f16", 2],
2002
+ "vec3<f16>": ["f16", 3],
2003
+ "vec4<f16>": ["f16", 4],
2004
+ i32: ["i32", 1],
2005
+ "vec2<i32>": ["i32", 2],
2006
+ "vec3<i32>": ["i32", 3],
2007
+ "vec4<i32>": ["i32", 4],
2008
+ u32: ["u32", 1],
2009
+ "vec2<u32>": ["u32", 2],
2010
+ "vec3<u32>": ["u32", 3],
2011
+ "vec4<u32>": ["u32", 4]
2012
+ };
2013
+ var TYPE_SIZES2 = {
2014
+ f32: 4,
2015
+ f16: 2,
2016
+ i32: 4,
2017
+ u32: 4
2018
+ // 'bool-webgl': 4,
2019
+ };
2020
+
2021
+ // ../core/src/adapter/attribute-utils/get-attribute-from-layouts.ts
2022
+ function getAttributeInfosFromLayouts(shaderLayout, bufferLayout) {
2023
+ const attributeInfos = {};
2024
+ for (const attribute of shaderLayout.attributes) {
2025
+ attributeInfos[attribute.name] = getAttributeInfoFromLayouts(shaderLayout, bufferLayout, attribute.name);
2026
+ }
2027
+ return attributeInfos;
2028
+ }
2029
+ function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
2030
+ const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name2);
2031
+ const bufferMapping = getAttributeFromBufferLayout(bufferLayout, name2);
2032
+ if (!shaderDeclaration) {
2033
+ return null;
2034
+ }
2035
+ const attributeTypeInfo = decodeShaderAttributeType(shaderDeclaration.type);
2036
+ const vertexFormat = bufferMapping?.vertexFormat || attributeTypeInfo.defaultVertexFormat;
2037
+ const vertexFormatInfo = decodeVertexFormat(vertexFormat);
2038
+ return {
2039
+ attributeName: bufferMapping?.attributeName || shaderDeclaration.name,
2040
+ bufferName: bufferMapping?.bufferName || shaderDeclaration.name,
2041
+ location: shaderDeclaration.location,
2042
+ shaderType: shaderDeclaration.type,
2043
+ shaderDataType: attributeTypeInfo.dataType,
2044
+ shaderComponents: attributeTypeInfo.components,
2045
+ vertexFormat,
2046
+ bufferDataType: vertexFormatInfo.type,
2047
+ bufferComponents: vertexFormatInfo.components,
2048
+ // normalized is a property of the buffer's vertex format
2049
+ normalized: vertexFormatInfo.normalized,
2050
+ // integer is a property of the shader declaration
2051
+ integer: attributeTypeInfo.integer,
2052
+ stepMode: bufferMapping?.stepMode || shaderDeclaration.stepMode,
2053
+ byteOffset: bufferMapping?.byteOffset || 0,
2054
+ byteStride: bufferMapping?.byteStride || 0
2055
+ };
2056
+ }
2057
+ function getAttributeFromShaderLayout(shaderLayout, name2) {
2058
+ const attribute = shaderLayout.attributes.find((attr) => attr.name === name2);
2059
+ if (!attribute) {
2060
+ log.warn(`shader layout attribute "${name2}" not present in shader`);
2061
+ }
2062
+ return attribute || null;
2063
+ }
2064
+ function getAttributeFromBufferLayout(bufferLayouts, name2) {
2065
+ checkBufferLayouts(bufferLayouts);
2066
+ let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name2);
2067
+ if (bufferLayoutInfo) {
2068
+ return bufferLayoutInfo;
2069
+ }
2070
+ bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name2);
2071
+ if (bufferLayoutInfo) {
2072
+ return bufferLayoutInfo;
2073
+ }
2074
+ log.warn(`layout for attribute "${name2}" not present in buffer layout`);
2075
+ return null;
2076
+ }
2077
+ function checkBufferLayouts(bufferLayouts) {
2078
+ for (const bufferLayout of bufferLayouts) {
2079
+ if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) {
2080
+ log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
2081
+ }
2082
+ }
2083
+ }
2084
+ function getAttributeFromShortHand(bufferLayouts, name2) {
2085
+ for (const bufferLayout of bufferLayouts) {
2086
+ if (bufferLayout.format && bufferLayout.name === name2) {
2087
+ return {
2088
+ attributeName: bufferLayout.name,
2089
+ bufferName: name2,
2090
+ stepMode: bufferLayout.stepMode,
2091
+ vertexFormat: bufferLayout.format,
2092
+ // If offset is needed, use `attributes` field.
2093
+ byteOffset: 0,
2094
+ byteStride: bufferLayout.byteStride || 0
2095
+ };
2096
+ }
2097
+ }
2098
+ return null;
2099
+ }
2100
+ function getAttributeFromAttributesList(bufferLayouts, name2) {
2101
+ for (const bufferLayout of bufferLayouts) {
2102
+ let byteStride = bufferLayout.byteStride;
2103
+ if (typeof bufferLayout.byteStride !== "number") {
2104
+ for (const attributeMapping2 of bufferLayout.attributes || []) {
2105
+ const info = decodeVertexFormat(attributeMapping2.format);
2106
+ byteStride += info.byteLength;
2107
+ }
2108
+ }
2109
+ const attributeMapping = bufferLayout.attributes?.find((mapping) => mapping.attribute === name2);
2110
+ if (attributeMapping) {
2111
+ return {
2112
+ attributeName: attributeMapping.attribute,
2113
+ bufferName: bufferLayout.name,
2114
+ stepMode: bufferLayout.stepMode,
2115
+ vertexFormat: attributeMapping.format,
2116
+ byteOffset: attributeMapping.byteOffset,
2117
+ byteStride
2118
+ };
2119
+ }
2120
+ }
2121
+ return null;
2122
+ }
2123
+
1957
2124
  // ../core/src/lib/utils/cast.ts
1958
2125
  function cast(value) {
1959
2126
  return value;
@@ -2546,20 +2713,21 @@ var __exports__ = (() => {
2546
2713
  return format;
2547
2714
  }
2548
2715
  function getVertexBufferLayout(shaderLayout, bufferLayout) {
2716
+ const attributeInfos = getAttributeInfosFromLayouts(shaderLayout, bufferLayout);
2549
2717
  const vertexBufferLayouts = [];
2550
2718
  const usedAttributes = /* @__PURE__ */ new Set();
2551
2719
  for (const mapping of bufferLayout) {
2552
2720
  const vertexAttributes = [];
2553
2721
  let stepMode = "vertex";
2554
2722
  let byteStride = 0;
2555
- const byteOffset = mapping.byteOffset || 0;
2556
2723
  if (mapping.attributes) {
2557
- for (const interleaved of mapping.attributes) {
2558
- const attributeLayout = findAttributeLayout(shaderLayout, interleaved.name, usedAttributes);
2724
+ for (const attributeMapping of mapping.attributes) {
2725
+ const attributeName = attributeMapping.attribute;
2726
+ const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
2559
2727
  stepMode = attributeLayout.stepMode || "vertex";
2560
2728
  vertexAttributes.push({
2561
- format: getWebGPUVertexFormat(interleaved.format || mapping.format),
2562
- offset: byteOffset + byteStride,
2729
+ format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
2730
+ offset: attributeMapping.byteOffset,
2563
2731
  shaderLocation: attributeLayout.location
2564
2732
  });
2565
2733
  byteStride += decodeVertexFormat(mapping.format).byteLength;
@@ -2570,7 +2738,8 @@ var __exports__ = (() => {
2570
2738
  stepMode = attributeLayout.stepMode || "vertex";
2571
2739
  vertexAttributes.push({
2572
2740
  format: getWebGPUVertexFormat(mapping.format),
2573
- offset: byteOffset,
2741
+ // We only support 0 offset for non-interleaved buffer layouts
2742
+ offset: 0,
2574
2743
  shaderLocation: attributeLayout.location
2575
2744
  });
2576
2745
  }
@@ -2602,7 +2771,7 @@ var __exports__ = (() => {
2602
2771
  for (const mapping of bufferLayout) {
2603
2772
  if ("attributes" in mapping) {
2604
2773
  for (const interleaved of mapping.attributes) {
2605
- usedAttributes.add(interleaved.name);
2774
+ usedAttributes.add(interleaved.attribute);
2606
2775
  }
2607
2776
  } else {
2608
2777
  usedAttributes.add(mapping.name);
@@ -2616,15 +2785,15 @@ var __exports__ = (() => {
2616
2785
  }
2617
2786
  return bufferSlots;
2618
2787
  }
2619
- function findAttributeLayout(shaderLayout, name, attributeNames) {
2620
- const attribute = shaderLayout.attributes.find((attribute2) => attribute2.name === name);
2788
+ function findAttributeLayout(shaderLayout, name2, attributeNames) {
2789
+ const attribute = shaderLayout.attributes.find((attribute2) => attribute2.name === name2);
2621
2790
  if (!attribute) {
2622
- throw new Error(`Unknown attribute ${name}`);
2791
+ throw new Error(`Unknown attribute ${name2}`);
2623
2792
  }
2624
- if (attributeNames.has(name)) {
2625
- throw new Error(`Duplicate attribute ${name}`);
2793
+ if (attributeNames.has(name2)) {
2794
+ throw new Error(`Duplicate attribute ${name2}`);
2626
2795
  }
2627
- attributeNames.add(name);
2796
+ attributeNames.add(name2);
2628
2797
  return attribute;
2629
2798
  }
2630
2799
 
@@ -2661,12 +2830,12 @@ var __exports__ = (() => {
2661
2830
  this._indexBuffer = cast(indexBuffer);
2662
2831
  }
2663
2832
  setAttributes(attributes) {
2664
- for (const [name, buffer] of Object.entries(attributes)) {
2665
- const bufferIndex = this._bufferSlots[name];
2833
+ for (const [name2, buffer] of Object.entries(attributes)) {
2834
+ const bufferIndex = this._bufferSlots[name2];
2666
2835
  if (bufferIndex >= 0) {
2667
2836
  this._buffers[bufferIndex] = buffer;
2668
2837
  } else {
2669
- throw new Error(`Setting attribute '${name}' not listed in shader layout for program ${this.id}`);
2838
+ throw new Error(`Setting attribute '${name2}' not listed in shader layout for program ${this.id}`);
2670
2839
  }
2671
2840
  }
2672
2841
  }
package/dist/index.cjs CHANGED
@@ -678,20 +678,21 @@ function getWebGPUVertexFormat(format) {
678
678
  return format;
679
679
  }
680
680
  function getVertexBufferLayout(shaderLayout, bufferLayout) {
681
+ const attributeInfos = (0, import_core7.getAttributeInfosFromLayouts)(shaderLayout, bufferLayout);
681
682
  const vertexBufferLayouts = [];
682
683
  const usedAttributes = /* @__PURE__ */ new Set();
683
684
  for (const mapping of bufferLayout) {
684
685
  const vertexAttributes = [];
685
686
  let stepMode = "vertex";
686
687
  let byteStride = 0;
687
- const byteOffset = mapping.byteOffset || 0;
688
688
  if (mapping.attributes) {
689
- for (const interleaved of mapping.attributes) {
690
- const attributeLayout = findAttributeLayout(shaderLayout, interleaved.name, usedAttributes);
689
+ for (const attributeMapping of mapping.attributes) {
690
+ const attributeName = attributeMapping.attribute;
691
+ const attributeLayout = findAttributeLayout(shaderLayout, attributeName, usedAttributes);
691
692
  stepMode = attributeLayout.stepMode || "vertex";
692
693
  vertexAttributes.push({
693
- format: getWebGPUVertexFormat(interleaved.format || mapping.format),
694
- offset: byteOffset + byteStride,
694
+ format: getWebGPUVertexFormat(attributeMapping.format || mapping.format),
695
+ offset: attributeMapping.byteOffset,
695
696
  shaderLocation: attributeLayout.location
696
697
  });
697
698
  byteStride += (0, import_core7.decodeVertexFormat)(mapping.format).byteLength;
@@ -702,7 +703,8 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
702
703
  stepMode = attributeLayout.stepMode || "vertex";
703
704
  vertexAttributes.push({
704
705
  format: getWebGPUVertexFormat(mapping.format),
705
- offset: byteOffset,
706
+ // We only support 0 offset for non-interleaved buffer layouts
707
+ offset: 0,
706
708
  shaderLocation: attributeLayout.location
707
709
  });
708
710
  }
@@ -736,7 +738,7 @@ function getBufferSlots(shaderLayout, bufferLayout) {
736
738
  for (const mapping of bufferLayout) {
737
739
  if ("attributes" in mapping) {
738
740
  for (const interleaved of mapping.attributes) {
739
- usedAttributes.add(interleaved.name);
741
+ usedAttributes.add(interleaved.attribute);
740
742
  }
741
743
  } else {
742
744
  usedAttributes.add(mapping.name);