@luma.gl/webgl 9.2.6 → 9.3.0-alpha.11

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 (247) hide show
  1. package/dist/adapter/converters/device-parameters.d.ts +1 -1
  2. package/dist/adapter/converters/device-parameters.d.ts.map +1 -1
  3. package/dist/adapter/converters/device-parameters.js +4 -1
  4. package/dist/adapter/converters/device-parameters.js.map +1 -1
  5. package/dist/adapter/converters/sampler-parameters.d.ts +1 -1
  6. package/dist/adapter/converters/sampler-parameters.d.ts.map +1 -1
  7. package/dist/adapter/converters/sampler-parameters.js +1 -1
  8. package/dist/adapter/converters/sampler-parameters.js.map +1 -1
  9. package/dist/adapter/converters/shader-formats.d.ts +1 -64
  10. package/dist/adapter/converters/shader-formats.d.ts.map +1 -1
  11. package/dist/adapter/converters/shader-formats.js +1 -64
  12. package/dist/adapter/converters/shader-formats.js.map +1 -1
  13. package/dist/adapter/converters/webgl-shadertypes.d.ts +1 -3
  14. package/dist/adapter/converters/webgl-shadertypes.d.ts.map +1 -1
  15. package/dist/adapter/converters/webgl-shadertypes.js +2 -7
  16. package/dist/adapter/converters/webgl-shadertypes.js.map +1 -1
  17. package/dist/adapter/converters/webgl-texture-table.d.ts +8 -4
  18. package/dist/adapter/converters/webgl-texture-table.d.ts.map +1 -1
  19. package/dist/adapter/converters/webgl-texture-table.js +125 -61
  20. package/dist/adapter/converters/webgl-texture-table.js.map +1 -1
  21. package/dist/adapter/converters/webgl-vertex-formats.d.ts +1 -1
  22. package/dist/adapter/converters/webgl-vertex-formats.d.ts.map +1 -1
  23. package/dist/adapter/converters/webgl-vertex-formats.js +4 -4
  24. package/dist/adapter/converters/webgl-vertex-formats.js.map +1 -1
  25. package/dist/adapter/device-helpers/webgl-device-features.d.ts +1 -1
  26. package/dist/adapter/device-helpers/webgl-device-features.d.ts.map +1 -1
  27. package/dist/adapter/device-helpers/webgl-device-features.js +1 -2
  28. package/dist/adapter/device-helpers/webgl-device-features.js.map +1 -1
  29. package/dist/adapter/device-helpers/webgl-device-info.d.ts +1 -1
  30. package/dist/adapter/device-helpers/webgl-device-info.d.ts.map +1 -1
  31. package/dist/adapter/device-helpers/webgl-device-info.js +6 -1
  32. package/dist/adapter/device-helpers/webgl-device-info.js.map +1 -1
  33. package/dist/adapter/device-helpers/webgl-device-limits.d.ts +1 -1
  34. package/dist/adapter/device-helpers/webgl-device-limits.d.ts.map +1 -1
  35. package/dist/adapter/device-helpers/webgl-device-limits.js +2 -2
  36. package/dist/adapter/device-helpers/webgl-device-limits.js.map +1 -1
  37. package/dist/adapter/helpers/format-utils.d.ts +1 -1
  38. package/dist/adapter/helpers/format-utils.d.ts.map +1 -1
  39. package/dist/adapter/helpers/format-utils.js +1 -1
  40. package/dist/adapter/helpers/format-utils.js.map +1 -1
  41. package/dist/adapter/helpers/get-shader-layout-from-glsl.js +36 -22
  42. package/dist/adapter/helpers/get-shader-layout-from-glsl.js.map +1 -1
  43. package/dist/adapter/helpers/parse-shader-compiler-log.d.ts +1 -1
  44. package/dist/adapter/helpers/parse-shader-compiler-log.d.ts.map +1 -1
  45. package/dist/adapter/helpers/parse-shader-compiler-log.js +22 -2
  46. package/dist/adapter/helpers/parse-shader-compiler-log.js.map +1 -1
  47. package/dist/adapter/helpers/set-uniform.d.ts +1 -1
  48. package/dist/adapter/helpers/set-uniform.d.ts.map +1 -1
  49. package/dist/adapter/helpers/set-uniform.js +2 -2
  50. package/dist/adapter/helpers/set-uniform.js.map +1 -1
  51. package/dist/adapter/helpers/webgl-texture-utils.d.ts +1 -1
  52. package/dist/adapter/helpers/webgl-texture-utils.d.ts.map +1 -1
  53. package/dist/adapter/helpers/webgl-texture-utils.js +9 -9
  54. package/dist/adapter/helpers/webgl-texture-utils.js.map +1 -1
  55. package/dist/adapter/helpers/webgl-topology-utils.d.ts +1 -1
  56. package/dist/adapter/helpers/webgl-topology-utils.d.ts.map +1 -1
  57. package/dist/adapter/helpers/webgl-topology-utils.js +3 -3
  58. package/dist/adapter/helpers/webgl-topology-utils.js.map +1 -1
  59. package/dist/adapter/resources/webgl-buffer.d.ts +1 -1
  60. package/dist/adapter/resources/webgl-buffer.d.ts.map +1 -1
  61. package/dist/adapter/resources/webgl-buffer.js +20 -5
  62. package/dist/adapter/resources/webgl-buffer.js.map +1 -1
  63. package/dist/adapter/resources/webgl-command-buffer.d.ts +7 -8
  64. package/dist/adapter/resources/webgl-command-buffer.d.ts.map +1 -1
  65. package/dist/adapter/resources/webgl-command-buffer.js +33 -43
  66. package/dist/adapter/resources/webgl-command-buffer.js.map +1 -1
  67. package/dist/adapter/resources/webgl-command-encoder.d.ts +6 -5
  68. package/dist/adapter/resources/webgl-command-encoder.d.ts.map +1 -1
  69. package/dist/adapter/resources/webgl-command-encoder.js +23 -8
  70. package/dist/adapter/resources/webgl-command-encoder.js.map +1 -1
  71. package/dist/adapter/resources/webgl-fence.d.ts +14 -0
  72. package/dist/adapter/resources/webgl-fence.d.ts.map +1 -0
  73. package/dist/adapter/resources/webgl-fence.js +49 -0
  74. package/dist/adapter/resources/webgl-fence.js.map +1 -0
  75. package/dist/adapter/resources/webgl-framebuffer.d.ts +3 -1
  76. package/dist/adapter/resources/webgl-framebuffer.d.ts.map +1 -1
  77. package/dist/adapter/resources/webgl-framebuffer.js +10 -1
  78. package/dist/adapter/resources/webgl-framebuffer.js.map +1 -1
  79. package/dist/adapter/resources/webgl-query-set.d.ts +37 -31
  80. package/dist/adapter/resources/webgl-query-set.d.ts.map +1 -1
  81. package/dist/adapter/resources/webgl-query-set.js +247 -96
  82. package/dist/adapter/resources/webgl-query-set.js.map +1 -1
  83. package/dist/adapter/resources/webgl-render-pass.d.ts +1 -1
  84. package/dist/adapter/resources/webgl-render-pass.d.ts.map +1 -1
  85. package/dist/adapter/resources/webgl-render-pass.js +28 -11
  86. package/dist/adapter/resources/webgl-render-pass.js.map +1 -1
  87. package/dist/adapter/resources/webgl-render-pipeline.d.ts +17 -21
  88. package/dist/adapter/resources/webgl-render-pipeline.d.ts.map +1 -1
  89. package/dist/adapter/resources/webgl-render-pipeline.js +94 -192
  90. package/dist/adapter/resources/webgl-render-pipeline.js.map +1 -1
  91. package/dist/adapter/resources/webgl-sampler.d.ts +1 -1
  92. package/dist/adapter/resources/webgl-sampler.d.ts.map +1 -1
  93. package/dist/adapter/resources/webgl-sampler.js +1 -1
  94. package/dist/adapter/resources/webgl-sampler.js.map +1 -1
  95. package/dist/adapter/resources/webgl-shader.d.ts +1 -1
  96. package/dist/adapter/resources/webgl-shader.d.ts.map +1 -1
  97. package/dist/adapter/resources/webgl-shader.js +15 -8
  98. package/dist/adapter/resources/webgl-shader.js.map +1 -1
  99. package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts +24 -0
  100. package/dist/adapter/resources/webgl-shared-render-pipeline.d.ts.map +1 -0
  101. package/dist/adapter/resources/webgl-shared-render-pipeline.js +155 -0
  102. package/dist/adapter/resources/webgl-shared-render-pipeline.js.map +1 -0
  103. package/dist/adapter/resources/webgl-texture.d.ts +42 -4
  104. package/dist/adapter/resources/webgl-texture.d.ts.map +1 -1
  105. package/dist/adapter/resources/webgl-texture.js +289 -65
  106. package/dist/adapter/resources/webgl-texture.js.map +1 -1
  107. package/dist/adapter/resources/webgl-transform-feedback.js +6 -6
  108. package/dist/adapter/resources/webgl-transform-feedback.js.map +1 -1
  109. package/dist/adapter/resources/webgl-vertex-array.d.ts +2 -2
  110. package/dist/adapter/resources/webgl-vertex-array.d.ts.map +1 -1
  111. package/dist/adapter/resources/webgl-vertex-array.js +1 -1
  112. package/dist/adapter/resources/webgl-vertex-array.js.map +1 -1
  113. package/dist/adapter/webgl-adapter.d.ts.map +1 -1
  114. package/dist/adapter/webgl-adapter.js +22 -23
  115. package/dist/adapter/webgl-adapter.js.map +1 -1
  116. package/dist/adapter/webgl-canvas-context.d.ts +2 -2
  117. package/dist/adapter/webgl-canvas-context.d.ts.map +1 -1
  118. package/dist/adapter/webgl-canvas-context.js +16 -6
  119. package/dist/adapter/webgl-canvas-context.js.map +1 -1
  120. package/dist/adapter/webgl-device.d.ts +10 -5
  121. package/dist/adapter/webgl-device.d.ts.map +1 -1
  122. package/dist/adapter/webgl-device.js +78 -28
  123. package/dist/adapter/webgl-device.js.map +1 -1
  124. package/dist/adapter/webgl-presentation-context.d.ts +21 -0
  125. package/dist/adapter/webgl-presentation-context.d.ts.map +1 -0
  126. package/dist/adapter/webgl-presentation-context.js +64 -0
  127. package/dist/adapter/webgl-presentation-context.js.map +1 -0
  128. package/dist/constants/index.d.ts +3 -0
  129. package/dist/constants/index.d.ts.map +1 -0
  130. package/dist/constants/index.js +5 -0
  131. package/dist/constants/index.js.map +1 -0
  132. package/dist/constants/webgl-constants.d.ts +822 -0
  133. package/dist/constants/webgl-constants.d.ts.map +1 -0
  134. package/dist/constants/webgl-constants.js +928 -0
  135. package/dist/constants/webgl-constants.js.map +1 -0
  136. package/dist/constants/webgl-types.d.ts +480 -0
  137. package/dist/constants/webgl-types.d.ts.map +1 -0
  138. package/dist/constants/webgl-types.js +6 -0
  139. package/dist/constants/webgl-types.js.map +1 -0
  140. package/dist/context/debug/spector.d.ts.map +1 -1
  141. package/dist/context/debug/spector.js +4 -4
  142. package/dist/context/debug/spector.js.map +1 -1
  143. package/dist/context/debug/webgl-developer-tools.js +11 -9
  144. package/dist/context/debug/webgl-developer-tools.js.map +1 -1
  145. package/dist/context/helpers/create-browser-context.d.ts.map +1 -1
  146. package/dist/context/helpers/create-browser-context.js +46 -36
  147. package/dist/context/helpers/create-browser-context.js.map +1 -1
  148. package/dist/context/helpers/webgl-context-data.d.ts +5 -1
  149. package/dist/context/helpers/webgl-context-data.d.ts.map +1 -1
  150. package/dist/context/helpers/webgl-context-data.js +9 -10
  151. package/dist/context/helpers/webgl-context-data.js.map +1 -1
  152. package/dist/context/helpers/webgl-extensions.d.ts +1 -1
  153. package/dist/context/helpers/webgl-extensions.d.ts.map +1 -1
  154. package/dist/context/parameters/unified-parameter-api.d.ts +2 -2
  155. package/dist/context/parameters/unified-parameter-api.d.ts.map +1 -1
  156. package/dist/context/parameters/unified-parameter-api.js +2 -2
  157. package/dist/context/parameters/unified-parameter-api.js.map +1 -1
  158. package/dist/context/parameters/webgl-parameter-tables.d.ts +1 -1
  159. package/dist/context/parameters/webgl-parameter-tables.d.ts.map +1 -1
  160. package/dist/context/parameters/webgl-parameter-tables.js +1 -1
  161. package/dist/context/parameters/webgl-parameter-tables.js.map +1 -1
  162. package/dist/context/polyfills/polyfill-webgl1-extensions.js +1 -1
  163. package/dist/context/polyfills/polyfill-webgl1-extensions.js.map +1 -1
  164. package/dist/context/state-tracker/webgl-state-tracker.js +2 -2
  165. package/dist/context/state-tracker/webgl-state-tracker.js.map +1 -1
  166. package/dist/dist.dev.js +1898 -997
  167. package/dist/dist.min.js +2 -2
  168. package/dist/index.cjs +3 -5255
  169. package/dist/index.cjs.map +4 -4
  170. package/dist/index.d.ts +3 -0
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +2 -0
  173. package/dist/index.js.map +1 -1
  174. package/dist/utils/fill-array.js +1 -1
  175. package/dist/utils/fill-array.js.map +1 -1
  176. package/dist/webgl-constants.d.ts +2 -0
  177. package/dist/webgl-constants.d.ts.map +1 -0
  178. package/dist/webgl-constants.js +5 -0
  179. package/dist/webgl-constants.js.map +1 -0
  180. package/dist/webgl-types.d.ts +2 -0
  181. package/dist/webgl-types.d.ts.map +1 -0
  182. package/dist/{types.js → webgl-types.js} +1 -1
  183. package/dist/webgl-types.js.map +1 -0
  184. package/package.json +19 -5
  185. package/src/adapter/converters/device-parameters.ts +6 -2
  186. package/src/adapter/converters/sampler-parameters.ts +1 -1
  187. package/src/adapter/converters/shader-formats.ts +1 -66
  188. package/src/adapter/converters/webgl-shadertypes.ts +2 -10
  189. package/src/adapter/converters/webgl-texture-table.ts +160 -68
  190. package/src/adapter/converters/webgl-vertex-formats.ts +4 -4
  191. package/src/adapter/device-helpers/webgl-device-features.ts +2 -3
  192. package/src/adapter/device-helpers/webgl-device-info.ts +7 -1
  193. package/src/adapter/device-helpers/webgl-device-limits.ts +2 -2
  194. package/src/adapter/helpers/format-utils.ts +1 -1
  195. package/src/adapter/helpers/get-shader-layout-from-glsl.ts +44 -24
  196. package/src/adapter/helpers/parse-shader-compiler-log.ts +25 -3
  197. package/src/adapter/helpers/set-uniform.ts +2 -2
  198. package/src/adapter/helpers/webgl-texture-utils.ts +9 -9
  199. package/src/adapter/helpers/webgl-topology-utils.ts +3 -3
  200. package/src/adapter/resources/webgl-buffer.ts +17 -5
  201. package/src/adapter/resources/webgl-command-buffer.ts +48 -52
  202. package/src/adapter/resources/webgl-command-encoder.ts +28 -11
  203. package/src/adapter/resources/webgl-fence.ts +55 -0
  204. package/src/adapter/resources/webgl-framebuffer.ts +12 -1
  205. package/src/adapter/resources/webgl-query-set.ts +295 -101
  206. package/src/adapter/resources/webgl-render-pass.ts +30 -13
  207. package/src/adapter/resources/webgl-render-pipeline.ts +131 -227
  208. package/src/adapter/resources/webgl-sampler.ts +1 -1
  209. package/src/adapter/resources/webgl-shader.ts +15 -8
  210. package/src/adapter/resources/webgl-shared-render-pipeline.ts +211 -0
  211. package/src/adapter/resources/webgl-texture.ts +458 -84
  212. package/src/adapter/resources/webgl-transform-feedback.ts +6 -6
  213. package/src/adapter/resources/webgl-vertex-array.ts +1 -1
  214. package/src/adapter/webgl-adapter.ts +26 -24
  215. package/src/adapter/webgl-canvas-context.ts +19 -8
  216. package/src/adapter/webgl-device.ts +94 -35
  217. package/src/adapter/webgl-presentation-context.ts +93 -0
  218. package/src/constants/index.d.ts.map +1 -0
  219. package/src/constants/index.js.map +1 -0
  220. package/src/constants/index.ts +31 -0
  221. package/src/constants/webgl-constants.d.ts.map +1 -0
  222. package/src/constants/webgl-constants.js.map +1 -0
  223. package/src/constants/webgl-constants.ts +1051 -0
  224. package/src/constants/webgl-types.d.ts.map +1 -0
  225. package/src/constants/webgl-types.js.map +1 -0
  226. package/src/constants/webgl-types.ts +813 -0
  227. package/src/context/debug/spector.ts +4 -4
  228. package/src/context/debug/webgl-developer-tools.ts +20 -9
  229. package/src/context/helpers/create-browser-context.ts +54 -43
  230. package/src/context/helpers/webgl-context-data.ts +17 -11
  231. package/src/context/helpers/webgl-extensions.ts +1 -1
  232. package/src/context/parameters/unified-parameter-api.ts +3 -3
  233. package/src/context/parameters/webgl-parameter-tables.ts +1 -1
  234. package/src/context/polyfills/polyfill-webgl1-extensions.ts +1 -1
  235. package/src/context/state-tracker/webgl-state-tracker.ts +2 -2
  236. package/src/index.ts +27 -0
  237. package/src/utils/fill-array.ts +1 -1
  238. package/src/webgl-constants.d.ts.map +1 -0
  239. package/src/webgl-constants.js.map +1 -0
  240. package/src/webgl-constants.ts +5 -0
  241. package/src/webgl-types.d.ts.map +1 -0
  242. package/src/webgl-types.js.map +1 -0
  243. package/src/webgl-types.ts +29 -0
  244. package/dist/types.d.ts +0 -11
  245. package/dist/types.d.ts.map +0 -1
  246. package/dist/types.js.map +0 -1
  247. package/src/types.ts +0 -14
