@luma.gl/core 9.2.5 → 9.3.0-alpha.10

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 (280) hide show
  1. package/dist/adapter/canvas-context.d.ts +6 -162
  2. package/dist/adapter/canvas-context.d.ts.map +1 -1
  3. package/dist/adapter/canvas-context.js +5 -419
  4. package/dist/adapter/canvas-context.js.map +1 -1
  5. package/dist/adapter/canvas-observer.d.ts +32 -0
  6. package/dist/adapter/canvas-observer.d.ts.map +1 -0
  7. package/dist/adapter/canvas-observer.js +90 -0
  8. package/dist/adapter/canvas-observer.js.map +1 -0
  9. package/dist/adapter/canvas-surface.d.ts +150 -0
  10. package/dist/adapter/canvas-surface.d.ts.map +1 -0
  11. package/dist/adapter/canvas-surface.js +392 -0
  12. package/dist/adapter/canvas-surface.js.map +1 -0
  13. package/dist/adapter/device.d.ts +81 -16
  14. package/dist/adapter/device.d.ts.map +1 -1
  15. package/dist/adapter/device.js +196 -10
  16. package/dist/adapter/device.js.map +1 -1
  17. package/dist/adapter/luma.js +1 -1
  18. package/dist/adapter/luma.js.map +1 -1
  19. package/dist/adapter/presentation-context.d.ts +11 -0
  20. package/dist/adapter/presentation-context.d.ts.map +1 -0
  21. package/dist/adapter/presentation-context.js +12 -0
  22. package/dist/adapter/presentation-context.js.map +1 -0
  23. package/dist/adapter/resources/buffer.d.ts +5 -5
  24. package/dist/adapter/resources/buffer.d.ts.map +1 -1
  25. package/dist/adapter/resources/buffer.js +18 -7
  26. package/dist/adapter/resources/buffer.js.map +1 -1
  27. package/dist/adapter/resources/command-buffer.d.ts +3 -1
  28. package/dist/adapter/resources/command-buffer.d.ts.map +1 -1
  29. package/dist/adapter/resources/command-buffer.js +3 -1
  30. package/dist/adapter/resources/command-buffer.js.map +1 -1
  31. package/dist/adapter/resources/command-encoder.d.ts +30 -7
  32. package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
  33. package/dist/adapter/resources/command-encoder.js +68 -2
  34. package/dist/adapter/resources/command-encoder.js.map +1 -1
  35. package/dist/adapter/resources/compute-pipeline.d.ts +2 -2
  36. package/dist/adapter/resources/compute-pipeline.d.ts.map +1 -1
  37. package/dist/adapter/resources/fence.d.ts +16 -0
  38. package/dist/adapter/resources/fence.d.ts.map +1 -0
  39. package/dist/adapter/resources/fence.js +17 -0
  40. package/dist/adapter/resources/fence.js.map +1 -0
  41. package/dist/adapter/resources/framebuffer.d.ts +1 -1
  42. package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
  43. package/dist/adapter/resources/framebuffer.js +15 -12
  44. package/dist/adapter/resources/framebuffer.js.map +1 -1
  45. package/dist/adapter/resources/query-set.d.ts +17 -1
  46. package/dist/adapter/resources/query-set.d.ts.map +1 -1
  47. package/dist/adapter/resources/query-set.js.map +1 -1
  48. package/dist/adapter/resources/render-pipeline.d.ts +28 -10
  49. package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
  50. package/dist/adapter/resources/render-pipeline.js +21 -2
  51. package/dist/adapter/resources/render-pipeline.js.map +1 -1
  52. package/dist/adapter/resources/resource.d.ts +13 -0
  53. package/dist/adapter/resources/resource.d.ts.map +1 -1
  54. package/dist/adapter/resources/resource.js +243 -14
  55. package/dist/adapter/resources/resource.js.map +1 -1
  56. package/dist/adapter/resources/shader.js +27 -25
  57. package/dist/adapter/resources/shader.js.map +1 -1
  58. package/dist/adapter/resources/shared-render-pipeline.d.ts +22 -0
  59. package/dist/adapter/resources/shared-render-pipeline.d.ts.map +1 -0
  60. package/dist/adapter/resources/shared-render-pipeline.js +25 -0
  61. package/dist/adapter/resources/shared-render-pipeline.js.map +1 -0
  62. package/dist/adapter/resources/texture-view.d.ts +1 -1
  63. package/dist/adapter/resources/texture-view.d.ts.map +1 -1
  64. package/dist/adapter/resources/texture.d.ts +168 -28
  65. package/dist/adapter/resources/texture.d.ts.map +1 -1
  66. package/dist/adapter/resources/texture.js +284 -25
  67. package/dist/adapter/resources/texture.js.map +1 -1
  68. package/dist/adapter/types/attachments.d.ts +1 -1
  69. package/dist/adapter/types/attachments.d.ts.map +1 -1
  70. package/dist/adapter/types/buffer-layout.d.ts +1 -1
  71. package/dist/adapter/types/buffer-layout.d.ts.map +1 -1
  72. package/dist/adapter/types/parameters.d.ts +3 -1
  73. package/dist/adapter/types/parameters.d.ts.map +1 -1
  74. package/dist/adapter/types/parameters.js +1 -0
  75. package/dist/adapter/types/parameters.js.map +1 -1
  76. package/dist/adapter/types/shader-layout.d.ts +10 -6
  77. package/dist/adapter/types/shader-layout.d.ts.map +1 -1
  78. package/dist/adapter/types/uniforms.d.ts +6 -0
  79. package/dist/adapter/types/uniforms.d.ts.map +1 -1
  80. package/dist/adapter-utils/bind-groups.d.ts +9 -0
  81. package/dist/adapter-utils/bind-groups.d.ts.map +1 -0
  82. package/dist/adapter-utils/bind-groups.js +41 -0
  83. package/dist/adapter-utils/bind-groups.js.map +1 -0
  84. package/dist/adapter-utils/format-compiler-log.d.ts.map +1 -1
  85. package/dist/adapter-utils/format-compiler-log.js +23 -15
  86. package/dist/adapter-utils/format-compiler-log.js.map +1 -1
  87. package/dist/adapter-utils/get-attribute-from-layouts.d.ts +2 -2
  88. package/dist/adapter-utils/get-attribute-from-layouts.d.ts.map +1 -1
  89. package/dist/adapter-utils/get-attribute-from-layouts.js +6 -6
  90. package/dist/adapter-utils/get-attribute-from-layouts.js.map +1 -1
  91. package/dist/dist.dev.js +2692 -645
  92. package/dist/dist.min.js +10 -9
  93. package/dist/factories/bind-group-factory.d.ts +20 -0
  94. package/dist/factories/bind-group-factory.d.ts.map +1 -0
  95. package/dist/factories/bind-group-factory.js +79 -0
  96. package/dist/factories/bind-group-factory.js.map +1 -0
  97. package/dist/factories/core-module-state.d.ts +7 -0
  98. package/dist/factories/core-module-state.d.ts.map +1 -0
  99. package/dist/{shadertypes/data-types/shader-types.js → factories/core-module-state.js} +1 -1
  100. package/dist/factories/core-module-state.js.map +1 -0
  101. package/dist/factories/pipeline-factory.d.ts +54 -0
  102. package/dist/factories/pipeline-factory.d.ts.map +1 -0
  103. package/dist/factories/pipeline-factory.js +270 -0
  104. package/dist/factories/pipeline-factory.js.map +1 -0
  105. package/dist/factories/shader-factory.d.ts +20 -0
  106. package/dist/factories/shader-factory.d.ts.map +1 -0
  107. package/dist/factories/shader-factory.js +84 -0
  108. package/dist/factories/shader-factory.js.map +1 -0
  109. package/dist/index.cjs +2427 -554
  110. package/dist/index.cjs.map +4 -4
  111. package/dist/index.d.ts +30 -14
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +19 -7
  114. package/dist/index.js.map +1 -1
  115. package/dist/portable/shader-block-writer.d.ts +51 -0
  116. package/dist/portable/shader-block-writer.d.ts.map +1 -0
  117. package/dist/portable/shader-block-writer.js +185 -0
  118. package/dist/portable/shader-block-writer.js.map +1 -0
  119. package/dist/portable/uniform-block.d.ts +1 -1
  120. package/dist/portable/uniform-block.d.ts.map +1 -1
  121. package/dist/portable/uniform-store.d.ts +55 -24
  122. package/dist/portable/uniform-store.d.ts.map +1 -1
  123. package/dist/portable/uniform-store.js +73 -25
  124. package/dist/portable/uniform-store.js.map +1 -1
  125. package/dist/shadertypes/data-types/data-type-decoder.d.ts +20 -0
  126. package/dist/shadertypes/data-types/data-type-decoder.d.ts.map +1 -0
  127. package/dist/shadertypes/data-types/data-type-decoder.js +79 -0
  128. package/dist/shadertypes/data-types/data-type-decoder.js.map +1 -0
  129. package/dist/shadertypes/data-types/data-types.d.ts +31 -12
  130. package/dist/shadertypes/data-types/data-types.d.ts.map +1 -1
  131. package/dist/shadertypes/data-types/decode-data-types.d.ts.map +1 -1
  132. package/dist/shadertypes/data-types/decode-data-types.js +2 -1
  133. package/dist/shadertypes/data-types/decode-data-types.js.map +1 -1
  134. package/dist/{image-utils → shadertypes/image-types}/image-types.d.ts +0 -6
  135. package/dist/shadertypes/image-types/image-types.d.ts.map +1 -0
  136. package/dist/shadertypes/image-types/image-types.js.map +1 -0
  137. package/dist/shadertypes/shader-types/shader-block-layout.d.ts +72 -0
  138. package/dist/shadertypes/shader-types/shader-block-layout.d.ts.map +1 -0
  139. package/dist/shadertypes/shader-types/shader-block-layout.js +209 -0
  140. package/dist/shadertypes/shader-types/shader-block-layout.js.map +1 -0
  141. package/dist/shadertypes/shader-types/shader-type-decoder.d.ts +41 -0
  142. package/dist/shadertypes/shader-types/shader-type-decoder.d.ts.map +1 -0
  143. package/dist/shadertypes/{data-types/decode-shader-types.js → shader-types/shader-type-decoder.js} +43 -4
  144. package/dist/shadertypes/shader-types/shader-type-decoder.js.map +1 -0
  145. package/dist/shadertypes/shader-types/shader-types.d.ts +101 -0
  146. package/dist/shadertypes/shader-types/shader-types.d.ts.map +1 -0
  147. package/dist/shadertypes/shader-types/shader-types.js +30 -0
  148. package/dist/shadertypes/shader-types/shader-types.js.map +1 -0
  149. package/dist/shadertypes/texture-types/pixel-utils.d.ts.map +1 -0
  150. package/dist/shadertypes/{textures → texture-types}/pixel-utils.js +4 -4
  151. package/dist/shadertypes/texture-types/pixel-utils.js.map +1 -0
  152. package/dist/shadertypes/texture-types/texture-format-decoder.d.ts +36 -0
  153. package/dist/shadertypes/texture-types/texture-format-decoder.d.ts.map +1 -0
  154. package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.js +109 -37
  155. package/dist/shadertypes/texture-types/texture-format-decoder.js.map +1 -0
  156. package/dist/shadertypes/texture-types/texture-format-generics.d.ts +34 -0
  157. package/dist/shadertypes/texture-types/texture-format-generics.d.ts.map +1 -0
  158. package/dist/shadertypes/texture-types/texture-format-generics.js.map +1 -0
  159. package/dist/shadertypes/texture-types/texture-format-table.d.ts.map +1 -0
  160. package/dist/shadertypes/{textures → texture-types}/texture-format-table.js +10 -9
  161. package/dist/shadertypes/texture-types/texture-format-table.js.map +1 -0
  162. package/dist/shadertypes/{textures → texture-types}/texture-formats.d.ts +51 -17
  163. package/dist/shadertypes/texture-types/texture-formats.d.ts.map +1 -0
  164. package/dist/shadertypes/{textures → texture-types}/texture-formats.js +1 -0
  165. package/dist/shadertypes/texture-types/texture-formats.js.map +1 -0
  166. package/dist/shadertypes/texture-types/texture-layout.d.ts +5 -0
  167. package/dist/shadertypes/texture-types/texture-layout.d.ts.map +1 -0
  168. package/dist/shadertypes/texture-types/texture-layout.js +41 -0
  169. package/dist/shadertypes/texture-types/texture-layout.js.map +1 -0
  170. package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts +24 -0
  171. package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts.map +1 -0
  172. package/dist/shadertypes/vertex-types/vertex-format-decoder.js +106 -0
  173. package/dist/shadertypes/vertex-types/vertex-format-decoder.js.map +1 -0
  174. package/dist/shadertypes/vertex-types/vertex-formats.d.ts +50 -0
  175. package/dist/shadertypes/vertex-types/vertex-formats.d.ts.map +1 -0
  176. package/dist/shadertypes/vertex-types/vertex-formats.js.map +1 -0
  177. package/dist/utils/array-equal.d.ts +1 -1
  178. package/dist/utils/array-equal.d.ts.map +1 -1
  179. package/dist/utils/array-equal.js +15 -9
  180. package/dist/utils/array-equal.js.map +1 -1
  181. package/dist/utils/assert.d.ts +5 -0
  182. package/dist/utils/assert.d.ts.map +1 -0
  183. package/dist/utils/assert.js +17 -0
  184. package/dist/utils/assert.js.map +1 -0
  185. package/dist/utils/stats-manager.d.ts.map +1 -1
  186. package/dist/utils/stats-manager.js +61 -1
  187. package/dist/utils/stats-manager.js.map +1 -1
  188. package/package.json +6 -6
  189. package/src/adapter/canvas-context.ts +7 -556
  190. package/src/adapter/canvas-observer.ts +130 -0
  191. package/src/adapter/canvas-surface.ts +521 -0
  192. package/src/adapter/device.ts +312 -24
  193. package/src/adapter/presentation-context.ts +16 -0
  194. package/src/adapter/resources/buffer.ts +19 -9
  195. package/src/adapter/resources/command-buffer.ts +4 -2
  196. package/src/adapter/resources/command-encoder.ts +101 -10
  197. package/src/adapter/resources/compute-pipeline.ts +2 -2
  198. package/src/adapter/resources/fence.ts +32 -0
  199. package/src/adapter/resources/framebuffer.ts +16 -13
  200. package/src/adapter/resources/query-set.ts +17 -1
  201. package/src/adapter/resources/render-pipeline.ts +52 -16
  202. package/src/adapter/resources/resource.ts +289 -14
  203. package/src/adapter/resources/shader.ts +28 -28
  204. package/src/adapter/resources/shared-render-pipeline.ts +40 -0
  205. package/src/adapter/resources/texture-view.ts +1 -1
  206. package/src/adapter/resources/texture.ts +427 -49
  207. package/src/adapter/types/attachments.ts +1 -1
  208. package/src/adapter/types/buffer-layout.ts +1 -1
  209. package/src/adapter/types/parameters.ts +4 -1
  210. package/src/adapter/types/shader-layout.ts +15 -9
  211. package/src/adapter/types/uniforms.ts +12 -0
  212. package/src/adapter-utils/bind-groups.ts +71 -0
  213. package/src/adapter-utils/format-compiler-log.ts +23 -15
  214. package/src/adapter-utils/get-attribute-from-layouts.ts +8 -11
  215. package/src/factories/bind-group-factory.ts +139 -0
  216. package/src/factories/core-module-state.ts +11 -0
  217. package/src/factories/pipeline-factory.ts +328 -0
  218. package/src/factories/shader-factory.ts +103 -0
  219. package/src/index.ts +70 -26
  220. package/src/portable/shader-block-writer.ts +254 -0
  221. package/src/portable/uniform-block.ts +1 -1
  222. package/src/portable/uniform-store.ts +98 -40
  223. package/src/shadertypes/data-types/data-type-decoder.ts +105 -0
  224. package/src/shadertypes/data-types/data-types.ts +100 -48
  225. package/src/shadertypes/data-types/decode-data-types.ts +2 -1
  226. package/src/{image-utils → shadertypes/image-types}/image-types.ts +0 -7
  227. package/src/shadertypes/shader-types/shader-block-layout.ts +340 -0
  228. package/src/shadertypes/{data-types/decode-shader-types.ts → shader-types/shader-type-decoder.ts} +88 -14
  229. package/src/shadertypes/shader-types/shader-types.ts +207 -0
  230. package/src/shadertypes/{textures → texture-types}/pixel-utils.ts +4 -4
  231. package/src/shadertypes/{textures → texture-types}/texture-format-decoder.ts +166 -45
  232. package/src/shadertypes/{textures → texture-types}/texture-format-generics.ts +42 -48
  233. package/src/shadertypes/{textures → texture-types}/texture-format-table.ts +10 -9
  234. package/src/shadertypes/{textures → texture-types}/texture-formats.ts +73 -17
  235. package/src/shadertypes/texture-types/texture-layout.ts +60 -0
  236. package/src/shadertypes/vertex-types/vertex-format-decoder.ts +131 -0
  237. package/src/shadertypes/vertex-types/vertex-formats.ts +183 -0
  238. package/src/utils/array-equal.ts +21 -9
  239. package/src/utils/assert.ts +18 -0
  240. package/src/utils/stats-manager.ts +76 -2
  241. package/dist/image-utils/image-types.d.ts.map +0 -1
  242. package/dist/image-utils/image-types.js.map +0 -1
  243. package/dist/portable/uniform-buffer-layout.d.ts +0 -28
  244. package/dist/portable/uniform-buffer-layout.d.ts.map +0 -1
  245. package/dist/portable/uniform-buffer-layout.js +0 -96
  246. package/dist/portable/uniform-buffer-layout.js.map +0 -1
  247. package/dist/shadertypes/data-types/decode-shader-types.d.ts +0 -17
  248. package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +0 -1
  249. package/dist/shadertypes/data-types/decode-shader-types.js.map +0 -1
  250. package/dist/shadertypes/data-types/shader-types.d.ts +0 -45
  251. package/dist/shadertypes/data-types/shader-types.d.ts.map +0 -1
  252. package/dist/shadertypes/data-types/shader-types.js.map +0 -1
  253. package/dist/shadertypes/textures/pixel-utils.d.ts.map +0 -1
  254. package/dist/shadertypes/textures/pixel-utils.js.map +0 -1
  255. package/dist/shadertypes/textures/texture-format-decoder.d.ts +0 -18
  256. package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +0 -1
  257. package/dist/shadertypes/textures/texture-format-decoder.js.map +0 -1
  258. package/dist/shadertypes/textures/texture-format-generics.d.ts +0 -33
  259. package/dist/shadertypes/textures/texture-format-generics.d.ts.map +0 -1
  260. package/dist/shadertypes/textures/texture-format-generics.js.map +0 -1
  261. package/dist/shadertypes/textures/texture-format-table.d.ts.map +0 -1
  262. package/dist/shadertypes/textures/texture-format-table.js.map +0 -1
  263. package/dist/shadertypes/textures/texture-formats.d.ts.map +0 -1
  264. package/dist/shadertypes/textures/texture-formats.js.map +0 -1
  265. package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts +0 -18
  266. package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts.map +0 -1
  267. package/dist/shadertypes/vertex-arrays/decode-vertex-format.js +0 -100
  268. package/dist/shadertypes/vertex-arrays/decode-vertex-format.js.map +0 -1
  269. package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts +0 -27
  270. package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts.map +0 -1
  271. package/dist/shadertypes/vertex-arrays/vertex-formats.js.map +0 -1
  272. package/src/portable/uniform-buffer-layout.ts +0 -118
  273. package/src/shadertypes/data-types/shader-types.ts +0 -87
  274. package/src/shadertypes/vertex-arrays/decode-vertex-format.ts +0 -124
  275. package/src/shadertypes/vertex-arrays/vertex-formats.ts +0 -91
  276. /package/dist/{image-utils → shadertypes/image-types}/image-types.js +0 -0
  277. /package/dist/shadertypes/{textures → texture-types}/pixel-utils.d.ts +0 -0
  278. /package/dist/shadertypes/{textures → texture-types}/texture-format-generics.js +0 -0
  279. /package/dist/shadertypes/{textures → texture-types}/texture-format-table.d.ts +0 -0
  280. /package/dist/shadertypes/{vertex-arrays → vertex-types}/vertex-formats.js +0 -0
