@luma.gl/webgl 9.0.0-beta.4 → 9.0.0-beta.5

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 (237) hide show
  1. package/dist/adapter/converters/device-parameters.js +240 -158
  2. package/dist/adapter/converters/sampler-parameters.d.ts +0 -4
  3. package/dist/adapter/converters/sampler-parameters.d.ts.map +1 -1
  4. package/dist/adapter/converters/sampler-parameters.js +73 -68
  5. package/dist/adapter/converters/shader-formats.js +33 -46
  6. package/dist/adapter/converters/texture-formats.d.ts +9 -18
  7. package/dist/adapter/converters/texture-formats.d.ts.map +1 -1
  8. package/dist/adapter/converters/texture-formats.js +454 -871
  9. package/dist/adapter/converters/vertex-formats.js +52 -61
  10. package/dist/adapter/device-helpers/device-features.d.ts +2 -5
  11. package/dist/adapter/device-helpers/device-features.d.ts.map +1 -1
  12. package/dist/adapter/device-helpers/device-features.js +56 -87
  13. package/dist/adapter/device-helpers/device-limits.d.ts +2 -4
  14. package/dist/adapter/device-helpers/device-limits.d.ts.map +1 -1
  15. package/dist/adapter/device-helpers/device-limits.js +88 -83
  16. package/dist/adapter/device-helpers/get-device-info.d.ts +1 -1
  17. package/dist/adapter/device-helpers/get-device-info.d.ts.map +1 -1
  18. package/dist/adapter/device-helpers/get-device-info.js +79 -63
  19. package/dist/adapter/device-helpers/webgl-device-features.d.ts +6 -0
  20. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -0
  21. package/dist/adapter/device-helpers/webgl-device-features.js +52 -0
  22. package/dist/adapter/device-helpers/webgl-device-info.d.ts +4 -0
  23. package/dist/adapter/device-helpers/webgl-device-info.d.ts.map +1 -0
  24. package/dist/adapter/device-helpers/webgl-device-info.js +87 -0
  25. package/dist/adapter/device-helpers/webgl-device-limits.d.ts +50 -0
  26. package/dist/adapter/device-helpers/webgl-device-limits.d.ts.map +1 -0
  27. package/dist/adapter/device-helpers/webgl-device-limits.js +92 -0
  28. package/dist/adapter/helpers/decode-webgl-types.js +87 -76
  29. package/dist/adapter/helpers/get-shader-layout.d.ts +1 -1
  30. package/dist/adapter/helpers/get-shader-layout.d.ts.map +1 -1
  31. package/dist/adapter/helpers/get-shader-layout.js +261 -226
  32. package/dist/adapter/helpers/parse-shader-compiler-log.js +46 -37
  33. package/dist/adapter/helpers/set-uniform.d.ts +1 -1
  34. package/dist/adapter/helpers/set-uniform.d.ts.map +1 -1
  35. package/dist/adapter/helpers/set-uniform.js +67 -82
  36. package/dist/adapter/helpers/webgl-topology-utils.js +77 -93
  37. package/dist/adapter/objects/constants-to-keys.d.ts +1 -1
  38. package/dist/adapter/objects/constants-to-keys.d.ts.map +1 -1
  39. package/dist/adapter/objects/constants-to-keys.js +18 -12
  40. package/dist/adapter/objects/webgl-renderbuffer.js +76 -80
  41. package/dist/adapter/objects/webgl-resource.d.ts +1 -1
  42. package/dist/adapter/objects/webgl-resource.d.ts.map +1 -1
  43. package/dist/adapter/objects/webgl-resource.js +204 -154
  44. package/dist/adapter/resources/webgl-buffer.d.ts +2 -3
  45. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  46. package/dist/adapter/resources/webgl-buffer.js +160 -119
  47. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  48. package/dist/adapter/resources/webgl-command-buffer.js +268 -171
  49. package/dist/adapter/resources/webgl-command-encoder.js +32 -40
  50. package/dist/adapter/resources/webgl-external-texture.js +92 -1
  51. package/dist/adapter/resources/webgl-framebuffer.d.ts +2 -2
  52. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  53. package/dist/adapter/resources/webgl-framebuffer.js +167 -139
  54. package/dist/adapter/resources/webgl-render-pass.js +121 -95
  55. package/dist/adapter/resources/webgl-render-pipeline.d.ts +11 -1
  56. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  57. package/dist/adapter/resources/webgl-render-pipeline.js +378 -228
  58. package/dist/adapter/resources/webgl-sampler.d.ts +0 -2
  59. package/dist/adapter/resources/webgl-sampler.d.ts.map +1 -1
  60. package/dist/adapter/resources/webgl-sampler.js +43 -34
  61. package/dist/adapter/resources/webgl-shader.d.ts +10 -1
  62. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  63. package/dist/adapter/resources/webgl-shader.js +106 -45
  64. package/dist/adapter/resources/webgl-texture.d.ts +2 -6
  65. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  66. package/dist/adapter/resources/webgl-texture.js +614 -699
  67. package/dist/adapter/resources/webgl-transform-feedback.d.ts +1 -1
  68. package/dist/adapter/resources/webgl-transform-feedback.d.ts.map +1 -1
  69. package/dist/adapter/resources/webgl-transform-feedback.js +143 -145
  70. package/dist/adapter/resources/webgl-vertex-array.d.ts +1 -1
  71. package/dist/adapter/resources/webgl-vertex-array.d.ts.map +1 -1
  72. package/dist/adapter/resources/webgl-vertex-array.js +229 -158
  73. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  74. package/dist/adapter/webgl-canvas-context.js +58 -37
  75. package/dist/adapter/webgl-device.d.ts +7 -15
  76. package/dist/adapter/webgl-device.d.ts.map +1 -1
  77. package/dist/adapter/webgl-device.js +440 -381
  78. package/dist/classic/accessor.js +132 -102
  79. package/dist/classic/clear.d.ts +2 -2
  80. package/dist/classic/clear.d.ts.map +1 -1
  81. package/dist/classic/clear.js +73 -73
  82. package/dist/classic/copy-and-blit.d.ts.map +1 -1
  83. package/dist/classic/copy-and-blit.js +176 -177
  84. package/dist/classic/format-utils.d.ts +2 -2
  85. package/dist/classic/format-utils.js +38 -32
  86. package/dist/classic/typed-array-utils.js +95 -81
  87. package/dist/context/{polyfill → context}/context-data.d.ts +2 -1
  88. package/dist/context/context/context-data.d.ts.map +1 -0
  89. package/dist/context/context/context-data.js +33 -0
  90. package/dist/context/context/create-browser-context.d.ts +1 -6
  91. package/dist/context/context/create-browser-context.d.ts.map +1 -1
  92. package/dist/context/context/create-browser-context.js +62 -49
  93. package/dist/context/debug/spector.js +54 -50
  94. package/dist/context/debug/webgl-developer-tools.d.ts +1 -2
  95. package/dist/context/debug/webgl-developer-tools.d.ts.map +1 -1
  96. package/dist/context/debug/webgl-developer-tools.js +102 -76
  97. package/dist/context/parameters/unified-parameter-api.d.ts +3 -3
  98. package/dist/context/parameters/unified-parameter-api.d.ts.map +1 -1
  99. package/dist/context/parameters/unified-parameter-api.js +95 -46
  100. package/dist/context/parameters/webgl-parameter-tables.d.ts +110 -99
  101. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  102. package/dist/context/parameters/webgl-parameter-tables.js +456 -404
  103. package/dist/context/state-tracker/deep-array-equal.js +18 -14
  104. package/dist/context/state-tracker/track-context-state.d.ts +4 -4
  105. package/dist/context/state-tracker/track-context-state.d.ts.map +1 -1
  106. package/dist/context/state-tracker/track-context-state.js +190 -126
  107. package/dist/context/state-tracker/with-parameters.d.ts +1 -1
  108. package/dist/context/state-tracker/with-parameters.d.ts.map +1 -1
  109. package/dist/context/state-tracker/with-parameters.js +45 -29
  110. package/dist/dist.dev.js +2568 -3786
  111. package/dist/index.cjs +1346 -2464
  112. package/dist/index.cjs.map +7 -0
  113. package/dist/index.d.ts +2 -5
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +36 -26
  116. package/dist/types.js +2 -1
  117. package/dist.min.js +9 -42
  118. package/package.json +11 -15
  119. package/src/adapter/converters/device-parameters.ts +0 -1
  120. package/src/adapter/converters/sampler-parameters.ts +0 -17
  121. package/src/adapter/converters/texture-formats.ts +86 -154
  122. package/src/adapter/device-helpers/webgl-device-features.ts +69 -0
  123. package/src/adapter/device-helpers/{get-device-info.ts → webgl-device-info.ts} +3 -4
  124. package/src/adapter/device-helpers/{device-limits.ts → webgl-device-limits.ts} +25 -23
  125. package/src/adapter/helpers/get-shader-layout.ts +17 -28
  126. package/src/adapter/helpers/set-uniform.ts +1 -3
  127. package/src/adapter/objects/constants-to-keys.ts +1 -1
  128. package/src/adapter/objects/webgl-renderbuffer.ts +4 -4
  129. package/src/adapter/objects/webgl-resource.ts +3 -18
  130. package/src/adapter/resources/webgl-buffer.ts +6 -11
  131. package/src/adapter/resources/webgl-command-buffer.ts +20 -30
  132. package/src/adapter/resources/webgl-external-texture.ts +2 -3
  133. package/src/adapter/resources/webgl-framebuffer.ts +4 -5
  134. package/src/adapter/resources/webgl-render-pass.ts +7 -7
  135. package/src/adapter/resources/webgl-render-pipeline.ts +106 -31
  136. package/src/adapter/resources/webgl-sampler.ts +5 -9
  137. package/src/adapter/resources/webgl-shader.ts +57 -10
  138. package/src/adapter/resources/webgl-texture.ts +29 -103
  139. package/src/adapter/resources/webgl-transform-feedback.ts +14 -15
  140. package/src/adapter/resources/webgl-vertex-array.ts +16 -18
  141. package/src/adapter/webgl-canvas-context.ts +1 -7
  142. package/src/adapter/webgl-device.ts +18 -67
  143. package/src/classic/clear.ts +13 -14
  144. package/src/classic/copy-and-blit.ts +1 -2
  145. package/src/context/context/context-data.ts +44 -0
  146. package/src/context/context/create-browser-context.ts +7 -32
  147. package/src/context/debug/webgl-developer-tools.ts +6 -8
  148. package/src/context/parameters/unified-parameter-api.ts +3 -3
  149. package/src/context/parameters/webgl-parameter-tables.ts +66 -75
  150. package/src/context/state-tracker/track-context-state.ts +18 -17
  151. package/src/context/state-tracker/with-parameters.ts +1 -1
  152. package/src/index.ts +2 -17
  153. package/dist/adapter/converters/device-parameters.js.map +0 -1
  154. package/dist/adapter/converters/sampler-parameters.js.map +0 -1
  155. package/dist/adapter/converters/shader-formats.js.map +0 -1
  156. package/dist/adapter/converters/texture-formats.js.map +0 -1
  157. package/dist/adapter/converters/vertex-formats.js.map +0 -1
  158. package/dist/adapter/device-helpers/device-features.js.map +0 -1
  159. package/dist/adapter/device-helpers/device-limits.js.map +0 -1
  160. package/dist/adapter/device-helpers/get-device-info.js.map +0 -1
  161. package/dist/adapter/device-helpers/is-old-ie.d.ts +0 -2
  162. package/dist/adapter/device-helpers/is-old-ie.d.ts.map +0 -1
  163. package/dist/adapter/device-helpers/is-old-ie.js +0 -9
  164. package/dist/adapter/device-helpers/is-old-ie.js.map +0 -1
  165. package/dist/adapter/helpers/decode-webgl-types.js.map +0 -1
  166. package/dist/adapter/helpers/get-shader-layout.js.map +0 -1
  167. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +0 -1
  168. package/dist/adapter/helpers/set-uniform.js.map +0 -1
  169. package/dist/adapter/helpers/webgl-topology-utils.js.map +0 -1
  170. package/dist/adapter/objects/constants-to-keys.js.map +0 -1
  171. package/dist/adapter/objects/webgl-renderbuffer.js.map +0 -1
  172. package/dist/adapter/objects/webgl-resource.js.map +0 -1
  173. package/dist/adapter/resources/webgl-buffer.js.map +0 -1
  174. package/dist/adapter/resources/webgl-command-buffer.js.map +0 -1
  175. package/dist/adapter/resources/webgl-command-encoder.js.map +0 -1
  176. package/dist/adapter/resources/webgl-external-texture.js.map +0 -1
  177. package/dist/adapter/resources/webgl-framebuffer.js.map +0 -1
  178. package/dist/adapter/resources/webgl-render-pass.js.map +0 -1
  179. package/dist/adapter/resources/webgl-render-pipeline.js.map +0 -1
  180. package/dist/adapter/resources/webgl-sampler.js.map +0 -1
  181. package/dist/adapter/resources/webgl-shader.js.map +0 -1
  182. package/dist/adapter/resources/webgl-texture.js.map +0 -1
  183. package/dist/adapter/resources/webgl-transform-feedback.js.map +0 -1
  184. package/dist/adapter/resources/webgl-vertex-array.js.map +0 -1
  185. package/dist/adapter/webgl-canvas-context.js.map +0 -1
  186. package/dist/adapter/webgl-device.js.map +0 -1
  187. package/dist/classic/accessor.js.map +0 -1
  188. package/dist/classic/clear.js.map +0 -1
  189. package/dist/classic/copy-and-blit.js.map +0 -1
  190. package/dist/classic/format-utils.js.map +0 -1
  191. package/dist/classic/typed-array-utils.js.map +0 -1
  192. package/dist/context/context/create-browser-context.js.map +0 -1
  193. package/dist/context/context/create-headless-context.d.ts +0 -9
  194. package/dist/context/context/create-headless-context.d.ts.map +0 -1
  195. package/dist/context/context/create-headless-context.js +0 -42
  196. package/dist/context/context/create-headless-context.js.map +0 -1
  197. package/dist/context/context/webgl-checks.d.ts +0 -13
  198. package/dist/context/context/webgl-checks.d.ts.map +0 -1
  199. package/dist/context/context/webgl-checks.js +0 -31
  200. package/dist/context/context/webgl-checks.js.map +0 -1
  201. package/dist/context/debug/spector.js.map +0 -1
  202. package/dist/context/debug/webgl-developer-tools.js.map +0 -1
  203. package/dist/context/parameters/unified-parameter-api.js.map +0 -1
  204. package/dist/context/parameters/webgl-parameter-tables.js.map +0 -1
  205. package/dist/context/polyfill/context-data.d.ts.map +0 -1
  206. package/dist/context/polyfill/context-data.js +0 -12
  207. package/dist/context/polyfill/context-data.js.map +0 -1
  208. package/dist/context/polyfill/get-parameter-polyfill.d.ts +0 -2
  209. package/dist/context/polyfill/get-parameter-polyfill.d.ts.map +0 -1
  210. package/dist/context/polyfill/get-parameter-polyfill.js +0 -85
  211. package/dist/context/polyfill/get-parameter-polyfill.js.map +0 -1
  212. package/dist/context/polyfill/polyfill-context.d.ts +0 -5
  213. package/dist/context/polyfill/polyfill-context.d.ts.map +0 -1
  214. package/dist/context/polyfill/polyfill-context.js +0 -87
  215. package/dist/context/polyfill/polyfill-context.js.map +0 -1
  216. package/dist/context/polyfill/polyfill-table.d.ts +0 -48
  217. package/dist/context/polyfill/polyfill-table.d.ts.map +0 -1
  218. package/dist/context/polyfill/polyfill-table.js +0 -137
  219. package/dist/context/polyfill/polyfill-table.js.map +0 -1
  220. package/dist/context/polyfill/polyfill-vertex-array-object.d.ts +0 -2
  221. package/dist/context/polyfill/polyfill-vertex-array-object.d.ts.map +0 -1
  222. package/dist/context/polyfill/polyfill-vertex-array-object.js +0 -265
  223. package/dist/context/polyfill/polyfill-vertex-array-object.js.map +0 -1
  224. package/dist/context/state-tracker/deep-array-equal.js.map +0 -1
  225. package/dist/context/state-tracker/track-context-state.js.map +0 -1
  226. package/dist/context/state-tracker/with-parameters.js.map +0 -1
  227. package/dist/index.js.map +0 -1
  228. package/dist/types.js.map +0 -1
  229. package/src/adapter/device-helpers/device-features.ts +0 -161
  230. package/src/adapter/device-helpers/is-old-ie.ts +0 -14
  231. package/src/context/context/create-headless-context.ts +0 -51
  232. package/src/context/context/webgl-checks.ts +0 -51
  233. package/src/context/polyfill/context-data.ts +0 -30
  234. package/src/context/polyfill/get-parameter-polyfill.ts +0 -122
  235. package/src/context/polyfill/polyfill-context.ts +0 -104
  236. package/src/context/polyfill/polyfill-table.ts +0 -167
  237. package/src/context/polyfill/polyfill-vertex-array-object.ts +0 -365