@@ -8,15 +8,15 @@ import type {
8
8
  PrimitiveTopology,
9
9
  ShaderLayout,
10
10
  UniformValue,
11
- Binding,
11
+ Bindings,
12
+ BindingsByGroup,
12
13
  RenderPass,
13
14
  VertexArray
14
15
  } from '@luma.gl/core';
15
- import {RenderPipeline, log} from '@luma.gl/core';
16
+ import {RenderPipeline, flattenBindingsByGroup, log, normalizeBindingsByGroup} from '@luma.gl/core';
16
17
  // import {getAttributeInfosFromLayouts} from '@luma.gl/core';
17
- import {GL} from '@luma.gl/constants';
18
+ import {GL} from '@luma.gl/webgl/constants';
18
19
 
19
- import {getShaderLayoutFromGLSL} from '../helpers/get-shader-layout-from-glsl';
20
20
  import {withDeviceAndGLParameters} from '../converters/device-parameters';
21
21
  import {setUniform} from '../helpers/set-uniform';
22
22
  // import {copyUniform, checkUniformValues} from '../../classes/uniforms';
@@ -30,8 +30,7 @@ import {WEBGLTextureView} from './webgl-texture-view';
30
30
  import {WEBGLRenderPass} from './webgl-render-pass';
31
31
  import {WEBGLTransformFeedback} from './webgl-transform-feedback';
