@luma.gl/webgpu 9.3.0-alpha.2 → 9.3.0-alpha.4

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/index.cjs CHANGED
@@ -7,8 +7,8 @@ var __esm = (fn, res) => function __init() {
7
7
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
8
  };
9
9
  var __export = (target, all) => {
10
- for (var name2 in all)
11
- __defProp(target, name2, { get: all[name2], enumerable: true });
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
12
  };
13
13
  var __copyProps = (to, from, except, desc) => {
14
14
  if (from && typeof from === "object" || typeof from === "function") {
@@ -30,13 +30,15 @@ var init_webgpu_buffer = __esm({
30
30
  device;
31
31
  handle;
32
32
  byteLength;
33
+ paddedByteLength;
33
34
  constructor(device, props) {
34
35
  var _a, _b;
35
36
  super(device, props);
36
37
  this.device = device;
37
38
  this.byteLength = props.byteLength || ((_a = props.data) == null ? void 0 : _a.byteLength) || 0;
39
+ this.paddedByteLength = Math.ceil(this.byteLength / 4) * 4;
38
40
  const mappedAtCreation = Boolean(this.props.onMapped || props.data);
39
- const size = Math.ceil(this.byteLength / 4) * 4;
41
+ const size = this.paddedByteLength;
40
42
  this.device.pushErrorScope("out-of-memory");
41
43
  this.device.pushErrorScope("validation");
42
44
  this.handle = this.props.handle || this.device.handle.createBuffer({
@@ -89,18 +91,21 @@ var init_webgpu_buffer = __esm({
89
91
  });
90
92
  }
91
93
  async mapAndWriteAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
94
+ const alignedByteLength = Math.ceil(byteLength / 4) * 4;
92
95
  const isMappable = (this.usage & import_core.Buffer.MAP_WRITE) !== 0;
93
- const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_WRITE | import_core.Buffer.COPY_SRC, 0, this.byteLength) : null;
96
+ const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_WRITE | import_core.Buffer.COPY_SRC, 0, this.paddedByteLength) : null;
94
97
  const writeBuffer = mappableBuffer || this;
95
98
  this.device.pushErrorScope("validation");
96
99
  try {
97
100
  await this.device.handle.queue.onSubmittedWorkDone();
98
- await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset, byteLength);
99
- const arrayBuffer = writeBuffer.handle.getMappedRange(byteOffset, byteLength);
101
+ await writeBuffer.handle.mapAsync(GPUMapMode.WRITE, byteOffset, alignedByteLength);
102
+ const mappedRange = writeBuffer.handle.getMappedRange(byteOffset, alignedByteLength);
103
+ const arrayBuffer = mappedRange.slice(0, byteLength);
100
104
  await callback(arrayBuffer, "mapped");
105
+ new Uint8Array(mappedRange).set(new Uint8Array(arrayBuffer), 0);
101
106
  writeBuffer.handle.unmap();
102
107
  if (mappableBuffer) {
103
- this._copyBuffer(mappableBuffer, byteOffset, byteLength);
108
+ this._copyBuffer(mappableBuffer, byteOffset, alignedByteLength);
104
109
  }
105
110
  } finally {
106
111
  this.device.popErrorScope((error) => {
@@ -114,24 +119,37 @@ var init_webgpu_buffer = __esm({
114
119
  return this.mapAndReadAsync((arrayBuffer) => new Uint8Array(arrayBuffer.slice(0)), byteOffset, byteLength);
115
120
  }
116
121
  async mapAndReadAsync(callback, byteOffset = 0, byteLength = this.byteLength - byteOffset) {
122
+ const requestedEnd = byteOffset + byteLength;
123
+ if (requestedEnd > this.byteLength) {
124
+ throw new Error("Mapping range exceeds buffer size");
125
+ }
126
+ let mappedByteOffset = byteOffset;
127
+ let mappedByteLength = byteLength;
128
+ let sliceByteOffset = 0;
129
+ let lifetime = "mapped";
117
130
  if (byteOffset % 8 !== 0 || byteLength % 4 !== 0) {
118
- throw new Error("byteOffset must be multiple of 8 and byteLength multiple of 4");
131
+ mappedByteOffset = Math.floor(byteOffset / 8) * 8;
132
+ const alignedEnd = Math.ceil(requestedEnd / 4) * 4;
133
+ mappedByteLength = alignedEnd - mappedByteOffset;
134
+ sliceByteOffset = byteOffset - mappedByteOffset;
135
+ lifetime = "copied";
119
136
  }
120
- if (byteOffset + byteLength > this.handle.size) {
137
+ if (mappedByteOffset + mappedByteLength > this.paddedByteLength) {
121
138
  throw new Error("Mapping range exceeds buffer size");
122
139
  }
123
140
  const isMappable = (this.usage & import_core.Buffer.MAP_READ) !== 0;
124
- const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST, 0, this.byteLength) : null;
141
+ const mappableBuffer = !isMappable ? this._getMappableBuffer(import_core.Buffer.MAP_READ | import_core.Buffer.COPY_DST, 0, this.paddedByteLength) : null;
125
142
  const readBuffer = mappableBuffer || this;
126
143
  this.device.pushErrorScope("validation");
127
144
  try {
128
145
  await this.device.handle.queue.onSubmittedWorkDone();
129
146
  if (mappableBuffer) {
130
- mappableBuffer._copyBuffer(this);
147
+ mappableBuffer._copyBuffer(this, mappedByteOffset, mappedByteLength);
131
148
  }
132
- await readBuffer.handle.mapAsync(GPUMapMode.READ, byteOffset, byteLength);
133
- const arrayBuffer = readBuffer.handle.getMappedRange(byteOffset, byteLength);
134
- const result = await callback(arrayBuffer, "mapped");
149
+ await readBuffer.handle.mapAsync(GPUMapMode.READ, mappedByteOffset, mappedByteLength);
150
+ const arrayBuffer = readBuffer.handle.getMappedRange(mappedByteOffset, mappedByteLength);
151
+ const mappedRange = lifetime === "mapped" ? arrayBuffer : arrayBuffer.slice(sliceByteOffset, sliceByteOffset + byteLength);
152
+ const result = await callback(mappedRange, lifetime);
135
153
  readBuffer.handle.unmap();
136
154
  return result;
137
155
  } finally {
@@ -824,7 +842,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
824
842
  for (const [bindingName, value] of Object.entries(bindings)) {
825
843
  let bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
826
844
  if (bindingLayout) {
827
- const entry = getBindGroupEntry(value, bindingLayout.location);
845
+ const entry = getBindGroupEntry(value, bindingLayout.location, void 0, bindingName);
828
846
  if (entry) {
829
847
  entries.push(entry);
830
848
  }
@@ -834,7 +852,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
834
852
  ignoreWarnings: true
835
853
  });
836
854
  if (bindingLayout) {
837
- const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true });
855
+ const entry = getBindGroupEntry(value, bindingLayout.location, { sampler: true }, bindingName);
838
856
  if (entry) {
839
857
  entries.push(entry);
840
858
  }
@@ -843,7 +861,7 @@ function getBindGroupEntries(bindings, shaderLayout) {
843
861
  }
844
862
  return entries;
845
863
  }
846
- function getBindGroupEntry(binding, index, options) {
864
+ function getBindGroupEntry(binding, index, options, bindingName = "unknown") {
847
865
  if (binding instanceof import_core8.Buffer) {
848
866
  return {
849
867
  binding: index,
@@ -858,6 +876,12 @@ function getBindGroupEntry(binding, index, options) {
858
876
  resource: binding.handle
859
877
  };
860
878
  }
879
+ if (binding instanceof import_core8.TextureView) {
880
+ return {
881
+ binding: index,
882
+ resource: binding.handle
883
+ };
884
+ }
861
885
  if (binding instanceof import_core8.Texture) {
862
886
  if (options == null ? void 0 : options.sampler) {
863
887
  return {
@@ -870,7 +894,7 @@ function getBindGroupEntry(binding, index, options) {
870
894
  resource: binding.view.handle
871
895
  };
872
896
  }
873
- import_core8.log.warn(`invalid binding ${name}`, binding);
897
+ import_core8.log.warn(`invalid binding ${bindingName}`, binding);
874
898
  return null;
875
899
  }
876
900
  var import_core8;
@@ -952,17 +976,17 @@ function getVertexBufferLayout(shaderLayout, bufferLayout) {
952
976
  });
953
977
  return vertexBufferLayouts;
954
978
  }
955
- function findAttributeLayout(shaderLayout, name2, attributeNames) {
956
- const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name === name2);
979
+ function findAttributeLayout(shaderLayout, name, attributeNames) {
980
+ const attribute = shaderLayout.attributes.find((attribute_) => attribute_.name === name);
957
981
  if (!attribute) {
958
- import_core9.log.warn(`Supplied attribute not present in shader layout: ${name2}`)();
982
+ import_core9.log.warn(`Supplied attribute not present in shader layout: ${name}`)();
959
983
  return null;
960
984
  }
961
985
  if (attributeNames) {
962
- if (attributeNames.has(name2)) {
963
- throw new Error(`Found multiple entries for attribute: ${name2}`);
986
+ if (attributeNames.has(name)) {
987
+ throw new Error(`Found multiple entries for attribute: ${name}`);
964
988
  }
965
- attributeNames.add(name2);
989
+ attributeNames.add(name);
966
990
  }
967
991
  return attribute;
968
992
  }
@@ -1026,8 +1050,8 @@ var init_webgpu_render_pipeline = __esm({
1026
1050
  * @todo Do we want to expose BindGroups in the API and remove this?
1027
1051
  */
1028
1052
  setBindings(bindings) {
1029
- for (const [name2, binding] of Object.entries(bindings)) {
1030
- if (this._bindings[name2] !== binding) {
1053
+ for (const [name, binding] of Object.entries(bindings)) {
1054
+ if (this._bindings[name] !== binding) {
1031
1055
  this._bindGroup = null;
1032
1056
  }
1033
1057
  }
@@ -1763,8 +1787,7 @@ var init_webgpu_pipeline_layout = __esm({
1763
1787
  }
1764
1788
  mapShaderLayoutToBindGroupEntries() {
1765
1789
  const bindGroupEntries = [];
1766
- for (let i = 0; i < this.props.shaderLayout.bindings.length; i++) {
1767
- const binding = this.props.shaderLayout.bindings[i];
1790
+ for (const binding of this.props.shaderLayout.bindings) {
1768
1791
  const bindingTypeInfo = {};
1769
1792
  switch (binding.type) {
1770
1793
  case "uniform": {