typegpu 0.11.9 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/bin.mjs +28 -6
  2. package/builtin.d.ts +51 -53
  3. package/builtin.js +30 -34
  4. package/common/fullScreenTriangle.d.ts +2 -10
  5. package/common/fullScreenTriangle.js +20 -28
  6. package/common/index.d.ts +2 -9
  7. package/common/index.js +3 -12
  8. package/common/writeSoA.d.ts +11 -12
  9. package/common/writeSoA.js +88 -76
  10. package/core/buffer/buffer.d.ts +79 -62
  11. package/core/buffer/buffer.js +283 -205
  12. package/core/buffer/bufferBinding.d.ts +71 -0
  13. package/core/buffer/bufferBinding.js +154 -0
  14. package/core/buffer/bufferUsage.d.ts +14 -45
  15. package/core/buffer/bufferUsage.js +1 -171
  16. package/core/buffer/laidOutBuffer.d.ts +25 -0
  17. package/core/buffer/laidOutBuffer.js +55 -0
  18. package/core/commandEncoder/attachments.d.ts +125 -0
  19. package/core/commandEncoder/attachments.js +29 -0
  20. package/core/commandEncoder/commandEncoder.d.ts +53 -0
  21. package/core/commandEncoder/commandEncoder.js +56 -0
  22. package/core/commandEncoder/computePass.d.ts +58 -0
  23. package/core/commandEncoder/computePass.js +63 -0
  24. package/core/commandEncoder/renderPass.d.ts +121 -0
  25. package/core/commandEncoder/renderPass.js +196 -0
  26. package/core/constant/tgpuConstant.d.ts +26 -26
  27. package/core/constant/tgpuConstant.js +76 -65
  28. package/core/declare/tgpuDeclare.d.ts +3 -6
  29. package/core/declare/tgpuDeclare.js +36 -36
  30. package/core/function/autoIO.d.ts +61 -33
  31. package/core/function/autoIO.js +68 -73
  32. package/core/function/comptime.d.ts +11 -13
  33. package/core/function/comptime.js +60 -52
  34. package/core/function/createCallableSchema.d.ts +16 -0
  35. package/core/function/createCallableSchema.js +50 -40
  36. package/core/function/dualImpl.d.ts +44 -0
  37. package/core/function/dualImpl.js +71 -50
  38. package/core/function/entryInputRouter.d.ts +26 -0
  39. package/core/function/entryInputRouter.js +31 -33
  40. package/core/function/extractArgs.d.ts +38 -0
  41. package/core/function/extractArgs.js +202 -200
  42. package/core/function/fnCore.d.ts +44 -5
  43. package/core/function/fnCore.js +148 -93
  44. package/core/function/fnTypes.d.ts +31 -29
  45. package/core/function/fnTypes.js +1 -0
  46. package/core/function/ioSchema.d.ts +12 -10
  47. package/core/function/ioSchema.js +65 -47
  48. package/core/function/shelllessImpl.d.ts +9 -12
  49. package/core/function/shelllessImpl.js +17 -22
  50. package/core/function/templateUtils.d.ts +2 -0
  51. package/core/function/templateUtils.js +9 -8
  52. package/core/function/tgpuComputeFn.d.ts +26 -28
  53. package/core/function/tgpuComputeFn.js +47 -48
  54. package/core/function/tgpuFn.d.ts +34 -37
  55. package/core/function/tgpuFn.js +179 -153
  56. package/core/function/tgpuFragmentFn.d.ts +52 -53
  57. package/core/function/tgpuFragmentFn.js +63 -56
  58. package/core/function/tgpuVertexFn.d.ts +36 -39
  59. package/core/function/tgpuVertexFn.js +56 -53
  60. package/core/pipeline/computePipeline.d.ts +141 -53
  61. package/core/pipeline/computePipeline.js +291 -225
  62. package/core/pipeline/connectAttachmentToShader.d.ts +4 -0
  63. package/core/pipeline/connectAttachmentToShader.js +25 -22
  64. package/core/pipeline/connectTargetsToShader.d.ts +3 -0
  65. package/core/pipeline/connectTargetsToShader.js +29 -27
  66. package/core/pipeline/drawState.d.ts +52 -0
  67. package/core/pipeline/drawState.js +225 -0
  68. package/core/pipeline/performanceTracker.d.ts +14 -0
  69. package/core/pipeline/performanceTracker.js +34 -0
  70. package/core/pipeline/pipelineUtils.d.ts +18 -0
  71. package/core/pipeline/pipelineUtils.js +54 -25
  72. package/core/pipeline/priors.d.ts +1 -0
  73. package/core/pipeline/priors.js +12 -0
  74. package/core/pipeline/renderPipeline.d.ts +246 -261
  75. package/core/pipeline/renderPipeline.js +487 -480
  76. package/core/pipeline/timeable.d.ts +28 -18
  77. package/core/pipeline/timeable.js +90 -52
  78. package/core/pipeline/typeGuards.d.ts +17 -0
  79. package/core/pipeline/typeGuards.js +52 -22
  80. package/core/pipeline/webgpuLimitations.d.ts +10 -0
  81. package/core/pipeline/webgpuLimitations.js +81 -0
  82. package/core/querySet/querySet.d.ts +26 -21
  83. package/core/querySet/querySet.js +127 -103
  84. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +13 -18
  85. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +89 -90
  86. package/core/resolve/externals.d.ts +25 -8
  87. package/core/resolve/externals.js +78 -54
  88. package/core/resolve/namespace.d.ts +22 -25
  89. package/core/resolve/namespace.js +16 -21
  90. package/core/resolve/resolvableString.d.ts +7 -0
  91. package/core/resolve/resolvableString.js +13 -0
  92. package/core/resolve/resolveData.d.ts +10 -0
  93. package/core/resolve/resolveData.js +162 -121
  94. package/core/resolve/stitch.d.ts +8 -0
  95. package/core/resolve/stitch.js +23 -21
  96. package/core/resolve/tgpuResolve.d.ts +55 -53
  97. package/core/resolve/tgpuResolve.js +106 -53
  98. package/core/root/configurableImpl.d.ts +10 -0
  99. package/core/root/configurableImpl.js +17 -19
  100. package/core/root/init.d.ts +76 -38
  101. package/core/root/init.js +346 -455
  102. package/core/root/rootTypes.d.ts +461 -636
  103. package/core/root/rootTypes.js +1 -0
  104. package/core/sampler/sampler.d.ts +50 -31
  105. package/core/sampler/sampler.js +120 -113
  106. package/core/simulate/tgpuSimulate.d.ts +9 -12
  107. package/core/simulate/tgpuSimulate.js +68 -71
  108. package/core/slot/accessor.d.ts +36 -13
  109. package/core/slot/accessor.js +138 -91
  110. package/core/slot/internalSlots.d.ts +2 -0
  111. package/core/slot/internalSlots.js +1 -6
  112. package/core/slot/lazy.d.ts +2 -6
  113. package/core/slot/lazy.js +71 -39
  114. package/core/slot/slot.d.ts +2 -6
  115. package/core/slot/slot.js +45 -38
  116. package/core/slot/slotTypes.d.ts +78 -80
  117. package/core/slot/slotTypes.js +11 -16
  118. package/core/texture/externalTexture.d.ts +20 -11
  119. package/core/texture/externalTexture.js +46 -46
  120. package/core/texture/texture.d.ts +152 -97
  121. package/core/texture/texture.js +407 -314
  122. package/core/texture/textureFormats.d.ts +42 -23
  123. package/core/texture/textureFormats.js +104 -75
  124. package/core/texture/textureProps.d.ts +7 -10
  125. package/core/texture/textureProps.js +1 -0
  126. package/core/texture/textureUtils.d.ts +8 -0
  127. package/core/texture/textureUtils.js +185 -179
  128. package/core/texture/usageExtension.d.ts +21 -18
  129. package/core/texture/usageExtension.js +13 -17
  130. package/core/unroll/tgpuUnroll.d.ts +20 -19
  131. package/core/unroll/tgpuUnroll.js +82 -91
  132. package/core/valueProxyUtils.d.ts +3 -0
  133. package/core/valueProxyUtils.js +52 -41
  134. package/core/variable/tgpuVariable.d.ts +26 -27
  135. package/core/variable/tgpuVariable.js +93 -96
  136. package/core/vertexLayout/connectAttributesToShader.d.ts +9 -0
  137. package/core/vertexLayout/connectAttributesToShader.js +61 -56
  138. package/core/vertexLayout/vertexAttribute.d.ts +21 -17
  139. package/core/vertexLayout/vertexAttribute.js +1 -0
  140. package/core/vertexLayout/vertexLayout.d.ts +24 -18
  141. package/core/vertexLayout/vertexLayout.js +130 -99
  142. package/core/whitespaces.d.ts +2 -0
  143. package/core/whitespaces.js +16 -0
  144. package/data/alignIO.d.ts +7 -0
  145. package/data/alignIO.js +13 -13
  146. package/data/alignmentOf.d.ts +5 -8
  147. package/data/alignmentOf.js +90 -75
  148. package/data/array.d.ts +17 -9
  149. package/data/array.js +57 -40
  150. package/data/atomic.d.ts +2 -7
  151. package/data/atomic.js +26 -23
  152. package/data/attributes.d.ts +19 -21
  153. package/data/attributes.js +192 -132
  154. package/data/autoStruct.d.ts +36 -3
  155. package/data/autoStruct.js +84 -81
  156. package/data/compiledIO.d.ts +5 -0
  157. package/data/compiledIO.js +231 -215
  158. package/data/dataIO.d.ts +13 -11
  159. package/data/dataIO.js +643 -589
  160. package/data/dataTypes.d.ts +83 -65
  161. package/data/dataTypes.js +66 -68
  162. package/data/deepEqual.d.ts +2 -7
  163. package/data/deepEqual.js +80 -55
  164. package/data/disarray.d.ts +6 -10
  165. package/data/disarray.js +52 -46
  166. package/data/float16Conversion.d.ts +4 -0
  167. package/data/float16Conversion.js +7 -0
  168. package/data/generalizeFn.d.ts +25 -0
  169. package/data/generalizeFn.js +89 -0
  170. package/data/getLongestContiguousPrefix.d.ts +4 -8
  171. package/data/getLongestContiguousPrefix.js +6 -11
  172. package/data/index.d.ts +30 -31
  173. package/data/index.js +39 -172
  174. package/data/instanceToSchema.d.ts +24 -27
  175. package/data/instanceToSchema.js +1 -0
  176. package/data/isContiguous.d.ts +4 -8
  177. package/data/isContiguous.js +6 -11
  178. package/data/matrix.d.ts +21 -21
  179. package/data/matrix.js +513 -505
  180. package/data/numberOps.d.ts +5 -0
  181. package/data/numberOps.js +21 -21
  182. package/data/numeric.d.ts +21 -12
  183. package/data/numeric.js +287 -197
  184. package/data/offsetUtils.d.ts +9 -13
  185. package/data/offsetUtils.js +204 -144
  186. package/data/offsets.d.ts +8 -0
  187. package/data/offsets.js +33 -33
  188. package/data/partialIO.d.ts +13 -8
  189. package/data/partialIO.js +124 -113
  190. package/data/ptr.d.ts +12 -12
  191. package/data/ptr.js +42 -44
  192. package/data/ref.d.ts +40 -27
  193. package/data/ref.js +125 -95
  194. package/data/sampler.d.ts +99 -101
  195. package/data/sampler.js +17 -21
  196. package/data/schemaCallWrapper.d.ts +19 -0
  197. package/data/schemaCallWrapper.js +31 -26
  198. package/data/schemaMemoryLayout.d.ts +8 -0
  199. package/data/schemaMemoryLayout.js +213 -185
  200. package/data/sizeOf.d.ts +4 -8
  201. package/data/sizeOf.js +6 -11
  202. package/data/snippet.d.ts +96 -20
  203. package/data/snippet.js +75 -86
  204. package/data/struct.d.ts +4 -7
  205. package/data/struct.js +51 -39
  206. package/data/texture.d.ts +253 -250
  207. package/data/texture.js +238 -200
  208. package/data/unstruct.d.ts +2 -7
  209. package/data/unstruct.js +43 -37
  210. package/data/vector.d.ts +33 -21
  211. package/data/vector.js +234 -221
  212. package/data/vectorImpl.d.ts +231 -0
  213. package/data/vectorImpl.js +563 -515
  214. package/data/vectorOps.d.ts +25 -0
  215. package/data/vectorOps.js +118 -669
  216. package/data/vertexFormatData.d.ts +181 -184
  217. package/data/vertexFormatData.js +104 -106
  218. package/data/wgslTypes.d.ts +665 -600
  219. package/data/wgslTypes.js +220 -198
  220. package/errors.d.ts +50 -24
  221. package/errors.js +146 -126
  222. package/execMode.d.ts +16 -0
  223. package/execMode.js +47 -40
  224. package/extension.d.ts +13 -8
  225. package/extension.js +10 -16
  226. package/getGPUValue.d.ts +1 -0
  227. package/getGPUValue.js +2 -7
  228. package/index.d.ts +28 -68
  229. package/index.js +8 -28
  230. package/indexNamedExports.d.ts +69 -42
  231. package/indexNamedExports.js +25 -0
  232. package/internal.d.ts +16 -0
  233. package/internal.js +12 -0
  234. package/mathUtils.d.ts +5 -0
  235. package/mathUtils.js +7 -11
  236. package/memo.d.ts +11 -0
  237. package/memo.js +20 -22
  238. package/minify.d.ts +5 -0
  239. package/minify.js +93 -0
  240. package/nameUtils.d.ts +29 -0
  241. package/nameUtils.js +427 -394
  242. package/package.json +5 -1
  243. package/resolutionCtx.d.ts +162 -22
  244. package/resolutionCtx.js +911 -629
  245. package/serial/registry.d.ts +15 -0
  246. package/serial/registry.js +106 -0
  247. package/serial/restore.d.ts +49 -0
  248. package/serial/restore.js +68 -0
  249. package/serial/schema.d.ts +58 -0
  250. package/serial/schema.js +209 -0
  251. package/serial/types.d.ts +5 -0
  252. package/serial/types.js +1 -0
  253. package/shared/env.d.ts +9 -0
  254. package/shared/env.js +9 -12
  255. package/shared/generators.d.ts +4 -0
  256. package/shared/generators.js +10 -12
  257. package/shared/meta.d.ts +29 -14
  258. package/shared/meta.js +71 -55
  259. package/shared/normalizeMetadata.d.ts +32 -27
  260. package/shared/normalizeMetadata.js +23 -36
  261. package/shared/repr.d.ts +73 -55
  262. package/shared/repr.js +1 -0
  263. package/shared/soul.d.ts +17 -0
  264. package/shared/soul.js +1 -0
  265. package/shared/stringify.d.ts +2 -0
  266. package/shared/stringify.js +29 -20
  267. package/shared/symbols.d.ts +26 -20
  268. package/shared/symbols.js +79 -79
  269. package/shared/tseynit.d.ts +2 -0
  270. package/shared/tseynit.js +160 -75
  271. package/shared/utilityTypes.d.ts +30 -14
  272. package/shared/utilityTypes.js +2 -6
  273. package/shared/vertexFormat.d.ts +41 -43
  274. package/shared/vertexFormat.js +59 -62
  275. package/std/array.d.ts +2 -7
  276. package/std/array.js +18 -23
  277. package/std/atomic.d.ts +14 -18
  278. package/std/atomic.js +96 -95
  279. package/std/bitcast.d.ts +193 -10
  280. package/std/bitcast.js +309 -39
  281. package/std/boolean.d.ts +19 -33
  282. package/std/boolean.js +296 -292
  283. package/std/copy.d.ts +2 -7
  284. package/std/copy.js +27 -24
  285. package/std/derivative.d.ts +11 -15
  286. package/std/derivative.js +56 -79
  287. package/std/discard.d.ts +1 -6
  288. package/std/discard.js +7 -14
  289. package/std/environment.d.ts +19 -14
  290. package/std/environment.js +71 -51
  291. package/std/extensions.d.ts +2 -8
  292. package/std/extensions.js +10 -11
  293. package/std/index.d.ts +20 -24
  294. package/std/index.js +32 -187
  295. package/std/matrix.d.ts +6 -12
  296. package/std/matrix.js +60 -69
  297. package/std/numeric.d.ts +150 -146
  298. package/std/numeric.js +771 -727
  299. package/std/operators.d.ts +19 -27
  300. package/std/operators.js +195 -194
  301. package/std/packing.d.ts +5 -11
  302. package/std/packing.js +67 -75
  303. package/std/range.d.ts +6 -11
  304. package/std/range.js +48 -36
  305. package/std/subgroup.d.ts +33 -37
  306. package/std/subgroup.js +180 -217
  307. package/std/texture.d.ts +70 -38
  308. package/std/texture.js +176 -172
  309. package/taskQueue.d.ts +6 -0
  310. package/taskQueue.js +30 -0
  311. package/tgpu.d.ts +16 -0
  312. package/tgpu.js +17 -44
  313. package/tgpuBindGroupLayout.d.ts +132 -152
  314. package/tgpuBindGroupLayout.js +346 -268
  315. package/tgpuLogger.d.ts +34 -0
  316. package/tgpuLogger.js +64 -0
  317. package/tgpuUnstable.d.ts +16 -22
  318. package/tgpuUnstable.js +13 -35
  319. package/tgsl/accessIndex.d.ts +2 -0
  320. package/tgsl/accessIndex.js +76 -33
  321. package/tgsl/accessProp.d.ts +2 -0
  322. package/tgsl/accessProp.js +142 -101
  323. package/tgsl/accessStructProp.d.ts +5 -0
  324. package/tgsl/accessStructProp.js +13 -15
  325. package/tgsl/consoleLog/deserializers.d.ts +13 -0
  326. package/tgsl/consoleLog/deserializers.js +119 -103
  327. package/tgsl/consoleLog/logGenerator.d.ts +21 -0
  328. package/tgsl/consoleLog/logGenerator.js +85 -80
  329. package/tgsl/consoleLog/serializers.d.ts +21 -0
  330. package/tgsl/consoleLog/serializers.js +119 -100
  331. package/tgsl/consoleLog/types.d.ts +40 -39
  332. package/tgsl/consoleLog/types.js +1 -0
  333. package/tgsl/conversion.d.ts +33 -0
  334. package/tgsl/conversion.js +271 -216
  335. package/tgsl/forOfUtils.d.ts +15 -0
  336. package/tgsl/forOfUtils.js +85 -70
  337. package/tgsl/generationHelpers.d.ts +22 -39
  338. package/tgsl/generationHelpers.js +85 -58
  339. package/tgsl/infixDispatch.d.ts +70 -0
  340. package/tgsl/infixDispatch.js +48 -46
  341. package/tgsl/jsPolyfills.d.ts +16 -19
  342. package/tgsl/jsPolyfills.js +44 -42
  343. package/tgsl/makeDereferenceable.d.ts +48 -0
  344. package/tgsl/makeDereferenceable.js +86 -0
  345. package/tgsl/makeResolvable.d.ts +22 -0
  346. package/tgsl/makeResolvable.js +33 -0
  347. package/tgsl/shaderGenerator.d.ts +77 -17
  348. package/tgsl/shaderGenerator.js +1 -0
  349. package/tgsl/shellless.d.ts +6 -9
  350. package/tgsl/shellless.js +73 -43
  351. package/tgsl/wgslGenerator.d.ts +66 -59
  352. package/tgsl/wgslGenerator.js +1345 -760
  353. package/types.d.ts +287 -222
  354. package/types.js +61 -44
  355. package/unwrapper.d.ts +31 -26
  356. package/unwrapper.js +1 -0
  357. package/wgslExtensions.d.ts +3 -5
  358. package/wgslExtensions.js +12 -16
  359. package/_virtual/rolldown_runtime.js +0 -13
  360. package/core/buffer/bufferShorthand.d.ts +0 -50
  361. package/core/buffer/bufferShorthand.js +0 -55
  362. package/core/pipeline/applyPipelineState.js +0 -37
  363. package/core/pipeline/limitsOverflow.js +0 -13
  364. package/package.js +0 -5
  365. package/tgsl/shaderGenerator_members.d.ts +0 -33
  366. package/tgsl/shaderGenerator_members.js +0 -12
