@luma.gl/webgl 9.2.0-alpha.1 → 9.2.0-alpha.3

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 (72) hide show
  1. package/dist/adapter/converters/sampler-parameters.js +13 -2
  2. package/dist/adapter/converters/sampler-parameters.js.map +1 -1
  3. package/dist/adapter/converters/webgl-shadertypes.d.ts.map +1 -1
  4. package/dist/adapter/converters/webgl-shadertypes.js +1 -2
  5. package/dist/adapter/converters/webgl-shadertypes.js.map +1 -1
  6. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
  7. package/dist/adapter/converters/webgl-texture-table.js +15 -11
  8. package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
  9. package/dist/adapter/converters/webgl-vertex-formats.d.ts.map +1 -1
  10. package/dist/adapter/converters/webgl-vertex-formats.js +1 -2
  11. package/dist/adapter/converters/webgl-vertex-formats.js.map +1 -1
  12. package/dist/adapter/helpers/webgl-texture-utils.d.ts +0 -217
  13. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  14. package/dist/adapter/helpers/webgl-texture-utils.js +3 -3
  15. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -1
  16. package/dist/adapter/resources/webgl-buffer.d.ts +7 -7
  17. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  18. package/dist/adapter/resources/webgl-buffer.js +24 -15
  19. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  20. package/dist/adapter/resources/webgl-command-buffer.d.ts +2 -1
  21. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  22. package/dist/adapter/resources/webgl-command-buffer.js +1 -0
  23. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
  24. package/dist/adapter/resources/webgl-framebuffer.d.ts +2 -2
  25. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  26. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
  27. package/dist/adapter/resources/webgl-query-set.d.ts +2 -2
  28. package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
  29. package/dist/adapter/resources/webgl-query-set.js.map +1 -1
  30. package/dist/adapter/resources/webgl-render-pass.d.ts +1 -0
  31. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  32. package/dist/adapter/resources/webgl-render-pass.js +1 -0
  33. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  34. package/dist/adapter/resources/webgl-render-pipeline.d.ts +2 -2
  35. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  36. package/dist/adapter/resources/webgl-render-pipeline.js +2 -1
  37. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  38. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  39. package/dist/adapter/resources/webgl-texture.js +8 -5
  40. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  41. package/dist/adapter/resources/webgl-vertex-array.d.ts +1 -1
  42. package/dist/adapter/webgl-adapter.d.ts +2 -1
  43. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  44. package/dist/adapter/webgl-adapter.js +35 -25
  45. package/dist/adapter/webgl-adapter.js.map +1 -1
  46. package/dist/adapter/webgl-device.d.ts +12 -4
  47. package/dist/adapter/webgl-device.d.ts.map +1 -1
  48. package/dist/adapter/webgl-device.js +60 -17
  49. package/dist/adapter/webgl-device.js.map +1 -1
  50. package/dist/context/debug/webgl-developer-tools.js +1 -0
  51. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  52. package/dist/dist.dev.js +124 -57
  53. package/dist/dist.min.js +2 -2
  54. package/dist/index.cjs +117 -57
  55. package/dist/index.cjs.map +2 -2
  56. package/package.json +4 -4
  57. package/src/adapter/converters/sampler-parameters.ts +13 -2
  58. package/src/adapter/converters/webgl-shadertypes.ts +1 -2
  59. package/src/adapter/converters/webgl-texture-table.ts +20 -14
  60. package/src/adapter/converters/webgl-vertex-formats.ts +1 -2
  61. package/src/adapter/helpers/webgl-texture-utils.ts +3 -224
  62. package/src/adapter/resources/webgl-buffer.ts +38 -20
  63. package/src/adapter/resources/webgl-command-buffer.ts +4 -3
  64. package/src/adapter/resources/webgl-command-encoder.ts +1 -1
  65. package/src/adapter/resources/webgl-framebuffer.ts +2 -2
  66. package/src/adapter/resources/webgl-query-set.ts +2 -2
  67. package/src/adapter/resources/webgl-render-pass.ts +1 -0
  68. package/src/adapter/resources/webgl-render-pipeline.ts +7 -3
  69. package/src/adapter/resources/webgl-texture.ts +8 -5
  70. package/src/adapter/webgl-adapter.ts +36 -28
  71. package/src/adapter/webgl-device.ts +85 -31
  72. package/src/context/debug/webgl-developer-tools.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma.gl/webgl",
