typegpu 0.10.0 → 0.10.2

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 (263) hide show
  1. package/{chunk-BYypO7fO.js → _virtual/_rolldown/runtime.js} +1 -1
  2. package/builtin.d.ts +50 -0
  3. package/builtin.js +37 -0
  4. package/common/fullScreenTriangle.d.ts +26 -0
  5. package/common/fullScreenTriangle.js +36 -0
  6. package/common/index.d.ts +2 -3
  7. package/common/index.js +3 -4
  8. package/core/buffer/buffer.d.ts +74 -0
  9. package/core/buffer/buffer.js +197 -0
  10. package/core/buffer/bufferShorthand.d.ts +48 -0
  11. package/core/buffer/bufferShorthand.js +49 -0
  12. package/core/buffer/bufferUsage.d.ts +45 -0
  13. package/core/buffer/bufferUsage.js +163 -0
  14. package/core/constant/tgpuConstant.d.ts +28 -0
  15. package/core/constant/tgpuConstant.js +67 -0
  16. package/core/declare/tgpuDeclare.d.ts +18 -0
  17. package/core/declare/tgpuDeclare.js +40 -0
  18. package/core/function/autoIO.d.ts +37 -0
  19. package/core/function/autoIO.js +87 -0
  20. package/core/function/comptime.d.ts +39 -0
  21. package/core/function/comptime.js +51 -0
  22. package/core/function/createCallableSchema.js +42 -0
  23. package/core/function/dualImpl.js +54 -0
  24. package/core/function/extractArgs.js +204 -0
  25. package/core/function/fnCore.js +79 -0
  26. package/core/function/fnTypes.d.ts +34 -0
  27. package/core/function/ioSchema.d.ts +10 -0
  28. package/core/function/ioSchema.js +30 -0
  29. package/core/function/shelllessImpl.d.ts +28 -0
  30. package/core/function/shelllessImpl.js +23 -0
  31. package/core/function/templateUtils.js +13 -0
  32. package/core/function/tgpuComputeFn.d.ts +49 -0
  33. package/core/function/tgpuComputeFn.js +62 -0
  34. package/core/function/tgpuFn.d.ts +52 -0
  35. package/core/function/tgpuFn.js +170 -0
  36. package/core/function/tgpuFragmentFn.d.ts +68 -0
  37. package/core/function/tgpuFragmentFn.js +68 -0
  38. package/core/function/tgpuVertexFn.d.ts +55 -0
  39. package/core/function/tgpuVertexFn.js +65 -0
  40. package/core/pipeline/applyPipelineState.js +37 -0
  41. package/core/pipeline/computePipeline.d.ts +58 -0
  42. package/core/pipeline/computePipeline.js +226 -0
  43. package/core/pipeline/connectAttachmentToShader.js +26 -0
  44. package/core/pipeline/connectTargetsToShader.js +29 -0
  45. package/core/pipeline/limitsOverflow.js +13 -0
  46. package/core/pipeline/renderPipeline.d.ts +266 -0
  47. package/core/pipeline/renderPipeline.js +471 -0
  48. package/core/pipeline/timeable.d.ts +23 -0
  49. package/core/pipeline/timeable.js +61 -0
  50. package/core/pipeline/typeGuards.js +29 -0
  51. package/core/querySet/querySet.d.ts +22 -0
  52. package/core/querySet/querySet.js +103 -0
  53. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
  54. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +96 -0
  55. package/core/resolve/externals.d.ts +10 -0
  56. package/core/resolve/externals.js +58 -0
  57. package/core/resolve/namespace.d.ts +38 -0
  58. package/core/resolve/namespace.js +41 -0
  59. package/core/resolve/resolveData.js +146 -0
  60. package/core/resolve/stitch.js +25 -0
  61. package/core/resolve/tgpuResolve.d.ts +151 -0
  62. package/core/resolve/tgpuResolve.js +68 -0
  63. package/core/root/configurableImpl.js +18 -0
  64. package/core/root/init.d.ts +69 -0
  65. package/core/root/init.js +457 -0
  66. package/core/root/rootTypes.d.ts +622 -0
  67. package/core/sampler/sampler.d.ts +35 -0
  68. package/core/sampler/sampler.js +116 -0
  69. package/core/simulate/tgpuSimulate.d.ts +36 -0
  70. package/core/simulate/tgpuSimulate.js +76 -0
  71. package/core/slot/accessor.d.ts +13 -0
  72. package/core/slot/accessor.js +97 -0
  73. package/core/slot/internalSlots.js +7 -0
  74. package/core/slot/lazy.d.ts +6 -0
  75. package/core/slot/lazy.js +42 -0
  76. package/core/slot/slot.d.ts +6 -0
  77. package/core/slot/slot.js +40 -0
  78. package/core/slot/slotTypes.d.ts +92 -0
  79. package/core/slot/slotTypes.js +21 -0
  80. package/core/texture/externalTexture.d.ts +12 -0
  81. package/core/texture/externalTexture.js +48 -0
  82. package/core/texture/texture.d.ts +118 -0
  83. package/core/texture/texture.js +312 -0
  84. package/core/texture/textureFormats.d.ts +29 -0
  85. package/core/texture/textureFormats.js +99 -0
  86. package/core/texture/textureProps.d.ts +11 -0
  87. package/core/texture/textureUtils.js +224 -0
  88. package/core/texture/usageExtension.d.ts +21 -0
  89. package/core/texture/usageExtension.js +21 -0
  90. package/core/unroll/tgpuUnroll.d.ts +13 -0
  91. package/core/unroll/tgpuUnroll.js +36 -0
  92. package/core/valueProxyUtils.js +44 -0
  93. package/core/variable/tgpuVariable.d.ts +38 -0
  94. package/core/variable/tgpuVariable.js +101 -0
  95. package/core/vertexLayout/connectAttributesToShader.js +59 -0
  96. package/core/vertexLayout/vertexAttribute.d.ts +29 -0
  97. package/core/vertexLayout/vertexLayout.d.ts +19 -0
  98. package/core/vertexLayout/vertexLayout.js +103 -0
  99. package/data/alignIO.js +15 -0
  100. package/data/alignmentOf.d.ts +10 -0
  101. package/data/alignmentOf.js +88 -0
  102. package/data/array.d.ts +28 -0
  103. package/data/array.js +48 -0
  104. package/data/atomic.d.ts +15 -0
  105. package/data/atomic.js +25 -0
  106. package/data/attributes.d.ts +121 -0
  107. package/data/attributes.js +145 -0
  108. package/data/autoStruct.d.ts +3 -0
  109. package/data/autoStruct.js +83 -0
  110. package/data/compiledIO.js +231 -0
  111. package/data/dataIO.js +549 -0
  112. package/data/dataTypes.d.ts +115 -0
  113. package/data/dataTypes.js +97 -0
  114. package/data/deepEqual.d.ts +25 -0
  115. package/data/deepEqual.js +58 -0
  116. package/data/disarray.d.ts +34 -0
  117. package/data/disarray.js +52 -0
  118. package/data/getLongestContiguousPrefix.d.ts +10 -0
  119. package/data/getLongestContiguousPrefix.js +15 -0
  120. package/data/index.d.ts +26 -4
  121. package/data/index.js +27 -7
  122. package/data/instanceToSchema.d.ts +33 -0
  123. package/data/isContiguous.d.ts +10 -0
  124. package/data/isContiguous.js +15 -0
  125. package/data/matrix.d.ts +126 -0
  126. package/data/matrix.js +517 -0
  127. package/data/numberOps.js +24 -0
  128. package/data/numeric.d.ts +81 -0
  129. package/data/numeric.js +234 -0
  130. package/data/offsetUtils.d.ts +33 -0
  131. package/data/offsetUtils.js +167 -0
  132. package/data/offsets.js +36 -0
  133. package/data/partialIO.js +68 -0
  134. package/data/ptr.d.ts +12 -0
  135. package/data/ptr.js +46 -0
  136. package/data/ref.d.ts +37 -0
  137. package/data/ref.js +96 -0
  138. package/data/sampler.d.ts +107 -0
  139. package/data/sampler.js +26 -0
  140. package/data/schemaCallWrapper.js +32 -0
  141. package/data/schemaMemoryLayout.js +200 -0
  142. package/data/sizeOf.d.ts +10 -0
  143. package/data/sizeOf.js +15 -0
  144. package/data/snippet.d.ts +26 -0
  145. package/data/snippet.js +61 -0
  146. package/data/struct.d.ts +17 -0
  147. package/data/struct.js +46 -0
  148. package/data/texture.d.ts +292 -0
  149. package/{texture-Dg5ybJro.js → data/texture.js} +6 -3
  150. package/data/unstruct.d.ts +24 -0
  151. package/data/unstruct.js +43 -0
  152. package/data/vector.d.ts +191 -0
  153. package/data/vector.js +247 -0
  154. package/data/vectorImpl.js +516 -0
  155. package/data/vectorOps.js +664 -0
  156. package/data/vertexFormatData.d.ts +190 -0
  157. package/data/vertexFormatData.js +110 -0
  158. package/data/wgslTypes.d.ts +896 -0
  159. package/data/wgslTypes.js +215 -0
  160. package/errors.d.ts +44 -0
  161. package/errors.js +128 -0
  162. package/execMode.js +51 -0
  163. package/extension.d.ts +11 -0
  164. package/extension.js +18 -0
  165. package/getGPUValue.js +9 -0
  166. package/index.d.ts +40 -243
  167. package/index.js +19 -6318
  168. package/indexNamedExports.d.ts +38 -0
  169. package/mathUtils.js +13 -0
  170. package/memo.js +22 -0
  171. package/nameRegistry.d.ts +30 -0
  172. package/nameRegistry.js +449 -0
  173. package/package.js +5 -0
  174. package/package.json +23 -23
  175. package/resolutionCtx.d.ts +29 -0
  176. package/resolutionCtx.js +546 -0
  177. package/shared/env.js +13 -0
  178. package/shared/generators.js +14 -0
  179. package/shared/meta.d.ts +39 -0
  180. package/shared/meta.js +63 -0
  181. package/shared/repr.d.ts +108 -0
  182. package/shared/stringify.js +22 -0
  183. package/shared/symbols.d.ts +61 -0
  184. package/shared/symbols.js +71 -0
  185. package/shared/utilityTypes.d.ts +29 -0
  186. package/shared/utilityTypes.js +7 -0
  187. package/shared/vertexFormat.d.ts +70 -0
  188. package/shared/vertexFormat.js +64 -0
  189. package/std/array.d.ts +7 -0
  190. package/std/array.js +27 -0
  191. package/std/atomic.d.ts +19 -0
  192. package/std/atomic.js +113 -0
  193. package/std/bitcast.d.ts +10 -0
  194. package/std/bitcast.js +43 -0
  195. package/std/boolean.d.ts +127 -0
  196. package/std/boolean.js +274 -0
  197. package/std/derivative.d.ts +16 -0
  198. package/std/derivative.js +89 -0
  199. package/std/discard.d.ts +6 -0
  200. package/std/discard.js +16 -0
  201. package/std/extensions.d.ts +8 -0
  202. package/std/extensions.js +14 -0
  203. package/std/index.d.ts +15 -3
  204. package/std/index.js +16 -5
  205. package/std/matrix.d.ts +41 -0
  206. package/std/matrix.js +87 -0
  207. package/std/numeric.d.ts +254 -0
  208. package/std/numeric.js +847 -0
  209. package/std/operators.d.ts +48 -0
  210. package/std/operators.js +153 -0
  211. package/std/packing.d.ts +26 -0
  212. package/std/packing.js +86 -0
  213. package/std/subgroup.d.ts +47 -0
  214. package/std/subgroup.js +220 -0
  215. package/std/texture.d.ts +108 -0
  216. package/std/texture.js +197 -0
  217. package/tgpu.js +44 -0
  218. package/tgpuBindGroupLayout.d.ts +161 -0
  219. package/tgpuBindGroupLayout.js +271 -0
  220. package/tgpuUnstable.d.ts +48 -0
  221. package/tgpuUnstable.js +66 -0
  222. package/tgsl/accessIndex.js +45 -0
  223. package/tgsl/accessProp.js +113 -0
  224. package/tgsl/consoleLog/deserializers.js +117 -0
  225. package/tgsl/consoleLog/logGenerator.js +86 -0
  226. package/tgsl/consoleLog/serializers.js +225 -0
  227. package/tgsl/consoleLog/types.d.ts +54 -0
  228. package/tgsl/consoleLog/types.js +12 -0
  229. package/tgsl/conversion.js +200 -0
  230. package/tgsl/forOfUtils.js +45 -0
  231. package/tgsl/generationHelpers.d.ts +37 -0
  232. package/tgsl/generationHelpers.js +67 -0
  233. package/tgsl/math.js +45 -0
  234. package/tgsl/shaderGenerator.d.ts +18 -0
  235. package/tgsl/shellless.d.ts +11 -0
  236. package/tgsl/shellless.js +53 -0
  237. package/tgsl/wgslGenerator.js +585 -0
  238. package/types.d.ts +255 -0
  239. package/types.js +43 -0
  240. package/unwrapper.d.ts +27 -0
  241. package/wgslExtensions.d.ts +5 -0
  242. package/wgslExtensions.js +18 -0
  243. package/builtin-ClEnM-Ye.js +0 -818
  244. package/builtin-ClEnM-Ye.js.map +0 -1
  245. package/common/index.d.ts.map +0 -1
  246. package/common/index.js.map +0 -1
  247. package/data/index.d.ts.map +0 -1
  248. package/data/index.js.map +0 -1
  249. package/deepEqual-yZXvaV2C.js +0 -413
  250. package/deepEqual-yZXvaV2C.js.map +0 -1
  251. package/extensions-0SFbU9FH.js +0 -2032
  252. package/extensions-0SFbU9FH.js.map +0 -1
  253. package/fullScreenTriangle-MdLGaAMR.js +0 -543
  254. package/fullScreenTriangle-MdLGaAMR.js.map +0 -1
  255. package/index.d.ts.map +0 -1
  256. package/index.js.map +0 -1
  257. package/indexNamedExports-Cdy7USiY.d.ts +0 -5696
  258. package/indexNamedExports-Cdy7USiY.d.ts.map +0 -1
  259. package/operators-HTxa_0k9.js +0 -4156
  260. package/operators-HTxa_0k9.js.map +0 -1
  261. package/std/index.d.ts.map +0 -1
  262. package/std/index.js.map +0 -1
  263. package/texture-Dg5ybJro.js.map +0 -1