@@ -1,106 +1,130 @@
1
- import { $internal } from "../../shared/symbols.js";
2
1
  import { setName } from "../../shared/meta.js";
3
-
4
- //#region src/core/querySet/querySet.ts
5
- function INTERNAL_createQuerySet(group, type, count, rawQuerySet) {
6
- return new TgpuQuerySetImpl(group, type, count, rawQuerySet);
2
+ import { $internal, $soul } from "../../shared/symbols.js";
3
+ export function INTERNAL_createQuerySet(group, type, count, rawQuerySet) {
4
+ return new TgpuQuerySetImpl(group, type, count, rawQuerySet);
7
5
  }
8
- function isQuerySet(value) {
9
- const maybe = value;
10
- return maybe?.resourceType === "query-set" && !!maybe[$internal];
6
+ export function isQuerySet(value) {
7
+ const maybe = value;
8
+ return maybe?.resourceType === 'query-set' && !!maybe[$internal];
9
+ }
10
+ class TgpuQuerySetImpl {
11
+ resourceType = 'query-set';
12
+ #ownQuerySet;
13
+ #destroyed = false;
14
+ #available = true;
15
+ #readBuffer = undefined;
16
+ #resolveBuffer = undefined;
17
+ [$soul];
18
+ [$internal];
19
+ constructor(root, type, count, rawQuerySet) {
20
+ this.#ownQuerySet = !rawQuerySet;
21
+ this[$soul] = {
22
+ type: 'query-set',
23
+ device: root.device,
24
+ queryType: type,
25
+ count,
26
+ raw: rawQuerySet,
27
+ label: undefined,
28
+ };
29
+ // oxlint-disable-next-line typescript/no-this-alias
30
+ const self = this;
31
+ this[$internal] = {
32
+ get readBuffer() {
33
+ if (!self.#readBuffer) {
34
+ self.#readBuffer = self[$soul].device.createBuffer({
35
+ size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
36
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
37
+ });
38
+ }
39
+ return self.#readBuffer;
40
+ },
41
+ get resolveBuffer() {
42
+ if (!self.#resolveBuffer) {
43
+ self.#resolveBuffer = self[$soul].device.createBuffer({
44
+ size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
45
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
46
+ });
47
+ }
48
+ return self.#resolveBuffer;
49
+ },
50
+ materialize: () => {
51
+ if (this.#destroyed) {
52
+ throw new Error('This QuerySet has been destroyed.');
53
+ }
54
+ const soul = this[$soul];
55
+ if (!soul.raw) {
56
+ soul.raw = soul.device.createQuerySet({
57
+ type: soul.queryType,
58
+ count: soul.count,
59
+ });
60
+ }
61
+ return soul.raw;
62
+ },
63
+ };
64
+ }
65
+ get type() {
66
+ return this[$soul].queryType;
67
+ }
68
+ get count() {
69
+ return this[$soul].count;
70
+ }
71
+ get querySet() {
72
+ return this[$internal].materialize();
73
+ }
74
+ get destroyed() {
75
+ return this.#destroyed;
76
+ }
77
+ get available() {
78
+ return this.#available;
79
+ }
80
+ $name(label) {
81
+ setName(this, label);
82
+ const raw = this[$soul].raw;
83
+ if (raw) {
84
+ raw.label = label;
85
+ }
86
+ return this;
87
+ }
88
+ resolve() {
89
+ if (this.#destroyed) {
90
+ throw new Error('This QuerySet has been destroyed.');
91
+ }
92
+ if (!this.#available) {
93
+ throw new Error('This QuerySet is busy resolving or reading.');
94
+ }
95
+ const commandEncoder = this[$soul].device.createCommandEncoder();
96
+ commandEncoder.resolveQuerySet(this.querySet, 0, this.count, this[$internal].resolveBuffer, 0);
97
+ this[$soul].device.queue.submit([commandEncoder.finish()]);
98
+ }
99
+ async read() {
100
+ if (!this.#resolveBuffer) {
101
+ throw new Error('QuerySet must be resolved before reading.');
102
+ }
103
+ this.#available = false;
104
+ try {
105
+ const commandEncoder = this[$soul].device.createCommandEncoder();
106
+ commandEncoder.copyBufferToBuffer(this[$internal].resolveBuffer, 0, this[$internal].readBuffer, 0, this.count * BigUint64Array.BYTES_PER_ELEMENT);
107
+ this[$soul].device.queue.submit([commandEncoder.finish()]);
108
+ const readBuffer = this[$internal].readBuffer;
109
+ await readBuffer.mapAsync(GPUMapMode.READ);
110
+ const data = new BigUint64Array(readBuffer.getMappedRange().slice());
111
+ readBuffer.unmap();
112
+ return Array.from(data);
113
+ }
114
+ finally {
115
+ this.#available = true;
116
+ }
117
+ }
118
+ destroy() {
119
+ if (this.#destroyed) {
120
+ return;
121
+ }
122
+ this.#destroyed = true;
123
+ if (this[$soul].raw && this.#ownQuerySet) {
124
+ this[$soul].raw.destroy();
125
+ }
126
+ this.#readBuffer?.destroy();
127
+ this.#resolveBuffer?.destroy();
128
+ this.#readBuffer = this.#resolveBuffer = undefined;
129
+ }
11
130
  }
