@luma.gl/webgl 9.0.0-alpha.27 → 9.0.0-alpha.29

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 (54) hide show
  1. package/dist/adapter/helpers/get-shader-layout.d.ts +8 -5
  2. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  3. package/dist/adapter/helpers/get-shader-layout.js +59 -16
  4. package/dist/adapter/helpers/get-shader-layout.js.map +1 -1
  5. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts +12 -0
  6. package/dist/adapter/helpers/get-vertex-buffer-layout.d.ts.map +1 -0
  7. package/dist/adapter/helpers/get-vertex-buffer-layout.js +84 -0
  8. package/dist/adapter/helpers/get-vertex-buffer-layout.js.map +1 -0
  9. package/dist/adapter/objects/webgl-vertex-array-object.js +2 -2
  10. package/dist/adapter/objects/webgl-vertex-array-object.js.map +1 -1
  11. package/dist/adapter/resources/webgl-buffer.d.ts +13 -4
  12. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  13. package/dist/adapter/resources/webgl-buffer.js +23 -21
  14. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  15. package/dist/adapter/resources/webgl-external-texture.js.map +1 -1
  16. package/dist/adapter/resources/webgl-render-pipeline.d.ts +27 -4
  17. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  18. package/dist/adapter/resources/webgl-render-pipeline.js +25 -7
  19. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  20. package/dist/adapter/webgl-device.d.ts.map +1 -1
  21. package/dist/adapter/webgl-device.js +5 -2
  22. package/dist/adapter/webgl-device.js.map +1 -1
  23. package/dist/classic/buffer-with-accessor.d.ts +5 -15
  24. package/dist/classic/buffer-with-accessor.d.ts.map +1 -1
  25. package/dist/classic/buffer-with-accessor.js +25 -30
  26. package/dist/classic/buffer-with-accessor.js.map +1 -1
  27. package/dist/classic/copy-and-blit.d.ts.map +1 -1
  28. package/dist/classic/copy-and-blit.js +2 -2
  29. package/dist/classic/copy-and-blit.js.map +1 -1
  30. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  31. package/dist/context/debug/webgl-developer-tools.js +2 -1
  32. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  33. package/dist/context/parameters/webgl-parameter-tables.js +2 -2
  34. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -1
  35. package/dist/dist.dev.js +164 -83
  36. package/dist/index.cjs +207 -146
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +1 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist.min.js +22 -22
  42. package/package.json +5 -5
  43. package/src/adapter/helpers/get-shader-layout.ts +93 -33
  44. package/src/adapter/helpers/get-vertex-buffer-layout.ts +123 -0
  45. package/src/adapter/objects/webgl-vertex-array-object.ts +2 -2
  46. package/src/adapter/resources/webgl-buffer.ts +40 -41
  47. package/src/adapter/resources/webgl-external-texture.ts +1 -1
  48. package/src/adapter/resources/webgl-render-pipeline.ts +51 -35
  49. package/src/adapter/webgl-device.ts +4 -2
  50. package/src/classic/buffer-with-accessor.ts +42 -43
  51. package/src/classic/copy-and-blit.ts +2 -3
  52. package/src/context/debug/webgl-developer-tools.ts +8 -2
  53. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  54. package/src/index.ts +1 -1
