@luma.gl/webgl 9.0.0-beta.3 → 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
@@ -1,245 +1,395 @@
1
+ // luma.gl, MIT license
2
+ // Copyright (c) vis.gl contributors
1
3
  import { RenderPipeline, cast, splitUniformsAndBindings, log } from '@luma.gl/core';
2
4
  import { mergeShaderLayout } from '@luma.gl/core';
3
- import { getShaderLayout } from "../helpers/get-shader-layout.js";
4
- import { withDeviceAndGLParameters } from "../converters/device-parameters.js";
5
- import { setUniform } from "../helpers/set-uniform.js";
6
- import { WEBGLBuffer } from "./webgl-buffer.js";
7
- import { WEBGLFramebuffer } from "./webgl-framebuffer.js";
8
- import { WEBGLTexture } from "./webgl-texture.js";
9
- import { getGLDrawMode } from "../helpers/webgl-topology-utils.js";
5
+ // import {mergeShaderLayout, getAttributeInfosFromLayouts} from '@luma.gl/core';
6
+ import { GL } from '@luma.gl/constants';
7
+ import { getShaderLayout } from '../helpers/get-shader-layout';
8
+ import { withDeviceAndGLParameters } from '../converters/device-parameters';
9
+ import { setUniform } from '../helpers/set-uniform';
10
+ import { WEBGLBuffer } from './webgl-buffer';
11
+ import { WEBGLFramebuffer } from './webgl-framebuffer';
12
+ import { WEBGLTexture } from './webgl-texture';
13
+ import { getGLDrawMode } from '../helpers/webgl-topology-utils';
10
14
  const LOG_PROGRAM_PERF_PRIORITY = 4;