12
- var TgpuQuerySetImpl = class {
13
- resourceType = "query-set";
14
- type;
15
- count;
16
- #rawQuerySet;
17
- #device;
18
- #querySet;
19
- #ownQuerySet;
20
- #destroyed = false;
21
- #available = true;
22
- #readBuffer = void 0;
23
- #resolveBuffer = void 0;
24
- constructor(root, type, count, rawQuerySet) {
25
- this.#device = root.device;
26
- this.type = type;
27
- this.count = count;
28
- this.#rawQuerySet = rawQuerySet;
29
- this.#ownQuerySet = !rawQuerySet;
30
- this.#querySet = rawQuerySet;
31
- }
32
- get querySet() {
33
- if (this.#destroyed) throw new Error("This QuerySet has been destroyed.");
34
- if (this.#rawQuerySet) return this.#rawQuerySet;
35
- if (this.#querySet) return this.#querySet;
36
- this.#querySet = this.#device.createQuerySet({
37
- type: this.type,
38
- count: this.count
39
- });
40
- return this.#querySet;
41
- }
42
- get destroyed() {
43
- return this.#destroyed;
44
- }
45
- get available() {
46
- return this.#available;
47
- }
48
- get [$internal]() {
49
- const self = this;
50
- return {
51
- get readBuffer() {
52
- if (!self.#readBuffer) self.#readBuffer = self.#device.createBuffer({
53
- size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
54
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
55
- });
56
- return self.#readBuffer;
57
- },
58
- get resolveBuffer() {
59
- if (!self.#resolveBuffer) self.#resolveBuffer = self.#device.createBuffer({
60
- size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
61
- usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
62
- });
63
- return self.#resolveBuffer;
64
- }
65
- };
66
- }
67
- $name(label) {
68
- setName(this, label);
69
- if (this.#querySet) this.#querySet.label = label;
70
- return this;
71
- }
72
- resolve() {
73
- if (this.#destroyed) throw new Error("This QuerySet has been destroyed.");
74
- if (!this.#available) throw new Error("This QuerySet is busy resolving or reading.");
75
- const commandEncoder = this.#device.createCommandEncoder();
76
- commandEncoder.resolveQuerySet(this.querySet, 0, this.count, this[$internal].resolveBuffer, 0);
77
- this.#device.queue.submit([commandEncoder.finish()]);
78
- }
79
- async read() {
80
- if (!this.#resolveBuffer) throw new Error("QuerySet must be resolved before reading.");
81
- this.#available = false;
82
- try {
83
- const commandEncoder = this.#device.createCommandEncoder();
84
- commandEncoder.copyBufferToBuffer(this[$internal].resolveBuffer, 0, this[$internal].readBuffer, 0, this.count * BigUint64Array.BYTES_PER_ELEMENT);
85
- this.#device.queue.submit([commandEncoder.finish()]);
86
- const readBuffer = this[$internal].readBuffer;
87
- await readBuffer.mapAsync(GPUMapMode.READ);
88
- const data = new BigUint64Array(readBuffer.getMappedRange().slice());
89
- readBuffer.unmap();
90
- return Array.from(data);
91
- } finally {
92
- this.#available = true;
93
- }
94
- }
95
- destroy() {
96
- if (this.#destroyed) return;
97
- this.#destroyed = true;
98
- if (this.#querySet && this.#ownQuerySet) this.#querySet.destroy();
99
- this.#readBuffer?.destroy();
100
- this.#resolveBuffer?.destroy();
101
- this.#readBuffer = this.#resolveBuffer = void 0;
102
- }
103
- };
104
-
105
- //#endregion
106
- export { INTERNAL_createQuerySet, isQuerySet };
@@ -1,22 +1,18 @@
1
- import { $gpuValueOf } from "../../shared/symbols.js";
2
- import { Origin } from "../../data/snippet.js";
3
- import { BaseData } from "../../data/wgslTypes.js";
4
- import { InferGPU } from "../../shared/repr.js";
5
- import { AnyData } from "../../data/dataTypes.js";
6
-
7
- //#region src/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts
8
-
1
+ import type { AnyData } from '../../data/dataTypes.ts';
2
+ import { type Origin } from '../../data/snippet.ts';
3
+ import type { BaseData } from '../../data/wgslTypes.ts';
4
+ import type { InferGPU } from '../../shared/repr.ts';
5
+ import { $gpuValueOf } from '../../shared/symbols.ts';
9
6
  /**
10
7
  * Extra declaration that will be included in final WGSL code
11
8
  * when resolving objects that use it.
12
9
  */
13
- interface TgpuRawCodeSnippet<TDataType extends BaseData> {
14
- $: InferGPU<TDataType>;
15
- value: InferGPU<TDataType>;
16
- readonly [$gpuValueOf]: InferGPU<TDataType>;
17
- $uses(dependencyMap: Record<string, unknown>): this;
10
+ export interface TgpuRawCodeSnippet<TDataType extends BaseData> {
11
+ $: InferGPU<TDataType>;
12
+ readonly [$gpuValueOf]: InferGPU<TDataType>;
13
+ $uses(dependencyMap: Record<string, unknown>): this;
18
14
  }
19
- type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument' | 'constant-immutable-def' | 'runtime-immutable-def'>;
15
+ export type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument' | 'constant-immutable-def' | 'runtime-immutable-def'>;
20
16
  /**
21
17
  * An advanced API that creates a typed shader expression which
22
18
  * can be injected into the final shader bundle upon use.
@@ -24,6 +20,7 @@ type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument
24
20
  * @param expression The code snippet that will be injected in place of `foo.$`
25
21
  * @param type The type of the expression
26
22
  * @param [origin='runtime'] Where the value originates from.
23
+ * @param [possibleSideEffects=true] Whether generating this snippet may produce a WGSL expression with observable side-effects (e.g. calling a barrier, discarding a fragment, or writing to memory).
27
24
  *
28
25
  * **-- Which origin to choose?**
29
26
  *
@@ -42,7 +39,7 @@ type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument
42
39
  * // final shader bundle, but we cannot
43
40
  * // refer to it in any other way.
44
41
  * const existingGlobal = tgpu['~unstable']
45
- * .rawCodeSnippet('EXISTING_GLOBAL', d.f32, 'constant');
42
+ * .rawCodeSnippet('EXISTING_GLOBAL', d.f32, 'constant', false);
46
43
  *
47
44
  * const foo = () => {
48
45
  * 'use gpu';
@@ -55,6 +52,4 @@ type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'local-def' | 'argument
55
52
  * // }
56
53
  * ```
57
54
  */
58
- declare function rawCodeSnippet<TDataType extends AnyData>(expression: string, type: TDataType, origin?: RawCodeSnippetOrigin | undefined): TgpuRawCodeSnippet<TDataType>;
59
- //#endregion
60
- export { RawCodeSnippetOrigin, TgpuRawCodeSnippet, rawCodeSnippet };
55
+ export declare function rawCodeSnippet<TDataType extends AnyData>(expression: string, type: TDataType, origin?: RawCodeSnippetOrigin | undefined, possibleSideEffects?: boolean | undefined): TgpuRawCodeSnippet<TDataType>;
@@ -1,94 +1,93 @@
1
- import { $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
2
1
  import { snip } from "../../data/snippet.js";
3
- import { inCodegenMode } from "../../execMode.js";
4
- import { valueProxyHandler } from "../valueProxyUtils.js";
2
+ import { makeDereferenceable } from "../../tgsl/makeDereferenceable.js";
3
+ import { makeResolvable } from "../../tgsl/makeResolvable.js";
4
+ import { $gpuValueOf, $internal } from "../../shared/symbols.js";
5
5
  import { replaceExternalsInWgsl } from "../resolve/externals.js";
6
-
7
- //#region src/core/rawCodeSnippet/tgpuRawCodeSnippet.ts
8
6
  /**
9
- * An advanced API that creates a typed shader expression which
10
- * can be injected into the final shader bundle upon use.
11
- *
12
- * @param expression The code snippet that will be injected in place of `foo.$`
13
- * @param type The type of the expression
14
- * @param [origin='runtime'] Where the value originates from.
15
- *
16
- * **-- Which origin to choose?**
17
- *
18
- * Usually 'runtime' (the default) is a safe bet, but if you're sure that the expression or
19
- * computation is constant (either a reference to a constant, a numeric literal,
20
- * or an operation on constants), then pass 'constant' as it might lead to better
21
- * optimizations.
22
- *
23
- * If what the expression is a direct reference to an existing value (e.g. a uniform, a
24
- * storage binding, ...), then choose from 'uniform', 'mutable', 'readonly', 'workgroup',
25
- * 'private' or 'handle' depending on the address space of the referred value.
26
- *
27
- * @example
28
- * ```ts
29
- * // An identifier that we know will be in the
30
- * // final shader bundle, but we cannot
31
- * // refer to it in any other way.
32
- * const existingGlobal = tgpu['~unstable']
33
- * .rawCodeSnippet('EXISTING_GLOBAL', d.f32, 'constant');
34
- *
35
- * const foo = () => {
36
- * 'use gpu';
37
- * return existingGlobal.$ * 2;
38
- * };
39
- *
40
- * const wgsl = tgpu.resolve([foo]);
41
- * // fn foo() -> f32 {
42
- * // return EXISTING_GLOBAL * 2;
43
- * // }
44
- * ```
45
- */
46
- function rawCodeSnippet(expression, type, origin = "runtime") {
47
- return new TgpuRawCodeSnippetImpl(expression, type, origin);
7
+ * An advanced API that creates a typed shader expression which
8
+ * can be injected into the final shader bundle upon use.
9
+ *
10
+ * @param expression The code snippet that will be injected in place of `foo.$`
11
+ * @param type The type of the expression
12
+ * @param [origin='runtime'] Where the value originates from.
13
+ * @param [possibleSideEffects=true] Whether generating this snippet may produce a WGSL expression with observable side-effects (e.g. calling a barrier, discarding a fragment, or writing to memory).
14
+ *
15
+ * **-- Which origin to choose?**
16
+ *
17
+ * Usually 'runtime' (the default) is a safe bet, but if you're sure that the expression or
18
+ * computation is constant (either a reference to a constant, a numeric literal,
19
+ * or an operation on constants), then pass 'constant' as it might lead to better
20
+ * optimizations.
21
+ *
22
+ * If what the expression is a direct reference to an existing value (e.g. a uniform, a
23
+ * storage binding, ...), then choose from 'uniform', 'mutable', 'readonly', 'workgroup',
24
+ * 'private' or 'handle' depending on the address space of the referred value.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * // An identifier that we know will be in the
29
+ * // final shader bundle, but we cannot
30
+ * // refer to it in any other way.
31
+ * const existingGlobal = tgpu['~unstable']
32
+ * .rawCodeSnippet('EXISTING_GLOBAL', d.f32, 'constant', false);
33
+ *
34
+ * const foo = () => {
35
+ * 'use gpu';
36
+ * return existingGlobal.$ * 2;
37
+ * };
38
+ *
39
+ * const wgsl = tgpu.resolve([foo]);
40
+ * // fn foo() -> f32 {
41
+ * // return EXISTING_GLOBAL * 2;
42
+ * // }
43
+ * ```
44
+ */
45
+ export function rawCodeSnippet(expression, type, origin = 'runtime', possibleSideEffects = true) {
46
+ return new TgpuRawCodeSnippetImpl(expression, type, origin, possibleSideEffects);
47
+ }
48
+ // --------------
49
+ // Implementation
50
+ // --------------
51
+ class TgpuRawCodeSnippetImpl {
52
+ dataType;
53
+ origin;
54
+ possibleSideEffects;
55
+ #expression;
56
+ #externals;
57
+ static {
58
+ TgpuRawCodeSnippetImpl.prototype[$internal] = true;
59
+ makeDereferenceable(makeResolvable(TgpuRawCodeSnippetImpl.prototype, {
60
+ asString() {
61
+ return `raw(${String(this.dataType)}): "${this.#expression}"`;
62
+ },
63
+ resolve(ctx) {
64
+ const replacedExpression = replaceExternalsInWgsl(ctx, this.#externals ?? {}, this.#expression);
65
+ return snip(replacedExpression, this.dataType, this.origin, this.possibleSideEffects);
66
+ },
67
+ }), {
68
+ codegenMode: {
69
+ getBaseSnippet(trackingProxy) {
70
+ return snip(trackingProxy, this.dataType, this.origin, this.possibleSideEffects);
71
+ },
72
+ },
73
+ normalMode: {
74
+ get() {
75
+ throw new Error('Raw code snippets can only be used on the GPU.');
76
+ },
77
+ },
78
+ });
79
+ }
80
+ constructor(expression, type, origin, possibleSideEffects) {
81
+ this.dataType = type;
82
+ this.origin = origin;
83
+ this.possibleSideEffects = possibleSideEffects;
84
+ this.#expression = expression;
85
+ }
86
+ $uses(dependencyMap) {
87
+ if (this.#externals !== undefined) {
88
+ throw new Error("Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.");
89
+ }
90
+ this.#externals = dependencyMap;
91
+ return this;
92
+ }
48
93
  }
49
- var TgpuRawCodeSnippetImpl = class {
50
- [$internal];
51
- dataType;
52
- origin;
53
- #expression;
54
- #externals;
55
- constructor(expression, type, origin) {
56
- this[$internal] = true;
57
- this.dataType = type;
58
- this.origin = origin;
59
- this.#expression = expression;
60
- }
61
- $uses(dependencyMap) {
62
- if (this.#externals !== void 0) throw new Error("Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.");
63
- this.#externals = dependencyMap;
64
- return this;
65
- }
66
- [$resolve](ctx) {
67
- return snip(replaceExternalsInWgsl(ctx, this.#externals ?? {}, this.#expression), this.dataType, this.origin);
68
- }
69
- toString() {
70
- return `raw(${String(this.dataType)}): "${this.#expression}"`;
71
- }
72
- get [$gpuValueOf]() {
73
- const dataType = this.dataType;
74
- const origin = this.origin;
75
- return new Proxy({
76
- [$internal]: true,
77
- get [$ownSnippet]() {
78
- return snip(this, dataType, origin);
79
- },
80
- [$resolve]: (ctx) => ctx.resolve(this),
81
- toString: () => `raw(${String(this.dataType)}): "${this.#expression}".$`
82
- }, valueProxyHandler);
83
- }
84
- get $() {
85
- if (!inCodegenMode()) throw new Error("Raw code snippets can only be used on the GPU.");
86
- return this[$gpuValueOf];
87
- }
88
- get value() {
89
- return this.$;
90
- }
91
- };
92
-
93
- //#endregion
94
- export { rawCodeSnippet };
@@ -1,12 +1,29 @@
1
- import "../../types.js";
2
- import "../function/fnCore.js";
3
-
4
- //#region src/core/resolve/externals.d.ts
5
-
1
+ import { type ResolutionCtx } from '../../types.ts';
2
+ import type { FnExternals } from '../function/fnCore.ts';
6
3
  /**
7
4
  * A key-value mapping where keys represent identifiers within shader code,
8
5
  * and values can either be another ExternalMap, or be any type that can be resolved to a code string.
9
6
  */
10
- type ExternalMap = Record<string, unknown>;
11
- //#endregion
12
- export { ExternalMap };
7
+ export type ExternalMap = Record<string, unknown>;
8
+ /**
9
+ * Merges function externals into one map.
10
+ */
11
+ export declare function mergeFunctionExternals(fnExternals: FnExternals): ExternalMap;
12
+ export declare function addArgTypesToExternals(implementation: string, argTypes: unknown[], core: {
13
+ setExternals: (key: 'args', externals: ExternalMap) => void;
14
+ }): void;
15
+ export declare function addReturnTypeToExternals(implementation: string, returnType: unknown, core: {
16
+ setExternals: (key: 'out', externals: ExternalMap) => void;
17
+ }): void;
18
+ export declare const anyIdent: RegExp;
19
+ export declare const boundedPropChain: RegExp;
20
+ /**
21
+ * Replaces all occurrences of external names in WGSL code with their resolved values.
22
+ * It adds all necessary definitions to the resolution context.
23
+ * @param ctx - The resolution context.
24
+ * @param externalMap - The external map. Assumes that keys don't contain dots.
25
+ * @param wgsl - The WGSL code.
26
+ *
27
+ * @returns The WGSL code with all external names replaced with their resolved values.
28
+ */
29
+ export declare function replaceExternalsInWgsl(ctx: ResolutionCtx, externalMap: ExternalMap, wgsl: string): string;
@@ -1,65 +1,89 @@
1
+ import { isLooseData } from "../../data/dataTypes.js";
1
2
  import { isWgslStruct } from "../../data/wgslTypes.js";
2
3
  import { getName, hasTinyestMetadata, isNamable, setName } from "../../shared/meta.js";
3
- import { isLooseData } from "../../data/dataTypes.js";
4
+ import { logger } from "../../tgpuLogger.js";
4
5
  import { isWgsl } from "../../types.js";
5
-
6
- //#region src/core/resolve/externals.ts
7
6
  function isResolvable(value) {
8
- return isWgsl(value) || isLooseData(value) || hasTinyestMetadata(value);
7
+ return isWgsl(value) || isLooseData(value) || hasTinyestMetadata(value);
9
8
  }
10
9
  /**
11
- * Merges function externals into one map.
12
- */
13
- function mergeFunctionExternals(fnExternals) {
14
- const base = fnExternals.pluginProvided ?? fnExternals.userProvided ?? {};
15
- const result = Object.defineProperties({}, Object.getOwnPropertyDescriptors(base));
16
- for (const flatExternal of [fnExternals.args, fnExternals.out].filter((e) => e !== void 0)) for (const [key, value] of Object.entries(flatExternal)) {
17
- if (key in result && result[key] !== value) throw new Error(`Key '${key}' appears in externals despite already being used for argument/return type. Please rename this external.`);
18
- result[key] = value;
19
- }
20
- return result;
21
- }
22
- function addArgTypesToExternals(implementation, argTypes, core) {
23
- const argTypeNames = [...implementation.matchAll(/:\s*(?<arg>.*?)\s*[,)]/g)].map((found) => found?.[1]);
24
- const args = Object.fromEntries(argTypes.flatMap((argType, i) => {
25
- const argTypeName = argTypeNames?.[i];
26
- return isWgslStruct(argType) && argTypeName !== void 0 ? [[argTypeName, argType]] : [];
27
- }));
28
- core.setExternals("args", args);
10
+ * Merges function externals into one map.
11
+ */
12
+ export function mergeFunctionExternals(fnExternals) {
13
+ const base = fnExternals.pluginProvided ?? fnExternals.userProvided ?? {};
14
+ // avoid calling any of the getters
15
+ const result = Object.defineProperties({}, Object.getOwnPropertyDescriptors(base));
16
+ for (const flatExternal of [fnExternals.args, fnExternals.out].filter((e) => e !== undefined)) {
17
+ for (const [key, value] of Object.entries(flatExternal)) {
18
+ if (key in result && result[key] !== value) {
19
+ throw new Error(`Key '${key}' appears in externals despite already being used for argument/return type. Please rename this external.`);
20
+ }
21
+ result[key] = value;
22
+ }
23
+ }
24
+ return result;
29
25
  }
30
- function addReturnTypeToExternals(implementation, returnType, core) {
31
- const matched = implementation.match(/->\s(?<output>[\w\d_]+)\s{/);
32
- const outputName = matched ? matched[1]?.trim() : void 0;
33
- if (isWgslStruct(returnType) && outputName && !/\s/g.test(outputName)) core.setExternals("out", { [outputName]: returnType });
26
+ export function addArgTypesToExternals(implementation, argTypes, core) {
27
+ const argTypeNames = [...implementation.matchAll(/:\s*(?<arg>.*?)\s*[,)]/g)].map((found) => found?.[1]);
28
+ const args = Object.fromEntries(argTypes.flatMap((argType, i) => {
29
+ const argTypeName = argTypeNames?.[i];
30
+ return isWgslStruct(argType) && argTypeName !== undefined ? [[argTypeName, argType]] : [];
31
+ }));
32
+ core.setExternals('args', args);
34
33
  }
35
- function identifierRegex(name) {
36
- return new RegExp(`(?<![\\w\\$_.])${name.replaceAll(".", "\\.").replaceAll("$", "\\$")}(?![\\w\\$_])`, "g");
34
+ export function addReturnTypeToExternals(implementation, returnType, core) {
35
+ const matched = implementation.match(/->\s(?<output>[\w\d_]+)\s{/);
36
+ const outputName = matched ? matched[1]?.trim() : undefined;
37
+ if (isWgslStruct(returnType) && outputName && !/\s/g.test(outputName)) {
38
+ core.setExternals('out', { [outputName]: returnType });
39
+ }
37
40
  }
41
+ export const anyIdent = /([$_\p{XID_Start}][$\p{XID_Continue}]*)/u; // WGSL ident, modified to include $
42
+ const anyPropChain = new RegExp(`(${anyIdent.source})(\\.${anyIdent.source})*`, 'ug');
43
+ export const boundedPropChain = new RegExp(`(?<![\\p{XID_Continue}\\$.])${anyPropChain.source}(?![\\p{XID_Continue}\\$])`, 'ug');
38
44
  /**
39
- * Replaces all occurrences of external names in WGSL code with their resolved values.
40
- * It adds all necessary definitions to the resolution context.
41
- * @param ctx - The resolution context.
42
- * @param externalMap - The external map.
43
- * @param wgsl - The WGSL code.
44
- *
45
- * @returns The WGSL code with all external names replaced with their resolved values.
46
- */
47
- function replaceExternalsInWgsl(ctx, externalMap, wgsl) {
48
- return Object.entries(externalMap).reduce((acc, [externalName, external]) => {
49
- const externalRegex = identifierRegex(externalName);
50
- if (wgsl && externalName !== "Out" && externalName !== "in" && !externalRegex.test(wgsl)) console.warn(`The external '${externalName}' wasn't used in the resolved template.`);
51
- if (isResolvable(external)) {
52
- if (isNamable(external) && getName(external) === void 0) setName(external, externalName.split(".").at(-1));
53
- return acc.replaceAll(externalRegex, ctx.resolve(external).value);
54
- }
55
- if (external !== null && typeof external === "object") {
56
- const foundProperties = [...wgsl.matchAll(new RegExp(`${externalName.replaceAll(".", "\\.").replaceAll("$", "\\$")}\\.(?<prop>.*?)(?![\\w\\$_])`, "g"))].map((found) => found[1]);
57
- return [...new Set(foundProperties)].reduce((innerAcc, prop) => prop && prop in external ? replaceExternalsInWgsl(ctx, { [`${externalName}.${prop}`]: external[prop] }, innerAcc) : innerAcc, acc);
58
- }
59
- console.warn(`During resolution, the external '${externalName}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`);
60
- return acc;
61
- }, wgsl);
45
+ * Replaces all occurrences of external names in WGSL code with their resolved values.
46
+ * It adds all necessary definitions to the resolution context.
47
+ * @param ctx - The resolution context.
48
+ * @param externalMap - The external map. Assumes that keys don't contain dots.
49
+ * @param wgsl - The WGSL code.
50
+ *
51
+ * @returns The WGSL code with all external names replaced with their resolved values.
52
+ */
53
+ export function replaceExternalsInWgsl(ctx, externalMap, wgsl) {
54
+ const keys = Object.keys(externalMap);
55
+ if (keys.length === 0) {
56
+ return wgsl;
57
+ }
58
+ const maybeInvalidKey = keys.find((key) => key.includes('.'));
59
+ if (maybeInvalidKey) {
60
+ throw new Error(`External key '${maybeInvalidKey}' contains invalid character '.'`);
61
+ }
62
+ return wgsl.replaceAll(boundedPropChain, (match) => {
63
+ const chain = match.split('.');
64
+ if (!Object.hasOwn(externalMap, chain.at(0))) {
65
+ // this prop access does not start with an external
66
+ return match;
67
+ }
68
+ let currentItem = externalMap;
69
+ let suffix = '';
70
+ for (const [i, elem] of chain.entries()) {
71
+ currentItem = currentItem[elem];
72
+ if (isResolvable(currentItem) || typeof currentItem === 'string') {
73
+ suffix = chain
74
+ .slice(i + 1)
75
+ .map((s) => `.${s}`)
76
+ .join('');
77
+ if (isNamable(currentItem) && getName(currentItem) === undefined) {
78
+ setName(currentItem, chain.slice(0, i + 1).join('_'));
79
+ }
80
+ break;
81
+ }
82
+ if (typeof currentItem !== 'object' || currentItem === null || i === chain.length - 1) {
83
+ logger.warn('external-omitted', `During resolution, the external '${chain.slice(0, i + 1).join('.')}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`);
84
+ return match;
85
+ }
86
+ }
87
+ return ctx.resolve(currentItem).value + suffix;
88
+ });
62
89
  }
63
-
64
- //#endregion
65
- export { addArgTypesToExternals, addReturnTypeToExternals, mergeFunctionExternals, replaceExternalsInWgsl };