@@ -0,0 +1,254 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {CompositeUniformValue, UniformValue} from '../adapter/types/uniforms';
6
+ import {getScratchArrayBuffer} from '../utils/array-utils-flat';
7
+ import {isNumberArray} from '../utils/is-array';
8
+ import {log} from '../utils/log';
9
+ import type {
10
+ CompositeShaderType,
11
+ VariableShaderType
12
+ } from '../shadertypes/shader-types/shader-types';
13
+ import {
14
+ getLeafLayoutInfo,
15
+ isCompositeShaderTypeStruct,
16
+ type ShaderBlockLayout
17
+ } from '../shadertypes/shader-types/shader-block-layout';
18
+
19
+ /**
20
+ * Serializes nested JavaScript uniform values according to a {@link ShaderBlockLayout}.
21
+ */
22
+ export class ShaderBlockWriter {
23
+ /** Layout metadata used to flatten and serialize values. */
24
+ readonly layout: ShaderBlockLayout;
25
+
26
+ /**
27
+ * Creates a writer for a precomputed shader-block layout.
28
+ */
29
+ constructor(layout: ShaderBlockLayout) {
30
+ this.layout = layout;
31
+ }
32
+
33
+ /**
34
+ * Returns `true` if the flattened layout contains the given field.
35
+ */
36
+ has(name: string): boolean {
37
+ return Boolean(this.layout.fields[name]);
38
+ }
39
+
40
+ /**
41
+ * Returns offset and size metadata for a flattened field.
42
+ */
43
+ get(name: string): {offset: number; size: number} | undefined {
44
+ const entry = this.layout.fields[name];
45
+ return entry ? {offset: entry.offset, size: entry.size} : undefined;
46
+ }
47
+
48
+ /**
49
+ * Flattens nested composite values into leaf-path values understood by {@link UniformBlock}.
50
+ *
51
+ * Top-level values may be supplied either in nested object form matching the
52
+ * declared composite shader types or as already-flattened leaf-path values.
53
+ */
54
+ getFlatUniformValues(
55
+ uniformValues: Readonly<Record<string, CompositeUniformValue>>
56
+ ): Record<string, UniformValue> {
57
+ const flattenedUniformValues: Record<string, UniformValue> = {};
58
+
59
+ for (const [name, value] of Object.entries(uniformValues)) {
60
+ const uniformType = this.layout.uniformTypes[name];
61
+ if (uniformType) {
62
+ this._flattenCompositeValue(flattenedUniformValues, name, uniformType, value);
63
+ } else if (this.layout.fields[name]) {
64
+ flattenedUniformValues[name] = value as UniformValue;
65
+ }
66
+ }
67
+
68
+ return flattenedUniformValues;
69
+ }
70
+
71
+ /**
72
+ * Serializes the supplied values into buffer-backed binary data.
73
+ *
74
+ * The returned view length matches {@link ShaderBlockLayout.byteLength}, which
75
+ * is the exact packed size of the block.
76
+ */
77
+ getData(uniformValues: Readonly<Record<string, CompositeUniformValue>>): Uint8Array {
78
+ const buffer = getScratchArrayBuffer(this.layout.byteLength);
79
+ new Uint8Array(buffer, 0, this.layout.byteLength).fill(0);
80
+ const typedArrays = {
81
+ i32: new Int32Array(buffer),
82
+ u32: new Uint32Array(buffer),
83
+ f32: new Float32Array(buffer),
84
+ f16: new Uint16Array(buffer)
85
+ };
86
+
87
+ const flattenedUniformValues = this.getFlatUniformValues(uniformValues);
88
+ for (const [name, value] of Object.entries(flattenedUniformValues)) {
89
+ this._writeLeafValue(typedArrays, name, value);
90
+ }
91
+
92
+ return new Uint8Array(buffer, 0, this.layout.byteLength);
93
+ }
94
+
95
+ /**
96
+ * Recursively flattens nested values using the declared composite shader type.
97
+ */
98
+ private _flattenCompositeValue(
99
+ flattenedUniformValues: Record<string, UniformValue>,
100
+ baseName: string,
101
+ uniformType: CompositeShaderType,
102
+ value: CompositeUniformValue | undefined
103
+ ): void {
104
+ if (value === undefined) {
105
+ return;
106
+ }
107
+
108
+ if (typeof uniformType === 'string' || this.layout.fields[baseName]) {
109
+ flattenedUniformValues[baseName] = value as UniformValue;
110
+ return;
111
+ }
112
+
113
+ if (Array.isArray(uniformType)) {
114
+ const elementType = uniformType[0] as CompositeShaderType;
115
+ const length = uniformType[1] as number;
116
+
117
+ if (Array.isArray(elementType)) {
118
+ throw new Error(`Nested arrays are not supported for ${baseName}`);
119
+ }
120
+
121
+ if (typeof elementType === 'string' && isNumberArray(value)) {
122
+ this._flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value);
123
+ return;
124
+ }
125
+
126
+ if (!Array.isArray(value)) {
127
+ log.warn(`Unsupported uniform array value for ${baseName}:`, value)();
128
+ return;
129
+ }
130
+
131
+ for (let index = 0; index < Math.min(value.length, length); index++) {
132
+ const elementValue = value[index];
133
+ if (elementValue === undefined) {
134
+ continue;
135
+ }
136
+
137
+ this._flattenCompositeValue(
138
+ flattenedUniformValues,
139
+ `${baseName}[${index}]`,
140
+ elementType,
141
+ elementValue
142
+ );
143
+ }
144
+ return;
145
+ }
146
+
147
+ if (isCompositeShaderTypeStruct(uniformType) && isCompositeUniformObject(value)) {
148
+ for (const [key, subValue] of Object.entries(value)) {
149
+ if (subValue === undefined) {
150
+ continue;
151
+ }
152
+
153
+ const nestedName = `${baseName}.${key}`;
154
+ this._flattenCompositeValue(flattenedUniformValues, nestedName, uniformType[key], subValue);
155
+ }
156
+ return;
157
+ }
158
+
159
+ log.warn(`Unsupported uniform value for ${baseName}:`, value)();
160
+ }
161
+
162
+ /**
163
+ * Expands tightly packed numeric arrays into per-element leaf fields.
164
+ */
165
+ private _flattenPackedArray(
166
+ flattenedUniformValues: Record<string, UniformValue>,
167
+ baseName: string,
168
+ elementType: VariableShaderType,
169
+ length: number,
170
+ value: UniformValue
171
+ ): void {
172
+ const numericValue = value as Readonly<ArrayLike<number>>;
173
+ const elementLayout = getLeafLayoutInfo(elementType, this.layout.layout);
174
+ const packedElementLength = elementLayout.components;
175
+
176
+ for (let index = 0; index < length; index++) {
177
+ const start = index * packedElementLength;
178
+ if (start >= numericValue.length) {
179
+ break;
180
+ }
181
+
182
+ if (packedElementLength === 1) {
183
+ flattenedUniformValues[`${baseName}[${index}]`] = Number(numericValue[start]);
184
+ } else {
185
+ flattenedUniformValues[`${baseName}[${index}]`] = sliceNumericArray(
186
+ value,
187
+ start,
188
+ start + packedElementLength
189
+ ) as UniformValue;
190
+ }
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Writes one flattened leaf value into its typed-array view.
196
+ */
197
+ private _writeLeafValue(
198
+ typedArrays: Record<string, any>,
199
+ name: string,
200
+ value: UniformValue
201
+ ): void {
202
+ const entry = this.layout.fields[name];
203
+ if (!entry) {
204
+ log.warn(`Uniform ${name} not found in layout`)();
205
+ return;
206
+ }
207
+
208
+ const {type, components, columns, rows, offset, columnStride} = entry;
209
+ const array = typedArrays[type];
210
+
211
+ if (components === 1) {
212
+ array[offset] = Number(value);
213
+ return;
214
+ }
215
+
216
+ const sourceValue = value as Readonly<ArrayLike<number>>;
217
+
218
+ if (columns === 1) {
219
+ for (let componentIndex = 0; componentIndex < components; componentIndex++) {
220
+ array[offset + componentIndex] = Number(sourceValue[componentIndex] ?? 0);
221
+ }
222
+ return;
223
+ }
224
+
225
+ let sourceIndex = 0;
226
+ for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
227
+ const columnOffset = offset + columnIndex * columnStride;
228
+ for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
229
+ array[columnOffset + rowIndex] = Number(sourceValue[sourceIndex++] ?? 0);
230
+ }
231
+ }
232
+ }
233
+ }
234
+
235
+ /**
236
+ * Type guard for nested uniform objects.
237
+ */
238
+ function isCompositeUniformObject(
239
+ value: CompositeUniformValue
240
+ ): value is Record<string, CompositeUniformValue | undefined> {
241
+ return (
242
+ Boolean(value) &&
243
+ typeof value === 'object' &&
244
+ !Array.isArray(value) &&
245
+ !ArrayBuffer.isView(value)
246
+ );
247
+ }
248
+
249
+ /**
250
+ * Slices a numeric array-like value without changing its numeric representation.
251
+ */
252
+ function sliceNumericArray(value: UniformValue, start: number, end: number): number[] {
253
+ return Array.prototype.slice.call(value, start, end) as number[];
254
+ }
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {VariableShaderType} from '../shadertypes/data-types/shader-types';
5
+ import type {VariableShaderType} from '../shadertypes/shader-types/shader-types';
6
6
  import type {UniformValue} from '../adapter/types/uniforms';
