@luma.gl/webgl 9.1.0-alpha.9 → 9.1.0-beta.1

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 (200) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +3 -3
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/device-parameters.js +1 -0
  4. package/dist/adapter/converters/device-parameters.js.map +1 -0
  5. package/dist/adapter/converters/sampler-parameters.js +7 -4
  6. package/dist/adapter/converters/sampler-parameters.js.map +1 -0
  7. package/dist/adapter/converters/shader-formats.js +1 -0
  8. package/dist/adapter/converters/shader-formats.js.map +1 -0
  9. package/dist/adapter/converters/vertex-formats.js +1 -0
  10. package/dist/adapter/converters/vertex-formats.js.map +1 -0
  11. package/dist/adapter/converters/webgl-texture-table.d.ts +40 -0
  12. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -0
  13. package/dist/adapter/converters/webgl-texture-table.js +304 -0
  14. package/dist/adapter/converters/webgl-texture-table.js.map +1 -0
  15. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  16. package/dist/adapter/device-helpers/webgl-device-features.js +2 -2
  17. package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -0
  18. package/dist/adapter/device-helpers/webgl-device-info.js +1 -0
  19. package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -0
  20. package/dist/adapter/device-helpers/webgl-device-limits.js +1 -0
  21. package/dist/adapter/device-helpers/webgl-device-limits.js.map +1 -0
  22. package/dist/adapter/helpers/decode-webgl-types.js +1 -0
  23. package/dist/adapter/helpers/decode-webgl-types.js.map +1 -0
  24. package/dist/adapter/helpers/format-utils.d.ts.map +1 -0
  25. package/dist/{classic → adapter/helpers}/format-utils.js +7 -0
  26. package/dist/adapter/helpers/format-utils.js.map +1 -0
  27. package/dist/adapter/helpers/get-shader-layout.d.ts +1 -1
  28. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  29. package/dist/adapter/helpers/get-shader-layout.js +5 -4
  30. package/dist/adapter/helpers/get-shader-layout.js.map +1 -0
  31. package/dist/adapter/helpers/parse-shader-compiler-log.js +1 -0
  32. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -0
  33. package/dist/adapter/helpers/set-uniform.js +1 -0
  34. package/dist/adapter/helpers/set-uniform.js.map +1 -0
  35. package/dist/adapter/helpers/typed-array-utils.d.ts.map +1 -0
  36. package/dist/{classic → adapter/helpers}/typed-array-utils.js +1 -0
  37. package/dist/adapter/helpers/typed-array-utils.js.map +1 -0
  38. package/dist/adapter/helpers/webgl-texture-utils.d.ts +96 -25
  39. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  40. package/dist/adapter/helpers/webgl-texture-utils.js +225 -236
  41. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -0
  42. package/dist/adapter/helpers/webgl-topology-utils.js +1 -0
  43. package/dist/adapter/helpers/webgl-topology-utils.js.map +1 -0
  44. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  45. package/dist/adapter/resources/webgl-buffer.js +4 -1
  46. package/dist/adapter/resources/webgl-buffer.js.map +1 -0
  47. package/dist/adapter/resources/webgl-command-buffer.d.ts +59 -2
  48. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  49. package/dist/adapter/resources/webgl-command-buffer.js +89 -32
  50. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -0
  51. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  52. package/dist/adapter/resources/webgl-command-encoder.js +4 -0
  53. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -0
  54. package/dist/adapter/resources/webgl-external-texture.js +15 -0
  55. package/dist/adapter/resources/webgl-external-texture.js.map +1 -0
  56. package/dist/adapter/resources/webgl-framebuffer.d.ts +33 -35
  57. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  58. package/dist/adapter/resources/webgl-framebuffer.js +70 -75
  59. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -0
  60. package/dist/adapter/resources/webgl-query-set.js +1 -0
  61. package/dist/adapter/resources/webgl-query-set.js.map +1 -0
  62. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  63. package/dist/adapter/resources/webgl-render-pass.js +33 -18
  64. package/dist/adapter/resources/webgl-render-pass.js.map +1 -0
  65. package/dist/adapter/resources/webgl-render-pipeline.d.ts +3 -4
  66. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  67. package/dist/adapter/resources/webgl-render-pipeline.js +44 -22
  68. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -0
  69. package/dist/adapter/resources/webgl-sampler.js +1 -0
  70. package/dist/adapter/resources/webgl-sampler.js.map +1 -0
  71. package/dist/adapter/resources/webgl-shader.d.ts +1 -0
  72. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  73. package/dist/adapter/resources/webgl-shader.js +13 -6
  74. package/dist/adapter/resources/webgl-shader.js.map +1 -0
  75. package/dist/adapter/resources/webgl-texture-view.js +1 -0
  76. package/dist/adapter/resources/webgl-texture-view.js.map +1 -0
  77. package/dist/adapter/resources/webgl-texture.d.ts +32 -20
  78. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  79. package/dist/adapter/resources/webgl-texture.js +163 -218
  80. package/dist/adapter/resources/webgl-texture.js.map +1 -0
  81. package/dist/adapter/resources/webgl-transform-feedback.js +1 -0
  82. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -0
  83. package/dist/adapter/resources/webgl-vertex-array.js +1 -0
  84. package/dist/adapter/resources/webgl-vertex-array.js.map +1 -0
  85. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  86. package/dist/adapter/webgl-adapter.js +5 -10
  87. package/dist/adapter/webgl-adapter.js.map +1 -0
  88. package/dist/adapter/webgl-canvas-context.d.ts +4 -6
  89. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  90. package/dist/adapter/webgl-canvas-context.js +13 -17
  91. package/dist/adapter/webgl-canvas-context.js.map +1 -0
  92. package/dist/adapter/webgl-device.d.ts +20 -19
  93. package/dist/adapter/webgl-device.d.ts.map +1 -1
  94. package/dist/adapter/webgl-device.js +75 -51
  95. package/dist/adapter/webgl-device.js.map +1 -0
  96. package/dist/context/debug/spector-types.js +2 -1
  97. package/dist/context/debug/spector-types.js.map +1 -0
  98. package/dist/context/debug/spector.d.ts +5 -5
  99. package/dist/context/debug/spector.d.ts.map +1 -1
  100. package/dist/context/debug/spector.js +7 -6
  101. package/dist/context/debug/spector.js.map +1 -0
  102. package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
  103. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  104. package/dist/context/debug/webgl-developer-tools.js +7 -19
  105. package/dist/context/debug/webgl-developer-tools.js.map +1 -0
  106. package/dist/context/helpers/create-browser-context.d.ts +6 -22
  107. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  108. package/dist/context/helpers/create-browser-context.js +41 -32
  109. package/dist/context/helpers/create-browser-context.js.map +1 -0
  110. package/dist/context/helpers/webgl-context-data.js +1 -0
  111. package/dist/context/helpers/webgl-context-data.js.map +1 -0
  112. package/dist/context/helpers/webgl-extensions.js +1 -0
  113. package/dist/context/helpers/webgl-extensions.js.map +1 -0
  114. package/dist/context/parameters/unified-parameter-api.js +1 -0
  115. package/dist/context/parameters/unified-parameter-api.js.map +1 -0
  116. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  117. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  118. package/dist/context/parameters/webgl-parameter-tables.js +3 -2
  119. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -0
  120. package/dist/context/polyfills/polyfill-webgl1-extensions.js +1 -0
  121. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -0
  122. package/dist/context/state-tracker/deep-array-equal.js +1 -0
  123. package/dist/context/state-tracker/deep-array-equal.js.map +1 -0
  124. package/dist/context/state-tracker/webgl-state-tracker.js +1 -0
  125. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -0
  126. package/dist/context/state-tracker/with-parameters.js +1 -0
  127. package/dist/context/state-tracker/with-parameters.js.map +1 -0
  128. package/dist/deprecated/accessor.d.ts.map +1 -0
  129. package/dist/{classic → deprecated}/accessor.js +37 -1
  130. package/dist/deprecated/accessor.js.map +1 -0
  131. package/dist/dist.dev.js +2234 -2373
  132. package/dist/dist.min.js +2 -2
  133. package/dist/index.cjs +2124 -2256
  134. package/dist/index.cjs.map +4 -4
  135. package/dist/index.d.ts +2 -3
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +3 -4
  138. package/dist/index.js.map +1 -0
  139. package/dist/types.js +1 -0
  140. package/dist/types.js.map +1 -0
  141. package/dist/utils/fill-array.d.ts +4 -4
  142. package/dist/utils/fill-array.d.ts.map +1 -1
  143. package/dist/utils/fill-array.js +1 -0
  144. package/dist/utils/fill-array.js.map +1 -0
  145. package/dist/utils/load-script.js +1 -0
  146. package/dist/utils/load-script.js.map +1 -0
  147. package/dist/utils/split-uniforms-and-bindings.d.ts +1 -1
  148. package/dist/utils/split-uniforms-and-bindings.d.ts.map +1 -1
  149. package/dist/utils/split-uniforms-and-bindings.js +1 -0
  150. package/dist/utils/split-uniforms-and-bindings.js.map +1 -0
  151. package/dist/utils/uid.js +1 -0
  152. package/dist/utils/uid.js.map +1 -0
  153. package/package.json +5 -5
  154. package/src/adapter/converters/device-parameters.ts +3 -3
  155. package/src/adapter/converters/sampler-parameters.ts +6 -4
  156. package/src/adapter/converters/webgl-texture-table.ts +404 -0
  157. package/src/adapter/device-helpers/webgl-device-features.ts +5 -2
  158. package/src/{classic → adapter/helpers}/format-utils.ts +6 -0
  159. package/src/adapter/helpers/get-shader-layout.ts +7 -4
  160. package/src/adapter/helpers/webgl-texture-utils.ts +400 -57
  161. package/src/adapter/resources/webgl-buffer.ts +3 -1
  162. package/src/adapter/resources/webgl-command-buffer.ts +125 -41
  163. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  164. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  165. package/src/adapter/resources/webgl-framebuffer.ts +79 -85
  166. package/src/adapter/resources/webgl-render-pass.ts +56 -42
  167. package/src/adapter/resources/webgl-render-pipeline.ts +56 -26
  168. package/src/adapter/resources/webgl-shader.ts +15 -7
  169. package/src/adapter/resources/webgl-texture.ts +188 -250
  170. package/src/adapter/webgl-adapter.ts +4 -12
  171. package/src/adapter/webgl-canvas-context.ts +16 -19
  172. package/src/adapter/webgl-device.ts +125 -88
  173. package/src/context/debug/spector-types.ts +1 -1
  174. package/src/context/debug/spector.ts +11 -11
  175. package/src/context/debug/webgl-developer-tools.ts +8 -31
  176. package/src/context/helpers/create-browser-context.ts +53 -63
  177. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  178. package/src/{classic → deprecated}/accessor.ts +44 -3
  179. package/src/index.ts +2 -5
  180. package/src/utils/fill-array.ts +4 -4
  181. package/src/utils/split-uniforms-and-bindings.ts +3 -3
  182. package/dist/adapter/converters/texture-formats.d.ts +0 -83
  183. package/dist/adapter/converters/texture-formats.d.ts.map +0 -1
  184. package/dist/adapter/converters/texture-formats.js +0 -511
  185. package/dist/classic/accessor.d.ts.map +0 -1
  186. package/dist/classic/clear.d.ts +0 -22
  187. package/dist/classic/clear.d.ts.map +0 -1
  188. package/dist/classic/clear.js +0 -86
  189. package/dist/classic/copy-and-blit.d.ts +0 -64
  190. package/dist/classic/copy-and-blit.d.ts.map +0 -1
  191. package/dist/classic/copy-and-blit.js +0 -194
  192. package/dist/classic/format-utils.d.ts.map +0 -1
  193. package/dist/classic/typed-array-utils.d.ts.map +0 -1
  194. package/src/adapter/converters/texture-formats.ts +0 -657
  195. package/src/classic/clear.ts +0 -115
  196. package/src/classic/copy-and-blit.ts +0 -323
  197. /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
  198. /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
  199. /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
  200. /package/src/{classic → adapter/helpers}/typed-array-utils.ts +0 -0