3
- "version": "9.2.0-alpha.1",
3
+ "version": "9.2.0-alpha.3",
4
4
  "description": "WebGL2 adapter for the luma.gl core API",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,12 +40,12 @@
40
40
  "prepublishOnly": "npm run build-minified-bundle && npm run build-dev-bundle"
41
41
  },
42
42
  "peerDependencies": {
43
- "@luma.gl/core": "9.2.0-alpha.0"
43
+ "@luma.gl/core": "9.2.0-alpha.1"
44
44
  },
45
45
  "dependencies": {
46
- "@luma.gl/constants": "9.2.0-alpha.1",
46
+ "@luma.gl/constants": "9.2.0-alpha.3",
47
47
  "@math.gl/types": "^4.1.0",
48
48
  "@probe.gl/env": "^4.0.8"
49
49
  },
50
- "gitHead": "d6d2f791f2ce96f4b5acb68e05faea62c35440fb"
50
+ "gitHead": "16fcea2620b1fd45cb744de730c2622a724cc15b"
51
51
  }
@@ -99,8 +99,19 @@ function convertMinFilterMode(
99
99
  case 'none':
100
100
  return convertMaxFilterMode(minFilter);
101
101
  case 'nearest':
102
- return minFilter === 'nearest' ? GL.NEAREST_MIPMAP_NEAREST : GL.NEAREST_MIPMAP_LINEAR;
102
+ switch (minFilter) {
103
+ case 'nearest':
104
+ return GL.NEAREST_MIPMAP_NEAREST;
105
+ case 'linear':
106
+ return GL.LINEAR_MIPMAP_NEAREST;
107
+ }
108
+ break;
103
109
  case 'linear':
104
- return minFilter === 'nearest' ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR_MIPMAP_LINEAR;
110
+ switch (minFilter) {
111
+ case 'nearest':
112
+ return GL.NEAREST_MIPMAP_LINEAR;
113
+ case 'linear':
114
+ return GL.LINEAR_MIPMAP_LINEAR;
115
+ }
105
116
  }
106
117
  }