15
+ /** Creates a new render pipeline */
11
16
  export class WEBGLRenderPipeline extends RenderPipeline {
12
- constructor(device, props) {
13
- super(device, props);
14
- this.device = void 0;
15
- this.handle = void 0;
16
- this.vs = void 0;
17
- this.fs = void 0;
18
- this.introspectedLayout = void 0;
19
- this.uniforms = {};
20
- this.bindings = {};
21
- this.varyings = null;
22
- this._uniformCount = 0;
23
- this._uniformSetters = {};
24
- this.device = device;
25
- this.handle = this.props.handle || this.device.gl.createProgram();
26
- this.device.setSpectorMetadata(this.handle, {
27
- id: this.props.id
28
- });
29
- this.vs = cast(props.vs);
30
- this.fs = cast(props.fs);
31
- const {
32
- varyings,
33
- bufferMode = 35981
34
- } = props;
35
- if (varyings && varyings.length > 0) {
36
- var _this$device$gl;
37
- this.device.assertWebGL2();
38
- this.varyings = varyings;
39
- (_this$device$gl = this.device.gl2) === null || _this$device$gl === void 0 ? void 0 : _this$device$gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
17
+ /** The WebGL device that created this render pipeline */
18
+ device;
19
+ /** Handle to underlying WebGL program */
20
+ handle;
21
+ /** vertex shader */
22
+ vs;
23
+ /** fragment shader */
24
+ fs;
25
+ /** The layout extracted from shader by WebGL introspection APIs */
26
+ introspectedLayout;
27
+ /** Uniforms set on this model */
28
+ uniforms = {};
29
+ /** Bindings set on this model */
30
+ bindings = {};
31
+ /** WebGL varyings */
32
+ varyings = null;
33
+ _uniformCount = 0;
34
+ _uniformSetters = {}; // TODO are these used?
35
+ constructor(device, props) {
36
+ super(device, props);
37
+ this.device = device;
38
+ this.handle = this.props.handle || this.device.gl.createProgram();
39
+ this.device.setSpectorMetadata(this.handle, { id: this.props.id });
40
+ // Create shaders if needed
41
+ this.vs = cast(props.vs);
42
+ this.fs = cast(props.fs);
43
+ // assert(this.vs.stage === 'vertex');
44
+ // assert(this.fs.stage === 'fragment');
45
+ // Setup varyings if supplied
46
+ // @ts-expect-error WebGL only
47
+ const { varyings, bufferMode = GL.SEPARATE_ATTRIBS } = props;
48
+ if (varyings && varyings.length > 0) {
49
+ this.varyings = varyings;
50
+ this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
51
+ }
52
+ this._linkShaders();
53
+ this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
54
+ // Merge provided layout with introspected layout
55
+ this.shaderLayout = mergeShaderLayout(this.introspectedLayout, props.shaderLayout);
56
+ // WebGPU has more restrictive topology support than WebGL
57
+ switch (this.props.topology) {
58
+ case 'triangle-fan-webgl':
59
+ case 'line-loop-webgl':
60
+ log.warn(`Primitive topology ${this.props.topology} is deprecated and will be removed in v9.1`);
61
+ break;
62
+ default:
63
+ }
40
64
  }
41
- this._compileAndLink();
42
- this.introspectedLayout = getShaderLayout(this.device.gl, this.handle);
43
- this.shaderLayout = mergeShaderLayout(this.introspectedLayout, props.shaderLayout);
44
- switch (this.props.topology) {
45
- case 'triangle-fan-webgl':
46
- case 'line-loop-webgl':
47
- log.warn(`Primitive topology ${this.props.topology} is deprecated and will be removed in v9.1`);
48
- break;
49
- default:
65
+ destroy() {
66
+ if (this.handle) {
67
+ this.device.gl.deleteProgram(this.handle);
68
+ // this.handle = null;
69
+ this.destroyed = true;
70
+ }
50
71
  }
51
- }
52
- destroy() {
53
- if (this.handle) {
54
- this.device.gl.deleteProgram(this.handle);
55
- this.destroyed = true;
72
+ /**
73
+ * Bindings include: textures, samplers and uniform buffers
74
+ * @todo needed for portable model
75
+ */
76
+ setBindings(bindings) {
77
+ // if (log.priority >= 2) {
78
+ // checkUniformValues(uniforms, this.id, this._uniformSetters);
79
+ // }
80
+ for (const [name, value] of Object.entries(bindings)) {
81
+ // Accept both `xyz` and `xyzUniforms` as valid names for `xyzUniforms` uniform block
82
+ // This convention allows shaders to name uniform blocks as `uniform appUniforms {} app;`
83
+ // and reference them as `app` from both GLSL and JS.
84
+ // TODO - this is rather hacky - we could also remap the name directly in the shader layout.
85
+ const binding = this.shaderLayout.bindings.find(binding => binding.name === name) ||
86
+ this.shaderLayout.bindings.find(binding => binding.name === `${name}Uniforms`);
87
+ if (!binding) {
88
+ const validBindings = this.shaderLayout.bindings
89
+ .map(binding => `"${binding.name}"`)
90
+ .join(', ');
91
+ log.warn(`Unknown binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`)();
92
+ continue; // eslint-disable-line no-continue
93
+ }
94
+ if (!value) {
95
+ log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
96
+ }
97
+ switch (binding.type) {
98
+ case 'uniform':
99
+ // @ts-expect-error
100
+ if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
101
+ throw new Error('buffer value');
102
+ }
103
+ break;
104
+ case 'texture':
105
+ if (!(value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
106
+ throw new Error('texture value');
107
+ }
108
+ break;
109
+ case 'sampler':
110
+ log.warn(`Ignoring sampler ${name}`)();
111
+ break;
112
+ default:
113
+ throw new Error(binding.type);
114
+ }
115
+ this.bindings[name] = value;
116
+ }
56
117
  }
57
- }
58
- setBindings(bindings) {
59
- for (const [name, value] of Object.entries(bindings)) {
60
- const binding = this.shaderLayout.bindings.find(binding => binding.name === name) || this.shaderLayout.bindings.find(binding => binding.name === `${name}Uniforms`);
61
- if (!binding) {
62
- const validBindings = this.shaderLayout.bindings.map(binding => `"${binding.name}"`).join(', ');
63
- log.warn(`Unknown binding "${name}" in render pipeline "${this.id}", expected one of ${validBindings}`)();
64
- continue;
65
- }
66
- if (!value) {
67
- log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
68
- }
69
- switch (binding.type) {
70
- case 'uniform':
71
- if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
72
- throw new Error('buffer value');
73
- }
74
- break;
75
- case 'texture':
76
- if (!(value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
77
- throw new Error('texture value');
78
- }
79
- break;
80
- case 'sampler':
81
- log.warn(`Ignoring sampler ${name}`)();
82
- break;
83
- default:
84
- throw new Error(binding.type);
85
- }
86
- this.bindings[name] = value;
118
+ /** This function is @deprecated, use uniform buffers */
119
+ setUniforms(uniforms) {
120
+ const { bindings } = splitUniformsAndBindings(uniforms);
121
+ Object.keys(bindings).forEach(name => {
122
+ log.warn(`Unsupported value "${JSON.stringify(bindings[name])}" used in setUniforms() for key ${name}. Use setBindings() instead?`)();
123
+ });
124
+ // TODO - check against layout
125
+ Object.assign(this.uniforms, uniforms);
87
126
  }
88
- }
89
- setUniforms(uniforms) {
90
- const {
91
- bindings
92
- } = splitUniformsAndBindings(uniforms);
93
- Object.keys(bindings).forEach(name => {
94
- log.warn(`Unsupported value "${JSON.stringify(bindings[name])}" used in setUniforms() for key ${name}. Use setBindings() instead?`)();
95
- });
96
- Object.assign(this.uniforms, uniforms);
97
- }
98
- draw(options) {
99
- var _vertexArray$indexBuf;
100
- const {
101
- renderPass,
102
- vertexArray,
103
- vertexCount,
104
- instanceCount,
105
- firstVertex = 0,
106
- transformFeedback
107
- } = options;
108
- const glDrawMode = getGLDrawMode(this.props.topology);
109
- const isIndexed = Boolean(vertexArray.indexBuffer);
110
- const glIndexType = (_vertexArray$indexBuf = vertexArray.indexBuffer) === null || _vertexArray$indexBuf === void 0 ? void 0 : _vertexArray$indexBuf.glIndexType;
111
- const isInstanced = Number(instanceCount) > 0;
112
- if (!this._areTexturesRenderable() || vertexCount === 0) {
113
- return false;
127
+ /** @todo needed for portable model
128
+ * @note The WebGL API is offers many ways to draw things
129
+ * This function unifies those ways into a single call using common parameters with sane defaults
130
+ */
131
+ draw(options) {
132
+ // If we are using async linking, we need to wait until linking completes
133
+ if (this.linkStatus !== 'success') {
134
+ return false;
135
+ }
136
+ const { renderPass, vertexArray, vertexCount,
137
+ // indexCount,
138
+ instanceCount, firstVertex = 0,
139
+ // firstIndex,
140
+ // firstInstance,
141
+ // baseVertex,
142
+ transformFeedback } = options;
143
+ const glDrawMode = getGLDrawMode(this.props.topology);
144
+ const isIndexed = Boolean(vertexArray.indexBuffer);
145
+ const glIndexType = vertexArray.indexBuffer?.glIndexType;
146
+ const isInstanced = Number(instanceCount) > 0;
147
+ // Avoid WebGL draw call when not rendering any data or values are incomplete
148
+ // Note: async textures set as uniforms might still be loading.
149
+ // Now that all uniforms have been updated, check if any texture
150
+ // in the uniforms is not yet initialized, then we don't draw
151
+ if (!this._areTexturesRenderable() || vertexCount === 0) {
152
+ // (isInstanced && instanceCount === 0)
153
+ return false;
154
+ }
155
+ this.device.gl.useProgram(this.handle);
156
+ // Note: Rebinds constant attributes before each draw call
157
+ vertexArray.bindBeforeRender(renderPass);
158
+ if (transformFeedback) {
159
+ transformFeedback.begin(this.props.topology);
160
+ }
161
+ // We have to apply bindings before every draw call since other draw calls will overwrite
162
+ this._applyBindings();
163
+ this._applyUniforms();
164
+ const webglRenderPass = renderPass;
165
+ // // TODO - Use polyfilled WebGL2RenderingContext instead of ANGLE extension
166
+ // if (isIndexed && isInstanced) {
167
+ // // ANGLE_instanced_arrays extension
168
+ // this.device.gl.drawElementsInstanced(
169
+ // drawMode,
170
+ // vertexCount || 0, // indexCount?
171
+ // indexType,
172
+ // firstVertex,
173
+ // instanceCount || 0
174
+ // );
175
+ // // } else if (isIndexed && this.device.isWebGL2 && !isNaN(start) && !isNaN(end)) {
176
+ // // this.device.gldrawRangeElements(drawMode, start, end, vertexCount, indexType, offset);
177
+ // } else if (isIndexed) {
178
+ // this.device.gl.drawElements(drawMode, vertexCount || 0, indexType, firstVertex); // indexCount?
179
+ // } else if (isInstanced) {
180
+ // this.device.gl.drawArraysInstanced(
181
+ // drawMode,
182
+ // firstVertex,
183
+ // vertexCount || 0,
184
+ // instanceCount || 0
185
+ // );
186
+ // } else {
187
+ // this.device.gl.drawArrays(drawMode, firstVertex, vertexCount || 0);
188
+ // }
189
+ // });
190
+ withDeviceAndGLParameters(this.device, this.props.parameters, webglRenderPass.glParameters, () => {
191
+ if (isIndexed && isInstanced) {
192
+ // ANGLE_instanced_arrays extension
193
+ this.device.gl.drawElementsInstanced(glDrawMode, vertexCount || 0, // indexCount?
194
+ glIndexType, firstVertex, instanceCount || 0);
195
+ // } else if (isIndexed && this.device.isWebGL2 && !isNaN(start) && !isNaN(end)) {
196
+ // this.device.gldrawRangeElements(glDrawMode, start, end, vertexCount, glIndexType, offset);
197
+ }
198
+ else if (isIndexed) {
199
+ this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex); // indexCount?
200
+ }
201
+ else if (isInstanced) {
202
+ this.device.gl.drawArraysInstanced(glDrawMode, firstVertex, vertexCount || 0, instanceCount || 0);
203
+ }
204
+ else {
205
+ this.device.gl.drawArrays(glDrawMode, firstVertex, vertexCount || 0);
206
+ }
207
+ if (transformFeedback) {
208
+ transformFeedback.end();
209
+ }
210
+ });
211
+ vertexArray.unbindAfterRender(renderPass);
212
+ return true;
114
213
  }
115
- this.device.gl.useProgram(this.handle);
116
- vertexArray.bindBeforeRender(renderPass);
117
- if (transformFeedback) {
118
- transformFeedback.begin(this.props.topology);
214
+ // PRIVATE METHODS
215
+ // setAttributes(attributes: Record<string, Buffer>): void {}
216
+ // setBindings(bindings: Record<string, Binding>): void {}
217
+ async _linkShaders() {
218
+ const { gl } = this.device;
219
+ gl.attachShader(this.handle, this.vs.handle);
220
+ gl.attachShader(this.handle, this.fs.handle);
221
+ log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
222
+ gl.linkProgram(this.handle);
223
+ log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
224
+ // TODO Avoid checking program linking error in production
225
+ if (log.level === 0) {
226
+ // return;
227
+ }
228
+ if (!this.device.features.has('shader-status-async-webgl')) {
229
+ const status = this._getLinkStatus();
230
+ this._reportLinkStatus(status);
231
+ return;
232
+ }
233
+ // async case
234
+ log.once(1, 'RenderPipeline linking is asynchronous')();
235
+ await this._waitForLinkComplete();
236
+ log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
237
+ const status = this._getLinkStatus();
238
+ this._reportLinkStatus(status);
119
239
  }
120
- this._applyBindings();
121
- this._applyUniforms();
122
- const webglRenderPass = renderPass;
123
- withDeviceAndGLParameters(this.device, this.props.parameters, webglRenderPass.glParameters, () => {
124
- if (isIndexed && isInstanced) {
125
- var _this$device$gl2;
126
- (_this$device$gl2 = this.device.gl2) === null || _this$device$gl2 === void 0 ? void 0 : _this$device$gl2.drawElementsInstanced(glDrawMode, vertexCount || 0, glIndexType, firstVertex, instanceCount || 0);
127
- } else if (isIndexed) {
128
- this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex);
129
- } else if (isInstanced) {
130
- var _this$device$gl3;
131
- (_this$device$gl3 = this.device.gl2) === null || _this$device$gl3 === void 0 ? void 0 : _this$device$gl3.drawArraysInstanced(glDrawMode, firstVertex, vertexCount || 0, instanceCount || 0);
132
- } else {
133
- this.device.gl.drawArrays(glDrawMode, firstVertex, vertexCount || 0);
134
- }
135
- if (transformFeedback) {
136
- transformFeedback.end();
137
- }
138
- });
139
- vertexArray.unbindAfterRender(renderPass);
140
- return true;
141
- }
142
- _compileAndLink() {
143
- const {
144
- gl
145
- } = this.device;
146
- gl.attachShader(this.handle, this.vs.handle);
147
- gl.attachShader(this.handle, this.fs.handle);
148
- log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
149
- gl.linkProgram(this.handle);
150
- log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
151
- if (!gl.debug && log.level === 0) {}
152
- const linked = gl.getProgramParameter(this.handle, 35714);
153
- if (!linked) {
154
- throw new Error(`Error linking: ${gl.getProgramInfoLog(this.handle)}`);
240
+ /** Report link status. First, check for shader compilation failures if linking fails */
241
+ _reportLinkStatus(status) {
242
+ switch (status) {
243
+ case 'success':
244
+ return;
245
+ default:
246
+ // First check for shader compilation failures if linking fails
247
+ if (this.vs.compilationStatus === 'error') {
248
+ this.vs.debugShader();
249
+ throw new Error(`Error during compilation of shader ${this.vs.id}`);
250
+ }
251
+ if (this.fs?.compilationStatus === 'error') {
252
+ this.vs.debugShader();
253
+ throw new Error(`Error during compilation of shader ${this.fs.id}`);
254
+ }
255
+ throw new Error(`Error during ${status}: ${this.device.gl.getProgramInfoLog(this.handle)}`);
256
+ }
155
257
  }
156
- gl.validateProgram(this.handle);
157
- const validated = gl.getProgramParameter(this.handle, 35715);
158
- if (!validated) {
159
- throw new Error(`Error validating: ${gl.getProgramInfoLog(this.handle)}`);
258
+ /**
259
+ * Get the shader compilation status
260
+ * TODO - Load log even when no error reported, to catch warnings?
261
+ * https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
262
+ */
263
+ _getLinkStatus() {
264
+ const { gl } = this.device;
265
+ const linked = gl.getProgramParameter(this.handle, gl.LINK_STATUS);
266
+ if (!linked) {
267
+ this.linkStatus = 'error';
268
+ return 'linking';
269
+ }
270
+ gl.validateProgram(this.handle);
271
+ const validated = gl.getProgramParameter(this.handle, gl.VALIDATE_STATUS);
272
+ if (!validated) {
273
+ this.linkStatus = 'error';
274
+ return 'validation';
275
+ }
276
+ this.linkStatus = 'success';
277
+ return 'success';
160
278
  }
161
- }
162
- _areTexturesRenderable() {
163
- let texturesRenderable = true;
164
- for (const [, texture] of Object.entries(this.bindings)) {
165
- if (texture instanceof WEBGLTexture) {
166
- texture.update();
167
- texturesRenderable = texturesRenderable && texture.loaded;
168
- }
279
+ /** Use KHR_parallel_shader_compile extension if available */
280
+ async _waitForLinkComplete() {
281
+ const waitMs = async (ms) => await new Promise(resolve => setTimeout(resolve, ms));
282
+ const DELAY_MS = 10; // Shader compilation is typically quite fast (with some exceptions)
283
+ // If status polling is not available, we can't wait for completion. Just wait a little to minimize blocking
284
+ if (!this.device.features.has('shader-status-async-webgl')) {
285
+ await waitMs(DELAY_MS);
286
+ return;
287
+ }
288
+ const { gl } = this.device;
289
+ for (;;) {
290
+ const complete = gl.getProgramParameter(this.handle, GL.COMPLETION_STATUS);
291
+ if (complete) {
292
+ return;
293
+ }
294
+ await waitMs(DELAY_MS);
295
+ }
169
296
  }
170
- return texturesRenderable;
171
- }
172
- _applyBindings() {
173
- this.device.gl.useProgram(this.handle);
174
- const {
175
- gl2
176
- } = this.device;
177
- if (!gl2) {
178
- throw new Error('bindings');
297
+ /**
298
+ * Checks if all texture-values uniforms are renderable (i.e. loaded)
299
+ * Update a texture if needed (e.g. from video)
300
+ * Note: This is currently done before every draw call
301
+ */
302
+ _areTexturesRenderable() {
303
+ let texturesRenderable = true;
304
+ for (const [, texture] of Object.entries(this.bindings)) {
305
+ if (texture instanceof WEBGLTexture) {
306
+ texture.update();
307
+ texturesRenderable = texturesRenderable && texture.loaded;
308
+ }
309
+ }
310
+ return texturesRenderable;
179
311
  }
180
- let textureUnit = 0;
181
- let uniformBufferIndex = 0;
182
- for (const binding of this.shaderLayout.bindings) {
183
- const value = this.bindings[binding.name] || this.bindings[binding.name.replace(/Uniforms$/, '')];
184
- if (!value) {
185
- throw new Error(`No value for binding ${binding.name} in ${this.id}`);
186
- }
187
- switch (binding.type) {
188
- case 'uniform':
189
- const {
190
- name
191
- } = binding;
192
- const location = gl2.getUniformBlockIndex(this.handle, name);
193
- if (location === 4294967295) {
194
- throw new Error(`Invalid uniform block name ${name}`);
195
- }
196
- gl2.uniformBlockBinding(this.handle, uniformBufferIndex, location);
197
- if (value instanceof WEBGLBuffer) {
198
- gl2.bindBufferBase(35345, uniformBufferIndex, value.handle);
199
- } else {
200
- gl2.bindBufferRange(35345, uniformBufferIndex, value.buffer.handle, value.offset || 0, value.size || value.buffer.byteLength - value.offset);
201
- }
202
- uniformBufferIndex += 1;
203
- break;
204
- case 'texture':
205
- if (!(value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
206
- throw new Error('texture');
207
- }
208
- let texture;
209
- if (value instanceof WEBGLTexture) {
210
- texture = value;
211
- } else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTexture) {
212
- log.warn('Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead')();
213
- texture = value.colorAttachments[0];
214
- } else {
215
- throw new Error('No texture');
216
- }
217
- gl2.activeTexture(33984 + textureUnit);
218
- gl2.bindTexture(texture.target, texture.handle);
219
- textureUnit += 1;
220
- break;
221
- case 'sampler':
222
- break;
223
- case 'storage':
224
- case 'read-only-storage':
225
- throw new Error(`binding type '${binding.type}' not supported in WebGL`);
226
- }
312
+ /** Apply any bindings (before each draw call) */
313
+ _applyBindings() {
314
+ // If we are using async linking, we need to wait until linking completes
315
+ if (this.linkStatus !== 'success') {
316
+ return;
317
+ }
318
+ const { gl } = this.device;
319
+ gl.useProgram(this.handle);
320
+ let textureUnit = 0;
321
+ let uniformBufferIndex = 0;
322
+ for (const binding of this.shaderLayout.bindings) {
323
+ // Accept both `xyz` and `xyzUniforms` as valid names for `xyzUniforms` uniform block
324
+ const value = this.bindings[binding.name] || this.bindings[binding.name.replace(/Uniforms$/, '')];
325
+ if (!value) {
326
+ throw new Error(`No value for binding ${binding.name} in ${this.id}`);
327
+ }
328
+ switch (binding.type) {
329
+ case 'uniform':
330
+ // Set buffer
331
+ const { name } = binding;
332
+ const location = gl.getUniformBlockIndex(this.handle, name);
333
+ if (location === GL.INVALID_INDEX) {
334
+ throw new Error(`Invalid uniform block name ${name}`);
335
+ }
336
+ gl.uniformBlockBinding(this.handle, uniformBufferIndex, location);
337
+ // console.debug(binding, location);
338
+ if (value instanceof WEBGLBuffer) {
339
+ gl.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
340
+ }
341
+ else {
342
+ gl.bindBufferRange(GL.UNIFORM_BUFFER, uniformBufferIndex,
343
+ // @ts-expect-error
344
+ value.buffer.handle,
345
+ // @ts-expect-error
346
+ value.offset || 0,
347
+ // @ts-expect-error
348
+ value.size || value.buffer.byteLength - value.offset);
349
+ }
350
+ uniformBufferIndex += 1;
351
+ break;
352
+ case 'texture':
353
+ if (!(value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) {
354
+ throw new Error('texture');
355
+ }
356
+ let texture;
357
+ if (value instanceof WEBGLTexture) {
358
+ texture = value;
359
+ }
360
+ else if (value instanceof WEBGLFramebuffer &&
361
+ value.colorAttachments[0] instanceof WEBGLTexture) {
362
+ log.warn('Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead')();
363
+ texture = value.colorAttachments[0];
364
+ }
365
+ else {
366
+ throw new Error('No texture');
367
+ }
368
+ gl.activeTexture(GL.TEXTURE0 + textureUnit);
369
+ gl.bindTexture(texture.target, texture.handle);
370
+ // gl.bindSampler(textureUnit, sampler.handle);
371
+ textureUnit += 1;
372
+ break;
373
+ case 'sampler':
374
+ // ignore
375
+ break;
376
+ case 'storage':
377
+ case 'read-only-storage':
378
+ throw new Error(`binding type '${binding.type}' not supported in WebGL`);
379
+ }
380
+ }
227
381
  }
228
- }
229
- _applyUniforms() {
230
- for (const uniformLayout of this.shaderLayout.uniforms || []) {
231
- var _this$uniforms$name;
232
- const {
233
- name,
234
- location,
235
- type,
236
- textureUnit
237
- } = uniformLayout;
238
- const value = (_this$uniforms$name = this.uniforms[name]) !== null && _this$uniforms$name !== void 0 ? _this$uniforms$name : textureUnit;
239
- if (value !== undefined) {
240
- setUniform(this.device.gl, location, type, value);
241
- }
382
+ /**
383
+ * Due to program sharing, uniforms need to be reset before every draw call
384
+ * (though caching will avoid redundant WebGL calls)
385
+ */
386
+ _applyUniforms() {
387
+ for (const uniformLayout of this.shaderLayout.uniforms || []) {
388
+ const { name, location, type, textureUnit } = uniformLayout;
389
+ const value = this.uniforms[name] ?? textureUnit;
390
+ if (value !== undefined) {
391
+ setUniform(this.device.gl, location, type, value);
392
+ }
393
+ }
242
394
  }
243
- }
244
395
  }
245
- //# sourceMappingURL=webgl-render-pipeline.js.map
@@ -3,8 +3,6 @@ import { GLSamplerParameters } from '@luma.gl/constants';
3
3
  import type { WebGLDevice } from '../webgl-device';
4
4
  /**
5
5
  * Sampler object -
6
- * Under WebGL2 we create an actual WebGL sampler
7
- * Under WebGL1, we just store the sampler parameters
8
6
  * so that they can be set directly on the texture
9
7
  * https://github.com/WebGLSamples/WebGL2Samples/blob/master/samples/sampler_object.html
10
8
  */
@@ -1 +1 @@
1
- {"version":3,"file":"webgl-sampler.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgl-sampler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EAAK,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAEjD;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,OAAO;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;gBAE7B,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY;IAU3C,OAAO,IAAI,IAAI;IAQf,QAAQ,IAAI,MAAM;IAI3B,4CAA4C;IAC5C,OAAO,CAAC,qBAAqB;CAgB9B"}
1
+ {"version":3,"file":"webgl-sampler.d.ts","sourceRoot":"","sources":["../../../src/adapter/resources/webgl-sampler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EAAK,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAE3D,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,OAAO;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;gBAE7B,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY;IAQ3C,OAAO,IAAI,IAAI;IAQf,QAAQ,IAAI,MAAM;IAI3B,4CAA4C;IAC5C,OAAO,CAAC,qBAAqB;CAgB9B"}