@@ -65,12 +65,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
65
65
  // @ts-expect-error WebGL only
66
66
  const {varyings, bufferMode = GL.SEPARATE_ATTRIBS} = props;
67
67
  if (varyings && varyings.length > 0) {
68
- this.device.assertWebGL2();
69
68
  this.varyings = varyings;
70
- this.device.gl2?.transformFeedbackVaryings(this.handle, varyings, bufferMode);
69
+ this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
71
70
  }
72
71
 
73
- this._compileAndLink();
72
+ this._linkShaders();
74
73
 
75
74
  this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
76
75
  // Merge provided layout with introspected layout
@@ -80,7 +79,9 @@ export class WEBGLRenderPipeline extends RenderPipeline {
80
79
  switch (this.props.topology) {
81
80
  case 'triangle-fan-webgl':
82
81
  case 'line-loop-webgl':
83
- log.warn(`Primitive topology ${this.props.topology} is deprecated and will be removed in v9.1`);
82
+ log.warn(
83
+ `Primitive topology ${this.props.topology} is deprecated and will be removed in v9.1`
84
+ );
84
85
  break;
85
86
  default:
86
87
  }
@@ -152,7 +153,9 @@ export class WEBGLRenderPipeline extends RenderPipeline {
152
153
  const {bindings} = splitUniformsAndBindings(uniforms);
153
154
  Object.keys(bindings).forEach(name => {
154
155
  log.warn(
155
- `Unsupported value "${JSON.stringify(bindings[name])}" used in setUniforms() for key ${name}. Use setBindings() instead?`
156
+ `Unsupported value "${JSON.stringify(
157
+ bindings[name]
158
+ )}" used in setUniforms() for key ${name}. Use setBindings() instead?`
156
159
  )();
157
160
  });
158
161
  // TODO - check against layout
@@ -176,6 +179,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
176
179
  baseVertex?: number;
177
180
  transformFeedback?: WEBGLTransformFeedback;
178
181
  }): boolean {
182
+ // If we are using async linking, we need to wait until linking completes
183
+ if (this.linkStatus !== 'success') {
184
+ return false;
185
+ }
186
+
179
187
  const {
180
188
  renderPass,
181
189
  vertexArray,
@@ -220,7 +228,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
220
228
  // // TODO - Use polyfilled WebGL2RenderingContext instead of ANGLE extension
221
229
  // if (isIndexed && isInstanced) {
222
230
  // // ANGLE_instanced_arrays extension
223
- // this.device.gl2?.drawElementsInstanced(
231
+ // this.device.gl.drawElementsInstanced(
224
232
  // drawMode,
225
233
  // vertexCount || 0, // indexCount?
226
234
  // indexType,
@@ -228,11 +236,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
228
236
  // instanceCount || 0
229
237
  // );
230
238
  // // } else if (isIndexed && this.device.isWebGL2 && !isNaN(start) && !isNaN(end)) {
231
- // // this.device.gl2.drawRangeElements(drawMode, start, end, vertexCount, indexType, offset);
239
+ // // this.device.gldrawRangeElements(drawMode, start, end, vertexCount, indexType, offset);
232
240
  // } else if (isIndexed) {
233
241
  // this.device.gl.drawElements(drawMode, vertexCount || 0, indexType, firstVertex); // indexCount?
234
242
  // } else if (isInstanced) {
235
- // this.device.gl2?.drawArraysInstanced(
243
+ // this.device.gl.drawArraysInstanced(
236
244
  // drawMode,
237
245
  // firstVertex,
238
246
  // vertexCount || 0,
@@ -250,7 +258,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
250
258
  () => {
251
259
  if (isIndexed && isInstanced) {
252
260
  // ANGLE_instanced_arrays extension
253
- this.device.gl2?.drawElementsInstanced(
261
+ this.device.gl.drawElementsInstanced(
254
262
  glDrawMode,
255
263
  vertexCount || 0, // indexCount?
256
264
  glIndexType,
@@ -258,11 +266,11 @@ export class WEBGLRenderPipeline extends RenderPipeline {
258
266
  instanceCount || 0
259
267
  );
260
268
  // } else if (isIndexed && this.device.isWebGL2 && !isNaN(start) && !isNaN(end)) {
261
- // this.device.gl2.drawRangeElements(glDrawMode, start, end, vertexCount, glIndexType, offset);
269
+ // this.device.gldrawRangeElements(glDrawMode, start, end, vertexCount, glIndexType, offset);
262
270
  } else if (isIndexed) {
263
271
  this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex); // indexCount?
264
272
  } else if (isInstanced) {
265
- this.device.gl2?.drawArraysInstanced(
273
+ this.device.gl.drawArraysInstanced(
266
274
  glDrawMode,
267
275
  firstVertex,
268
276
  vertexCount || 0,
@@ -283,10 +291,12 @@ export class WEBGLRenderPipeline extends RenderPipeline {
283
291
  return true;
284
292
  }
285
293
 
294
+ // PRIVATE METHODS
295
+
286
296
  // setAttributes(attributes: Record<string, Buffer>): void {}
287
297
  // setBindings(bindings: Record<string, Binding>): void {}
288
298
 
289
- protected _compileAndLink() {
299
+ protected async _linkShaders() {
290
300
  const {gl} = this.device;
291
301
  gl.attachShader(this.handle, this.vs.handle);
292
302
  gl.attachShader(this.handle, this.fs.handle);
@@ -294,25 +304,89 @@ export class WEBGLRenderPipeline extends RenderPipeline {
294
304
  gl.linkProgram(this.handle);
295
305
  log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
296
306
 
297
- // Avoid checking program linking error in production
298
- // @ts-expect-error
299
- if (!gl.debug && log.level === 0) {
307
+ // TODO Avoid checking program linking error in production
308
+ if (log.level === 0) {
300
309
  // return;
301
310
  }
302
311
 
312
+ if (!this.device.features.has('shader-status-async-webgl')) {
313
+ const status = this._getLinkStatus();
314
+ this._reportLinkStatus(status);
315
+ return;
316
+ }
317
+
318
+ // async case
319
+ log.once(1, 'RenderPipeline linking is asynchronous')();
320
+ await this._waitForLinkComplete();
321
+ log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
322
+ const status = this._getLinkStatus();
323
+ this._reportLinkStatus(status);
324
+ }
325
+
326
+ /** Report link status. First, check for shader compilation failures if linking fails */
327
+ _reportLinkStatus(status: 'success' | 'linking' | 'validation') {
328
+ switch (status) {
329
+ case 'success':
330
+ return;
331
+
332
+ default:
333
+ // First check for shader compilation failures if linking fails
334
+ if (this.vs.compilationStatus === 'error') {
335
+ this.vs.debugShader();
336
+ throw new Error(`Error during compilation of shader ${this.vs.id}`);
337
+ }
338
+ if (this.fs?.compilationStatus === 'error') {
339
+ this.vs.debugShader();
340
+ throw new Error(`Error during compilation of shader ${this.fs.id}`);
341
+ }
342
+ throw new Error(`Error during ${status}: ${this.device.gl.getProgramInfoLog(this.handle)}`);
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Get the shader compilation status
348
+ * TODO - Load log even when no error reported, to catch warnings?
349
+ * https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
350
+ */
351
+ _getLinkStatus(): 'success' | 'linking' | 'validation' {
352
+ const {gl} = this.device;
303
353
  const linked = gl.getProgramParameter(this.handle, gl.LINK_STATUS);
304
354
  if (!linked) {
305
- throw new Error(`Error linking: ${gl.getProgramInfoLog(this.handle)}`);
355
+ this.linkStatus = 'error';
356
+ return 'linking';
306
357
  }
307
358
 
308
359
  gl.validateProgram(this.handle);
309
360
  const validated = gl.getProgramParameter(this.handle, gl.VALIDATE_STATUS);
310
361
  if (!validated) {
311
- throw new Error(`Error validating: ${gl.getProgramInfoLog(this.handle)}`);
362
+ this.linkStatus = 'error';
363
+ return 'validation';
312
364
  }
365
+
366
+ this.linkStatus = 'success';
367
+ return 'success';
313
368
  }
314
369
 
315
- // PRIVATE METHODS
370
+ /** Use KHR_parallel_shader_compile extension if available */
371
+ async _waitForLinkComplete(): Promise<void> {
372
+ const waitMs = async (ms: number) => await new Promise(resolve => setTimeout(resolve, ms));
373
+ const DELAY_MS = 10; // Shader compilation is typically quite fast (with some exceptions)
374
+
375
+ // If status polling is not available, we can't wait for completion. Just wait a little to minimize blocking
376
+ if (!this.device.features.has('shader-status-async-webgl')) {
377
+ await waitMs(DELAY_MS);
378
+ return;
379
+ }
380
+
381
+ const {gl} = this.device;
382
+ for (;;) {
383
+ const complete = gl.getProgramParameter(this.handle, GL.COMPLETION_STATUS);
384
+ if (complete) {
385
+ return;
386
+ }
387
+ await waitMs(DELAY_MS);
388
+ }
389
+ }
316
390
 
317
391
  /**
318
392
  * Checks if all texture-values uniforms are renderable (i.e. loaded)
@@ -334,13 +408,14 @@ export class WEBGLRenderPipeline extends RenderPipeline {
334
408
 
335
409
  /** Apply any bindings (before each draw call) */
336
410
  _applyBindings() {
337
- this.device.gl.useProgram(this.handle);
338
-
339
- const {gl2} = this.device;
340
- if (!gl2) {
341
- throw new Error('bindings');
411
+ // If we are using async linking, we need to wait until linking completes
412
+ if (this.linkStatus !== 'success') {
413
+ return;
342
414
  }
343
415
 
416
+ const {gl} = this.device;
417
+ gl.useProgram(this.handle);
418
+
344
419
  let textureUnit = 0;
345
420
  let uniformBufferIndex = 0;
346
421
  for (const binding of this.shaderLayout.bindings) {
@@ -354,16 +429,16 @@ export class WEBGLRenderPipeline extends RenderPipeline {
354
429
  case 'uniform':
355
430
  // Set buffer
356
431
  const {name} = binding;
357
- const location = gl2.getUniformBlockIndex(this.handle, name);
358
- if (location as GL === GL.INVALID_INDEX) {
432
+ const location = gl.getUniformBlockIndex(this.handle, name);
433
+ if ((location as GL) === GL.INVALID_INDEX) {
359
434
  throw new Error(`Invalid uniform block name ${name}`);
360
435
  }
361
- gl2.uniformBlockBinding(this.handle, uniformBufferIndex, location);
436
+ gl.uniformBlockBinding(this.handle, uniformBufferIndex, location);
362
437
  // console.debug(binding, location);
363
438
  if (value instanceof WEBGLBuffer) {
364
- gl2.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
439
+ gl.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
365
440
  } else {
366
- gl2.bindBufferRange(
441
+ gl.bindBufferRange(
367
442
  GL.UNIFORM_BUFFER,
368
443
  uniformBufferIndex,
369
444
  // @ts-expect-error
@@ -396,9 +471,9 @@ export class WEBGLRenderPipeline extends RenderPipeline {
396
471
  throw new Error('No texture');
397
472
  }
398
473
 
399
- gl2.activeTexture(GL.TEXTURE0 + textureUnit);
400
- gl2.bindTexture(texture.target, texture.handle);
401
- // gl2.bindSampler(textureUnit, sampler.handle);
474
+ gl.activeTexture(GL.TEXTURE0 + textureUnit);
475
+ gl.bindTexture(texture.target, texture.handle);
476
+ // gl.bindSampler(textureUnit, sampler.handle);
402
477
  textureUnit += 1;
403
478
  break;
404
479
 
@@ -8,8 +8,6 @@ import type {WebGLDevice} from '../webgl-device';
8
8
 
9
9
  /**
10
10
  * Sampler object -
11
- * Under WebGL2 we create an actual WebGL sampler
12
- * Under WebGL1, we just store the sampler parameters
13
11
  * so that they can be set directly on the texture
14
12
  * https://github.com/WebGLSamples/WebGL2Samples/blob/master/samples/sampler_object.html
15
13
  */
@@ -22,15 +20,13 @@ export class WEBGLSampler extends Sampler {
22
20
  super(device, props);
23
21
  this.device = device;
24
22
  this.parameters = convertSamplerParametersToWebGL(props);
25
- if (this.device.isWebGL2) {
26
- this.handle = this.handle || this.device.gl2.createSampler();
27
- this._setSamplerParameters(this.parameters);
28
- }
23
+ this.handle = this.handle || this.device.gl.createSampler();
24
+ this._setSamplerParameters(this.parameters);
29
25
  }
30
26
 
31
27
  override destroy(): void {
32
28
  if (this.handle) {
33
- this.device.gl2.deleteSampler(this.handle);
29
+ this.device.gl.deleteSampler(this.handle);
34
30
  // @ts-expect-error read-only/undefined
35
31
  this.handle = undefined;
36
32
  }
@@ -49,10 +45,10 @@ export class WEBGLSampler extends Sampler {
49
45
  switch (param) {
50
46
  case GL.TEXTURE_MIN_LOD:
51
47
  case GL.TEXTURE_MAX_LOD:
52
- this.device.gl2.samplerParameterf(this.handle, param, value);
48
+ this.device.gl.samplerParameterf(this.handle, param, value);
53
49
  break;
54
50
  default:
55
- this.device.gl2.samplerParameteri(this.handle, param, value);
51
+ this.device.gl.samplerParameteri(this.handle, param, value);
56
52
  break;
57
53
  }
58
54
  }
@@ -1,7 +1,7 @@
1
1
  // luma.gl, MIT license
2
2
  // Copyright (c) vis.gl contributors
3
3
 
4
- import {Shader, ShaderProps, CompilerMessage} from '@luma.gl/core';
4
+ import {Shader, ShaderProps, CompilerMessage, log} from '@luma.gl/core';
5
5
  import {GL} from '@luma.gl/constants';
6
6
  import {parseShaderCompilerLog} from '../helpers/parse-shader-compiler-log';
7
7
  import {WebGLDevice} from '../webgl-device';
@@ -39,6 +39,7 @@ export class WEBGLShader extends Shader {
39
39
  }
40
40
 
41
41
  override async getCompilationInfo(): Promise<readonly CompilerMessage[]> {
42
+ await this._waitForCompilationComplete();
42
43
  return this.getCompilationInfoSync();
43
44
  }
44
45
 
@@ -49,7 +50,8 @@ export class WEBGLShader extends Shader {
49
50
 
50
51
  // PRIVATE METHODS
51
52
 
52
- _compile(source: string): void {
53
+ /** Compile a shader and get compilation status */
54
+ protected async _compile(source: string): Promise<void> {
53
55
  const addGLSLVersion = (source: string) =>
54
56
  source.startsWith('#version ') ? source : `#version 100\n${source}`;
55
57
  source = addGLSLVersion(source);
@@ -58,18 +60,64 @@ export class WEBGLShader extends Shader {
58
60
  gl.shaderSource(this.handle, source);
59
61
  gl.compileShader(this.handle);
60
62
 
61
- // TODO - For performance reasons, avoid checking shader compilation errors on production?
62
- // TODO - Load log even when no error reported, to catch warnings?
63
- // https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
64
- this.compilationStatus = gl.getShaderParameter(this.handle, GL.COMPILE_STATUS) ? 'success' : 'error';
63
+ // For performance reasons, avoid checking shader compilation errors on production
64
+ if (log.level === 0) {
65
+ this.compilationStatus = 'pending';
66
+ return;
67
+ }
68
+
69
+ // Sync case - slower, but advantage is that it throws in the constructor, making break on error more useful
70
+ if (!this.device.features.has('shader-status-async-webgl')) {
71
+ this._getCompilationStatus();
72
+ if (this.compilationStatus === 'error') {
73
+ throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);
74
+ }
75
+ // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
76
+ this.debugShader();
77
+ return;
78
+ }
65
79
 
66
- // The `Shader` base class will determine if debug window should be opened based on props
80
+ // async case
81
+ log.once(1, 'Shader compilation is asynchronous')();
82
+ await this._waitForCompilationComplete();
83
+ log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
84
+ this._getCompilationStatus();
85
+
86
+ // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
67
87
  this.debugShader();
88
+ }
89
+
90
+ /** Use KHR_parallel_shader_compile extension if available */
91
+ protected async _waitForCompilationComplete(): Promise<void> {
92
+ const waitMs = async (ms: number) => await new Promise(resolve => setTimeout(resolve, ms));
93
+ const DELAY_MS = 10; // Shader compilation is typically quite fast (with some exceptions)
68
94
 
69
- if (this.compilationStatus === 'error') {
70
- throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);
95
+ // If status polling is not available, we can't wait for completion. Just wait a little to minimize blocking
96
+ if (!this.device.features.has('shader-status-async-webgl')) {
97
+ await waitMs(DELAY_MS);
98
+ return;
99
+ }
100
+
101
+ const {gl} = this.device;
102
+ for (;;) {
103
+ const complete = gl.getShaderParameter(this.handle, GL.COMPLETION_STATUS);
104
+ if (complete) {
105
+ return;
106
+ }
107
+ await waitMs(DELAY_MS);
71
108
  }
72
109
  }
110
+
111
+ /**
112
+ * Get the shader compilation status
113
+ * TODO - Load log even when no error reported, to catch warnings?
114
+ * https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
115
+ */
116
+ protected _getCompilationStatus() {
117
+ this.compilationStatus = this.device.gl.getShaderParameter(this.handle, GL.COMPILE_STATUS)
118
+ ? 'success'
119
+ : 'error';
120
+ }
73
121
  }
74
122
 
75
123
  // TODO - Original code from luma.gl v8 - keep until new debug functionality has matured
@@ -81,4 +129,3 @@ export class WEBGLShader extends Shader {
81
129
  // log.error(`GLSL compilation errors in ${shaderDescription}\n${formattedLog}`)();
82
130
  // displayShaderLog(parsedLog, source, shaderName);
83
131
  // }
84
-