package/dist/dist.dev.js CHANGED
@@ -55,11 +55,11 @@ var __exports__ = (() => {
55
55
  convertGLToTextureFormat: () => convertGLToTextureFormat,
56
56
  copyToTexture: () => copyToTexture,
57
57
  getParameters: () => getParameters,
58
- getProgramBindings: () => getProgramBindings,
59
58
  getShaderLayout: () => getShaderLayout,
60
59
  getWebGL2Context: () => getWebGL2Context,
61
60
  isWebGL: () => isWebGL,
62
61
  isWebGL2: () => isWebGL2,
62
+ mergeShaderLayout: () => mergeShaderLayout,
63
63
  polyfillContext: () => polyfillContext,
64
64
  popContextState: () => popContextState,
65
65
  pushContextState: () => pushContextState,
@@ -1970,8 +1970,8 @@ var __exports__ = (() => {
1970
1970
  function decodeVertexType(type) {
1971
1971
  const dataType = TYPE_MAP[type];
1972
1972
  const bytes = getDataTypeBytes(dataType);
1973
- const integer = !type.startsWith("float");
1974
1973
  const normalized = type.includes("norm");
1974
+ const integer = !normalized && !type.startsWith("float");
1975
1975
  const signed = type.startsWith("s");
1976
1976
  return {
1977
1977
  dataType: TYPE_MAP[type],
@@ -3703,8 +3703,8 @@ var __exports__ = (() => {
3703
3703
  [GL.PIXEL_PACK_BUFFER_BINDING]: GL.PIXEL_PACK_BUFFER,
3704
3704
  [GL.PIXEL_UNPACK_BUFFER_BINDING]: GL.PIXEL_UNPACK_BUFFER
3705
3705
  };
3706
- const target = bindingMap[key];
3707
- gl2.bindBuffer(target, value);
3706
+ const glTarget = bindingMap[key];
3707
+ gl2.bindBuffer(glTarget, value);
3708
3708
  };
3709
3709
  function isArray(array) {
3710
3710
  return Array.isArray(array) || ArrayBuffer.isView(array) && !(array instanceof DataView);
@@ -5828,8 +5828,14 @@ void main(void) {}`;
5828
5828
  // src/adapter/resources/webgl-buffer.ts
5829
5829
  var DEBUG_DATA_LENGTH = 10;
5830
5830
  var WEBGLBuffer = class extends Buffer2 {
5831
+ /** Target in OpenGL defines the type of buffer */
5832
+ /** Usage is a hint on how frequently the buffer will be updates */
5833
+ /** Index type is needed when issuing draw calls, so we pre-compute it */
5834
+ glIndexType = GL.UNSIGNED_SHORT;
5835
+ /** Number of bytes allocated on the GPU for this buffer */
5836
+ /** Number of bytes used */
5837
+ /** A partial CPU-side copy of the data in this buffer, for debugging purposes */
5831
5838
  debugData = null;
5832
- // accessor: {};
5833
5839
  constructor(device, props = {}) {
5834
5840
  super(device, props);
5835
5841
  this.device = device;
@@ -5841,8 +5847,9 @@ void main(void) {}`;
5841
5847
  ...this.props,
5842
5848
  data: typeof this.props.data
5843
5849
  });
5844
- this.target = this.props.target || getWebGLTarget(this.props.usage);
5845
- this.webglUsage = this.props.webglUsage || getWebGLUsage(this.props.usage);
5850
+ this.glTarget = getWebGLTarget(this.props.usage);
5851
+ this.glUsage = getWebGLUsage(this.props.usage);
5852
+ this.glIndexType = this.props.indexType === "uint32" ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT;
5846
5853
  this.debugData = null;
5847
5854
  if (props.data) {
5848
5855
  this._initWithData(props.data, props.byteOffset, props.byteLength);
@@ -5851,14 +5858,14 @@ void main(void) {}`;
5851
5858
  }
5852
5859
  }
5853
5860
  // PRIVATE METHODS
5854
- // Allocate a new buffer and initialize to contents of typed array
5861
+ /** Allocate a new buffer and initialize to contents of typed array */
5855
5862
  _initWithData(data, byteOffset = 0, byteLength = data.byteLength + byteOffset) {
5856
5863
  assert2(ArrayBuffer.isView(data));
5857
- const target = this._getWriteTarget();
5858
- this.gl.bindBuffer(target, this.handle);
5859
- this.gl.bufferData(target, byteLength, this.webglUsage);
5860
- this.gl.bufferSubData(target, byteOffset, data);
5861
- this.gl.bindBuffer(target, null);
5864
+ const glTarget = this._getWriteTarget();
5865
+ this.gl.bindBuffer(glTarget, this.handle);
5866
+ this.gl.bufferData(glTarget, byteLength, this.glUsage);
5867
+ this.gl.bufferSubData(glTarget, byteOffset, data);
5868
+ this.gl.bindBuffer(glTarget, null);
5862
5869
  this.debugData = data.slice(0, DEBUG_DATA_LENGTH);
5863
5870
  this.bytesUsed = byteLength;
5864
5871
  this.byteLength = byteLength;
@@ -5872,10 +5879,10 @@ void main(void) {}`;
5872
5879
  if (byteLength === 0) {
5873
5880
  data = new Float32Array(0);
5874
5881
  }
5875
- const target = this._getWriteTarget();
5876
- this.gl.bindBuffer(target, this.handle);
5877
- this.gl.bufferData(target, data, this.webglUsage);
5878
- this.gl.bindBuffer(target, null);
5882
+ const glTarget = this._getWriteTarget();
5883
+ this.gl.bindBuffer(glTarget, this.handle);
5884
+ this.gl.bufferData(glTarget, data, this.glUsage);
5885
+ this.gl.bindBuffer(glTarget, null);
5879
5886
  this.debugData = null;
5880
5887
  this.bytesUsed = byteLength;
5881
5888
  this.byteLength = byteLength;
@@ -5893,15 +5900,15 @@ void main(void) {}`;
5893
5900
  write(data, byteOffset = 0) {
5894
5901
  const srcOffset = 0;
5895
5902
  const byteLength = void 0;
5896
- const target = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.target;
5897
- this.gl.bindBuffer(target, this.handle);
5903
+ const glTarget = this.device.isWebGL2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
5904
+ this.gl.bindBuffer(glTarget, this.handle);
5898
5905
  if (srcOffset !== 0 || byteLength !== void 0) {
5899
5906
  this.device.assertWebGL2();
5900
- this.gl2.bufferSubData(target, byteOffset, data, srcOffset, byteLength);
5907
+ this.gl2.bufferSubData(glTarget, byteOffset, data, srcOffset, byteLength);
5901
5908
  } else {
5902
- this.gl.bufferSubData(target, byteOffset, data);
5909
+ this.gl.bufferSubData(glTarget, byteOffset, data);
5903
5910
  }
5904
- this.gl.bindBuffer(target, null);
5911
+ this.gl.bindBuffer(glTarget, null);
5905
5912
  }
5906
5913
  /** Read data from the buffer */
5907
5914
  async readAsync(byteOffset = 0, byteLength) {
@@ -5918,10 +5925,10 @@ void main(void) {}`;
5918
5925
  this.debugData = null;
5919
5926
  }
5920
5927
  _getWriteTarget() {
5921
- return this.target;
5928
+ return this.glTarget;
5922
5929
  }
5923
5930
  _getReadTarget() {
5924
- return this.target;
5931
+ return this.glTarget;
5925
5932
  }
5926
5933
  };
5927
5934
  function getWebGLTarget(usage) {
@@ -5946,7 +5953,7 @@ void main(void) {}`;
5946
5953
  if (usage & Buffer2.UNIFORM) {
5947
5954
  return GL.DYNAMIC_DRAW;
5948
5955
  }
5949
- return GL.DYNAMIC_DRAW;
5956
+ return GL.STATIC_DRAW;
5950
5957
  }
5951
5958
 
5952
5959
  // src/adapter/resources/webgl-sampler.ts
@@ -7367,7 +7374,7 @@ void main(void) {}`;
7367
7374
  return gl2.luma;
7368
7375
  }
7369
7376
  async function loadWebGLDeveloperTools() {
7370
- if (!globalThis.WebGLDebugUtils) {
7377
+ if (isBrowser() && !globalThis.WebGLDebugUtils) {
7371
7378
  globalThis.global = globalThis.global || globalThis;
7372
7379
  globalThis.global.module = {};
7373
7380
  await loadScript(WEBGL_DEBUG_CDN_URL);
@@ -7664,9 +7671,6 @@ void main(void) {}`;
7664
7671
  const bufferProps = {
7665
7672
  ...props
7666
7673
  };
7667
- if (bufferProps.offset) {
7668
- bufferProps.byteOffset = bufferProps.offset;
7669
- }
7670
7674
  return bufferProps;
7671
7675
  }
7672
7676
  var BufferWithAccessor = class extends WEBGLBuffer {
@@ -7709,11 +7713,11 @@ void main(void) {}`;
7709
7713
  };
7710
7714
  }
7711
7715
  props = checkProps("Buffer", props, PROP_CHECKS_INITIALIZE);
7712
- this.webglUsage = props.webglUsage || GL.STATIC_DRAW;
7716
+ this.glUsage = props.glUsage || GL.STATIC_DRAW;
7713
7717
  this.debugData = null;
7714
7718
  this.setAccessor(Object.assign({}, props, props.accessor));
7715
7719
  if (props.data) {
7716
- this._setData(props.data, props.offset, props.byteLength);
7720
+ this._setData(props.data, props.byteOffset, props.byteLength);
7717
7721
  } else {
7718
7722
  this._setByteLength(props.byteLength || 0);
7719
7723
  }
@@ -7769,15 +7773,15 @@ void main(void) {}`;
7769
7773
  } = options;
7770
7774
  const byteLength = options.byteLength || options.length;
7771
7775
  assert2(data);
7772
- const target = this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.target;
7773
- this.gl.bindBuffer(target, this.handle);
7776
+ const glTarget = this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
7777
+ this.gl.bindBuffer(glTarget, this.handle);
7774
7778
  if (srcOffset !== 0 || byteLength !== void 0) {
7775
7779
  assertWebGL2Context(this.gl);
7776
- this.gl.bufferSubData(this.target, offset, data, srcOffset, byteLength);
7780
+ this.gl.bufferSubData(this.glTarget, offset, data, srcOffset, byteLength);
7777
7781
  } else {
7778
- this.gl.bufferSubData(target, offset, data);
7782
+ this.gl.bufferSubData(glTarget, offset, data);
7779
7783
  }
7780
- this.gl.bindBuffer(target, null);
7784
+ this.gl.bindBuffer(glTarget, null);
7781
7785
  this.debugData = null;
7782
7786
  this._inferType(data);
7783
7787
  return this;
@@ -7852,35 +7856,35 @@ void main(void) {}`;
7852
7856
  */
7853
7857
  bind(options) {
7854
7858
  const {
7855
- target = this.target,
7859
+ glTarget = this.glTarget,
7856
7860
  // target for the bind operation
7857
7861
  index = this.accessor && this.accessor.index,
7858
7862
  // index = index of target (indexed bind point)
7859
7863
  offset = 0,
7860
7864
  size
7861
7865
  } = options || {};
7862
- if (target === GL.UNIFORM_BUFFER || target === GL.TRANSFORM_FEEDBACK_BUFFER) {
7866
+ if (glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER) {
7863
7867
  if (size !== void 0) {
7864
- this.gl2?.bindBufferRange(target, index, this.handle, offset, size);
7868
+ this.gl2?.bindBufferRange(glTarget, index, this.handle, offset, size);
7865
7869
  } else {
7866
7870
  assert2(offset === 0);
7867
- this.gl2?.bindBufferBase(target, index, this.handle);
7871
+ this.gl2?.bindBufferBase(glTarget, index, this.handle);
7868
7872
  }
7869
7873
  } else {
7870
- this.gl.bindBuffer(target, this.handle);
7874
+ this.gl.bindBuffer(glTarget, this.handle);
7871
7875
  }
7872
7876
  return this;
7873
7877
  }
7874
7878
  unbind(options) {
7875
7879
  const {
7876
- target = this.target,
7880
+ glTarget = this.glTarget,
7877
7881
  index = this.accessor && this.accessor.index
7878
7882
  } = options || {};
7879
- const isIndexedBuffer = target === GL.UNIFORM_BUFFER || target === GL.TRANSFORM_FEEDBACK_BUFFER;
7883
+ const isIndexedBuffer = glTarget === GL.UNIFORM_BUFFER || glTarget === GL.TRANSFORM_FEEDBACK_BUFFER;
7880
7884
  if (isIndexedBuffer) {
7881
- this.gl2?.bindBufferBase(target, index, null);
7885
+ this.gl2?.bindBufferBase(glTarget, index, null);
7882
7886
  } else {
7883
- this.gl.bindBuffer(target, null);
7887
+ this.gl.bindBuffer(glTarget, null);
7884
7888
  }
7885
7889
  return this;
7886
7890
  }
@@ -7911,7 +7915,7 @@ void main(void) {}`;
7911
7915
  this.trackDeallocatedMemory();
7912
7916
  const target = this._getTarget();
7913
7917
  this.gl.bindBuffer(target, this.handle);
7914
- this.gl.bufferData(target, byteLength, this.webglUsage);
7918
+ this.gl.bufferData(target, byteLength, this.glUsage);
7915
7919
  this.gl.bufferSubData(target, offset, data);
7916
7920
  this.gl.bindBuffer(target, null);
7917
7921
  this.debugData = data.slice(0, DEBUG_DATA_LENGTH2);
@@ -7926,18 +7930,17 @@ void main(void) {}`;
7926
7930
  return this;
7927
7931
  }
7928
7932
  // Allocate a GPU buffer of specified size.
7929
- _setByteLength(byteLength, webglUsage = this.webglUsage) {
7933
+ _setByteLength(byteLength) {
7930
7934
  assert2(byteLength >= 0);
7931
7935
  this.trackDeallocatedMemory();
7932
7936
  let data = byteLength;
7933
7937
  if (byteLength === 0) {
7934
7938
  data = new Float32Array(0);
7935
7939
  }
7936
- const target = this._getTarget();
7937
- this.gl.bindBuffer(target, this.handle);
7938
- this.gl.bufferData(target, data, webglUsage);
7939
- this.gl.bindBuffer(target, null);
7940
- this.webglUsage = webglUsage;
7940
+ const glTarget = this._getTarget();
7941
+ this.gl.bindBuffer(glTarget, this.handle);
7942
+ this.gl.bufferData(glTarget, data, this.glUsage);
7943
+ this.gl.bindBuffer(glTarget, null);
7941
7944
  this.debugData = null;
7942
7945
  this.bytesUsed = byteLength;
7943
7946
  this.byteLength = byteLength;
@@ -7947,7 +7950,7 @@ void main(void) {}`;
7947
7950
  // Binding a buffer for the first time locks the type
7948
7951
  // In WebGL2, use GL.COPY_WRITE_BUFFER to avoid locking the type
7949
7952
  _getTarget() {
7950
- return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.target;
7953
+ return this.gl.webgl2 ? GL.COPY_WRITE_BUFFER : this.glTarget;
7951
7954
  }
7952
7955
  _getAvailableElementCount(srcByteOffset) {
7953
7956
  const ArrayType = getTypedArrayFromGLType(this.accessor.type || GL.FLOAT, {
@@ -7967,9 +7970,9 @@ void main(void) {}`;
7967
7970
  }
7968
7971
  // RESOURCE METHODS
7969
7972
  getParameter(pname) {
7970
- this.gl.bindBuffer(this.target, this.handle);
7971
- const value = this.gl.getBufferParameter(this.target, pname);
7972
- this.gl.bindBuffer(this.target, null);
7973
+ this.gl.bindBuffer(this.glTarget, this.handle);
7974
+ const value = this.gl.getBufferParameter(this.glTarget, pname);
7975
+ this.gl.bindBuffer(this.glTarget, null);
7973
7976
  return value;
7974
7977
  }
7975
7978
  // DEPRECATIONS - v7.0
@@ -8315,12 +8318,12 @@ ${formattedLog}`)();
8315
8318
 
8316
8319
  // src/adapter/helpers/get-shader-layout.ts
8317
8320
  function getShaderLayout(gl2, program) {
8318
- const programBindings = getProgramBindings(gl2, program);
8319
8321
  const shaderLayout = {
8320
8322
  attributes: [],
8321
8323
  bindings: []
8322
8324
  };
8323
- for (const attribute of programBindings.attributes) {
8325
+ const attributes = readAttributeBindings(gl2, program);
8326
+ for (const attribute of attributes) {
8324
8327
  const size = Math.min(attribute.accessor.size, 4);
8325
8328
  const format = (
8326
8329
  // attribute.accessor.format ||
@@ -8333,7 +8336,8 @@ ${formattedLog}`)();
8333
8336
  stepMode: attribute.accessor.divisor === 1 ? "instance" : "vertex"
8334
8337
  });
8335
8338
  }
8336
- for (const uniformBlock of programBindings.uniformBlocks) {
8339
+ const uniformBlocks = readUniformBlocks(gl2, program);
8340
+ for (const uniformBlock of uniformBlocks) {
8337
8341
  const uniforms2 = uniformBlock.uniforms.map((uniform) => ({
8338
8342
  name: uniform.name,
8339
8343
  format: uniform.format,
@@ -8350,8 +8354,9 @@ ${formattedLog}`)();
8350
8354
  uniforms: uniforms2
8351
8355
  });
8352
8356
  }
8357
+ const uniforms = readUniformBindings(gl2, program);
8353
8358
  let textureUnit = 0;
8354
- for (const uniform of programBindings.uniforms) {
8359
+ for (const uniform of uniforms) {
8355
8360
  if (isSamplerUniform(uniform.type)) {
8356
8361
  const {
8357
8362
  viewDimension,
@@ -8368,24 +8373,65 @@ ${formattedLog}`)();
8368
8373
  textureUnit += 1;
8369
8374
  }
8370
8375
  }
8371
- const uniforms = programBindings.uniforms?.filter((uniform) => uniform.location !== null) || [];
8372
8376
  if (uniforms.length) {
8373
8377
  shaderLayout.uniforms = uniforms;
8374
8378
  }
8375
- if (programBindings.varyings?.length) {
8376
- shaderLayout.varyings = programBindings.varyings;
8379
+ const varyings = readVaryings(gl2, program);
8380
+ if (varyings?.length) {
8381
+ shaderLayout.varyings = varyings;
8377
8382
  }
8378
8383
  return shaderLayout;
8379
8384
  }
8380
- function getProgramBindings(gl2, program) {
8381
- const config = {
8382
- attributes: readAttributeBindings(gl2, program),
8383
- uniforms: readUniformBindings(gl2, program),
8384
- uniformBlocks: readUniformBlocks(gl2, program),
8385
- varyings: readVaryings(gl2, program)
8385
+ function mergeShaderLayout(baseLayout, overrideLayout) {
8386
+ const mergedLayout = {
8387
+ ...baseLayout,
8388
+ attributes: baseLayout.attributes.map((attribute) => ({
8389
+ ...attribute
8390
+ }))
8386
8391
  };
8387
- Object.seal(config);
8388
- return config;
8392
+ for (const attribute of overrideLayout?.attributes || []) {
8393
+ const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name);
8394
+ if (!baseAttribute) {
8395
+ log.warn(`shader layout attribute ${attribute.name} not present in shader`);
8396
+ } else {
8397
+ baseAttribute.format = attribute.format || baseAttribute.format;
8398
+ baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
8399
+ }
8400
+ }
8401
+ return mergedLayout;
8402
+ }
8403
+ function mergeBufferMap(baseLayout, bufferMap) {
8404
+ const mergedLayout = {
8405
+ ...baseLayout,
8406
+ attributes: baseLayout.attributes.map((attribute) => ({
8407
+ ...attribute
8408
+ }))
8409
+ };
8410
+ for (const bufferMapping of bufferMap) {
8411
+ switch (bufferMapping.type) {
8412
+ case "interleave":
8413
+ for (const attributeOverride of bufferMapping.attributes) {
8414
+ overrideShaderLayoutAttribute(mergedLayout, attributeOverride);
8415
+ }
8416
+ break;
8417
+ default:
8418
+ overrideShaderLayoutAttribute(mergedLayout, bufferMapping);
8419
+ }
8420
+ }
8421
+ return mergedLayout;
8422
+ }
8423
+ function overrideShaderLayoutAttribute(layout, attributeOverride) {
8424
+ const attribute = getAttributeFromLayout(layout, attributeOverride.name);
8425
+ if (attribute && attributeOverride.format) {
8426
+ attribute.format = attributeOverride.format;
8427
+ }
8428
+ }
8429
+ function getAttributeFromLayout(shaderLayout, name) {
8430
+ const attribute = shaderLayout.attributes.find((attr) => attr.name === name);
8431
+ if (!attribute) {
8432
+ log.warn(`shader layout attribute "${name}" not present in shader`);
8433
+ }
8434
+ return attribute || null;
8389
8435
  }
8390
8436
  function readAttributeBindings(gl2, program) {
8391
8437
  const attributes = [];
@@ -8731,14 +8777,14 @@ ${formattedLog}`)();
8731
8777
  // Set (bind) an elements buffer, for indexed rendering.
8732
8778
  // Must be a Buffer bound to GL.ELEMENT_ARRAY_BUFFER. Constants not supported
8733
8779
  setElementBuffer(elementBuffer = null, opts = {}) {
8734
- assert2(!elementBuffer || elementBuffer.target === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
8780
+ assert2(!elementBuffer || elementBuffer.glTarget === GL.ELEMENT_ARRAY_BUFFER, ERR_ELEMENTS);
8735
8781
  this.bind(() => {
8736
8782
  this.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, elementBuffer ? elementBuffer.handle : null);
8737
8783
  });
8738
8784
  }
8739
8785
  /** Set a location in vertex attributes array to a buffer, enables the location, sets divisor */
8740
8786
  setBuffer(location, buffer, accessor) {
8741
- if (buffer.target === GL.ELEMENT_ARRAY_BUFFER) {
8787
+ if (buffer.glTarget === GL.ELEMENT_ARRAY_BUFFER) {
8742
8788
  this.setElementBuffer(buffer, accessor);
8743
8789
  return;
8744
8790
  }
@@ -8871,11 +8917,23 @@ ${formattedLog}`)();
8871
8917
  // src/adapter/resources/webgl-render-pipeline.ts
8872
8918
  var LOG_PROGRAM_PERF_PRIORITY = 4;
8873
8919
  var WEBGLRenderPipeline = class extends RenderPipeline {
8874
- // configuration: ProgramConfiguration;
8875
- // Experimental flag to avoid deleting Program object while it is cached
8876
- varyings = null;
8920
+ /** The WebGL device that created this render pipeline */
8921
+ /** Handle to underlying WebGL program */
8922
+ /** vertex shader */
8923
+ /** fragment shader */
8924
+ /** The merged layout */
8925
+ /** The layout extracted from shader by WebGL introspection APIs */
8926
+ /** Buffer map describing buffer interleaving etc */
8927
+ /** Uniforms set on this model */
8877
8928
  uniforms = {};
8929
+ /** Bindings set on this model */
8878
8930
  bindings = {};
8931
+ /** Any constant attributes */
8932
+ constantAttributes = {};
8933
+ /** Index buffer is stored separately */
8934
+ /** WebGL varyings */
8935
+ varyings = null;
8936
+ /** Stores attribute bindings */
8879
8937
  _textureUniforms = {};
8880
8938
  _textureIndexCounter = 0;
8881
8939
  _uniformCount = 0;
@@ -8900,7 +8958,10 @@ ${formattedLog}`)();
8900
8958
  this.device.gl2?.transformFeedbackVaryings(this.handle, varyings, bufferMode);
8901
8959
  }
8902
8960
  this._compileAndLink();
8903
- this.layout = props.layout || getShaderLayout(this.device.gl, this.handle);
8961
+ this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
8962
+ this.layout = mergeShaderLayout(this.introspectedLayout, props.layout);
8963
+ this.bufferMap = props.bufferMap || [];
8964
+ this.layout = mergeBufferMap(this.layout, this.bufferMap);
8904
8965
  this.vertexArrayObject = new WEBGLVertexArrayObject(this.device);
8905
8966
  }
8906
8967
  destroy() {
@@ -8912,7 +8973,7 @@ ${formattedLog}`)();
8912
8973
  setIndexBuffer(indexBuffer) {
8913
8974
  const webglBuffer = cast(indexBuffer);
8914
8975
  this.vertexArrayObject.setElementBuffer(webglBuffer);
8915
- this._indexBuffer = indexBuffer;
8976
+ this._indexBuffer = webglBuffer;
8916
8977
  }
8917
8978
  /** @todo needed for portable model */
8918
8979
  setAttributes(attributes) {
@@ -8959,6 +9020,7 @@ ${formattedLog}`)();
8959
9020
  }
8960
9021
  this.vertexArrayObject.setConstant(attribute.location, value);
8961
9022
  }
9023
+ Object.assign(this.constantAttributes, attributes);
8962
9024
  }
8963
9025
  /**
8964
9026
  * Bindings include: textures, samplers and uniform buffers
@@ -9014,7 +9076,7 @@ ${formattedLog}`)();
9014
9076
  } = options;
9015
9077
  const drawMode = getDrawMode(this.props.topology);
9016
9078
  const isIndexed = Boolean(this._indexBuffer);
9017
- const indexType = this._indexBuffer?.props.indexType === "uint16" ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
9079
+ const indexType = this._indexBuffer?.glIndexType;
9018
9080
  const isInstanced = Number(options.instanceCount) > 0;
9019
9081
  if (!this._areTexturesRenderable() || options.vertexCount === 0) {
9020
9082
  return false;
@@ -9028,6 +9090,7 @@ ${formattedLog}`)();
9028
9090
  }
9029
9091
  this._applyBindings();
9030
9092
  this._applyUniforms();
9093
+ this._applyConstantAttributes();
9031
9094
  const webglRenderPass = renderPass;
9032
9095
  withDeviceParameters(this.device, this.props.parameters, () => {
9033
9096
  withGLParameters(this.device, webglRenderPass.glParameters, () => {
@@ -9161,6 +9224,21 @@ ${formattedLog}`)();
9161
9224
  }
9162
9225
  }
9163
9226
  }
9227
+ /**
9228
+ * Constant attributes are only supported in WebGL, not in WebGPU
9229
+ * Any attribute that is disabled in the current vertex array object
9230
+ * is read from the context's global constant value for that attribute location.
9231
+ */
9232
+ _applyConstantAttributes() {
9233
+ for (const [name, value] of Object.entries(this.constantAttributes)) {
9234
+ const attribute = getAttributeLayout(this.layout, name);
9235
+ if (!attribute) {
9236
+ log.warn(`Ignoring constant value supplied for unknown attribute "${name}" in pipeline "${this.id}"`)();
9237
+ continue;
9238
+ }
9239
+ this.vertexArrayObject.setConstant(attribute.location, value);
9240
+ }
9241
+ }
9164
9242
  };