7
7
  import {
8
8
  ShaderLayout,
@@ -2,13 +2,44 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- import type {VariableShaderType} from '../shadertypes/data-types/shader-types';
6
- import type {UniformValue} from '../adapter/types/uniforms';
5
+ import type {CompositeShaderType} from '../shadertypes/shader-types/shader-types';
6
+ import type {CompositeUniformValue} from '../adapter/types/uniforms';
7
7
  import type {Device} from '../adapter/device';
8
8
  import {Buffer} from '../adapter/resources/buffer';
9
9
  import {log} from '../utils/log';
10
+ import {
11
+ makeShaderBlockLayout,
12
+ type ShaderBlockLayout
13
+ } from '../shadertypes/shader-types/shader-block-layout';
10
14
  import {UniformBlock} from './uniform-block';
11
- import {UniformBufferLayout} from './uniform-buffer-layout';
15
+ import {ShaderBlockWriter} from './shader-block-writer';
16
+
17
+ /** Definition of a single managed uniform block. */
18
+ export type UniformStoreBlockDefinition = {
19
+ /** Declared shader types for the block's uniforms. */
20
+ uniformTypes?: Record<string, CompositeShaderType>;
21
+ /** Reserved for future prop-level defaults. */
22
+ defaultProps?: Record<string, unknown>;
23
+ /** Initial uniform values written into the backing block. */
24
+ defaultUniforms?: Record<string, CompositeUniformValue>;
25
+ /** Explicit shader-block layout override. */
26
+ layout?: 'std140' | 'wgsl-uniform' | 'wgsl-storage';
27
+ };
28
+
29
+ /** Uniform block definitions keyed by block name. */
30
+ export type UniformStoreBlocks<TPropGroups extends Record<string, Record<string, unknown>>> =
31
+ Record<keyof TPropGroups, UniformStoreBlockDefinition>;
32
+
33
+ /**
34
+ * Smallest buffer size that can be used for uniform buffers.
35
+ *
36
+ * This is an allocation policy rather than part of {@link ShaderBlockLayout}.
37
+ * Layouts report the exact packed size, while the store applies any minimum
38
+ * buffer-size rule when allocating GPU buffers.
39
+ *
40
+ * TODO - does this depend on device?
41
+ */
42
+ const minUniformBufferSize = 1024;
12
43
 
13
44
  /**
14
45
  * A uniform store holds a uniform values for one or more uniform blocks,
@@ -23,41 +54,37 @@ export class UniformStore<
23
54
  Record<string, unknown>
24
55
  >
25
56
  > {
57
+ /** Device used to infer layout and allocate buffers. */
58
+ readonly device: Device;
26
59
  /** Stores the uniform values for each uniform block */
27
60
  uniformBlocks = new Map<keyof TPropGroups, UniformBlock>();
28
- /** Can generate data for a uniform buffer for each block from data */
29
- uniformBufferLayouts = new Map<keyof TPropGroups, UniformBufferLayout>();
61
+ /** Flattened layout metadata for each block. */
62
+ shaderBlockLayouts = new Map<keyof TPropGroups, ShaderBlockLayout>();
63
+ /** Serializers for block-backed uniform data. */
64
+ shaderBlockWriters = new Map<keyof TPropGroups, ShaderBlockWriter>();
30
65
  /** Actual buffer for the blocks */
31
66
  uniformBuffers = new Map<keyof TPropGroups, Buffer>();
32
67
 
33
68
  /**
34
- * Create a new UniformStore instance
35
- * @param blocks
69
+ * Creates a new {@link UniformStore} for the supplied device and block definitions.
36
70
  */
37
- constructor(
38
- blocks: Record<
39
- keyof TPropGroups,
40
- {
41
- uniformTypes?: Record<string, VariableShaderType>;
42
- uniformSizes?: Record<string, number>;
43
- defaultProps?: Record<string, unknown>;
44
- defaultUniforms?: Record<string, UniformValue>;
45
- }
46
- >
47
- ) {
71
+ constructor(device: Device, blocks: UniformStoreBlocks<TPropGroups>) {
72
+ this.device = device;
73
+
48
74
  for (const [bufferName, block] of Object.entries(blocks)) {
49
75
  const uniformBufferName = bufferName as keyof TPropGroups;
50
76
 
51
77
  // Create a layout object to help us generate correctly formatted binary uniform buffers
52
- const uniformBufferLayout = new UniformBufferLayout(
53
- block.uniformTypes ?? {},
54
- block.uniformSizes ?? {}
55
- );
56
- this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout);
78
+ const shaderBlockLayout = makeShaderBlockLayout(block.uniformTypes ?? {}, {
79
+ layout: block.layout ?? getDefaultUniformBufferLayout(device)
80
+ });
81
+ const shaderBlockWriter = new ShaderBlockWriter(shaderBlockLayout);
82
+ this.shaderBlockLayouts.set(uniformBufferName, shaderBlockLayout);
83
+ this.shaderBlockWriters.set(uniformBufferName, shaderBlockWriter);
57
84
 
58
85
  // Create a Uniform block to store the uniforms for each buffer.
59
86
  const uniformBlock = new UniformBlock({name: bufferName});
60
- uniformBlock.setUniforms(block.defaultUniforms || {});
87
+ uniformBlock.setUniforms(shaderBlockWriter.getFlatUniformValues(block.defaultUniforms || {}));
61
88
  this.uniformBlocks.set(uniformBufferName, uniformBlock);
62
89
  }
63
90
  }
@@ -71,13 +98,20 @@ export class UniformStore<
71
98
 
72
99
  /**
73
100
  * Set uniforms
74
- * Makes all properties partial
101
+ *
102
+ * Makes all group properties partial and eagerly propagates changes to any
103
+ * managed GPU buffers.
75
104
  */
76
105
  setUniforms(
77
106
  uniforms: Partial<{[group in keyof TPropGroups]: Partial<TPropGroups[group]>}>
78
107
  ): void {
79
108
  for (const [blockName, uniformValues] of Object.entries(uniforms)) {
80
- this.uniformBlocks.get(blockName)?.setUniforms(uniformValues);
109
+ const uniformBufferName = blockName as keyof TPropGroups;
110
+ const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
111
+ const flattenedUniforms = shaderBlockWriter?.getFlatUniformValues(
112
+ (uniformValues || {}) as Record<string, CompositeUniformValue>
113
+ );
114
+ this.uniformBlocks.get(uniformBufferName)?.setUniforms(flattenedUniforms || {});
81
115
  // We leverage logging in updateUniformBuffers(), even though slightly less efficient
82
116
  // this.updateUniformBuffer(blockName);
83
117
  }
@@ -85,24 +119,33 @@ export class UniformStore<
85
119
  this.updateUniformBuffers();
86
120
  }
87
121
 
88
- /** Get the required minimum length of the uniform buffer */
122
+ /**
123
+ * Returns the allocation size for the named uniform buffer.
124
+ *
125
+ * This may exceed the packed layout size because minimum buffer-size policy is
126
+ * applied at the store layer.
127
+ */
89
128
  getUniformBufferByteLength(uniformBufferName: keyof TPropGroups): number {
90
- return this.uniformBufferLayouts.get(uniformBufferName)?.byteLength || 0;
129
+ const packedByteLength = this.shaderBlockLayouts.get(uniformBufferName)?.byteLength || 0;
130
+ return Math.max(packedByteLength, minUniformBufferSize);
91
131
  }
92
132
 
93
- /** Get formatted binary memory that can be uploaded to a buffer */
133
+ /**
134
+ * Returns packed binary data that can be uploaded to the named uniform buffer.
135
+ *
136
+ * The returned view length matches the packed block size and is not padded to
137
+ * the store's minimum allocation size.
138
+ */
94
139
  getUniformBufferData(uniformBufferName: keyof TPropGroups): Uint8Array {
95
140
  const uniformValues = this.uniformBlocks.get(uniformBufferName)?.getAllUniforms() || {};
96
- // @ts-ignore
97
- return this.uniformBufferLayouts.get(uniformBufferName)?.getData(uniformValues);
141
+ const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
142
+ return shaderBlockWriter?.getData(uniformValues) || new Uint8Array(0);
98
143
  }
99
144
 
100
145
  /**
101
- * Creates an unmanaged uniform buffer (umnanaged means that application is responsible for destroying it)
102
- * The new buffer is initialized with current / supplied values
146
+ * Creates an unmanaged uniform buffer initialized with the current or supplied values.
103
147
  */
104
148
  createUniformBuffer(
105
- device: Device,
106
149
  uniformBufferName: keyof TPropGroups,
107
150
  uniforms?: Partial<{[group in keyof TPropGroups]: Partial<TPropGroups[group]>}>
108
151
  ): Buffer {
@@ -110,7 +153,7 @@ export class UniformStore<
110
153
  this.setUniforms(uniforms);
111
154
  }
112
155
  const byteLength = this.getUniformBufferByteLength(uniformBufferName);
113
- const uniformBuffer = device.createBuffer({
156
+ const uniformBuffer = this.device.createBuffer({
114
157
  usage: Buffer.UNIFORM | Buffer.COPY_DST,
115
158
  byteLength
116
159
  });
@@ -120,11 +163,11 @@ export class UniformStore<
120
163
  return uniformBuffer;
121
164
  }
122
165
 
123
- /** Get the managed uniform buffer. "managed" resources are destroyed when the uniformStore is destroyed. */
124
- getManagedUniformBuffer(device: Device, uniformBufferName: keyof TPropGroups): Buffer {
166
+ /** Returns the managed uniform buffer for the named block. */
167
+ getManagedUniformBuffer(uniformBufferName: keyof TPropGroups): Buffer {
125
168
  if (!this.uniformBuffers.get(uniformBufferName)) {
126
169
  const byteLength = this.getUniformBufferByteLength(uniformBufferName);
127
- const uniformBuffer = device.createBuffer({
170
+ const uniformBuffer = this.device.createBuffer({
128
171
  usage: Buffer.UNIFORM | Buffer.COPY_DST,
129
172
  byteLength
130
173
  });
@@ -135,7 +178,11 @@ export class UniformStore<
135
178
  return this.uniformBuffers.get(uniformBufferName);
136
179
  }
137
180
 
138
- /** Updates all uniform buffers where values have changed */
181
+ /**
182
+ * Updates every managed uniform buffer whose source uniforms have changed.
183
+ *
184
+ * @returns The first redraw reason encountered, or `false` if nothing changed.
185
+ */
139
186
  updateUniformBuffers(): false | string {
140
187
  let reason: false | string = false;
141
188
  for (const uniformBufferName of this.uniformBlocks.keys()) {
@@ -148,7 +195,11 @@ export class UniformStore<
148
195
  return reason;
149
196
  }
150
197
 
151
- /** Update one uniform buffer. Only updates if values have changed */
198
+ /**
199
+ * Updates one managed uniform buffer if its corresponding block is dirty.
200
+ *
201
+ * @returns The redraw reason for the update, or `false` if no write occurred.
202
+ */
152
203
  updateUniformBuffer(uniformBufferName: keyof TPropGroups): false | string {
153
204
  const uniformBlock = this.uniformBlocks.get(uniformBufferName);
154
205
  let uniformBuffer = this.uniformBuffers.get(uniformBufferName);
@@ -174,3 +225,10 @@ export class UniformStore<
174
225
  return reason;
175
226
  }
176
227
  }
228
+
229
+ /**
230
+ * Returns the default uniform-buffer layout for the supplied device.
231
+ */
232
+ function getDefaultUniformBufferLayout(device: Device): 'std140' | 'wgsl-uniform' | 'wgsl-storage' {
233
+ return device.type === 'webgpu' ? 'wgsl-uniform' : 'std140';
234
+ }
@@ -0,0 +1,105 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {TypedArray, TypedArrayConstructor} from '../../types';
6
+ import {
7
+ PrimitiveDataType,
8
+ SignedDataType,
9
+ NormalizedDataType,
10
+ DataTypeInfo,
11
+ TypedArrayConstructorT
12
+ } from './data-types';
13
+
14
+ export class DataTypeDecoder {
15
+ /**
16
+ * Gets info about a data type constant (signed or normalized)
17
+ * @returns underlying primitive / signed types, byte length, normalization, integer, signed flags
18
+ */
19
+ getDataTypeInfo<T extends NormalizedDataType = NormalizedDataType>(type: T): DataTypeInfo<T> {
20
+ const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
21
+ const normalized: boolean = type.includes('norm');
22
+ const integer: boolean = !normalized && !type.startsWith('float');
23
+ const signed: boolean = type.startsWith('s');
24
+ return {
25
+ signedType: signedType as DataTypeInfo<T>['signedType'],
26
+ primitiveType: primitiveType as DataTypeInfo<T>['primitiveType'],
27
+ byteLength: byteLength as DataTypeInfo<T>['byteLength'],
28
+ normalized: normalized as DataTypeInfo<T>['normalized'],
29
+ integer: integer as DataTypeInfo<T>['integer'],
30
+ signed: signed as DataTypeInfo<T>['signed']
31
+ // TODO - add webglOnly flag
32
+ };
33
+ }
34
+
35
+ /** Build a vertex format from a signed data type and a component */
36
+ getNormalizedDataType(signedDataType: SignedDataType): NormalizedDataType {
37
+ const dataType: NormalizedDataType = signedDataType;
38
+ // prettier-ignore
39
+ switch (dataType) {
40
+ case 'uint8': return 'unorm8';
41
+ case 'sint8': return 'snorm8';
42
+ case 'uint16': return 'unorm16';
43
+ case 'sint16': return 'snorm16';
44
+ default: return dataType;
45
+ }
46
+ }
47
+
48
+ /** Align offset to 1, 2 or 4 elements (4, 8 or 16 bytes) */
49
+ alignTo(size: number, count: number): number {
50
+ // prettier-ignore
51
+ switch (count) {
52
+ case 1: return size; // Pad upwards to even multiple of 2
53
+ case 2: return size + (size % 2); // Pad upwards to even multiple of 2
54
+ default: return size + ((4 - (size % 4)) % 4); // Pad upwards to even multiple of 4
55
+ }
56
+ }
57
+
58
+ /** Returns the VariableShaderType that corresponds to a typed array */
59
+ getDataType(arrayOrType: TypedArray | TypedArrayConstructor): SignedDataType {
60
+ const Constructor = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
61
+ if (Constructor === Uint8ClampedArray) {
62
+ return 'uint8';
63
+ }
64
+ const info = Object.values(NORMALIZED_TYPE_MAP).find(entry => Constructor === entry[4]);
65
+ if (!info) {
66
+ throw new Error(Constructor.name);
67
+ }
68
+ return info[0];
69
+ }
70
+
71
+ /** Returns the TypedArray that corresponds to a shader data type */
72
+ getTypedArrayConstructor<T extends NormalizedDataType>(
73
+ type: NormalizedDataType
74
+ ): TypedArrayConstructorT<T> {
75
+ const [, , , , Constructor] = NORMALIZED_TYPE_MAP[type];
76
+ return Constructor as unknown as TypedArrayConstructorT<T>;
77
+ }
78
+ }
79
+
80
+ /** Entry point for decoding luma.gl data types */
81
+ export const dataTypeDecoder = new DataTypeDecoder();
82
+
83
+ const NORMALIZED_TYPE_MAP = {
84
+ uint8: ['uint8', 'u32', 1, false, Uint8Array],
85
+ sint8: ['sint8', 'i32', 1, false, Int8Array],
86
+ unorm8: ['uint8', 'f32', 1, true, Uint8Array],
87
+ snorm8: ['sint8', 'f32', 1, true, Int8Array],
88
+ uint16: ['uint16', 'u32', 2, false, Uint16Array],
89
+ sint16: ['sint16', 'i32', 2, false, Int16Array],
90
+ unorm16: ['uint16', 'u32', 2, true, Uint16Array],
91
+ snorm16: ['sint16', 'i32', 2, true, Int16Array],
92
+ float16: ['float16', 'f16', 2, false, Uint16Array],
93
+ float32: ['float32', 'f32', 4, false, Float32Array],
94
+ uint32: ['uint32', 'u32', 4, false, Uint32Array],
95
+ sint32: ['sint32', 'i32', 4, false, Int32Array]
96
+ } satisfies Record<
97
+ NormalizedDataType,
98
+ [
99
+ SignedDataType,
100
+ PrimitiveDataType,
101
+ bytes: 1 | 2 | 4,
102
+ normalized: boolean,
103
+ arrayConstructor: TypedArrayConstructor
104
+ ]
105
+ >;