@@ -11,7 +11,6 @@ import type {
11
11
  } from '@luma.gl/core';
12
12
 
13
13
  import {GL} from '@luma.gl/constants';
14
- import {Accessor} from '../../classic/accessor'; // TODO - should NOT depend on classic API
15
14
  import {decodeGLUniformType, decodeGLAttributeType, isSamplerUniform} from './decode-webgl-types';
16
15
 
17
16
  /**
@@ -19,7 +18,10 @@ import {decodeGLUniformType, decodeGLAttributeType, isSamplerUniform} from './de
19
18
  * Note: `linkProgram()` needs to have been called
20
19
  * (although linking does not need to have been successful).
21
20
  */
22
- export function getShaderLayout(gl: WebGL2RenderingContext, program: WebGLProgram): ShaderLayout {
21
+ export function getShaderLayoutFromGLSL(
22
+ gl: WebGL2RenderingContext,
23
+ program: WebGLProgram
24
+ ): ShaderLayout {
23
25
  const shaderLayout: ShaderLayout = {
24
26
  attributes: [],
25
27
  bindings: []
@@ -40,6 +42,7 @@ export function getShaderLayout(gl: WebGL2RenderingContext, program: WebGLProgra
40
42
  shaderLayout.bindings.push({
41
43
  type: 'uniform',
42
44
  name: uniformBlock.name,
45
+ group: 0,
43
46
  location: uniformBlock.location,
44
47
  visibility: (uniformBlock.vertex ? 0x1 : 0) & (uniformBlock.fragment ? 0x2 : 0),
45
48
  minBindingSize: uniformBlock.byteLength,
@@ -55,6 +58,7 @@ export function getShaderLayout(gl: WebGL2RenderingContext, program: WebGLProgra
55
58
  shaderLayout.bindings.push({
56
59
  type: 'texture',
57
60
  name: uniform.name,
61
+ group: 0,
58
62
  location: textureUnit,
59
63
  viewDimension,
60
64
  sampleType
@@ -143,8 +147,7 @@ function readVaryings(gl: WebGL2RenderingContext, program: WebGLProgram): Varyin
143
147
  }
144
148
  const {name, type: compositeType, size} = activeInfo;
145
149
  const {glType, components} = decodeGLUniformType(compositeType);
146
- const accessor = new Accessor({type: glType, size: size * components});
147
- const varying = {location, name, accessor}; // Base values
150
+ const varying = {location, name, type: glType, size: size * components}; // Base values
148
151
  varyings.push(varying);
149
152
  }
150
153
 
@@ -6,51 +6,49 @@
6
6
  // WebGL... the texture API from hell... hopefully made simpler
7
7
  //
8
8
 
9
+ import {TypedArray} from '@math.gl/types';
9
10
  import type {ExternalImage} from '@luma.gl/core';
10
- // import {Buffer} from '@luma.gl/core';
11
+ import {Buffer, Texture, Framebuffer, FramebufferProps} from '@luma.gl/core';
11
12
  import {
12
13
  GL,
13
14
  GLTextureTarget,
14
15
  GLTextureCubeMapTarget,
15
16
  GLTexelDataFormat,
16
- GLPixelType
17
+ GLPixelType,
18
+ GLDataType
17
19
  } from '@luma.gl/constants';
18
20
 
19
- import {TypedArray} from '@math.gl/types';
21
+ import {WEBGLFramebuffer} from '../resources/webgl-framebuffer';
22
+ import {getGLTypeFromTypedArray, getTypedArrayFromGLType} from './typed-array-utils';
23
+ import {glFormatToComponents, glTypeToBytes} from './format-utils';
24
+ import {WEBGLBuffer} from '../resources/webgl-buffer';
25
+ import {WEBGLTexture} from '../resources/webgl-texture';
26
+ import {withGLParameters} from '../../context/state-tracker/with-parameters';
20
27
 
21
28
  /** A "border" parameter is required in many WebGL texture APIs, but must always be 0... */
22
29
  const BORDER = 0;
23
30
 
31
+ /**
32
+ * Options for setting data into a texture
33
+ */
24
34
  export type WebGLSetTextureOptions = {
25
35
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
26
36
  height: number;
27
37
  width: number;
28
- depth?: number;
29
- level?: number;
38
+ depth: number;
39
+ mipLevel?: number;
30
40
  glTarget: GLTextureTarget;
31
41
  glInternalFormat: GL;
32
42
  glFormat: GLTexelDataFormat;
33
43
  glType: GLPixelType;
34
44
  compressed?: boolean;
35
-
36
45
  byteOffset?: number;
37
46
  byteLength?: number;
38
47
  };
39
48
 
40
49
  /**
41
- * @param {*} pixels, data -
42
- * null - create empty texture of specified format
43
- * Typed array - init from image data in typed array
44
- * Buffer|WebGLBuffer - (WEBGL2) init from image data in WebGLBuffer
45
- * HTMLImageElement|Image - Inits with content of image. Auto width/height
46
- * HTMLCanvasElement - Inits with contents of canvas. Auto width/height
47
- * HTMLVideoElement - Creates video texture. Auto width/height
50
+ * Options for copying an image or data into a texture
48
51
  *
49
- * @param x - xOffset from where texture to be updated
50
- * @param y - yOffset from where texture to be updated
51
- * @param width - width of the sub image to be updated
52
- * @param height - height of the sub image to be updated
53
- * @param level - mip level to be updated
54
52
  * @param {GLenum} format - internal format of image data.
55
53
  * @param {GLenum} type
56
54
  * - format of array (autodetect from type) or
@@ -61,12 +59,19 @@ export type WebGLSetTextureOptions = {
61
59
  */
62
60
  export type WebGLCopyTextureOptions = {
63
61
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d';
64
- level?: number;
65
- height: number;
62
+ /** mip level to be updated */
63
+ mipLevel?: number;
64
+ /** width of the sub image to be updated */
66
65
  width: number;
66
+ /** height of the sub image to be updated */
67
+ height: number;
68
+ /** depth of texture to be updated */
67
69
  depth?: number;
70
+ /** xOffset from where texture to be updated */
68
71
  x?: number;
72
+ /** yOffset from where texture to be updated */
69
73
  y?: number;
74
+ /** yOffset from where texture to be updated */
70
75
  z?: number;
71
76
 
72
77
  glTarget: GLTextureTarget;
@@ -74,7 +79,6 @@ export type WebGLCopyTextureOptions = {
74
79
  glFormat: GL;
75
80
  glType: GL;
76
81
  compressed?: boolean;
77
-
78
82
  byteOffset?: number;
79
83
  byteLength?: number;
80
84
  };
@@ -112,35 +116,42 @@ export function initializeTextureStorage(
112
116
  /**
113
117
  * Copy a region of compressed data from a GPU memory buffer into this texture.
114
118
  */
115
- export function copyCPUImageToMipLevel(
119
+ export function copyExternalImageToMipLevel(
116
120
  gl: WebGL2RenderingContext,
121
+ handle: WebGLTexture,
117
122
  image: ExternalImage,
118
- options: WebGLCopyTextureOptions
123
+ options: WebGLCopyTextureOptions & {flipY?: boolean}
119
124
  ): void {
120
- const {dimension, width, height, depth = 0, level = 0} = options;
125
+ const {width, height} = options;
126
+ const {dimension, depth = 0, mipLevel = 0} = options;
121
127
  const {x = 0, y = 0, z = 0} = options;
122
128
  const {glFormat, glType} = options;
123
- const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
124
129
 
125
- // width = size.width,
126
- // height = size.height
130
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
127
131
 
128
- switch (dimension) {
129
- case '2d-array':
130
- case '3d':
131
- // prettier-ignore
132
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, image);
133
- break;
132
+ const glParameters = options.flipY ? {[GL.UNPACK_FLIP_Y_WEBGL]: true} : {};
133
+ withGLParameters(gl, glParameters, () => {
134
+ switch (dimension) {
135
+ case '2d-array':
136
+ case '3d':
137
+ gl.bindTexture(glTarget, handle);
138
+ // prettier-ignore
139
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, image);
140
+ gl.bindTexture(glTarget, null);
141
+ break;
134
142
 
135
- case '2d':
136
- case 'cube':
137
- // prettier-ignore
138
- gl.texSubImage2D(glTarget, level, x, y, width, height, glFormat, glType, image);
139
- break;
143
+ case '2d':
144
+ case 'cube':
145
+ gl.bindTexture(glTarget, handle);
146
+ // prettier-ignore
147
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, image);
148
+ gl.bindTexture(glTarget, null);
149
+ break;
140
150
 
141
- default:
142
- throw new Error(dimension);
143
- }
151
+ default:
152
+ throw new Error(dimension);
153
+ }
154
+ });
144
155
  }
145
156
 
146
157
  /**
@@ -151,7 +162,7 @@ export function copyCPUDataToMipLevel(
151
162
  typedArray: TypedArray,
152
163
  options: WebGLCopyTextureOptions
153
164
  ): void {
154
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
165
+ const {dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0} = options;
155
166
  const {x = 0, y = 0, z = 0} = options;
156
167
  const {glFormat, glType, compressed} = options;
157
168
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
@@ -163,10 +174,10 @@ export function copyCPUDataToMipLevel(
163
174
  case '3d':
164
175
  if (compressed) {
165
176
  // prettier-ignore
166
- gl.compressedTexSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, typedArray, byteOffset); // , byteLength
177
+ gl.compressedTexSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, typedArray, byteOffset); // , byteLength
167
178
  } else {
168
179
  // prettier-ignore
169
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, typedArray, byteOffset); // , byteLength
180
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, typedArray, byteOffset); // , byteLength
170
181
  }
171
182
  break;
172
183
 
@@ -174,10 +185,10 @@ export function copyCPUDataToMipLevel(
174
185
  case 'cube':
175
186
  if (compressed) {
176
187
  // prettier-ignore
177
- gl.compressedTexSubImage2D(glTarget, level, x, y, width, height, glFormat, typedArray, byteOffset); // , byteLength
188
+ gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, typedArray, byteOffset); // , byteLength
178
189
  } else {
179
190
  // prettier-ignore
180
- gl.texSubImage2D(glTarget, level, x, y, width, height, glFormat, glType, typedArray, byteOffset); // , byteLength
191
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, glType, typedArray, byteOffset); // , byteLength
181
192
  }
182
193
  break;
183
194
 
@@ -195,7 +206,7 @@ export function copyGPUBufferToMipLevel(
195
206
  byteLength: number,
196
207
  options: WebGLCopyTextureOptions
197
208
  ): void {
198
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
209
+ const {dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0} = options;
199
210
  const {x = 0, y = 0, z = 0} = options;
200
211
  const {glFormat, glType, compressed} = options;
201
212
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
@@ -209,10 +220,10 @@ export function copyGPUBufferToMipLevel(
209
220
  if (compressed) {
210
221
  // TODO enable extension?
211
222
  // prettier-ignore
212
- gl.compressedTexSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, byteLength, byteOffset);
223
+ gl.compressedTexSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, byteLength, byteOffset);
213
224
  } else {
214
225
  // prettier-ignore
215
- gl.texSubImage3D(glTarget, level, x, y, z, width, height, depth, glFormat, glType, byteOffset);
226
+ gl.texSubImage3D(glTarget, mipLevel, x, y, z, width, height, depth, glFormat, glType, byteOffset);
216
227
  }
217
228
  break;
218
229
 
@@ -220,10 +231,10 @@ export function copyGPUBufferToMipLevel(
220
231
  case 'cube':
221
232
  if (compressed) {
222
233
  // prettier-ignore
223
- gl.compressedTexSubImage2D(glTarget, level, x, y, width, height, glFormat, byteLength, byteOffset);
234
+ gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, byteLength, byteOffset);
224
235
  } else {
225
236
  // prettier-ignore
226
- gl.texSubImage2D(glTarget, level, x, y, width, height, BORDER, glFormat, byteOffset);
237
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, BORDER, glFormat, byteOffset);
227
238
  }
228
239
  break;
229
240
 
@@ -255,7 +266,7 @@ export function getWebGLTextureTarget(
255
266
  * @note We still bind the texture using GL.TEXTURE_CUBE_MAP, but we need to use the face-specific target when setting mip levels.
256
267
  * @returns glTarget unchanged, if dimension !== 'cube'.
257
268
  */
258
- function getWebGLCubeFaceTarget(
269
+ export function getWebGLCubeFaceTarget(
259
270
  glTarget: GLTextureTarget,
260
271
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d',
261
272
  level: number
@@ -270,7 +281,7 @@ function getWebGLCubeFaceTarget(
270
281
  * Wrapper for the messy WebGL texture API
271
282
  *
272
283
  export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextureOptions): void {
273
- const {dimension, width, height, depth = 0, level = 0} = options;
284
+ const {dimension, width, height, depth = 0, mipLevel = 0} = options;
274
285
  const {glInternalFormat, glFormat, glType, compressed} = options;
275
286
  const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
276
287
 
@@ -279,10 +290,10 @@ export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextu
279
290
  case '3d':
280
291
  if (compressed) {
281
292
  // prettier-ignore
282
- gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, null);
293
+ gl.compressedTexImage3D(glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, null);
283
294
  } else {
284
295
  // prettier-ignore
285
- gl.texImage3D( glTarget, level, glInternalFormat, width, height, depth, BORDER, glFormat, glType, null);
296
+ gl.texImage3D( glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, glFormat, glType, null);
286
297
  }
287
298
  break;
288
299
 
@@ -290,10 +301,10 @@ export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextu
290
301
  case 'cube':
291
302
  if (compressed) {
292
303
  // prettier-ignore
293
- gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, null);
304
+ gl.compressedTexImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, null);
294
305
  } else {
295
306
  // prettier-ignore
296
- gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, null);
307
+ gl.texImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, glFormat, glType, null);
297
308
  }
298
309
  break;
299
310
 
@@ -301,6 +312,7 @@ export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextu
301
312
  throw new Error(dimension);
302
313
  }
303
314
  }
315
+ */
304
316
 
305
317
  /**
306
318
  * Set a texture mip level to the contents of an external image.
@@ -482,3 +494,334 @@ export function setMipLevelFromGPUBuffer(
482
494
  gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
483
495
  }
484
496
  */
497
+ export type ReadPixelsToArrayOptions = {
498
+ sourceX?: number;
499
+ sourceY?: number;
500
+ sourceFormat?: number;
501
+ sourceAttachment?: number;
502
+ target?: Uint8Array | Uint16Array | Float32Array;
503
+ // following parameters are auto deduced if not provided
504
+ sourceWidth?: number;
505
+ sourceHeight?: number;
506
+ sourceDepth?: number;
507
+ sourceType?: number;
508
+ };
509
+
510
+ export type ReadPixelsToBufferOptions = {
511
+ sourceX?: number;
512
+ sourceY?: number;
513
+ sourceFormat?: number;
514
+ target?: Buffer; // A new Buffer object is created when not provided.
515
+ targetByteOffset?: number; // byte offset in buffer object
516
+ // following parameters are auto deduced if not provided
517
+ sourceWidth?: number;
518
+ sourceHeight?: number;
519
+ sourceType?: number;
520
+ };
521
+
522
+ /**
523
+ * Copies data from a type or a Texture object into ArrayBuffer object.
524
+ * App can provide targetPixelArray or have it auto allocated by this method
525
+ * newly allocated by this method unless provided by app.
526
+ * @deprecated Use CommandEncoder.copyTextureToBuffer and Buffer.read
527
+ * @note Slow requires roundtrip to GPU
528
+ *
529
+ * @param source
530
+ * @param options
531
+ * @returns pixel array,
532
+ */
533
+ export function readPixelsToArray(
534
+ source: Framebuffer | Texture,
535
+ options?: ReadPixelsToArrayOptions
536
+ ): Uint8Array | Uint16Array | Float32Array {
537
+ const {
538
+ sourceX = 0,
539
+ sourceY = 0,
540
+ sourceAttachment = 0 // TODO - support gl.readBuffer
541
+ } = options || {};
542
+ let {
543
+ target = null,
544
+ // following parameters are auto deduced if not provided
545
+ sourceWidth,
546
+ sourceHeight,
547
+ sourceDepth,
548
+ sourceFormat,
549
+ sourceType
550
+ } = options || {};
551
+
552
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(source);
553
+ // assert(framebuffer);
554
+ const {gl, handle} = framebuffer;
555
+
556
+ sourceWidth ||= framebuffer.width;
557
+ sourceHeight ||= framebuffer.height;
558
+
559
+ const texture = framebuffer.colorAttachments[sourceAttachment]?.texture;
560
+ if (!texture) {
561
+ throw new Error(`Invalid framebuffer attachment ${sourceAttachment}`);
562
+ }
563
+ sourceDepth = texture?.depth || 1;
564
+
565
+ sourceFormat ||= texture?.glFormat || GL.RGBA;
566
+ // Deduce the type from color attachment if not provided.
567
+ sourceType ||= texture?.glType || GL.UNSIGNED_BYTE;
568
+
569
+ // Deduce type and allocated pixelArray if needed
570
+ target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight, sourceDepth);
571
+
572
+ // Pixel array available, if necessary, deduce type from it.
573
+ sourceType = sourceType || getGLTypeFromTypedArray(target);
574
+
575
+ // Note: luma.gl overrides bindFramebuffer so that we can reliably restore the previous framebuffer (this is the only function for which we do that)
576
+ const prevHandle = gl.bindFramebuffer(
577
+ GL.FRAMEBUFFER,
578
+ handle
579
+ ) as unknown as WebGLFramebuffer | null;
580
+
581
+ // Select the color attachment to read from
582
+ gl.readBuffer(gl.COLOR_ATTACHMENT0 + sourceAttachment);
583
+
584
+ // There is a lot of hedging in the WebGL2 spec about what formats are guaranteed to be readable
585
+ // (It should always be possible to read RGBA/UNSIGNED_BYTE, but most other combinations are not guaranteed)
586
+ // Querying is possible but expensive:
587
+ // const {device} = framebuffer;
588
+ // texture.glReadFormat ||= gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
589
+ // texture.glReadType ||= gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
590
+ // console.log('params', device.getGLKey(texture.glReadFormat), device.getGLKey(texture.glReadType));
591
+
592
+ gl.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, target);
593
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
594
+ gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
595
+
596
+ if (deleteFramebuffer) {
597
+ framebuffer.destroy();
598
+ }
599
+
600
+ return target;
601
+ }
602
+
603
+ /**
604
+ * Copies data from a Framebuffer or a Texture object into a Buffer object.
605
+ * NOTE: doesn't wait for copy to be complete, it programs GPU to perform a DMA transffer.
606
+ * @deprecated Use CommandEncoder
607
+ * @param source
608
+ * @param options
609
+ */
610
+ export function readPixelsToBuffer(
611
+ source: Framebuffer | Texture,
612
+ options?: ReadPixelsToBufferOptions
613
+ ): WEBGLBuffer {
614
+ const {
615
+ target,
616
+ sourceX = 0,
617
+ sourceY = 0,
618
+ sourceFormat = GL.RGBA,
619
+ targetByteOffset = 0
620
+ } = options || {};
621
+ // following parameters are auto deduced if not provided
622
+ let {sourceWidth, sourceHeight, sourceType} = options || {};
623
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(source);
624
+ // assert(framebuffer);
625
+ sourceWidth = sourceWidth || framebuffer.width;
626
+ sourceHeight = sourceHeight || framebuffer.height;
627
+
628
+ // Asynchronous read (PIXEL_PACK_BUFFER) is WebGL2 only feature
629
+ const webglFramebuffer = framebuffer;
630
+
631
+ // deduce type if not available.
632
+ sourceType = sourceType || GL.UNSIGNED_BYTE;
633
+
634
+ let webglBufferTarget = target as unknown as WEBGLBuffer | undefined;
635
+ if (!webglBufferTarget) {
636
+ // Create new buffer with enough size
637
+ const components = glFormatToComponents(sourceFormat);
638
+ const byteCount = glTypeToBytes(sourceType);
639
+ const byteLength = targetByteOffset + sourceWidth * sourceHeight * components * byteCount;
640
+ webglBufferTarget = webglFramebuffer.device.createBuffer({byteLength});
641
+ }
642
+
643
+ // TODO(donmccurdy): Do we have tests to confirm this is working?
644
+ const commandEncoder = source.device.createCommandEncoder();
645
+ commandEncoder.copyTextureToBuffer({
646
+ sourceTexture: source as Texture,
647
+ width: sourceWidth,
648
+ height: sourceHeight,
649
+ origin: [sourceX, sourceY],
650
+ destinationBuffer: webglBufferTarget,
651
+ byteOffset: targetByteOffset
652
+ });
653
+ commandEncoder.destroy();
654
+
655
+ if (deleteFramebuffer) {
656
+ framebuffer.destroy();
657
+ }
658
+
659
+ return webglBufferTarget;
660
+ }
661
+
662
+ /**
663
+ * Copy a rectangle from a Framebuffer or Texture object into a texture (at an offset)
664
+ * @deprecated Use CommandEncoder
665
+ */
666
+ // eslint-disable-next-line complexity, max-statements
667
+ export function copyToTexture(
668
+ sourceTexture: Framebuffer | Texture,
669
+ destinationTexture: Texture | GL,
670
+ options?: {
671
+ sourceX?: number;
672
+ sourceY?: number;
673
+
674
+ targetX?: number;
675
+ targetY?: number;
676
+ targetZ?: number;
677
+ targetMipmaplevel?: number;
678
+ targetInternalFormat?: number;
679
+
680
+ width?: number; // defaults to target width
681
+ height?: number; // defaults to target height
682
+ }
683
+ ): Texture {
684
+ const {
685
+ sourceX = 0,
686
+ sourceY = 0,
687
+ // attachment = GL.COLOR_ATTACHMENT0, // TODO - support gl.readBuffer
688
+ targetMipmaplevel = 0,
689
+ targetInternalFormat = GL.RGBA
690
+ } = options || {};
691
+ let {
692
+ targetX,
693
+ targetY,
694
+ targetZ,
695
+ width, // defaults to target width
696
+ height // defaults to target height
697
+ } = options || {};
698
+
699
+ const {framebuffer, deleteFramebuffer} = getFramebuffer(sourceTexture);
700
+ // assert(framebuffer);
701
+ const webglFramebuffer = framebuffer;
702
+ const {device, handle} = webglFramebuffer;
703
+ const isSubCopy =
704
+ typeof targetX !== 'undefined' ||
705
+ typeof targetY !== 'undefined' ||
706
+ typeof targetZ !== 'undefined';
707
+ targetX = targetX || 0;
708
+ targetY = targetY || 0;
709
+ targetZ = targetZ || 0;
710
+ const prevHandle = device.gl.bindFramebuffer(GL.FRAMEBUFFER, handle);
711
+ // TODO - support gl.readBuffer (WebGL2 only)
712
+ // const prevBuffer = gl.readBuffer(attachment);
713
+ // assert(target);
714
+ let texture: WEBGLTexture | null = null;
715
+ let textureTarget: GL;
716
+ if (destinationTexture instanceof WEBGLTexture) {
717
+ texture = destinationTexture;
718
+ width = Number.isFinite(width) ? width : texture.width;
719
+ height = Number.isFinite(height) ? height : texture.height;
720
+ texture?.bind(0);
721
+ // @ts-ignore
722
+ textureTarget = texture.target;
723
+ } else {
724
+ // @ts-ignore
725
+ textureTarget = target;
726
+ }
727
+
728
+ if (!isSubCopy) {
729
+ device.gl.copyTexImage2D(
730
+ textureTarget,
731
+ targetMipmaplevel,
732
+ targetInternalFormat,
733
+ sourceX,
734
+ sourceY,
735
+ width,
736
+ height,
737
+ 0 /* border must be 0 */
738
+ );
739
+ } else {
740
+ switch (textureTarget) {
741
+ case GL.TEXTURE_2D:
742
+ case GL.TEXTURE_CUBE_MAP:
743
+ device.gl.copyTexSubImage2D(
744
+ textureTarget,
745
+ targetMipmaplevel,
746
+ targetX,
747
+ targetY,
748
+ sourceX,
749
+ sourceY,
750
+ width,
751
+ height
752
+ );
753
+ break;
754
+ case GL.TEXTURE_2D_ARRAY:
755
+ case GL.TEXTURE_3D:
756
+ device.gl.copyTexSubImage3D(
757
+ textureTarget,
758
+ targetMipmaplevel,
759
+ targetX,
760
+ targetY,
761
+ targetZ,
762
+ sourceX,
763
+ sourceY,
764
+ width,
765
+ height
766
+ );
767
+ break;
768
+ default:
769
+ }
770
+ }
771
+ if (texture) {
772
+ texture.unbind();
773
+ }
774
+ // @ts-expect-error
775
+ device.gl.bindFramebuffer(GL.FRAMEBUFFER, prevHandle || null);
776
+ if (deleteFramebuffer) {
777
+ framebuffer.destroy();
778
+ }
779
+ return texture;
780
+ }
781
+
782
+ function getFramebuffer(source: Texture | Framebuffer): {
783
+ framebuffer: WEBGLFramebuffer;
784
+ deleteFramebuffer: boolean;
785
+ } {
786
+ if (!(source instanceof Framebuffer)) {
787
+ return {framebuffer: toFramebuffer(source), deleteFramebuffer: true};
788
+ }
789
+ return {framebuffer: source as WEBGLFramebuffer, deleteFramebuffer: false};
790
+ }
791
+
792
+ /**
793
+ * Wraps a given texture into a framebuffer object, that can be further used
794
+ * to read data from the texture object.
795
+ */
796
+ export function toFramebuffer(texture: Texture, props?: FramebufferProps): WEBGLFramebuffer {
797
+ const {device, width, height, id} = texture;
798
+ const framebuffer = device.createFramebuffer({
799
+ ...props,
800
+ id: `framebuffer-for-${id}`,
801
+ width,
802
+ height,
803
+ colorAttachments: [texture]
804
+ });
805
+ return framebuffer as WEBGLFramebuffer;
806
+ }
807
+
808
+ // eslint-disable-next-line max-params
809
+ function getPixelArray(
810
+ pixelArray,
811
+ glType: GLDataType | GLPixelType,
812
+ glFormat: GL,
813
+ width: number,
814
+ height: number,
815
+ depth?: number
816
+ ): Uint8Array | Uint16Array | Float32Array {
817
+ if (pixelArray) {
818
+ return pixelArray;
819
+ }
820
+ // const formatInfo = decodeTextureFormat(format);
821
+ // Allocate pixel array if not already available, using supplied type
822
+ glType ||= GL.UNSIGNED_BYTE;
823
+ const ArrayType = getTypedArrayFromGLType(glType, {clamped: false});
824
+ const components = glFormatToComponents(glFormat);
825
+ // TODO - check for composite type (components = 1).
826
+ return new ArrayType(width * height * components) as Uint8Array | Uint16Array | Float32Array;
827
+ }
@@ -33,7 +33,9 @@ export class WEBGLBuffer extends Buffer {
33
33
 
34
34
  const handle = typeof props === 'object' ? props.handle : undefined;
35
35
  this.handle = handle || this.gl.createBuffer();
36
- device.setSpectorMetadata(this.handle, {...this.props, data: typeof this.props.data});
36
+ device._setWebGLDebugMetadata(this.handle, this, {
37
+ spector: {...this.props, data: typeof this.props.data}
38
+ });
37
39
 
38
40
  // - In WebGL1, need to make sure we use GL.ELEMENT_ARRAY_BUFFER when initializing element buffers
39
41
  // otherwise buffer type will lock to generic (non-element) buffer