@@ -48,10 +48,9 @@ export function getVertexFormatFromGL(type: GLDataType, components: 1 | 2 | 3 |
48
48
  const base = getVertexTypeFromGL(type);
49
49
  // prettier-ignore
50
50
  switch (components) {
51
- // @ts-expect-error TODO deal with lack of formats
52
51
  case 1: return base;
53
52
  case 2: return `${base}x2`;
54
- // @ts-expect-error TODO deal with lack of formats
53
+ // @ts-expect-error - deal with lack of "unaligned" formats
55
54
  case 3: return `${base}x3`;
56
55
  case 4: return `${base}x4`;
57
56
  }
@@ -8,7 +8,7 @@ import type {
8
8
  TextureFormatCapabilities,
9
9
  DeviceTextureFormatCapabilities
10
10
  } from '@luma.gl/core';
11
- import {getTextureFormatInfo} from '@luma.gl/core';
11
+ import {textureFormatDecoder} from '@luma.gl/core';
12
12
  import {GL, GLPixelType, GLExtensions, GLTexelDataFormat} from '@luma.gl/constants';
13
13
  import {getWebGLExtension} from '../../context/helpers/webgl-extensions';
14
14
  import {getGLFromVertexType} from './webgl-vertex-formats';
@@ -112,8 +112,8 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
112
112
  'r16uint': {gl: GL.R16UI, rb: true},
113
113
  'r16sint': {gl: GL.R16I, rb: true},
114
114
  'r16float': {gl: GL.R16F, rb: true},
115
- 'r16unorm-webgl': {gl: GL.R16_EXT, rb: true},
116
- 'r16snorm-webgl': {gl: GL.R16_SNORM_EXT},
115
+ 'r16unorm': {gl: GL.R16_EXT, rb: true},
116
+ 'r16snorm': {gl: GL.R16_SNORM_EXT},
117
117
 
118
118
  // Packed 16-bit formats
119
119
  'rgba4unorm-webgl': {gl: GL.RGBA4, rb: true},
@@ -124,7 +124,7 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
124
124
  'rgb8unorm-webgl': {gl: GL.RGB8},
125
125
  'rgb8snorm-webgl': {gl: GL.RGB8_SNORM},
126
126
 
127
- // 32-bit formats
127
+ // 32-bit formats
128
128
  'rgba8unorm': {gl: GL.RGBA8},
129
129
  'rgba8unorm-srgb': {gl: GL.SRGB8_ALPHA8},
130
130
  'rgba8snorm': {gl: GL.RGBA8_SNORM},
@@ -137,8 +137,8 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
137
137
  'rg16uint': {gl: GL.RG16UI},
138
138
  'rg16sint': {gl: GL.RG16I},
139
139
  'rg16float': {gl: GL.RG16F, rb: true},
140
- 'rg16unorm-webgl': {gl: GL.RG16_EXT},
141
- 'rg16snorm-webgl': {gl: GL.RG16_SNORM_EXT},
140
+ 'rg16unorm': {gl: GL.RG16_EXT},
141
+ 'rg16snorm': {gl: GL.RG16_SNORM_EXT},
142
142
 
143
143
  'r32uint': {gl: GL.R32UI, rb: true},
144
144
  'r32sint': {gl: GL.R32I, rb: true},
@@ -149,7 +149,7 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
149
149
  'rg11b10ufloat': {gl: GL.R11F_G11F_B10F, rb: true},
150
150
  'rgb10a2unorm': {gl: GL.RGB10_A2, rb: true},
151
151
  'rgb10a2uint': {gl: GL.RGB10_A2UI, rb: true},
152
-
152
+
153
153
  // 48-bit formats
154
154
  'rgb16unorm-webgl': {gl: GL.RGB16_EXT}, // rgb not renderable
155
155
  'rgb16snorm-webgl': {gl: GL.RGB16_SNORM_EXT}, // rgb not renderable
@@ -161,12 +161,12 @@ export const WEBGL_TEXTURE_FORMATS: Record<TextureFormat, WebGLFormatInfo> = {
161
161
  'rgba16uint': {gl: GL.RGBA16UI, rb: true},
162
162
  'rgba16sint': {gl: GL.RGBA16I, rb: true},
163
163
  'rgba16float': {gl: GL.RGBA16F},
164
- 'rgba16unorm-webgl': {gl: GL.RGBA16_EXT, rb: true},
165
- 'rgba16snorm-webgl': {gl: GL.RGBA16_SNORM_EXT},
164
+ 'rgba16unorm': {gl: GL.RGBA16_EXT, rb: true},
165
+ 'rgba16snorm': {gl: GL.RGBA16_SNORM_EXT},
166
166
 
167
167
  // 96-bit formats (deprecated!)
168
168
  'rgb32float-webgl': {gl: GL.RGB32F, x: EXT_color_buffer_float, dataFormat: GL.RGB, types: [GL.FLOAT]},
169
-
169
+
170
170
  // 128-bit formats
171
171
  'rgba32uint': {gl: GL.RGBA32UI, rb: true},
172
172
  'rgba32sint': {gl: GL.RGBA32I, rb: true},
@@ -332,7 +332,13 @@ export function getTextureFormatWebGL(format: TextureFormat): {
332
332
  } {
333
333
  const formatData = WEBGL_TEXTURE_FORMATS[format];
334
334
  const webglFormat = convertTextureFormatToGL(format);
335
- const decoded = getTextureFormatInfo(format);
335
+ const decoded = textureFormatDecoder.getInfo(format);
336
+
337
+ if (decoded.compressed) {
338
+ // TODO: Unclear whether this is always valid, this may be why ETC2 RGBA8 fails.
339
+ formatData.dataFormat = webglFormat as GLTexelDataFormat;
340
+ }
341
+
336
342
  return {
337
343
  internalFormat: webglFormat,
338
344
  format:
@@ -349,7 +355,7 @@ export function getTextureFormatWebGL(format: TextureFormat): {
349
355
  export function getDepthStencilAttachmentWebGL(
350
356
  format: TextureFormat
351
357
  ): GL.DEPTH_ATTACHMENT | GL.STENCIL_ATTACHMENT | GL.DEPTH_STENCIL_ATTACHMENT {
352
- const formatInfo = getTextureFormatInfo(format);
358
+ const formatInfo = textureFormatDecoder.getInfo(format);
353
359
  switch (formatInfo.attachment) {
354
360
  case 'depth':
355
361
  return GL.DEPTH_ATTACHMENT;
@@ -364,8 +370,8 @@ export function getDepthStencilAttachmentWebGL(
364
370
 
365
371
  /** TODO - VERY roundabout legacy way of calculating bytes per pixel */
366
372
  export function getTextureFormatBytesPerPixel(format: TextureFormat): number {
367
- const formatInfo = getTextureFormatInfo(format);
368
- return formatInfo.bytesPerPixel as number;
373
+ const formatInfo = textureFormatDecoder.getInfo(format);
374
+ return formatInfo.bytesPerPixel;
369
375
  }
370
376
 
371
377
  // DATA TYPE HELPERS
@@ -20,10 +20,9 @@ export function getVertexFormatFromGL(type: GLDataType, components: 1 | 2 | 3 |
20
20
  const base = getVertexTypeFromGL(type);
21
21
  // prettier-ignore
22
22
  switch (components) {
23
- // @ts-expect-error TODO deal with lack of formats
24
23
  case 1: return base;
25
24
  case 2: return `${base}x2`;
26
- // @ts-expect-error TODO deal with lack of formats
25
+ // @ts-expect-error TODO deal with lack of "unaligned" formats
27
26
  case 3: return `${base}x3`;
28
27
  case 4: return `${base}x4`;
29
28
  }
@@ -5,7 +5,7 @@
5
5
  // @ts-nocheck This file will be deleted in upcoming refactor
6
6
 
7
7
  import type {Buffer, Texture, FramebufferProps} from '@luma.gl/core';
8
- import {Framebuffer, getTypedArrayFromDataType, getDataTypeFromTypedArray} from '@luma.gl/core';
8
+ import {Framebuffer, getTypedArrayConstructor, getDataType} from '@luma.gl/core';
9
9
  import {
10
10
  GL,
11
11
  GLTextureTarget,
@@ -156,227 +156,6 @@ export function getWebGLCubeFaceTarget(
156
156
  ): GLTextureTarget | GLTextureCubeMapTarget {
157
157
  return dimension === 'cube' ? GL.TEXTURE_CUBE_MAP_POSITIVE_X + level : glTarget;
158
158
  }
159
-
160
- // texImage methods
161
-
162
- /**
163
- * Clear a texture mip level.
164
- * Wrapper for the messy WebGL texture API
165
- *
166
- export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextureOptions): void {
167
- const {dimension, width, height, depth = 0, mipLevel = 0} = options;
168
- const {glInternalFormat, glFormat, glType, compressed} = options;
169
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
170
-
171
- switch (dimension) {
172
- case '2d-array':
173
- case '3d':
174
- if (compressed) {
175
- // prettier-ignore
176
- gl.compressedTexImage3D(glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, null);
177
- } else {
178
- // prettier-ignore
179
- gl.texImage3D( glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, glFormat, glType, null);
180
- }
181
- break;
182
-
183
- case '2d':
184
- case 'cube':
185
- if (compressed) {
186
- // prettier-ignore
187
- gl.compressedTexImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, null);
188
- } else {
189
- // prettier-ignore
190
- gl.texImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, glFormat, glType, null);
191
- }
192
- break;
193
-
194
- default:
195
- throw new Error(dimension);
196
- }
197
- }
198
- */
199
-
200
- /**
201
- * Set a texture mip level to the contents of an external image.
202
- * Wrapper for the messy WebGL texture API
203
- * @note Corresponds to WebGPU device.queue.copyExternalImageToTexture()
204
- *
205
- export function setMipLevelFromExternalImage(
206
- gl: WebGL2RenderingContext,
207
- image: ExternalImage,
208
- options: WebGLSetTextureOptions
209
- ): void {
210
- const {dimension, width, height, depth = 0, level = 0} = options;
211
- const {glInternalFormat, glType} = options;
212
-
213
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
214
-
215
- // TODO - we can't change texture width (due to WebGPU limitations) -
216
- // and the width/heigh of an external image is implicit, so why do we need to extract it?
217
- // So what width height do we supply? The image size or the texture size?
218
- // const {width, height} = Texture.getExternalImageSize(image);
219
-
220
- switch (dimension) {
221
- case '2d-array':
222
- case '3d':
223
- // prettier-ignore
224
- gl.texImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, glInternalFormat, glType, image);
225
- break;
226
-
227
- case '2d':
228
- case 'cube':
229
- // prettier-ignore
230
- gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glInternalFormat, glType, image);
231
- break;
232
-
233
- default:
234
- throw new Error(dimension);
235
- }
236
- }
237
-
238
- /**
239
- * Set a texture mip level from CPU memory
240
- * Wrapper for the messy WebGL texture API
241
- * @note Not available (directly) in WebGPU
242
- *
243
- export function setMipLevelFromTypedArray(
244
- gl: WebGL2RenderingContext,
245
- data: TypedArray,
246
- parameters: {},
247
- options: {
248
- dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
249
- height: number;
250
- width: number;
251
- depth?: number;
252
- level?: number;
253
- offset?: number;
254
- glTarget: GLTextureTarget;
255
- glInternalFormat: GL;
256
- glFormat: GL;
257
- glType: GL;
258
- compressed?: boolean;
259
- }
260
- ): void {
261
- const {dimension, width, height, depth = 0, level = 0, offset = 0} = options;
262
- const {glInternalFormat, glFormat, glType, compressed} = options;
263
-
264
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
265
-
266
- withGLParameters(gl, parameters, () => {
267
- switch (dimension) {
268
- case '2d-array':
269
- case '3d':
270
- if (compressed) {
271
- // prettier-ignore
272
- gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, data);
273
- } else {
274
- // prettier-ignore
275
- gl.texImage3D( glTarget, level, glInternalFormat, width, height, depth, BORDER, glFormat, glType, data);
276
- }
277
- break;
278
-
279
- case '2d':
280
- if (compressed) {
281
- // prettier-ignore
282
- gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, data);
283
- } else {
284
- // prettier-ignore
285
- gl.texImage2D( glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, data, offset);
286
- }
287
- break;
288
-
289
- default:
290
- throw new Error(dimension);
291
- }
292
- });
293
- }
294
-
295
- /**
296
- * Set a texture level from CPU memory
297
- * @note Not available (directly) in WebGPU
298
- _setMipLevelFromTypedArray(
299
- depth: number,
300
- level: number,
301
- data: TextureLevelData,
302
- offset = 0,
303
- parameters
304
- ): void {
305
- withGLParameters(this.gl, parameters, () => {
306
- switch (this.props.dimension) {
307
- case '2d-array':
308
- case '3d':
309
- if (this.compressed) {
310
- // prettier-ignore
311
- this.device.gl.compressedTexImage3D(this.glTarget, level, this.glInternalFormat, data.width, data.height, depth, BORDER, data.data);
312
- } else {
313
- // prettier-ignore
314
- this.gl.texImage3D( this.glTarget, level, this.glInternalFormat, this.width, this.height, depth, BORDER, this.glFormat, this.glType, data.data);
315
- }
316
- break;
317
-
318
- case '2d':
319
- if (this.compressed) {
320
- // prettier-ignore
321
- this.device.gl.compressedTexImage2D(this.glTarget, level, this.glInternalFormat, data.width, data.height, BORDER, data.data);
322
- } else {
323
- // prettier-ignore
324
- this.device.gl.texImage2D( this.glTarget, level, this.glInternalFormat, this.width, this.height, BORDER, this.glFormat, this.glType, data.data, offset);
325
- }
326
- break;
327
-
328
- default:
329
- throw new Error(this.props.dimension);
330
- }
331
- });
332
- }
333
-
334
- * Set a texture level from a GPU buffer
335
- *
336
- export function setMipLevelFromGPUBuffer(
337
- gl: WebGL2RenderingContext,
338
- buffer: Buffer,
339
- options: WebGLSetTextureOptions
340
- ): void {
341
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
342
- const {glInternalFormat, glFormat, glType, compressed} = options;
343
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
344
-
345
- const webglBuffer = buffer as WEBGLBuffer;
346
- const imageSize = buffer.byteLength;
347
-
348
- // In WebGL the source buffer is not a parameter. Instead it needs to be bound to a special bind point
349
- gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, webglBuffer.handle);
350
-
351
- switch (dimension) {
352
- case '2d-array':
353
- case '3d':
354
- if (compressed) {
355
- // prettier-ignore
356
- gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, imageSize, byteOffset);
357
- } else {
358
- // prettier-ignore
359
- gl.texImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, glFormat, glType, byteOffset);
360
- }
361
- break;
362
-
363
- case '2d':
364
- if (compressed) {
365
- // prettier-ignore
366
- gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, imageSize, byteOffset);
367
- } else {
368
- // prettier-ignore
369
- gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, byteOffset);
370
- }
371
- break;
372
-
373
- default:
374
- throw new Error(dimension);
375
- }
376
-
377
- gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
378
- }
379
- */
380
159
  export type ReadPixelsToArrayOptions = {
381
160
  sourceX?: number;
382
161
  sourceY?: number;
@@ -453,7 +232,7 @@ export function readPixelsToArray(
453
232
  target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
454
233
 
455
234
  // Pixel array available, if necessary, deduce type from it.
456
- const signedType = getDataTypeFromTypedArray(target);
235
+ const signedType = getDataType(target);
457
236
  sourceType = sourceType || convertDataTypeToGLDataType(signedType);
458
237
 
459
238
  // Note: luma.gl overrides bindFramebuffer so that we can reliably restore the previous framebuffer (this is the only function for which we do that)
@@ -705,7 +484,7 @@ function getPixelArray(
705
484
  // Allocate pixel array if not already available, using supplied type
706
485
  glType ||= GL.UNSIGNED_BYTE;
707
486
  const shaderType = convertGLDataTypeToDataType(glType);
708
- const ArrayType = getTypedArrayFromDataType(shaderType);
487
+ const ArrayType = getTypedArrayConstructor(shaderType);
709
488
  const components = glFormatToComponents(glFormat);
710
489
  // TODO - check for composite type (components = 1).
711
490
  return new ArrayType(width * height * components) as Uint8Array | Uint16Array | Float32Array;
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {BufferProps} from '@luma.gl/core';
5
+ import type {BufferMapCallback, BufferProps} from '@luma.gl/core';
6
6
  import {Buffer} from '@luma.gl/core';
7
7
  import {GL} from '@luma.gl/constants';
8
8
  import {WebGLDevice} from '../webgl-device';
@@ -52,7 +52,16 @@ export class WEBGLBuffer extends Buffer {
52
52
  }
53
53
  }
54
54
 
55
- // PRIVATE METHODS
55
+ override destroy(): void {
56
+ if (!this.destroyed && this.handle) {
57
+ this.removeStats();
58
+ this.trackDeallocatedMemory();
59
+ this.gl.deleteBuffer(this.handle);
60
+ this.destroyed = true;
61
+ // @ts-expect-error
62
+ this.handle = null;
63
+ }
64
+ }
56
65
 
57
66
  /** Allocate a new buffer and initialize to contents of typed array */
58
67
  _initWithData(
@@ -102,18 +111,8 @@ export class WEBGLBuffer extends Buffer {
102
111
  return this;
103
112
  }
104
113
 
105
- override destroy(): void {
106
- if (!this.destroyed && this.handle) {
107
- this.removeStats();
108
- this.trackDeallocatedMemory();
109
- this.gl.deleteBuffer(this.handle);
110
- this.destroyed = true;
111
- // @ts-expect-error
112
- this.handle = null;
113
- }
114
- }
115
-
116
- override write(data: ArrayBufferView, byteOffset: number = 0): void {
114
+ write(data: ArrayBufferLike | ArrayBufferView, byteOffset: number = 0): void {
115
+ const dataView = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
117
116
  const srcOffset = 0;
118
117
  const byteLength = undefined; // data.byteLength;
119
118
 
@@ -123,22 +122,41 @@ export class WEBGLBuffer extends Buffer {
123
122
  this.gl.bindBuffer(glTarget, this.handle);
124
123
  // WebGL2: subData supports additional srcOffset and length parameters
125
124
  if (srcOffset !== 0 || byteLength !== undefined) {
126
- this.gl.bufferSubData(glTarget, byteOffset, data, srcOffset, byteLength);
125
+ this.gl.bufferSubData(glTarget, byteOffset, dataView, srcOffset, byteLength);
127
126
  } else {
128
- this.gl.bufferSubData(glTarget, byteOffset, data);
127
+ this.gl.bufferSubData(glTarget, byteOffset, dataView);
129
128
  }
130
129
  this.gl.bindBuffer(glTarget, null);
131
130
 
132
131
  this._setDebugData(data, byteOffset, data.byteLength);
133
132
  }
134
133
 
135
- /** Asynchronously read data from the buffer */
136
- override async readAsync(byteOffset = 0, byteLength?: number): Promise<Uint8Array> {
134
+ async mapAndWriteAsync(
135
+ callback: BufferMapCallback<void>,
136
+ byteOffset: number = 0,
137
+ byteLength: number = this.byteLength - byteOffset
138
+ ): Promise<void> {
139
+ const arrayBuffer = new ArrayBuffer(byteLength);
140
+ // eslint-disable-next-line @typescript-eslint/await-thenable
141
+ await callback(arrayBuffer, 'copied');
142
+ this.write(arrayBuffer, byteOffset);
143
+ }
144
+
145
+ async readAsync(byteOffset = 0, byteLength?: number): Promise<Uint8Array<ArrayBuffer>> {
137
146
  return this.readSyncWebGL(byteOffset, byteLength);
138
147
  }
139
148
 
140
- /** Synchronously read data from the buffer. WebGL only. */
141
- override readSyncWebGL(byteOffset = 0, byteLength?: number): Uint8Array {
149
+ async mapAndReadAsync<T>(
150
+ callback: BufferMapCallback<T>,
151
+ byteOffset = 0,
152
+ byteLength?: number
153
+ ): Promise<T> {
154
+ const data = await this.readAsync(byteOffset, byteLength);
155
+ // eslint-disable-next-line @typescript-eslint/await-thenable
156
+ return await callback(data.buffer, 'copied');
157
+ }
158
+
159
+ readSyncWebGL(byteOffset = 0, byteLength?: number): Uint8Array<ArrayBuffer> {
142
160
  byteLength = byteLength ?? this.byteLength - byteOffset;
143
161
  const data = new Uint8Array(byteLength);
144
162
  const dstOffset = 0;
@@ -8,7 +8,7 @@ import type {
8
8
  CopyTextureToBufferOptions,
9
9
  CopyTextureToTextureOptions
10
10
  // ClearTextureOptions,
11
- // ReadTextureOptions
11
+ // TextureReadOptions
12
12
  } from '@luma.gl/core';
13
13
  import {CommandBuffer, Texture, Framebuffer} from '@luma.gl/core';
14
14
  import {
@@ -53,7 +53,7 @@ type ClearTextureCommand = {
53
53
 
54
54
  type ReadTextureCommand = {
55
55
  name: 'read-texture';
56
- options: {}; // ReadTextureOptions;
56
+ options: {}; // TextureReadOptions;
57
57
  };
58
58
 
59
59
  type Command =
@@ -65,7 +65,8 @@ type Command =
65
65
  | ReadTextureCommand;
66
66
 
67
67
  export class WEBGLCommandBuffer extends CommandBuffer {
68
- device: WebGLDevice;
68
+ readonly device: WebGLDevice;
69
+ readonly handle = null;
69
70
  commands: Command[] = [];
70
71
 
71
72
  constructor(device: WebGLDevice) {
@@ -14,7 +14,7 @@ import type {
14
14
  CopyTextureToBufferOptions,
15
15
  CopyTextureToTextureOptions
16
16
  // ClearTextureOptions,
17
- // ReadTextureOptions,
17
+ // TextureReadOptions,
18
18
  } from '@luma.gl/core';
19
19
 
20
20
  import {WEBGLCommandBuffer} from './webgl-command-buffer';
@@ -14,9 +14,9 @@ export type Attachment = WEBGLTextureView | WEBGLTexture; // | WEBGLRenderbuffer
14
14
 
15
15
  /** luma.gl Framebuffer, WebGL implementation */
16
16
  export class WEBGLFramebuffer extends Framebuffer {
17
- device: WebGLDevice;
17
+ readonly device: WebGLDevice;
18
18
  gl: WebGL2RenderingContext;
19
- handle: WebGLFramebuffer;
19
+ readonly handle: WebGLFramebuffer;
20
20
 
21
21
  colorAttachments: WEBGLTextureView[] = [];
22
22
  depthStencilAttachment: WEBGLTextureView | null = null;
@@ -7,8 +7,8 @@ import {WebGLDevice} from '../webgl-device';
7
7
  * Asynchronous queries for different kinds of information
8
8
  */
9
9
  export class WEBGLQuerySet extends QuerySet {
10
- device: WebGLDevice;
11
- handle: WebGLQuery;
10
+ readonly device: WebGLDevice;
11
+ readonly handle: WebGLQuery;
12
12
 
13
13
  target: number | null = null;
14
14
  _queryPending = false;
@@ -15,6 +15,7 @@ const COLOR_CHANNELS: NumberArray4 = [0x1, 0x2, 0x4, 0x8]; // GPUColorWrite RED,
15
15
 
16
16
  export class WEBGLRenderPass extends RenderPass {
17
17
  readonly device: WebGLDevice;
18
+ readonly handle = null;
18
19
 
19
20
  /** Parameters that should be applied before each draw call */
20
21
  glParameters: GLParameters = {};
@@ -36,9 +36,9 @@ const LOG_PROGRAM_PERF_PRIORITY = 4;
36
36
  /** Creates a new render pipeline */
37
37
  export class WEBGLRenderPipeline extends RenderPipeline {
38
38
  /** The WebGL device that created this render pipeline */
39
- device: WebGLDevice;
39
+ readonly device: WebGLDevice;
40
40
  /** Handle to underlying WebGL program */
41
- handle: WebGLProgram;
41
+ readonly handle: WebGLProgram;
42
42
  /** vertex shader */
43
43
  vs: WEBGLShader;
44
44
  /** fragment shader */
@@ -344,7 +344,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
344
344
  }
345
345
 
346
346
  const linkErrorLog = this.device.gl.getProgramInfoLog(this.handle);
347
- this.device.reportError(new Error(`${errorType} during ${status}: ${linkErrorLog}`));
347
+ this.device.reportError(
348
+ new Error(`${errorType} during ${status}: ${linkErrorLog}`),
349
+ this
350
+ )();
351
+ this.device.debug();
348
352
  }
349
353
  }
350
354
 
@@ -147,10 +147,13 @@ export class WEBGLTexture extends Texture {
147
147
  const {glFormat, glType, compressed} = this;
148
148
  const glTarget = getWebGLCubeFaceTarget(this.glTarget, this.dimension, depth);
149
149
 
150
- const glParameters: GLValueParameters = {
151
- [GL.UNPACK_ROW_LENGTH]: options.bytesPerRow,
152
- [GL.UNPACK_IMAGE_HEIGHT]: options.rowsPerImage
153
- };
150
+ // WebGL automatically ignores these for compressed textures, but we are careful
151
+ const glParameters: GLValueParameters = !this.compressed
152
+ ? {
153
+ [GL.UNPACK_ROW_LENGTH]: options.bytesPerRow,
154
+ [GL.UNPACK_IMAGE_HEIGHT]: options.rowsPerImage
155
+ }
156
+ : {};
154
157
 
155
158
  this.gl.bindTexture(glTarget, this.handle);
156
159
 
@@ -252,7 +255,7 @@ export class WEBGLTexture extends Texture {
252
255
  * Sets sampler parameters on texture
253
256
  */
254
257
  _setSamplerParameters(parameters: GLSamplerParameters): void {
255
- log.log(1, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
258
+ log.log(2, `${this.id} sampler parameters`, this.device.getGLKeys(parameters))();
256
259
 
257
260
  this.gl.bindTexture(this.glTarget, this.handle);
258
261