@luma.gl/webgl 9.1.0-alpha.2 → 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 (216) 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 +19 -11
  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 -3
  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 +100 -29
  39. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  40. package/dist/adapter/helpers/webgl-texture-utils.js +231 -240
  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 +71 -76
  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 +49 -21
  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 +45 -23
  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 +33 -21
  78. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  79. package/dist/adapter/resources/webgl-texture.js +172 -242
  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 +21 -0
  86. package/dist/adapter/webgl-adapter.d.ts.map +1 -0
  87. package/dist/adapter/webgl-adapter.js +86 -0
  88. package/dist/adapter/webgl-adapter.js.map +1 -0
  89. package/dist/adapter/webgl-canvas-context.d.ts +4 -6
  90. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  91. package/dist/adapter/webgl-canvas-context.js +13 -17
  92. package/dist/adapter/webgl-canvas-context.js.map +1 -0
  93. package/dist/adapter/webgl-device.d.ts +35 -46
  94. package/dist/adapter/webgl-device.d.ts.map +1 -1
  95. package/dist/adapter/webgl-device.js +100 -156
  96. package/dist/adapter/webgl-device.js.map +1 -0
  97. package/dist/context/debug/spector-types.d.ts +1108 -0
  98. package/dist/context/debug/spector-types.d.ts.map +1 -0
  99. package/dist/context/debug/spector-types.js +698 -0
  100. package/dist/context/debug/spector-types.js.map +1 -0
  101. package/dist/context/debug/spector.d.ts +12 -8
  102. package/dist/context/debug/spector.d.ts.map +1 -1
  103. package/dist/context/debug/spector.js +24 -17
  104. package/dist/context/debug/spector.js.map +1 -0
  105. package/dist/context/debug/webgl-developer-tools.d.ts +2 -3
  106. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  107. package/dist/context/debug/webgl-developer-tools.js +7 -19
  108. package/dist/context/debug/webgl-developer-tools.js.map +1 -0
  109. package/dist/context/helpers/create-browser-context.d.ts +6 -22
  110. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  111. package/dist/context/helpers/create-browser-context.js +41 -32
  112. package/dist/context/helpers/create-browser-context.js.map +1 -0
  113. package/dist/context/helpers/webgl-context-data.js +1 -0
  114. package/dist/context/helpers/webgl-context-data.js.map +1 -0
  115. package/dist/context/helpers/webgl-extensions.js +1 -0
  116. package/dist/context/helpers/webgl-extensions.js.map +1 -0
  117. package/dist/context/parameters/unified-parameter-api.js +1 -0
  118. package/dist/context/parameters/unified-parameter-api.js.map +1 -0
  119. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  120. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  121. package/dist/context/parameters/webgl-parameter-tables.js +3 -2
  122. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -0
  123. package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts +9 -0
  124. package/dist/context/polyfills/polyfill-webgl1-extensions.d.ts.map +1 -0
  125. package/dist/context/polyfills/polyfill-webgl1-extensions.js +182 -0
  126. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -0
  127. package/dist/context/state-tracker/deep-array-equal.js +1 -0
  128. package/dist/context/state-tracker/deep-array-equal.js.map +1 -0
  129. package/dist/context/state-tracker/webgl-state-tracker.d.ts +43 -0
  130. package/dist/context/state-tracker/webgl-state-tracker.d.ts.map +1 -0
  131. package/dist/context/state-tracker/{track-context-state.js → webgl-state-tracker.js} +45 -74
  132. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -0
  133. package/dist/context/state-tracker/with-parameters.d.ts.map +1 -1
  134. package/dist/context/state-tracker/with-parameters.js +6 -4
  135. package/dist/context/state-tracker/with-parameters.js.map +1 -0
  136. package/dist/deprecated/accessor.d.ts.map +1 -0
  137. package/dist/{classic → deprecated}/accessor.js +37 -1
  138. package/dist/deprecated/accessor.js.map +1 -0
  139. package/dist/dist.dev.js +2397 -2430
  140. package/dist/dist.min.js +2 -2
  141. package/dist/index.cjs +2273 -2298
  142. package/dist/index.cjs.map +4 -4
  143. package/dist/index.d.ts +5 -4
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +6 -6
  146. package/dist/index.js.map +1 -0
  147. package/dist/types.js +1 -0
  148. package/dist/types.js.map +1 -0
  149. package/dist/utils/fill-array.d.ts +4 -4
  150. package/dist/utils/fill-array.d.ts.map +1 -1
  151. package/dist/utils/fill-array.js +1 -0
  152. package/dist/utils/fill-array.js.map +1 -0
  153. package/dist/utils/load-script.js +1 -0
  154. package/dist/utils/load-script.js.map +1 -0
  155. package/dist/utils/split-uniforms-and-bindings.d.ts +1 -1
  156. package/dist/utils/split-uniforms-and-bindings.d.ts.map +1 -1
  157. package/dist/utils/split-uniforms-and-bindings.js +1 -0
  158. package/dist/utils/split-uniforms-and-bindings.js.map +1 -0
  159. package/dist/utils/uid.d.ts +7 -0
  160. package/dist/utils/uid.d.ts.map +1 -0
  161. package/dist/utils/uid.js +15 -0
  162. package/dist/utils/uid.js.map +1 -0
  163. package/package.json +5 -5
  164. package/src/adapter/converters/device-parameters.ts +21 -15
  165. package/src/adapter/converters/sampler-parameters.ts +6 -4
  166. package/src/adapter/converters/webgl-texture-table.ts +404 -0
  167. package/src/adapter/device-helpers/webgl-device-features.ts +5 -3
  168. package/src/{classic → adapter/helpers}/format-utils.ts +6 -0
  169. package/src/adapter/helpers/get-shader-layout.ts +7 -4
  170. package/src/adapter/helpers/webgl-texture-utils.ts +410 -64
  171. package/src/adapter/resources/webgl-buffer.ts +3 -1
  172. package/src/adapter/resources/webgl-command-buffer.ts +125 -41
  173. package/src/adapter/resources/webgl-command-encoder.ts +6 -0
  174. package/src/adapter/resources/webgl-external-texture.ts +14 -0
  175. package/src/adapter/resources/webgl-framebuffer.ts +80 -86
  176. package/src/adapter/resources/webgl-render-pass.ts +72 -45
  177. package/src/adapter/resources/webgl-render-pipeline.ts +58 -27
  178. package/src/adapter/resources/webgl-shader.ts +15 -7
  179. package/src/adapter/resources/webgl-texture.ts +202 -274
  180. package/src/adapter/webgl-adapter.ts +105 -0
  181. package/src/adapter/webgl-canvas-context.ts +16 -19
  182. package/src/adapter/webgl-device.ts +144 -210
  183. package/src/context/debug/spector-types.ts +1154 -0
  184. package/src/context/debug/spector.ts +38 -29
  185. package/src/context/debug/webgl-developer-tools.ts +8 -31
  186. package/src/context/helpers/create-browser-context.ts +53 -63
  187. package/src/context/parameters/webgl-parameter-tables.ts +2 -2
  188. package/src/context/polyfills/polyfill-webgl1-extensions.ts +202 -0
  189. package/src/context/state-tracker/{track-context-state.ts → webgl-state-tracker.ts} +55 -94
  190. package/src/context/state-tracker/with-parameters.ts +5 -4
  191. package/src/{classic → deprecated}/accessor.ts +44 -3
  192. package/src/index.ts +7 -12
  193. package/src/utils/fill-array.ts +4 -4
  194. package/src/utils/split-uniforms-and-bindings.ts +3 -3
  195. package/src/utils/uid.ts +16 -0
  196. package/dist/adapter/converters/texture-formats.d.ts +0 -83
  197. package/dist/adapter/converters/texture-formats.d.ts.map +0 -1
  198. package/dist/adapter/converters/texture-formats.js +0 -518
  199. package/dist/classic/accessor.d.ts.map +0 -1
  200. package/dist/classic/clear.d.ts +0 -22
  201. package/dist/classic/clear.d.ts.map +0 -1
  202. package/dist/classic/clear.js +0 -86
  203. package/dist/classic/copy-and-blit.d.ts +0 -63
  204. package/dist/classic/copy-and-blit.d.ts.map +0 -1
  205. package/dist/classic/copy-and-blit.js +0 -193
  206. package/dist/classic/format-utils.d.ts.map +0 -1
  207. package/dist/classic/typed-array-utils.d.ts.map +0 -1
  208. package/dist/context/state-tracker/track-context-state.d.ts +0 -22
  209. package/dist/context/state-tracker/track-context-state.d.ts.map +0 -1
  210. package/src/adapter/converters/texture-formats.ts +0 -665
  211. package/src/classic/clear.ts +0 -115
  212. package/src/classic/copy-and-blit.ts +0 -318
  213. /package/dist/{classic → adapter/helpers}/format-utils.d.ts +0 -0
  214. /package/dist/{classic → adapter/helpers}/typed-array-utils.d.ts +0 -0
  215. /package/dist/{classic → deprecated}/accessor.d.ts +0 -0
  216. /package/src/{classic → adapter/helpers}/typed-array-utils.ts +0 -0