32
32
  import {getGLDrawMode} from '../helpers/webgl-topology-utils';
33
-
34
- const LOG_PROGRAM_PERF_PRIORITY = 4;
33
+ import {WEBGLSharedRenderPipeline} from './webgl-shared-render-pipeline';
35
34
 
36
35
  /** Creates a new render pipeline */
37
36
  export class WEBGLRenderPipeline extends RenderPipeline {
@@ -46,10 +45,10 @@ export class WEBGLRenderPipeline extends RenderPipeline {
46
45
  /** The layout extracted from shader by WebGL introspection APIs */
47
46
  introspectedLayout: ShaderLayout;
48
47
 
49
- /** Uniforms set on this model */
48
+ /** Compatibility path for direct pipeline.setBindings() usage */
49
+ bindings: Bindings = {};
50
+ /** Compatibility path for direct pipeline.uniforms usage */
50
51
  uniforms: Record<string, UniformValue> = {};
51
- /** Bindings set on this model */
52
- bindings: Record<string, Binding> = {};
53
52
  /** WebGL varyings */
54
53
  varyings: string[] | null = null;
55
54
 
@@ -63,64 +62,47 @@ export class WEBGLRenderPipeline extends RenderPipeline {
63
62
  constructor(device: WebGLDevice, props: RenderPipelineProps) {
64
63
  super(device, props);
65
64
  this.device = device;
66
- this.handle = this.props.handle || this.device.gl.createProgram();
65
+ const webglSharedRenderPipeline =
66
+ (this.sharedRenderPipeline as WEBGLSharedRenderPipeline | null) ||
67
+ (this.device._createSharedRenderPipelineWebGL(props) as WEBGLSharedRenderPipeline);
68
+
69
+ this.sharedRenderPipeline = webglSharedRenderPipeline;
70
+ this.handle = webglSharedRenderPipeline.handle;
71
+ this.vs = webglSharedRenderPipeline.vs;
72
+ this.fs = webglSharedRenderPipeline.fs;
73
+ this.linkStatus = webglSharedRenderPipeline.linkStatus;
74
+ this.introspectedLayout = webglSharedRenderPipeline.introspectedLayout;
67
75
  this.device._setWebGLDebugMetadata(this.handle, this, {spector: {id: this.props.id}});
68
76
 
69
- // Create shaders if needed
70
- this.vs = props.vs as WEBGLShader;
71
- this.fs = props.fs as WEBGLShader;
72
- // assert(this.vs.stage === 'vertex');
73
- // assert(this.fs.stage === 'fragment');
74
-
75
- // Setup varyings if supplied
76
- // @ts-expect-error WebGL only
77
- const {varyings, bufferMode = GL.SEPARATE_ATTRIBS} = props;
78
- if (varyings && varyings.length > 0) {
79
- this.varyings = varyings;
80
- this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode);
81
- }
82
-
83
- this._linkShaders();
84
- log.time(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
85
- this.introspectedLayout = getShaderLayoutFromGLSL(this.device.gl, this.handle);
86
- log.timeEnd(3, `RenderPipeline ${this.id} - shaderLayout introspection`)();
87
-
88
- // Merge provided layout with introspected layout
77
+ // WebGL only honors shaderLayout overrides for attributes that already exist in the
78
+ // linked program, and only the `type` / `stepMode` fields participate in the merge.
79
+ // Bindings and unknown attributes are ignored. If WebGL cache keys ever depend on
80
+ // `shaderLayout`, they need to match these merge semantics rather than the raw prop.
89
81
  this.shaderLayout = props.shaderLayout
90
82
  ? mergeShaderLayout(this.introspectedLayout, props.shaderLayout)
91
83
  : this.introspectedLayout;
92
84
  }
93
85
 
94
86
  override destroy(): void {
95
- if (this.handle) {
96
- // log.error(`Deleting program ${this.id}`)();
97
- this.device.gl.useProgram(null);
98
- this.device.gl.deleteProgram(this.handle);
99
- this.destroyed = true;
100
- // @ts-expect-error
101
- this.handle.destroyed = true;
102
- // @ts-ignore
103
- this.handle = null;
87
+ if (this.destroyed) {
88
+ return;
89
+ }
90
+ if (this.sharedRenderPipeline && !this.props._sharedRenderPipeline) {
91
+ this.sharedRenderPipeline.destroy();
104
92
  }
93
+ this.destroyResource();
105
94
  }
106
95
 
107
96
  /**
108
- * Bindings include: textures, samplers and uniform buffers
109
- * @todo needed for portable model
97
+ * Compatibility shim for code paths that still set bindings on the pipeline.
98
+ * Shared-model draws pass bindings per draw and do not rely on this state.
110
99
  */
111
- setBindings(bindings: Record<string, Binding>, options?: {disableWarnings?: boolean}): void {
112
- // if (log.priority >= 2) {
113
- // checkUniformValues(uniforms, this.id, this._uniformSetters);
114
- // }
115
-
116
- for (const [name, value] of Object.entries(bindings)) {
117
- // Accept both `xyz` and `xyzUniforms` as valid names for `xyzUniforms` uniform block
118
- // This convention allows shaders to name uniform blocks as `uniform appUniforms {} app;`
119
- // and reference them as `app` from both GLSL and JS.
120
- // TODO - this is rather hacky - we could also remap the name directly in the shader layout.
121
- const binding =
122
- this.shaderLayout.bindings.find(binding_ => binding_.name === name) ||
123
- this.shaderLayout.bindings.find(binding_ => binding_.name === `${name}Uniforms`);
100
+ setBindings(bindings: Bindings | BindingsByGroup, options?: {disableWarnings?: boolean}): void {
101
+ const flatBindings = flattenBindingsByGroup(
102
+ normalizeBindingsByGroup(this.shaderLayout, bindings)
103
+ );
104
+ for (const [name, value] of Object.entries(flatBindings)) {
105
+ const binding = getShaderLayoutBindingByName(this.shaderLayout, name);
124
106
 
125
107
  if (!binding) {
126
108
  const validBindings = this.shaderLayout.bindings
@@ -132,37 +114,37 @@ export class WEBGLRenderPipeline extends RenderPipeline {
132
114
  value
133
115
  )();
134
116
  }
135
- continue; // eslint-disable-line no-continue
136
- }
137
- if (!value) {
138
- log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
139
- }
140
- switch (binding.type) {
141
- case 'uniform':
142
- // @ts-expect-error
143
- if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
144
- throw new Error('buffer value');
145
- }
146
- break;
147
- case 'texture':
148
- if (
149
- !(
150
- value instanceof WEBGLTextureView ||
151
- value instanceof WEBGLTexture ||
152
- value instanceof WEBGLFramebuffer
153
- )
154
- ) {
155
- throw new Error(`${this} Bad texture binding for ${name}`);
156
- }
157
- break;
158
- case 'sampler':
159
- log.warn(`Ignoring sampler ${name}`)();
160
- break;
161
- default:
162
- throw new Error(binding.type);
163
- }
117
+ } else {
118
+ if (!value) {
119
+ log.warn(`Unsetting binding "${name}" in render pipeline "${this.id}"`)();
120
+ }
121
+ switch (binding.type) {
122
+ case 'uniform':
123
+ // @ts-expect-error
124
+ if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) {
125
+ throw new Error('buffer value');
126
+ }
127
+ break;
128
+ case 'texture':
129
+ if (
130
+ !(
131
+ value instanceof WEBGLTextureView ||
132
+ value instanceof WEBGLTexture ||
133
+ value instanceof WEBGLFramebuffer
134
+ )
135
+ ) {
136
+ throw new Error(`${this} Bad texture binding for ${name}`);
137
+ }
138
+ break;
139
+ case 'sampler':
140
+ log.warn(`Ignoring sampler ${name}`)();
141
+ break;
142
+ default:
143
+ throw new Error(binding.type);
144
+ }
164
145
 
165
- this.bindings[name] = value;
146
+ this.bindings[name] = value;
147
+ }
166
148
  }
167
149
  }
168
150
 
@@ -184,7 +166,16 @@ export class WEBGLRenderPipeline extends RenderPipeline {
184
166
  firstInstance?: number;
185
167
  baseVertex?: number;
186
168
  transformFeedback?: WEBGLTransformFeedback;
169
+ bindings?: Bindings;
170
+ bindGroups?: BindingsByGroup;
171
+ _bindGroupCacheKeys?: Partial<Record<number, object>>;
172
+ uniforms?: Record<string, UniformValue>;
187
173
  }): boolean {
174
+ this._syncLinkStatus();
175
+ const drawBindings = options.bindGroups
176
+ ? flattenBindingsByGroup(options.bindGroups)
177
+ : options.bindings || this.bindings;
178
+
188
179
  const {
189
180
  renderPass,
190
181
  parameters = this.props.parameters,
@@ -198,7 +189,8 @@ export class WEBGLRenderPipeline extends RenderPipeline {
198
189
  // firstIndex,
199
190
  // firstInstance,
200
191
  // baseVertex,
201
- transformFeedback
192
+ transformFeedback,
193
+ uniforms = this.uniforms
202
194
  } = options;
203
195
 
204
196
  const glDrawMode = getGLDrawMode(topology);
@@ -216,7 +208,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
216
208
  // Note: async textures set as uniforms might still be loading.
217
209
  // Now that all uniforms have been updated, check if any texture
218
210
  // in the uniforms is not yet initialized, then we don't draw
219
- if (!this._areTexturesRenderable()) {
211
+ if (!this._areTexturesRenderable(drawBindings)) {
220
212
  log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)();
221
213
  // Note: false means that the app needs to redraw the pipeline again.
222
214
  return false;
@@ -239,8 +231,8 @@ export class WEBGLRenderPipeline extends RenderPipeline {
239
231
  }
240
232
 
241
233
  // We have to apply bindings before every draw call since other draw calls will overwrite
242
- this._applyBindings();
243
- this._applyUniforms();
234
+ this._applyBindings(drawBindings, {disableWarnings: this.props.disableWarnings});
235
+ this._applyUniforms(uniforms);
244
236
 
245
237
  const webglRenderPass = renderPass as WEBGLRenderPass;
246
238
 
@@ -278,138 +270,16 @@ export class WEBGLRenderPipeline extends RenderPipeline {
278
270
  return true;
279
271
  }
280
272
 
281
- // PRIVATE METHODS
282
-
283
- // setAttributes(attributes: Record<string, Buffer>): void {}
284
- // setBindings(bindings: Record<string, Binding>): void {}
285
-
286
- protected async _linkShaders() {
287
- const {gl} = this.device;
288
- gl.attachShader(this.handle, this.vs.handle);
289
- gl.attachShader(this.handle, this.fs.handle);
290
- log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
291
- gl.linkProgram(this.handle);
292
- log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)();
293
-
294
- // TODO Avoid checking program linking error in production
295
- if (log.level === 0) {
296
- // return;
297
- }
298
-
299
- if (!this.device.features.has('compilation-status-async-webgl')) {
300
- const status = this._getLinkStatus();
301
- this._reportLinkStatus(status);
302
- return;
303
- }
304
-
305
- // async case
306
- log.once(1, 'RenderPipeline linking is asynchronous')();
307
- await this._waitForLinkComplete();
308
- log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();
309
- const status = this._getLinkStatus();
310
- this._reportLinkStatus(status);
311
- }
312
-
313
- /** Report link status. First, check for shader compilation failures if linking fails */
314
- async _reportLinkStatus(status: 'success' | 'link-error' | 'validation-error'): Promise<void> {
315
- switch (status) {
316
- case 'success':
317
- return;
318
-
319
- default:
320
- const errorType = status === 'link-error' ? 'Link error' : 'Validation error';
321
- // First check for shader compilation failures if linking fails
322
- switch (this.vs.compilationStatus) {
323
- case 'error':
324
- this.vs.debugShader();
325
- throw new Error(`${this} ${errorType} during compilation of ${this.vs}`);
326
- case 'pending':
327
- await this.vs.asyncCompilationStatus;
328
- this.vs.debugShader();
329
- break;
330
- case 'success':
331
- break;
332
- }
333
-
334
- switch (this.fs?.compilationStatus) {
335
- case 'error':
336
- this.fs.debugShader();
337
- throw new Error(`${this} ${errorType} during compilation of ${this.fs}`);
338
- case 'pending':
339
- await this.fs.asyncCompilationStatus;
340
- this.fs.debugShader();
341
- break;
342
- case 'success':
343
- break;
344
- }
345
-
346
- const linkErrorLog = this.device.gl.getProgramInfoLog(this.handle);
347
- this.device.reportError(
348
- new Error(`${errorType} during ${status}: ${linkErrorLog}`),
349
- this
350
- )();
351
- this.device.debug();
352
- }
353
- }
354
-
355
- /**
356
- * Get the shader compilation status
357
- * TODO - Load log even when no error reported, to catch warnings?
358
- * https://gamedev.stackexchange.com/questions/30429/how-to-detect-glsl-warnings
359
- */
360
- _getLinkStatus(): 'success' | 'link-error' | 'validation-error' {
361
- const {gl} = this.device;
362
- const linked = gl.getProgramParameter(this.handle, GL.LINK_STATUS);
363
- if (!linked) {
364
- this.linkStatus = 'error';
365
- return 'link-error';
366
- }
367
-
368
- gl.validateProgram(this.handle);
369
- const validated = gl.getProgramParameter(this.handle, GL.VALIDATE_STATUS);
370
- if (!validated) {
371
- this.linkStatus = 'error';
372
- return 'validation-error';
373
- }
374
-
375
- this.linkStatus = 'success';
376
- return 'success';
377
- }
378
-
379
- /** Use KHR_parallel_shader_compile extension if available */
380
- async _waitForLinkComplete(): Promise<void> {
381
- const waitMs = async (ms: number) => await new Promise(resolve => setTimeout(resolve, ms));
382
- const DELAY_MS = 10; // Shader compilation is typically quite fast (with some exceptions)
383
-
384
- // If status polling is not available, we can't wait for completion. Just wait a little to minimize blocking
385
- if (!this.device.features.has('compilation-status-async-webgl')) {
386
- await waitMs(DELAY_MS);
387
- return;
388
- }
389
-
390
- const {gl} = this.device;
391
- for (;;) {
392
- const complete = gl.getProgramParameter(this.handle, GL.COMPLETION_STATUS_KHR);
393
- if (complete) {
394
- return;
395
- }
396
- await waitMs(DELAY_MS);
397
- }
398
- }
399
-
400
273
  /**
401
274
  * Checks if all texture-values uniforms are renderable (i.e. loaded)
402
275
  * Update a texture if needed (e.g. from video)
403
276
  * Note: This is currently done before every draw call
404
277
  */
405
- _areTexturesRenderable() {
278
+ _areTexturesRenderable(bindings: Bindings) {
406
279
  let texturesRenderable = true;
407
280
 
408
281
  for (const bindingInfo of this.shaderLayout.bindings) {
409
- if (
410
- !this.bindings[bindingInfo.name] &&
411
- !this.bindings[bindingInfo.name.replace(/Uniforms$/, '')]
412
- ) {
282
+ if (!getBindingValueForLayoutBinding(bindings, bindingInfo.name)) {
413
283
  log.warn(`Binding ${bindingInfo.name} not found in ${this.id}`)();
414
284
  texturesRenderable = false;
415
285
  }
@@ -426,7 +296,9 @@ export class WEBGLRenderPipeline extends RenderPipeline {
426
296
  }
427
297
 
428
298
  /** Apply any bindings (before each draw call) */
429
- _applyBindings() {
299
+ _applyBindings(bindings: Bindings, _options?: {disableWarnings?: boolean}) {
300
+ this._syncLinkStatus();
301
+
430
302
  // If we are using async linking, we need to wait until linking completes
431
303
  if (this.linkStatus !== 'success') {
432
304
  return;
@@ -438,9 +310,7 @@ export class WEBGLRenderPipeline extends RenderPipeline {
438
310
  let textureUnit = 0;
439
311
  let uniformBufferIndex = 0;
440
312
  for (const binding of this.shaderLayout.bindings) {
441
- // Accept both `xyz` and `xyzUniforms` as valid names for `xyzUniforms` uniform block
442
- const value =
443
- this.bindings[binding.name] || this.bindings[binding.name.replace(/Uniforms$/, '')];
313
+ const value = getBindingValueForLayoutBinding(bindings, binding.name);
444
314
  if (!value) {
445
315
  throw new Error(`No value for binding ${binding.name} in ${this.id}`);
446
316
  }
@@ -452,20 +322,17 @@ export class WEBGLRenderPipeline extends RenderPipeline {
452
322
  if ((location as GL) === GL.INVALID_INDEX) {
453
323
  throw new Error(`Invalid uniform block name ${name}`);
454
324
  }
455
- gl.uniformBlockBinding(this.handle, uniformBufferIndex, location);
456
- // console.debug(binding, location);
325
+ gl.uniformBlockBinding(this.handle, location, uniformBufferIndex);
457
326
  if (value instanceof WEBGLBuffer) {
458
327
  gl.bindBufferBase(GL.UNIFORM_BUFFER, uniformBufferIndex, value.handle);
459
328
  } else {
329
+ const bufferBinding = value as {buffer: WEBGLBuffer; offset?: number; size?: number};
460
330
  gl.bindBufferRange(
461
331
  GL.UNIFORM_BUFFER,
462
332
  uniformBufferIndex,
463
- // @ts-expect-error
464
- value.buffer.handle,
465
- // @ts-expect-error
466
- value.offset || 0,
467
- // @ts-expect-error
468
- value.size || value.buffer.byteLength - value.offset
333
+ bufferBinding.buffer.handle,
334
+ bufferBinding.offset || 0,
335
+ bufferBinding.size || bufferBinding.buffer.byteLength - (bufferBinding.offset || 0)
469
336
  );
470
337
  }
471
338
  uniformBufferIndex += 1;
@@ -519,15 +386,19 @@ export class WEBGLRenderPipeline extends RenderPipeline {
519
386
  * Due to program sharing, uniforms need to be reset before every draw call
520
387
  * (though caching will avoid redundant WebGL calls)
521
388
  */
522
- _applyUniforms() {
389
+ _applyUniforms(uniforms: Record<string, UniformValue>) {
523
390
  for (const uniformLayout of this.shaderLayout.uniforms || []) {
524
391
  const {name, location, type, textureUnit} = uniformLayout;
525
- const value = this.uniforms[name] ?? textureUnit;
392
+ const value = uniforms[name] ?? textureUnit;
526
393
  if (value !== undefined) {
527
394
  setUniform(this.device.gl, location, type, value);
528
395
  }
529
396
  }
530
397
  }
398
+
399
+ private _syncLinkStatus(): void {
400
+ this.linkStatus = (this.sharedRenderPipeline as WEBGLSharedRenderPipeline).linkStatus;
401
+ }
531
402
  }
532
403
 
533
404
  /**
@@ -540,7 +411,8 @@ function mergeShaderLayout(baseLayout: ShaderLayout, overrideLayout: ShaderLayou
540
411
  // Deep clone the base layout
541
412
  const mergedLayout: ShaderLayout = {
542
413
  ...baseLayout,
543
- attributes: baseLayout.attributes.map(attribute => ({...attribute}))
414
+ attributes: baseLayout.attributes.map(attribute => ({...attribute})),
415
+ bindings: baseLayout.bindings.map(binding => ({...binding}))
544
416
  };
545
417
  // Merge the attributes
546
418
  for (const attribute of overrideLayout?.attributes || []) {
@@ -552,5 +424,37 @@ function mergeShaderLayout(baseLayout: ShaderLayout, overrideLayout: ShaderLayou
552
424
  baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode;
553
425
  }
554
426
  }
427
+
428
+ for (const binding of overrideLayout?.bindings || []) {
429
+ const baseBinding = getShaderLayoutBindingByName(mergedLayout, binding.name);
430
+ if (!baseBinding) {
431
+ log.warn(`shader layout binding ${binding.name} not present in shader`);
432
+ continue;
433
+ }
434
+ Object.assign(baseBinding, binding);
435
+ }
555
436
  return mergedLayout;
556
437
  }
438
+
439
+ function getShaderLayoutBindingByName(
440
+ shaderLayout: ShaderLayout,
441
+ bindingName: string
442
+ ): ShaderLayout['bindings'][number] | undefined {
443
+ return shaderLayout.bindings.find(
444
+ binding =>
445
+ binding.name === bindingName ||
446
+ binding.name === `${bindingName}Uniforms` ||
447
+ `${binding.name}Uniforms` === bindingName
448
+ );
449
+ }
450
+
451
+ function getBindingValueForLayoutBinding(
452
+ bindings: Bindings,
453
+ bindingName: string
454
+ ): Bindings[string] | undefined {
455
+ return (
456
+ bindings[bindingName] ||
457
+ bindings[`${bindingName}Uniforms`] ||
458
+ bindings[bindingName.replace(/Uniforms$/, '')]
459
+ );
460
+ }
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {Sampler, SamplerProps} from '@luma.gl/core';
6
- import {GL, GLSamplerParameters} from '@luma.gl/constants';
6
+ import {GL, GLSamplerParameters} from '@luma.gl/webgl/constants';
7
7
  import {convertSamplerParametersToWebGL} from '../converters/sampler-parameters';
8
8
  import type {WebGLDevice} from '../webgl-device';
9
9
 
@@ -3,7 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import {Shader, ShaderProps, CompilerMessage, log} from '@luma.gl/core';
6
- import {GL} from '@luma.gl/constants';
6
+ import {GL} from '@luma.gl/webgl/constants';
7
7
  import {parseShaderCompilerLog} from '../helpers/parse-shader-compiler-log';
8
8
  import {WebGLDevice} from '../webgl-device';
9
9
 
@@ -31,7 +31,13 @@ export class WEBGLShader extends Shader {
31
31
  // default framebuffer handle is null, so we can't set spector metadata...
32
32
  device._setWebGLDebugMetadata(this.handle, this, {spector: this.props});
33
33
 
34
- this._compile(this.source);
34
+ const compilationStatus = this._compile(this.source);
35
+ if (compilationStatus && typeof compilationStatus.catch === 'function') {
36
+ compilationStatus.catch(() => {
37
+ // Ensure any async compile status errors are consumed.
38
+ this.compilationStatus = 'error';
39
+ });
40
+ }
35
41
  }
36
42
 
37
43
  override destroy(): void {
@@ -71,7 +77,7 @@ export class WEBGLShader extends Shader {
71
77
  // PRIVATE METHODS
72
78
 
73
79
  /** Compile a shader and get compilation status */
74
- protected async _compile(source: string): Promise<void> {
80
+ protected _compile(source: string): void | Promise<void> {
75
81
  source = source.startsWith('#version ') ? source : `#version 300 es\n${source}`;
76
82
 
77
83
  const {gl} = this.device;
@@ -97,12 +103,13 @@ export class WEBGLShader extends Shader {
97
103
 
98
104
  // async case
99
105
  log.once(1, 'Shader compilation is asynchronous')();
100
- await this._waitForCompilationComplete();
101
- log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
102
- this._getCompilationStatus();
106
+ return this._waitForCompilationComplete().then(() => {
107
+ log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)();
108
+ this._getCompilationStatus();
103
109
 
104
- // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
105
- this.debugShader();
110
+ // The `Shader` base class will determine if debug window should be opened based on this.compilationStatus
111
+ this.debugShader();
112
+ });
106
113
  }
107
114
 
108
115
  /** Use KHR_parallel_shader_compile extension if available */