@@ -0,0 +1,103 @@
1
+ import { $internal } from "../../shared/symbols.js";
2
+ 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);
7
+ }
8
+ function isQuerySet(value) {
9
+ const maybe = value;
10
+ return maybe?.resourceType === "query-set" && !!maybe[$internal];
11
+ }
12
+ var TgpuQuerySetImpl = class {
13
+ resourceType = "query-set";
14
+ #device;
15
+ _querySet = null;
16
+ _ownQuerySet;
17
+ _destroyed = false;
18
+ _available = true;
19
+ _readBuffer = null;
20
+ _resolveBuffer = null;
21
+ constructor(root, type, count, rawQuerySet) {
22
+ this.type = type;
23
+ this.count = count;
24
+ this.rawQuerySet = rawQuerySet;
25
+ this.#device = root.device;
26
+ this._ownQuerySet = !rawQuerySet;
27
+ this._querySet = rawQuerySet || null;
28
+ }
29
+ get querySet() {
30
+ if (this._destroyed) throw new Error("This QuerySet has been destroyed.");
31
+ if (this.rawQuerySet) return this.rawQuerySet;
32
+ if (this._querySet) return this._querySet;
33
+ this._querySet = this.#device.createQuerySet({
34
+ type: this.type,
35
+ count: this.count
36
+ });
37
+ return this._querySet;
38
+ }
39
+ get destroyed() {
40
+ return this._destroyed;
41
+ }
42
+ get available() {
43
+ return this._available;
44
+ }
45
+ get [$internal]() {
46
+ const self = this;
47
+ return {
48
+ get readBuffer() {
49
+ if (!self._readBuffer) self._readBuffer = self.#device.createBuffer({
50
+ size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
51
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
52
+ });
53
+ return self._readBuffer;
54
+ },
55
+ get resolveBuffer() {
56
+ if (!self._resolveBuffer) self._resolveBuffer = self.#device.createBuffer({
57
+ size: self.count * BigUint64Array.BYTES_PER_ELEMENT,
58
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC
59
+ });
60
+ return self._resolveBuffer;
61
+ }
62
+ };
63
+ }
64
+ $name(label) {
65
+ setName(this, label);
66
+ if (this._querySet) this._querySet.label = label;
67
+ return this;
68
+ }
69
+ resolve() {
70
+ if (this._destroyed) throw new Error("This QuerySet has been destroyed.");
71
+ if (!this._available) throw new Error("This QuerySet is busy resolving or reading.");
72
+ const commandEncoder = this.#device.createCommandEncoder();
73
+ commandEncoder.resolveQuerySet(this.querySet, 0, this.count, this[$internal].resolveBuffer, 0);
74
+ this.#device.queue.submit([commandEncoder.finish()]);
75
+ }
76
+ async read() {
77
+ if (!this._resolveBuffer) throw new Error("QuerySet must be resolved before reading.");
78
+ this._available = false;
79
+ try {
80
+ const commandEncoder = this.#device.createCommandEncoder();
81
+ commandEncoder.copyBufferToBuffer(this[$internal].resolveBuffer, 0, this[$internal].readBuffer, 0, this.count * BigUint64Array.BYTES_PER_ELEMENT);
82
+ this.#device.queue.submit([commandEncoder.finish()]);
83
+ const readBuffer = this[$internal].readBuffer;
84
+ await readBuffer.mapAsync(GPUMapMode.READ);
85
+ const data = new BigUint64Array(readBuffer.getMappedRange().slice());
86
+ readBuffer.unmap();
87
+ return Array.from(data);
88
+ } finally {
89
+ this._available = true;
90
+ }
91
+ }
92
+ destroy() {
93
+ if (this._destroyed) return;
94
+ this._destroyed = true;
95
+ if (this._querySet && this._ownQuerySet) this._querySet.destroy();
96
+ this._readBuffer?.destroy();
97
+ this._resolveBuffer?.destroy();
98
+ this._readBuffer = this._resolveBuffer = null;
99
+ }
100
+ };
101
+
102
+ //#endregion
103
+ export { INTERNAL_createQuerySet, isQuerySet };
@@ -0,0 +1,59 @@
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
+ /**
9
+ * Extra declaration that will be included in final WGSL code
10
+ * when resolving objects that use it.
11
+ */
12
+ interface TgpuRawCodeSnippet<TDataType extends BaseData> {
13
+ $: InferGPU<TDataType>;
14
+ value: InferGPU<TDataType>;
15
+ readonly [$gpuValueOf]: InferGPU<TDataType>;
16
+ $uses(dependencyMap: Record<string, unknown>): this;
17
+ }
18
+ type RawCodeSnippetOrigin = Exclude<Origin, 'function' | 'this-function' | 'argument' | 'constant-ref'>;
19
+ /**
20
+ * An advanced API that creates a typed shader expression which
21
+ * can be injected into the final shader bundle upon use.
22
+ *
23
+ * @param expression The code snippet that will be injected in place of `foo.$`
24
+ * @param type The type of the expression
25
+ * @param [origin='runtime'] Where the value originates from.
26
+ *
27
+ * **-- Which origin to choose?**
28
+ *
29
+ * Usually 'runtime' (the default) is a safe bet, but if you're sure that the expression or
30
+ * computation is constant (either a reference to a constant, a numeric literal,
31
+ * or an operation on constants), then pass 'constant' as it might lead to better
32
+ * optimizations.
33
+ *
34
+ * If what the expression is a direct reference to an existing value (e.g. a uniform, a
35
+ * storage binding, ...), then choose from 'uniform', 'mutable', 'readonly', 'workgroup',
36
+ * 'private' or 'handle' depending on the address space of the referred value.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * // An identifier that we know will be in the
41
+ * // final shader bundle, but we cannot
42
+ * // refer to it in any other way.
43
+ * const existingGlobal = tgpu['~unstable']
44
+ * .rawCodeSnippet('EXISTING_GLOBAL', d.f32, 'constant');
45
+ *
46
+ * const foo = () => {
47
+ * 'use gpu';
48
+ * return existingGlobal.$ * 2;
49
+ * };
50
+ *
51
+ * const wgsl = tgpu.resolve([foo]);
52
+ * // fn foo() -> f32 {
53
+ * // return EXISTING_GLOBAL * 2;
54
+ * // }
55
+ * ```
56
+ */
57
+ declare function rawCodeSnippet<TDataType extends AnyData>(expression: string, type: TDataType, origin?: RawCodeSnippetOrigin | undefined): TgpuRawCodeSnippet<TDataType>;
58
+ //#endregion
59
+ export { RawCodeSnippetOrigin, TgpuRawCodeSnippet, rawCodeSnippet };
@@ -0,0 +1,96 @@
1
+ import { $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
2
+ import { snip } from "../../data/snippet.js";
3
+ import { inCodegenMode } from "../../execMode.js";
4
+ import { valueProxyHandler } from "../valueProxyUtils.js";
5
+ import { applyExternals, replaceExternalsInWgsl } from "../resolve/externals.js";
6
+
7
+ //#region src/core/rawCodeSnippet/tgpuRawCodeSnippet.ts
8
+ /**
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);
48
+ }
49
+ var TgpuRawCodeSnippetImpl = class {
50
+ [$internal];
51
+ dataType;
52
+ origin;
53
+ #expression;
54
+ #externalsToApply;
55
+ constructor(expression, type, origin) {
56
+ this[$internal] = true;
57
+ this.dataType = type;
58
+ this.origin = origin;
59
+ this.#expression = expression;
60
+ this.#externalsToApply = [];
61
+ }
62
+ $uses(dependencyMap) {
63
+ this.#externalsToApply.push(dependencyMap);
64
+ return this;
65
+ }
66
+ [$resolve](ctx) {
67
+ const externalMap = {};
68
+ for (const externals of this.#externalsToApply) applyExternals(externalMap, externals);
69
+ return snip(replaceExternalsInWgsl(ctx, externalMap, this.#expression), this.dataType, this.origin);
70
+ }
71
+ toString() {
72
+ return `raw(${String(this.dataType)}): "${this.#expression}"`;
73
+ }
74
+ get [$gpuValueOf]() {
75
+ const dataType = this.dataType;
76
+ const origin = this.origin;
77
+ return new Proxy({
78
+ [$internal]: true,
79
+ get [$ownSnippet]() {
80
+ return snip(this, dataType, origin);
81
+ },
82
+ [$resolve]: (ctx) => ctx.resolve(this),
83
+ toString: () => `raw(${String(this.dataType)}): "${this.#expression}".$`
84
+ }, valueProxyHandler);
85
+ }
86
+ get $() {
87
+ if (!inCodegenMode()) throw new Error("Raw code snippets can only be used on the GPU.");
88
+ return this[$gpuValueOf];
89
+ }
90
+ get value() {
91
+ return this.$;
92
+ }
93
+ };
94
+
95
+ //#endregion
96
+ export { rawCodeSnippet };
@@ -0,0 +1,10 @@
1
+ import "../../types.js";
2
+
3
+ //#region src/core/resolve/externals.d.ts
4
+ /**
5
+ * A key-value mapping where keys represent identifiers within shader code,
6
+ * and values can be any type that can be resolved to a code string.
7
+ */
8
+ type ExternalMap = Record<string, unknown>;
9
+ //#endregion
10
+ export { ExternalMap };
@@ -0,0 +1,58 @@
1
+ import { getName, hasTinyestMetadata, setName } from "../../shared/meta.js";
2
+ import { isWgslStruct } from "../../data/wgslTypes.js";
3
+ import { isLooseData } from "../../data/dataTypes.js";
4
+ import { isWgsl } from "../../types.js";
5
+
6
+ //#region src/core/resolve/externals.ts
7
+ /**
8
+ * Merges two external maps into one. If a key is present in both maps, the value from the new map is used.
9
+ * If the external value is a namable object, it is given a name if it does not already have one.
10
+ * @param existing - The existing external map.
11
+ * @param newExternals - The new external map.
12
+ */
13
+ function applyExternals(existing, newExternals) {
14
+ for (const [key, value] of Object.entries(newExternals)) {
15
+ existing[key] = value;
16
+ if (value && (typeof value === "object" || typeof value === "function") && getName(value) === void 0) setName(value, key);
17
+ }
18
+ }
19
+ function addArgTypesToExternals(implementation, argTypes, applyExternals) {
20
+ const argTypeNames = [...implementation.matchAll(/:\s*(?<arg>.*?)\s*[,)]/g)].map((found) => found ? found[1] : void 0);
21
+ applyExternals(Object.fromEntries(argTypes.flatMap((argType, i) => {
22
+ const argTypeName = argTypeNames ? argTypeNames[i] : void 0;
23
+ return isWgslStruct(argType) && argTypeName !== void 0 ? [[argTypeName, argType]] : [];
24
+ })));
25
+ }
26
+ function addReturnTypeToExternals(implementation, returnType, applyExternals) {
27
+ const matched = implementation.match(/->\s(?<output>[\w\d_]+)\s{/);
28
+ const outputName = matched ? matched[1]?.trim() : void 0;
29
+ if (isWgslStruct(returnType) && outputName && !/\s/g.test(outputName)) applyExternals({ [outputName]: returnType });
30
+ }
31
+ function identifierRegex(name) {
32
+ return new RegExp(`(?<![\\w\\$_.])${name.replaceAll(".", "\\.").replaceAll("$", "\\$")}(?![\\w\\$_])`, "g");
33
+ }
34
+ /**
35
+ * Replaces all occurrences of external names in WGSL code with their resolved values.
36
+ * It adds all necessary definitions to the resolution context.
37
+ * @param ctx - The resolution context.
38
+ * @param externalMap - The external map.
39
+ * @param wgsl - The WGSL code.
40
+ *
41
+ * @returns The WGSL code with all external names replaced with their resolved values.
42
+ */
43
+ function replaceExternalsInWgsl(ctx, externalMap, wgsl) {
44
+ return Object.entries(externalMap).reduce((acc, [externalName, external]) => {
45
+ const externalRegex = identifierRegex(externalName);
46
+ if (wgsl && externalName !== "Out" && externalName !== "In" && !externalRegex.test(wgsl)) console.warn(`The external '${externalName}' wasn't used in the resolved template.`);
47
+ if (isWgsl(external) || isLooseData(external) || hasTinyestMetadata(external)) return acc.replaceAll(externalRegex, ctx.resolve(external).value);
48
+ if (external !== null && typeof external === "object") {
49
+ const foundProperties = [...wgsl.matchAll(new RegExp(`${externalName.replaceAll(".", "\\.").replaceAll("$", "\\$")}\\.(?<prop>.*?)(?![\\w\\$_])`, "g"))].map((found) => found[1]);
50
+ return [...new Set(foundProperties)].reduce((innerAcc, prop) => prop && prop in external ? replaceExternalsInWgsl(ctx, { [`${externalName}.${prop}`]: external[prop] }, innerAcc) : innerAcc, acc);
51
+ }
52
+ 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.`);
53
+ return acc;
54
+ }, wgsl);
55
+ }
56
+
57
+ //#endregion
58
+ export { addArgTypesToExternals, addReturnTypeToExternals, applyExternals, replaceExternalsInWgsl };
@@ -0,0 +1,38 @@
1
+ import { $internal } from "../../shared/symbols.js";
2
+ import { ResolvedSnippet } from "../../data/snippet.js";
3
+ import { ShelllessRepository } from "../../tgsl/shellless.js";
4
+ import { TgpuLazy, TgpuSlot } from "../slot/slotTypes.js";
5
+ import { NameRegistry } from "../../nameRegistry.js";
6
+
7
+ //#region src/core/resolve/namespace.d.ts
8
+ type SlotToValueMap = Map<TgpuSlot<unknown>, unknown>;
9
+ interface NamespaceInternal {
10
+ readonly nameRegistry: NameRegistry;
11
+ readonly shelllessRepo: ShelllessRepository;
12
+ memoizedResolves: WeakMap<object, {
13
+ slotToValueMap: SlotToValueMap;
14
+ result: ResolvedSnippet;
15
+ }[]>;
16
+ memoizedLazy: WeakMap<TgpuLazy<unknown>, {
17
+ slotToValueMap: SlotToValueMap;
18
+ result: unknown;
19
+ }[]>;
20
+ listeners: { [K in keyof NamespaceEventMap]: Set<(event: NamespaceEventMap[K]) => void> };
21
+ }
22
+ type NamespaceEventMap = {
23
+ name: {
24
+ target: object;
25
+ name: string;
26
+ };
27
+ };
28
+ type DetachListener = () => void;
29
+ interface Namespace {
30
+ readonly [$internal]: NamespaceInternal;
31
+ on<TEvent extends keyof NamespaceEventMap>(event: TEvent, listener: (event: NamespaceEventMap[TEvent]) => void): DetachListener;
32
+ }
33
+ interface NamespaceOptions {
34
+ names?: 'random' | 'strict' | undefined;
35
+ }
36
+ declare function namespace(options?: NamespaceOptions): Namespace;
37
+ //#endregion
38
+ export { Namespace, namespace };
@@ -0,0 +1,41 @@
1
+ import { $internal } from "../../shared/symbols.js";
2
+ import { getName } from "../../shared/meta.js";
3
+ import { RandomNameRegistry, StrictNameRegistry } from "../../nameRegistry.js";
4
+ import { ShelllessRepository } from "../../tgsl/shellless.js";
5
+
6
+ //#region src/core/resolve/namespace.ts
7
+ var NamespaceImpl = class {
8
+ [$internal];
9
+ constructor(nameRegistry) {
10
+ this[$internal] = {
11
+ nameRegistry,
12
+ shelllessRepo: new ShelllessRepository(),
13
+ memoizedResolves: /* @__PURE__ */ new WeakMap(),
14
+ memoizedLazy: /* @__PURE__ */ new WeakMap(),
15
+ listeners: { name: /* @__PURE__ */ new Set() }
16
+ };
17
+ }
18
+ on(event, listener) {
19
+ if (event === "name") {
20
+ const listeners = this[$internal].listeners.name;
21
+ listeners.add(listener);
22
+ return () => listeners.delete(listener);
23
+ }
24
+ throw new Error(`Unsupported event: ${event}`);
25
+ }
26
+ };
27
+ function getUniqueName(namespace, resource) {
28
+ const name = namespace.nameRegistry.makeUnique(getName(resource), true);
29
+ for (const listener of namespace.listeners.name) listener({
30
+ target: resource,
31
+ name
32
+ });
33
+ return name;
34
+ }
35
+ function namespace(options) {
36
+ const { names = "strict" } = options ?? {};
37
+ return new NamespaceImpl(names === "strict" ? new StrictNameRegistry() : new RandomNameRegistry());
38
+ }
39
+
40
+ //#endregion
41
+ export { getUniqueName, namespace };
@@ -0,0 +1,146 @@
1
+ import { $internal } from "../../shared/symbols.js";
2
+ import { isLooseData } from "../../data/dataTypes.js";
3
+ import { assertExhaustive } from "../../shared/utilityTypes.js";
4
+ import { formatToWGSLType } from "../../data/vertexFormatData.js";
5
+ import { getAttributesString } from "../../data/attributes.js";
6
+ import { isWgslComparisonSampler, isWgslSampler } from "../../data/sampler.js";
7
+ import { accessModeMap, isWgslStorageTexture, isWgslTexture } from "../../data/texture.js";
8
+ import { isAttribute } from "../vertexLayout/connectAttributesToShader.js";
9
+
10
+ //#region src/core/resolve/resolveData.ts
11
+ /**
12
+ * Schemas for which their `type` property directly
13
+ * translates to the resulting WGSL code.
14
+ */
15
+ const identityTypes = [
16
+ "bool",
17
+ "f32",
18
+ "f16",
19
+ "i32",
20
+ "u32",
21
+ "vec2f",
22
+ "vec3f",
23
+ "vec4f",
24
+ "vec2h",
25
+ "vec3h",
26
+ "vec4h",
27
+ "vec2i",
28
+ "vec3i",
29
+ "vec4i",
30
+ "vec2u",
31
+ "vec3u",
32
+ "vec4u",
33
+ "vec2<bool>",
34
+ "vec3<bool>",
35
+ "vec4<bool>",
36
+ "mat2x2f",
37
+ "mat3x3f",
38
+ "mat4x4f",
39
+ "texture_external"
40
+ ];
41
+ function isIdentityType(data) {
42
+ return identityTypes.includes(data.type);
43
+ }
44
+ /**
45
+ * Resolves a single property of a struct.
46
+ * @param ctx - The resolution context.
47
+ * @param key - The key of the property.
48
+ * @param property - The property itself.
49
+ *
50
+ * @returns The resolved property string.
51
+ */
52
+ function resolveStructProperty(ctx, [key, property]) {
53
+ return ` ${getAttributesString(property)}${key}: ${ctx.resolve(property).value},\n`;
54
+ }
55
+ /**
56
+ * Resolves a struct and adds its declaration to the resolution context.
57
+ * @param ctx - The resolution context.
58
+ * @param struct - The struct to resolve.
59
+ *
60
+ * @returns The resolved struct name.
61
+ */
62
+ function resolveStruct(ctx, struct) {
63
+ if (struct[$internal].isAbstruct) throw new Error("Cannot resolve abstract struct types to WGSL.");
64
+ const id = ctx.getUniqueName(struct);
65
+ ctx.addDeclaration(`\
66
+ struct ${id} {
67
+ ${Object.entries(struct.propTypes).map((prop) => resolveStructProperty(ctx, prop)).join("")}\
68
+ }`);
69
+ return id;
70
+ }
71
+ /**
72
+ * Resolves an unstruct (struct that does not align data by default) to its struct data counterpart.
73
+ * @param ctx - The resolution context.
74
+ * @param unstruct - The unstruct to resolve.
75
+ *
76
+ * @returns The resolved unstruct name.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * resolveUnstruct(ctx, {
81
+ * uv: d.float16x2, // -> d.vec2f after resolution
82
+ * color: d.snorm8x4, -> d.vec4f after resolution
83
+ * });
84
+ * ```
85
+ */
86
+ function resolveUnstruct(ctx, unstruct) {
87
+ const id = ctx.getUniqueName(unstruct);
88
+ ctx.addDeclaration(`\
89
+ struct ${id} {
90
+ ${Object.entries(unstruct.propTypes).map((prop) => isAttribute(prop[1]) ? resolveStructProperty(ctx, [prop[0], formatToWGSLType[prop[1].format]]) : resolveStructProperty(ctx, prop)).join("")}
91
+ }`);
92
+ return id;
93
+ }
94
+ /**
95
+ * Resolves an array.
96
+ * @param ctx - The resolution context.
97
+ * @param array - The array to resolve.
98
+ *
99
+ * @returns The resolved array name along with its element type and count (if not runtime-sized).
100
+ *
101
+ * @example
102
+ * ```ts
103
+ * resolveArray(ctx, d.arrayOf(d.u32, 0)); // 'array<u32>' (not a real pattern, a function is preferred)
104
+ * resolveArray(ctx, d.arrayOf(d.u32, 5)); // 'array<u32, 5>'
105
+ * ```
106
+ */
107
+ function resolveArray(ctx, array) {
108
+ const element = ctx.resolve(array.elementType).value;
109
+ return array.elementCount === 0 ? `array<${element}>` : `array<${element}, ${array.elementCount}>`;
110
+ }
111
+ function resolveDisarray(ctx, disarray) {
112
+ const element = ctx.resolve(isAttribute(disarray.elementType) ? formatToWGSLType[disarray.elementType.format] : disarray.elementType).value;
113
+ return disarray.elementCount === 0 ? `array<${element}>` : `array<${element}, ${disarray.elementCount}>`;
114
+ }
115
+ /**
116
+ * Resolves a WGSL data-type schema to a string.
117
+ * @param ctx - The resolution context.
118
+ * @param data - The data-type to resolve.
119
+ *
120
+ * @returns The resolved data-type string.
121
+ */
122
+ function resolveData(ctx, data) {
123
+ if (isLooseData(data)) {
124
+ if (data.type === "unstruct") return resolveUnstruct(ctx, data);
125
+ if (data.type === "disarray") return resolveDisarray(ctx, data);
126
+ if (data.type === "loose-decorated") return ctx.resolve(isAttribute(data.inner) ? formatToWGSLType[data.inner.format] : data.inner).value;
127
+ return ctx.resolve(formatToWGSLType[data.type]).value;
128
+ }
129
+ if (isIdentityType(data)) return data.type;
130
+ if (data.type === "struct") return resolveStruct(ctx, data);
131
+ if (data.type === "array") return resolveArray(ctx, data);
132
+ if (data.type === "atomic") return `atomic<${resolveData(ctx, data.inner)}>`;
133
+ if (data.type === "decorated") return ctx.resolve(data.inner).value;
134
+ if (data.type === "ptr") {
135
+ if (data.addressSpace === "storage") return `ptr<storage, ${ctx.resolve(data.inner).value}, ${data.access === "read-write" ? "read_write" : data.access}>`;
136
+ return `ptr<${data.addressSpace}, ${ctx.resolve(data.inner).value}>`;
137
+ }
138
+ if (data.type === "abstractInt" || data.type === "abstractFloat" || data.type === "void" || data.type === "u16") throw new Error(`${data.type} has no representation in WGSL`);
139
+ if (isWgslStorageTexture(data)) return `${data.type}<${data.format}, ${accessModeMap[data.access]}>`;
140
+ if (isWgslTexture(data)) return data.type.startsWith("texture_depth") ? data.type : `${data.type}<${data.sampleType.type}>`;
141
+ if (isWgslComparisonSampler(data) || isWgslSampler(data)) return data.type;
142
+ assertExhaustive(data, "resolveData");
143
+ }
144
+
145
+ //#endregion
146
+ export { resolveData };
@@ -0,0 +1,25 @@
1
+ import { isSnippet } from "../../data/snippet.js";
2
+ import { getResolutionCtx } from "../../execMode.js";
3
+
4
+ //#region src/core/resolve/stitch.ts
5
+ /**
6
+ * "The reverse of snipping"
7
+ * Injects resolved snippets into a template string.
8
+ */
9
+ function stitch(strings, ...snippets) {
10
+ const ctx = getResolutionCtx();
11
+ function resolveSnippet(maybeSnippet) {
12
+ return isSnippet(maybeSnippet) ? ctx.resolve(maybeSnippet.value, maybeSnippet.dataType).value : maybeSnippet;
13
+ }
14
+ let result = "";
15
+ for (let i = 0; i < strings.length; ++i) {
16
+ result += strings[i];
17
+ const snippet = snippets[i];
18
+ if (Array.isArray(snippet)) result += snippet.filter((s) => s !== void 0).map(resolveSnippet).join(", ");
19
+ else if (snippet) result += resolveSnippet(snippet);
20
+ }
21
+ return result;
22
+ }
23
+
24
+ //#endregion
25
+ export { stitch };