@@ -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
  };
@@ -97,7 +101,7 @@ export function initializeTextureStorage(
97
101
  ): void {
98
102
  const {dimension, width, height, depth = 0} = options;
99
103
  const {glInternalFormat} = options;
100
- const glTarget = options.glTarget; // getCubeTargetWebGL(options.glTarget, dimension, depth);
104
+ const glTarget = options.glTarget; // getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
101
105
  switch (dimension) {
102
106
  case '2d-array':
103
107
  case '3d':
@@ -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 = getCubeTargetWebGL(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,20 +162,22 @@ 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
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
168
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
169
+
170
+ // gl.bindTexture(glTarget, null);
158
171
 
159
172
  switch (dimension) {
160
173
  case '2d-array':
161
174
  case '3d':
162
175
  if (compressed) {
163
176
  // prettier-ignore
164
- 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
165
178
  } else {
166
179
  // prettier-ignore
167
- 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
168
181
  }
169
182
  break;
170
183
 
@@ -172,10 +185,10 @@ export function copyCPUDataToMipLevel(
172
185
  case 'cube':
173
186
  if (compressed) {
174
187
  // prettier-ignore
175
- 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
176
189
  } else {
177
190
  // prettier-ignore
178
- 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
179
192
  }
180
193
  break;
181
194
 
@@ -193,10 +206,10 @@ export function copyGPUBufferToMipLevel(
193
206
  byteLength: number,
194
207
  options: WebGLCopyTextureOptions
195
208
  ): void {
196
- const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
209
+ const {dimension, width, height, depth = 0, mipLevel = 0, byteOffset = 0} = options;
197
210
  const {x = 0, y = 0, z = 0} = options;
198
211
  const {glFormat, glType, compressed} = options;
199
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
212
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
200
213
 
201
214
  gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, webglBuffer);
202
215
 
@@ -207,10 +220,10 @@ export function copyGPUBufferToMipLevel(
207
220
  if (compressed) {
208
221
  // TODO enable extension?
209
222
  // prettier-ignore
210
- 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);
211
224
  } else {
212
225
  // prettier-ignore
213
- 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);
214
227
  }
215
228
  break;
216
229
 
@@ -218,10 +231,10 @@ export function copyGPUBufferToMipLevel(
218
231
  case 'cube':
219
232
  if (compressed) {
220
233
  // prettier-ignore
221
- gl.compressedTexSubImage2D(glTarget, level, x, y, width, height, glFormat, byteLength, byteOffset);
234
+ gl.compressedTexSubImage2D(glTarget, mipLevel, x, y, width, height, glFormat, byteLength, byteOffset);
222
235
  } else {
223
236
  // prettier-ignore
224
- gl.texSubImage2D(glTarget, level, x, y, width, height, BORDER, glFormat, byteOffset);
237
+ gl.texSubImage2D(glTarget, mipLevel, x, y, width, height, BORDER, glFormat, byteOffset);
225
238
  }
226
239
  break;
227
240
 
@@ -250,9 +263,10 @@ export function getWebGLTextureTarget(
250
263
 
251
264
  /**
252
265
  * In WebGL, cube maps specify faces by overriding target instead of using the depth parameter.
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.
253
267
  * @returns glTarget unchanged, if dimension !== 'cube'.
254
268
  */
255
- function getCubeTargetWebGL(
269
+ export function getWebGLCubeFaceTarget(
256
270
  glTarget: GLTextureTarget,
257
271
  dimension: '1d' | '2d' | '2d-array' | 'cube' | 'cube-array' | '3d',
258
272
  level: number
@@ -267,19 +281,19 @@ function getCubeTargetWebGL(
267
281
  * Wrapper for the messy WebGL texture API
268
282
  *
269
283
  export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextureOptions): void {
270
- const {dimension, width, height, depth = 0, level = 0} = options;
284
+ const {dimension, width, height, depth = 0, mipLevel = 0} = options;
271
285
  const {glInternalFormat, glFormat, glType, compressed} = options;
272
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
286
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
273
287
 
274
288
  switch (dimension) {
275
289
  case '2d-array':
276
290
  case '3d':
277
291
  if (compressed) {
278
292
  // prettier-ignore
279
- gl.compressedTexImage3D(glTarget, level, glInternalFormat, width, height, depth, BORDER, null);
293
+ gl.compressedTexImage3D(glTarget, mipLevel, glInternalFormat, width, height, depth, BORDER, null);
280
294
  } else {
281
295
  // prettier-ignore
282
- 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);
283
297
  }
284
298
  break;
285
299
 
@@ -287,10 +301,10 @@ export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextu
287
301
  case 'cube':
288
302
  if (compressed) {
289
303
  // prettier-ignore
290
- gl.compressedTexImage2D(glTarget, level, glInternalFormat, width, height, BORDER, null);
304
+ gl.compressedTexImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, null);
291
305
  } else {
292
306
  // prettier-ignore
293
- gl.texImage2D(glTarget, level, glInternalFormat, width, height, BORDER, glFormat, glType, null);
307
+ gl.texImage2D(glTarget, mipLevel, glInternalFormat, width, height, BORDER, glFormat, glType, null);
294
308
  }
295
309
  break;
296
310
 
@@ -298,6 +312,7 @@ export function clearMipLevel(gl: WebGL2RenderingContext, options: WebGLSetTextu
298
312
  throw new Error(dimension);
299
313
  }
300
314
  }
315
+ */
301
316
 
302
317
  /**
303
318
  * Set a texture mip level to the contents of an external image.
@@ -312,7 +327,7 @@ export function setMipLevelFromExternalImage(
312
327
  const {dimension, width, height, depth = 0, level = 0} = options;
313
328
  const {glInternalFormat, glType} = options;
314
329
 
315
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
330
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
316
331
 
317
332
  // TODO - we can't change texture width (due to WebGPU limitations) -
318
333
  // and the width/heigh of an external image is implicit, so why do we need to extract it?
@@ -363,7 +378,7 @@ export function setMipLevelFromTypedArray(
363
378
  const {dimension, width, height, depth = 0, level = 0, offset = 0} = options;
364
379
  const {glInternalFormat, glFormat, glType, compressed} = options;
365
380
 
366
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
381
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
367
382
 
368
383
  withGLParameters(gl, parameters, () => {
369
384
  switch (dimension) {
@@ -442,7 +457,7 @@ export function setMipLevelFromGPUBuffer(
442
457
  ): void {
443
458
  const {dimension, width, height, depth = 0, level = 0, byteOffset = 0} = options;
444
459
  const {glInternalFormat, glFormat, glType, compressed} = options;
445
- const glTarget = getCubeTargetWebGL(options.glTarget, dimension, depth);
460
+ const glTarget = getWebGLCubeFaceTarget(options.glTarget, dimension, depth);
446
461
 
447
462
  const webglBuffer = buffer as WEBGLBuffer;
448
463
  const imageSize = buffer.byteLength;
@@ -479,3 +494,334 @@ export function setMipLevelFromGPUBuffer(
479
494
  gl.bindBuffer(GL.PIXEL_UNPACK_BUFFER, null);
480
495
  }
481
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