9165
9243
  function getDrawMode(topology) {
9166
9244
  switch (topology) {
@@ -9499,10 +9577,13 @@ ${formattedLog}`)();
9499
9577
  if (typeof props.canvas === "string") {
9500
9578
  await CanvasContext.pageLoaded;
9501
9579
  }
9502
- if (props.debug) {
9580
+ if (log.get("debug") || props.debug) {
9503
9581
  await loadWebGLDeveloperTools();
9504
9582
  }
9505
- if (props.spector) {
9583
+ const {
9584
+ spector: spector2
9585
+ } = props;
9586
+ if (log.get("spector") || spector2) {
9506
9587
  await loadSpectorJS();
9507
9588
  }
9508
9589
  log.probe(LOG_LEVEL2 + 1, "DOM is loaded")();
@@ -9920,7 +10001,7 @@ ${formattedLog}`)();
9920
10001
  });
9921
10002
  }
9922
10003
  target.bind({
9923
- target: GL.PIXEL_PACK_BUFFER
10004
+ glTarget: GL.PIXEL_PACK_BUFFER
9924
10005
  });
9925
10006
  withParameters(gl2, {
9926
10007
  framebuffer
@@ -9928,7 +10009,7 @@ ${formattedLog}`)();
9928
10009
  gl2.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, targetByteOffset);
9929
10010
  });
9930
10011
  target.unbind({
9931
- target: GL.PIXEL_PACK_BUFFER
10012
+ glTarget: GL.PIXEL_PACK_BUFFER
9932
10013
  });
9933
10014
  if (deleteFramebuffer) {
9934
10015
  framebuffer.destroy();