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,546 @@
1
+ import { $internal, $providing, $resolve, isMarkedInternal } from "./shared/symbols.js";
2
+ import { getName, hasTinyestMetadata, setName } from "./shared/meta.js";
3
+ import { Void, isPtr, isWgslArray, isWgslStruct } from "./data/wgslTypes.js";
4
+ import { UnknownData, isData } from "./data/dataTypes.js";
5
+ import { snip } from "./data/snippet.js";
6
+ import { MissingSlotValueError, ResolutionError, WgslTypeError, invariant } from "./errors.js";
7
+ import { isLazy, isProviding, isSlot } from "./core/slot/slotTypes.js";
8
+ import { CodegenState, NormalState, isSelfResolvable } from "./types.js";
9
+ import { provideCtx, topLevelState } from "./execMode.js";
10
+ import { stitch } from "./core/resolve/stitch.js";
11
+ import { safeStringify } from "./shared/stringify.js";
12
+ import { getBestConversion } from "./tgsl/conversion.js";
13
+ import { bool } from "./data/numeric.js";
14
+ import { getAttributesString } from "./data/attributes.js";
15
+ import { createIoSchema } from "./core/function/ioSchema.js";
16
+ import { AutoStruct } from "./data/autoStruct.js";
17
+ import { coerceToSnippet, concretize, numericLiteralToSnippet } from "./tgsl/generationHelpers.js";
18
+ import { accessProp } from "./tgsl/accessProp.js";
19
+ import { isTgpuFn } from "./core/function/tgpuFn.js";
20
+ import { getUniqueName } from "./core/resolve/namespace.js";
21
+ import { resolveData } from "./core/resolve/resolveData.js";
22
+ import { ConfigurableImpl } from "./core/root/configurableImpl.js";
23
+ import { naturalsExcept } from "./shared/generators.js";
24
+ import { TgpuBindGroupImpl, bindGroupLayout } from "./tgpuBindGroupLayout.js";
25
+ import { LogGeneratorImpl, LogGeneratorNullImpl } from "./tgsl/consoleLog/logGenerator.js";
26
+ import wgslGenerator from "./tgsl/wgslGenerator.js";
27
+ import { FuncParameterType } from "tinyest";
28
+
29
+ //#region src/resolutionCtx.ts
30
+ /**
31
+ * Inserted into bind group entry definitions that belong
32
+ * to the automatically generated catch-all bind group.
33
+ *
34
+ * A non-occupied group index can only be determined after
35
+ * every resource has been resolved, so this acts as a placeholder
36
+ * to be replaced with an actual numeric index at the very end
37
+ * of the resolution process.
38
+ */
39
+ const CATCHALL_BIND_GROUP_IDX_MARKER = "#CATCHALL#";
40
+ var ItemStateStackImpl = class {
41
+ _stack = [];
42
+ _itemDepth = 0;
43
+ get itemDepth() {
44
+ return this._itemDepth;
45
+ }
46
+ get topItem() {
47
+ const state = this._stack[this._stack.length - 1];
48
+ if (!state || state.type !== "item") throw new Error("Internal error, expected item layer to be on top.");
49
+ return state;
50
+ }
51
+ get topFunctionScope() {
52
+ return this._stack.findLast((e) => e.type === "functionScope");
53
+ }
54
+ pushItem() {
55
+ this._itemDepth++;
56
+ this._stack.push({
57
+ type: "item",
58
+ usedSlots: /* @__PURE__ */ new Set()
59
+ });
60
+ }
61
+ pushSlotBindings(pairs) {
62
+ this._stack.push({
63
+ type: "slotBinding",
64
+ bindingMap: new WeakMap(pairs)
65
+ });
66
+ }
67
+ pushFunctionScope(functionType, args, argAliases, returnType, externalMap) {
68
+ const scope = {
69
+ type: "functionScope",
70
+ functionType,
71
+ args,
72
+ argAliases,
73
+ returnType,
74
+ externalMap,
75
+ reportedReturnTypes: /* @__PURE__ */ new Set()
76
+ };
77
+ this._stack.push(scope);
78
+ return scope;
79
+ }
80
+ pushBlockScope() {
81
+ this._stack.push({
82
+ type: "blockScope",
83
+ declarations: /* @__PURE__ */ new Map(),
84
+ externals: /* @__PURE__ */ new Map()
85
+ });
86
+ }
87
+ pop(type) {
88
+ const layer = this._stack[this._stack.length - 1];
89
+ if (!layer || type && layer.type !== type) throw new Error(`Internal error, expected a ${type} layer to be on top.`);
90
+ const poppedValue = this._stack.pop();
91
+ if (type === "item") this._itemDepth--;
92
+ return poppedValue;
93
+ }
94
+ readSlot(slot) {
95
+ for (let i = this._stack.length - 1; i >= 0; --i) {
96
+ const layer = this._stack[i];
97
+ if (layer?.type === "item") layer.usedSlots.add(slot);
98
+ else if (layer?.type === "slotBinding") {
99
+ const boundValue = layer.bindingMap.get(slot);
100
+ if (boundValue !== void 0) return boundValue;
101
+ } else if (layer?.type === "functionScope" || layer?.type === "blockScope") {} else throw new Error("Unknown layer type.");
102
+ }
103
+ return slot.defaultValue;
104
+ }
105
+ getSnippetById(id) {
106
+ for (let i = this._stack.length - 1; i >= 0; --i) {
107
+ const layer = this._stack[i];
108
+ if (layer?.type === "functionScope") {
109
+ const arg = layer.args.find((a) => a.value === id);
110
+ if (arg !== void 0) return arg;
111
+ if (layer.argAliases[id]) return layer.argAliases[id];
112
+ const external = layer.externalMap[id];
113
+ if (external !== void 0 && external !== null) return coerceToSnippet(external);
114
+ return;
115
+ }
116
+ if (layer?.type === "blockScope") {
117
+ const snippet = layer.declarations.get(id) ?? layer.externals.get(id);
118
+ if (snippet !== void 0) return snippet;
119
+ }
120
+ }
121
+ }
122
+ defineBlockVariable(id, snippet) {
123
+ if (snippet.dataType === UnknownData) throw Error(`Tried to define variable '${id}' of unknown type`);
124
+ for (let i = this._stack.length - 1; i >= 0; --i) {
125
+ const layer = this._stack[i];
126
+ if (layer?.type === "blockScope") {
127
+ layer.declarations.set(id, snippet);
128
+ return;
129
+ }
130
+ }
131
+ throw new Error("No block scope found to define a variable in.");
132
+ }
133
+ setBlockExternals(externals) {
134
+ for (let i = this._stack.length - 1; i >= 0; --i) {
135
+ const layer = this._stack[i];
136
+ if (layer?.type === "blockScope") {
137
+ Object.entries(externals).forEach(([id, snippet]) => {
138
+ layer.externals.set(id, snippet);
139
+ });
140
+ return;
141
+ }
142
+ }
143
+ throw new Error("No block scope found to set externals in.");
144
+ }
145
+ clearBlockExternals() {
146
+ for (let i = this._stack.length - 1; i >= 0; --i) {
147
+ const layer = this._stack[i];
148
+ if (layer?.type === "blockScope") {
149
+ layer.externals.clear();
150
+ return;
151
+ }
152
+ }
153
+ throw new Error("No block scope found to clear externals in.");
154
+ }
155
+ };
156
+ const INDENT = [
157
+ "",
158
+ " ",
159
+ " ",
160
+ " ",
161
+ " ",
162
+ " ",
163
+ " ",
164
+ " ",
165
+ " "
166
+ ];
167
+ const N = INDENT.length - 1;
168
+ var IndentController = class {
169
+ identLevel = 0;
170
+ get pre() {
171
+ return INDENT[this.identLevel] ?? INDENT[N].repeat(this.identLevel / N) + INDENT[this.identLevel % N];
172
+ }
173
+ indent() {
174
+ const str = this.pre;
175
+ this.identLevel++;
176
+ return str;
177
+ }
178
+ dedent() {
179
+ this.identLevel--;
180
+ return this.pre;
181
+ }
182
+ withResetLevel(callback) {
183
+ const savedLevel = this.identLevel;
184
+ this.identLevel = 0;
185
+ try {
186
+ return callback();
187
+ } finally {
188
+ this.identLevel = savedLevel;
189
+ }
190
+ }
191
+ };
192
+ var ResolutionCtxImpl = class {
193
+ #namespaceInternal;
194
+ #shaderGenerator;
195
+ _indentController = new IndentController();
196
+ _itemStateStack = new ItemStateStackImpl();
197
+ #modeStack = [];
198
+ _declarations = [];
199
+ _varyingLocations;
200
+ #currentlyResolvedItems = /* @__PURE__ */ new WeakSet();
201
+ #logGenerator;
202
+ get varyingLocations() {
203
+ return this._varyingLocations;
204
+ }
205
+ [$internal] = { itemStateStack: this._itemStateStack };
206
+ /**
207
+ * A map from registered bind group layouts to random strings put in
208
+ * place of their group index. The whole tree has to be traversed to
209
+ * collect every use of a typed bind group layout, since they can be
210
+ * explicitly imposed group indices, and they cannot collide.
211
+ */
212
+ bindGroupLayoutsToPlaceholderMap = /* @__PURE__ */ new Map();
213
+ _nextFreeLayoutPlaceholderIdx = 0;
214
+ fixedBindings = [];
215
+ enableExtensions;
216
+ expectedType;
217
+ constructor(opts) {
218
+ this.enableExtensions = opts.enableExtensions;
219
+ this.#shaderGenerator = opts.shaderGenerator ?? wgslGenerator;
220
+ this.#logGenerator = opts.root ? new LogGeneratorImpl(opts.root) : new LogGeneratorNullImpl();
221
+ this.#namespaceInternal = opts.namespace[$internal];
222
+ }
223
+ getUniqueName(resource) {
224
+ return getUniqueName(this.#namespaceInternal, resource);
225
+ }
226
+ makeNameValid(name) {
227
+ return this.#namespaceInternal.nameRegistry.makeValid(name);
228
+ }
229
+ get pre() {
230
+ return this._indentController.pre;
231
+ }
232
+ get topFunctionScope() {
233
+ return this._itemStateStack.topFunctionScope;
234
+ }
235
+ get topFunctionReturnType() {
236
+ const scope = this._itemStateStack.topFunctionScope;
237
+ invariant(scope, "Internal error, expected function scope to be present.");
238
+ return scope.returnType;
239
+ }
240
+ get shelllessRepo() {
241
+ return this.#namespaceInternal.shelllessRepo;
242
+ }
243
+ indent() {
244
+ return this._indentController.indent();
245
+ }
246
+ dedent() {
247
+ return this._indentController.dedent();
248
+ }
249
+ withResetIndentLevel(callback) {
250
+ return this._indentController.withResetLevel(callback);
251
+ }
252
+ getById(id) {
253
+ const item = this._itemStateStack.getSnippetById(id);
254
+ if (item === void 0) return null;
255
+ return item;
256
+ }
257
+ defineVariable(id, snippet) {
258
+ this._itemStateStack.defineBlockVariable(id, snippet);
259
+ }
260
+ reportReturnType(dataType) {
261
+ const scope = this._itemStateStack.topFunctionScope;
262
+ invariant(scope, "Internal error, expected function scope to be present.");
263
+ scope.reportedReturnTypes.add(dataType);
264
+ }
265
+ pushBlockScope() {
266
+ this.#namespaceInternal.nameRegistry.pushBlockScope();
267
+ this._itemStateStack.pushBlockScope();
268
+ }
269
+ popBlockScope() {
270
+ this.#namespaceInternal.nameRegistry.popBlockScope();
271
+ this._itemStateStack.pop("blockScope");
272
+ }
273
+ setBlockExternals(externals) {
274
+ this._itemStateStack.setBlockExternals(externals);
275
+ }
276
+ clearBlockExternals() {
277
+ this._itemStateStack.clearBlockExternals();
278
+ }
279
+ generateLog(op, args) {
280
+ return this.#logGenerator.generateLog(this, op, args);
281
+ }
282
+ get logResources() {
283
+ return this.#logGenerator.logResources;
284
+ }
285
+ fnToWgsl(options) {
286
+ let fnScopePushed = false;
287
+ try {
288
+ this.#namespaceInternal.nameRegistry.pushFunctionScope();
289
+ const args = [];
290
+ const argAliases = [];
291
+ for (const [i, argType] of options.argTypes.entries()) {
292
+ const astParam = options.params[i];
293
+ const origin = isPtr(argType) ? argType.addressSpace === "storage" ? argType.access === "read" ? "readonly" : "mutable" : argType.addressSpace : "argument";
294
+ switch (astParam?.type) {
295
+ case FuncParameterType.identifier: {
296
+ const rawName = astParam.name;
297
+ const snippet = snip(this.makeNameValid(rawName), argType, origin);
298
+ args.push(snippet);
299
+ if (snippet.value !== rawName) argAliases.push([rawName, snippet]);
300
+ break;
301
+ }
302
+ case FuncParameterType.destructuredObject: {
303
+ const objSnippet = snip(`_arg_${i}`, argType, origin);
304
+ args.push(objSnippet);
305
+ argAliases.push(...astParam.props.map(({ name, alias }) => [alias, accessProp(objSnippet, name)]));
306
+ break;
307
+ }
308
+ case void 0: if (!(argType instanceof AutoStruct)) args.push(snip(`_arg_${i}`, argType, origin));
309
+ }
310
+ }
311
+ const scope = this._itemStateStack.pushFunctionScope(options.functionType, args, Object.fromEntries(argAliases), options.returnType, options.externalMap);
312
+ fnScopePushed = true;
313
+ this.#shaderGenerator.initGenerator(this);
314
+ const body = this.#shaderGenerator.functionDefinition(options.body);
315
+ let returnType = options.returnType;
316
+ if (returnType instanceof AutoStruct) if (isWgslStruct(scope.reportedReturnTypes.values().next().value)) returnType = returnType.completeStruct;
317
+ else returnType = void 0;
318
+ if (!returnType) {
319
+ const returnTypes = [...scope.reportedReturnTypes];
320
+ if (returnTypes.length === 0) returnType = Void;
321
+ else {
322
+ const conversion = getBestConversion(returnTypes);
323
+ if (conversion && !conversion.hasImplicitConversions) returnType = conversion.targetType;
324
+ }
325
+ if (!returnType) throw new Error(`Expected function to have a single return type, got [${returnTypes.join(", ")}]. Cast explicitly to the desired type.`);
326
+ returnType = concretize(returnType);
327
+ if (options.functionType === "vertex" || options.functionType === "fragment") returnType = createIoSchema(returnType);
328
+ }
329
+ return {
330
+ head: resolveFunctionHeader(this, args, returnType),
331
+ body,
332
+ returnType
333
+ };
334
+ } finally {
335
+ if (fnScopePushed) this._itemStateStack.pop("functionScope");
336
+ this.#namespaceInternal.nameRegistry.popFunctionScope();
337
+ }
338
+ }
339
+ addDeclaration(declaration) {
340
+ this._declarations.push(declaration);
341
+ }
342
+ allocateLayoutEntry(layout) {
343
+ const memoMap = this.bindGroupLayoutsToPlaceholderMap;
344
+ let placeholderKey = memoMap.get(layout);
345
+ if (!placeholderKey) {
346
+ placeholderKey = `#BIND_GROUP_LAYOUT_${this._nextFreeLayoutPlaceholderIdx++}#`;
347
+ memoMap.set(layout, placeholderKey);
348
+ }
349
+ return placeholderKey;
350
+ }
351
+ allocateFixedEntry(layoutEntry, resource) {
352
+ const binding = this.fixedBindings.length;
353
+ this.fixedBindings.push({
354
+ layoutEntry,
355
+ resource
356
+ });
357
+ return {
358
+ group: CATCHALL_BIND_GROUP_IDX_MARKER,
359
+ binding
360
+ };
361
+ }
362
+ readSlot(slot) {
363
+ const value = this._itemStateStack.readSlot(slot);
364
+ if (value === void 0) throw new MissingSlotValueError(slot);
365
+ return value;
366
+ }
367
+ withSlots(pairs, callback) {
368
+ if (pairs.length === 0) return callback();
369
+ this._itemStateStack.pushSlotBindings(pairs);
370
+ try {
371
+ return callback();
372
+ } finally {
373
+ this._itemStateStack.pop("slotBinding");
374
+ }
375
+ }
376
+ withVaryingLocations(locations, callback) {
377
+ this._varyingLocations = locations;
378
+ try {
379
+ return callback();
380
+ } finally {
381
+ this._varyingLocations = void 0;
382
+ }
383
+ }
384
+ withRenamed(item, name, callback) {
385
+ if (!name) return callback();
386
+ const oldName = getName(item);
387
+ try {
388
+ setName(item, name);
389
+ return callback();
390
+ } finally {
391
+ setName(item, oldName);
392
+ }
393
+ }
394
+ unwrap(eventual) {
395
+ if (isProviding(eventual)) return this.withRenamed(eventual[$providing].inner, getName(eventual), () => this.withSlots(eventual[$providing].pairs, () => this.unwrap(eventual[$providing].inner)));
396
+ let maybeEventual = eventual;
397
+ while (true) if (isSlot(maybeEventual)) maybeEventual = this.readSlot(maybeEventual);
398
+ else if (isLazy(maybeEventual)) maybeEventual = this._getOrCompute(maybeEventual);
399
+ else break;
400
+ return maybeEventual;
401
+ }
402
+ _getOrCompute(lazy) {
403
+ const instances = this.#namespaceInternal.memoizedLazy.get(lazy) ?? [];
404
+ this._itemStateStack.pushItem();
405
+ try {
406
+ for (const instance of instances) if ([...instance.slotToValueMap.entries()].every(([slot, expectedValue]) => slot.areEqual(this._itemStateStack.readSlot(slot), expectedValue))) return instance.result;
407
+ this.pushMode(new NormalState());
408
+ let result;
409
+ try {
410
+ result = lazy[$internal].compute();
411
+ } finally {
412
+ this.popMode("normal");
413
+ }
414
+ const slotToValueMap = /* @__PURE__ */ new Map();
415
+ for (const usedSlot of this._itemStateStack.topItem.usedSlots) slotToValueMap.set(usedSlot, this._itemStateStack.readSlot(usedSlot));
416
+ instances.push({
417
+ slotToValueMap,
418
+ result
419
+ });
420
+ this.#namespaceInternal.memoizedLazy.set(lazy, instances);
421
+ return result;
422
+ } catch (err) {
423
+ if (err instanceof ResolutionError) throw err.appendToTrace(lazy);
424
+ throw new ResolutionError(err, [lazy]);
425
+ } finally {
426
+ this._itemStateStack.pop("item");
427
+ }
428
+ }
429
+ /**
430
+ * @param item The item whose resolution should be either retrieved from the cache (if there is a cache hit), or resolved.
431
+ */
432
+ _getOrInstantiate(item) {
433
+ const instances = this.#namespaceInternal.memoizedResolves.get(item) ?? [];
434
+ this._itemStateStack.pushItem();
435
+ try {
436
+ for (const instance of instances) if ([...instance.slotToValueMap.entries()].every(([slot, expectedValue]) => slot.areEqual(this._itemStateStack.readSlot(slot), expectedValue))) return instance.result;
437
+ let result;
438
+ if (isData(item)) result = snip(resolveData(this, item), Void, "runtime");
439
+ else if (isLazy(item) || isSlot(item)) result = this.resolve(this.unwrap(item));
440
+ else if (isSelfResolvable(item)) result = item[$resolve](this);
441
+ else if (hasTinyestMetadata(item)) {
442
+ const shellless = this.#namespaceInternal.shelllessRepo.get(item, void 0);
443
+ if (!shellless) throw new Error(`Couldn't resolve ${item.name}. Make sure it's a function that accepts no arguments, or call it from another TypeGPU function.`);
444
+ return this.withResetIndentLevel(() => this.resolve(shellless));
445
+ } else throw new TypeError(`Unresolvable internal value: ${safeStringify(item)}`);
446
+ const slotToValueMap = /* @__PURE__ */ new Map();
447
+ for (const usedSlot of this._itemStateStack.topItem.usedSlots) slotToValueMap.set(usedSlot, this._itemStateStack.readSlot(usedSlot));
448
+ instances.push({
449
+ slotToValueMap,
450
+ result
451
+ });
452
+ this.#namespaceInternal.memoizedResolves.set(item, instances);
453
+ return result;
454
+ } catch (err) {
455
+ if (err instanceof ResolutionError) throw err.appendToTrace(item);
456
+ throw new ResolutionError(err, [item]);
457
+ } finally {
458
+ this._itemStateStack.pop("item");
459
+ }
460
+ }
461
+ resolve(item, schema) {
462
+ if (isTgpuFn(item) || hasTinyestMetadata(item)) {
463
+ if (this.#currentlyResolvedItems.has(item) && !this.#namespaceInternal.memoizedResolves.has(item)) throw new Error(`Recursive function ${item} detected. Recursion is not allowed on the GPU.`);
464
+ this.#currentlyResolvedItems.add(item);
465
+ }
466
+ if (isProviding(item)) return this.withRenamed(item[$providing].inner, getName(item), () => this.withSlots(item[$providing].pairs, () => this.resolve(item[$providing].inner, schema)));
467
+ if (isMarkedInternal(item) || hasTinyestMetadata(item)) {
468
+ if (this._itemStateStack.itemDepth === 0) try {
469
+ this.pushMode(new CodegenState());
470
+ const result = provideCtx(this, () => this._getOrInstantiate(item));
471
+ return snip(`${[...this._declarations].join("\n\n")}${result.value}`, Void, "runtime");
472
+ } finally {
473
+ this.popMode("codegen");
474
+ }
475
+ return this._getOrInstantiate(item);
476
+ }
477
+ if (typeof item === "number") {
478
+ const realSchema = schema ?? numericLiteralToSnippet(item).dataType;
479
+ invariant(realSchema !== UnknownData, "Schema has to be known for resolving numbers");
480
+ if (realSchema.type === "abstractInt") return snip(`${item}`, realSchema, "constant");
481
+ if (realSchema.type === "u32") return snip(`${item}u`, realSchema, "constant");
482
+ if (realSchema.type === "i32") return snip(`${item}i`, realSchema, "constant");
483
+ const exp = item.toExponential();
484
+ const decimal = realSchema.type === "abstractFloat" && Number.isInteger(item) ? `${item}.` : `${item}`;
485
+ const base = exp.length < decimal.length ? exp : decimal;
486
+ if (realSchema.type === "f32") return snip(`${base}f`, realSchema, "constant");
487
+ if (realSchema.type === "f16") return snip(`${base}h`, realSchema, "constant");
488
+ return snip(base, realSchema, "constant");
489
+ }
490
+ if (typeof item === "boolean") return snip(item ? "true" : "false", bool, "constant");
491
+ if (typeof item === "string") return snip(item, Void, "runtime");
492
+ if (schema && isWgslArray(schema)) {
493
+ if (!Array.isArray(item)) throw new WgslTypeError(`Cannot coerce ${item} into value of type '${schema}'`);
494
+ if (schema.elementCount !== item.length) throw new WgslTypeError(`Cannot create value of type '${schema}' from an array of length: ${item.length}`);
495
+ return snip(stitch`array<${this.resolve(schema.elementType)}, ${schema.elementCount}>(${item.map((element) => snip(element, schema.elementType, "runtime"))})`, schema, "runtime");
496
+ }
497
+ if (Array.isArray(item)) return snip(stitch`array(${item.map((element) => this.resolve(element))})`, UnknownData, "runtime");
498
+ if (schema && isWgslStruct(schema)) return snip(stitch`${this.resolve(schema)}(${Object.entries(schema.propTypes).map(([key, propType]) => snip(item[key], propType, "runtime"))})`, schema, "runtime");
499
+ throw new WgslTypeError(`Value ${item} (as json: ${safeStringify(item)}) is not resolvable${schema ? ` to type ${safeStringify(schema)}` : ""}`);
500
+ }
501
+ pushMode(mode) {
502
+ this.#modeStack.push(mode);
503
+ }
504
+ popMode(expected) {
505
+ const mode = this.#modeStack.pop();
506
+ if (expected !== void 0) invariant(mode?.type === expected, "Unexpected mode");
507
+ }
508
+ get mode() {
509
+ return this.#modeStack[this.#modeStack.length - 1] ?? topLevelState;
510
+ }
511
+ };
512
+ function resolve(item, options) {
513
+ const ctx = new ResolutionCtxImpl(options);
514
+ let code = (options.config ? ctx.withSlots(options.config(new ConfigurableImpl([])).bindings, () => ctx.resolve(item)) : ctx.resolve(item)).value;
515
+ const memoMap = ctx.bindGroupLayoutsToPlaceholderMap;
516
+ const usedBindGroupLayouts = [];
517
+ const automaticIds = naturalsExcept(new Set([...memoMap.keys()].map((layout) => layout.index).filter((v) => v !== void 0)));
518
+ const layoutEntries = ctx.fixedBindings.map((binding, idx) => [String(idx), binding.layoutEntry]);
519
+ const createCatchallGroup = () => {
520
+ const catchallIdx = automaticIds.next().value;
521
+ const catchallLayout = bindGroupLayout(Object.fromEntries(layoutEntries));
522
+ usedBindGroupLayouts[catchallIdx] = catchallLayout;
523
+ code = code.replaceAll(CATCHALL_BIND_GROUP_IDX_MARKER, String(catchallIdx));
524
+ return [catchallIdx, new TgpuBindGroupImpl(catchallLayout, Object.fromEntries(ctx.fixedBindings.map((binding, idx) => [String(idx), binding.resource])))];
525
+ };
526
+ const catchall = layoutEntries.length > 0 ? createCatchallGroup() : void 0;
527
+ for (const [layout, placeholder] of memoMap.entries()) {
528
+ const idx = layout.index ?? automaticIds.next().value;
529
+ usedBindGroupLayouts[idx] = layout;
530
+ code = code.replaceAll(placeholder, String(idx));
531
+ }
532
+ if (options.enableExtensions && options.enableExtensions.length > 0) code = `${options.enableExtensions.map((ext) => `enable ${ext};`).join("\n")}\n\n${code}`;
533
+ return {
534
+ code,
535
+ usedBindGroupLayouts,
536
+ catchall,
537
+ logResources: ctx.logResources
538
+ };
539
+ }
540
+ function resolveFunctionHeader(ctx, args, returnType) {
541
+ const argList = args.map((arg) => `${arg.value}: ${ctx.resolve(arg.dataType).value}`).join(", ");
542
+ return returnType.type !== "void" ? `(${argList}) -> ${getAttributesString(returnType)}${ctx.resolve(returnType).value} ` : `(${argList}) `;
543
+ }
544
+
545
+ //#endregion
546
+ export { ResolutionCtxImpl, resolve };
package/shared/env.js ADDED
@@ -0,0 +1,13 @@
1
+ //#region src/shared/env.ts
2
+ /**
3
+ * This can be used to branch functionality between "dev" and "prod" modes, so that our
4
+ * library can omit doing unnecessary work once it's out in the wild
5
+ *
6
+ * Even though the value of this constant uses Node.js specific APIs, pretty much every
7
+ * bundler replaces the expression below with either `development` or `production`
8
+ */
9
+ const DEV = process.env.NODE_ENV === "development";
10
+ const TEST = process.env.NODE_ENV === "test";
11
+
12
+ //#endregion
13
+ export { DEV, TEST };
@@ -0,0 +1,14 @@
1
+ //#region src/shared/generators.ts
2
+ /**
3
+ * Yields values in the sequence 0,1,2..∞ except for the ones in the `excluded` set.
4
+ */
5
+ function* naturalsExcept(excluded) {
6
+ let next = 0;
7
+ while (true) {
8
+ if (!excluded.has(next)) yield next;
9
+ next++;
10
+ }
11
+ }
12
+
13
+ //#endregion
14
+ export { naturalsExcept };
@@ -0,0 +1,39 @@
1
+ import { Block, FuncParameter } from "tinyest";
2
+
3
+ //#region src/shared/meta.d.ts
4
+ interface MetaData {
5
+ v?: number;
6
+ name?: string | undefined;
7
+ ast?: {
8
+ params: FuncParameter[];
9
+ body: Block;
10
+ externalNames: string[];
11
+ } | undefined;
12
+ externals?: Record<string, unknown> | (() => Record<string, unknown>) | undefined;
13
+ }
14
+ /**
15
+ * Don't use or you WILL get fired from your job.
16
+ *
17
+ * The information that this type describes is additional
18
+ * properties that we add onto `globalThis`, used by tools
19
+ * like `unplugin-typegpu` or our test suite.
20
+ *
21
+ * @internal
22
+ */
23
+ type INTERNAL_GlobalExt = typeof globalThis & {
24
+ __TYPEGPU_VERSION__: string | undefined;
25
+ __TYPEGPU_META__: WeakMap<object, MetaData>;
26
+ __TYPEGPU_AUTONAME__: <T>(exp: T, label: string) => T;
27
+ __TYPEGPU_MEASURE_PERF__?: boolean | undefined;
28
+ __TYPEGPU_PERF_RECORDS__?: Map<string, unknown[]> | undefined;
29
+ };
30
+ /**
31
+ * Can be assigned a name. Not to be confused with just having a name.
32
+ * The `$name` function should use `setName` to rename the object itself,
33
+ * even if `$getNameForward` symbol is present.
34
+ */
35
+ interface TgpuNamable {
36
+ $name(label: string): this;
37
+ }
38
+ //#endregion
39
+ export { INTERNAL_GlobalExt, TgpuNamable };
package/shared/meta.js ADDED
@@ -0,0 +1,63 @@
1
+ import { version } from "../package.js";
2
+ import { DEV, TEST } from "./env.js";
3
+ import { $getNameForward, isMarkedInternal } from "./symbols.js";
4
+
5
+ //#region src/shared/meta.ts
6
+ const globalWithMeta = globalThis;
7
+ if (globalWithMeta.__TYPEGPU_VERSION__ !== void 0) console.warn(`Found duplicate TypeGPU version. First was ${globalWithMeta.__TYPEGPU_VERSION__}, this one is ${version}. This may cause unexpected behavior.`);
8
+ globalWithMeta.__TYPEGPU_VERSION__ = version;
9
+ globalWithMeta.__TYPEGPU_AUTONAME__ = (exp, label) => isNamable(exp) && isMarkedInternal(exp) && !getName(exp) ? exp.$name(label) : exp;
10
+ /**
11
+ * Performance measurements are only enabled in dev & test environments for now
12
+ */
13
+ const PERF = (DEV || TEST) && {
14
+ get enabled() {
15
+ return !!globalWithMeta.__TYPEGPU_MEASURE_PERF__;
16
+ },
17
+ record(name, data) {
18
+ const records = globalWithMeta.__TYPEGPU_PERF_RECORDS__ ??= /* @__PURE__ */ new Map();
19
+ let entries = records.get(name);
20
+ if (!entries) {
21
+ entries = [];
22
+ records.set(name, entries);
23
+ }
24
+ entries.push(data);
25
+ }
26
+ } || void 0;
27
+ function isForwarded(value) {
28
+ return !!value?.[$getNameForward];
29
+ }
30
+ function getName(definition) {
31
+ if (isForwarded(definition)) return getName(definition[$getNameForward]);
32
+ return getMetaData(definition)?.name;
33
+ }
34
+ function setName(definition, name) {
35
+ if (isForwarded(definition)) {
36
+ setName(definition[$getNameForward], name);
37
+ return;
38
+ }
39
+ setMetaData(definition, { name });
40
+ }
41
+ function isNamable(value) {
42
+ return !!value?.$name;
43
+ }
44
+ /**
45
+ * AST's are given to functions with a 'use gpu' directive, which this function checks for.
46
+ */
47
+ function hasTinyestMetadata(value) {
48
+ return !!getMetaData(value)?.ast;
49
+ }
50
+ function getMetaData(definition) {
51
+ return globalWithMeta.__TYPEGPU_META__.get(definition);
52
+ }
53
+ function setMetaData(definition, metaData) {
54
+ globalWithMeta.__TYPEGPU_META__ ??= /* @__PURE__ */ new WeakMap();
55
+ const map = globalWithMeta.__TYPEGPU_META__;
56
+ map.set(definition, {
57
+ ...map.get(definition),
58
+ ...metaData
59
+ });
60
+ }
61
+
62
+ //#endregion
63
+ export { PERF, getMetaData, getName, hasTinyestMetadata, isNamable, setName };