typegpu 0.10.1 → 0.11.0-rc.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 (273) hide show
  1. package/_virtual/_rolldown/runtime.js +13 -0
  2. package/builtin.d.ts +50 -0
  3. package/builtin.js +35 -0
  4. package/common/fullScreenTriangle.d.ts +22 -0
  5. package/common/fullScreenTriangle.js +34 -0
  6. package/common/index.d.ts +4 -4
  7. package/common/index.js +8 -7
  8. package/common/writeSoA.d.ts +16 -0
  9. package/common/writeSoA.js +90 -0
  10. package/core/buffer/buffer.d.ts +79 -0
  11. package/core/buffer/buffer.js +246 -0
  12. package/core/buffer/bufferShorthand.d.ts +48 -0
  13. package/core/buffer/bufferShorthand.js +53 -0
  14. package/core/buffer/bufferUsage.d.ts +43 -0
  15. package/core/buffer/bufferUsage.js +165 -0
  16. package/core/constant/tgpuConstant.d.ts +29 -0
  17. package/core/constant/tgpuConstant.js +68 -0
  18. package/core/declare/tgpuDeclare.d.ts +18 -0
  19. package/core/declare/tgpuDeclare.js +39 -0
  20. package/core/function/autoIO.d.ts +38 -0
  21. package/core/function/autoIO.js +85 -0
  22. package/core/function/comptime.d.ts +39 -0
  23. package/core/function/comptime.js +49 -0
  24. package/core/function/createCallableSchema.js +40 -0
  25. package/core/function/dualImpl.js +52 -0
  26. package/core/function/entryInputRouter.js +39 -0
  27. package/core/function/extractArgs.js +204 -0
  28. package/core/function/fnCore.js +90 -0
  29. package/core/function/fnTypes.d.ts +40 -0
  30. package/core/function/ioSchema.d.ts +10 -0
  31. package/core/function/ioSchema.js +51 -0
  32. package/core/function/shelllessImpl.d.ts +28 -0
  33. package/core/function/shelllessImpl.js +21 -0
  34. package/core/function/templateUtils.js +12 -0
  35. package/core/function/tgpuComputeFn.d.ts +48 -0
  36. package/core/function/tgpuComputeFn.js +55 -0
  37. package/core/function/tgpuFn.d.ts +52 -0
  38. package/core/function/tgpuFn.js +168 -0
  39. package/core/function/tgpuFragmentFn.d.ts +72 -0
  40. package/core/function/tgpuFragmentFn.js +63 -0
  41. package/core/function/tgpuVertexFn.d.ts +59 -0
  42. package/core/function/tgpuVertexFn.js +59 -0
  43. package/core/pipeline/applyPipelineState.js +35 -0
  44. package/core/pipeline/computePipeline.d.ts +54 -0
  45. package/core/pipeline/computePipeline.js +227 -0
  46. package/core/pipeline/connectAttachmentToShader.js +24 -0
  47. package/core/pipeline/connectTargetsToShader.js +27 -0
  48. package/core/pipeline/limitsOverflow.js +12 -0
  49. package/core/pipeline/pipelineUtils.js +29 -0
  50. package/core/pipeline/renderPipeline.d.ts +284 -0
  51. package/core/pipeline/renderPipeline.js +489 -0
  52. package/core/pipeline/timeable.d.ts +20 -0
  53. package/core/pipeline/timeable.js +55 -0
  54. package/core/pipeline/typeGuards.js +27 -0
  55. package/core/querySet/querySet.d.ts +20 -0
  56. package/core/querySet/querySet.js +104 -0
  57. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
  58. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +94 -0
  59. package/core/resolve/externals.d.ts +8 -0
  60. package/core/resolve/externals.js +56 -0
  61. package/core/resolve/namespace.d.ts +38 -0
  62. package/core/resolve/namespace.js +39 -0
  63. package/core/resolve/resolveData.js +144 -0
  64. package/core/resolve/stitch.js +23 -0
  65. package/core/resolve/tgpuResolve.d.ts +153 -0
  66. package/core/resolve/tgpuResolve.js +66 -0
  67. package/core/root/configurableImpl.js +17 -0
  68. package/core/root/init.d.ts +64 -0
  69. package/core/root/init.js +464 -0
  70. package/core/root/rootTypes.d.ts +642 -0
  71. package/core/sampler/sampler.d.ts +31 -0
  72. package/core/sampler/sampler.js +116 -0
  73. package/core/simulate/tgpuSimulate.d.ts +36 -0
  74. package/core/simulate/tgpuSimulate.js +74 -0
  75. package/core/slot/accessor.d.ts +9 -0
  76. package/core/slot/accessor.js +95 -0
  77. package/core/slot/internalSlots.js +5 -0
  78. package/core/slot/lazy.d.ts +6 -0
  79. package/core/slot/lazy.js +40 -0
  80. package/core/slot/slot.d.ts +6 -0
  81. package/core/slot/slot.js +39 -0
  82. package/core/slot/slotTypes.d.ts +92 -0
  83. package/core/slot/slotTypes.js +19 -0
  84. package/core/texture/externalTexture.d.ts +6 -0
  85. package/core/texture/externalTexture.js +47 -0
  86. package/core/texture/texture.d.ts +114 -0
  87. package/core/texture/texture.js +314 -0
  88. package/core/texture/textureFormats.d.ts +29 -0
  89. package/core/texture/textureFormats.js +97 -0
  90. package/core/texture/textureProps.d.ts +11 -0
  91. package/core/texture/textureUtils.js +222 -0
  92. package/core/texture/usageExtension.d.ts +21 -0
  93. package/core/texture/usageExtension.js +19 -0
  94. package/core/unroll/tgpuUnroll.d.ts +68 -0
  95. package/core/unroll/tgpuUnroll.js +94 -0
  96. package/core/valueProxyUtils.js +42 -0
  97. package/core/variable/tgpuVariable.d.ts +38 -0
  98. package/core/variable/tgpuVariable.js +99 -0
  99. package/core/vertexLayout/connectAttributesToShader.js +57 -0
  100. package/core/vertexLayout/vertexAttribute.d.ts +29 -0
  101. package/core/vertexLayout/vertexLayout.d.ts +19 -0
  102. package/core/vertexLayout/vertexLayout.js +103 -0
  103. package/data/alignIO.js +14 -0
  104. package/data/alignmentOf.d.ts +9 -0
  105. package/data/alignmentOf.js +86 -0
  106. package/data/array.d.ts +26 -0
  107. package/data/array.js +46 -0
  108. package/data/atomic.d.ts +15 -0
  109. package/data/atomic.js +24 -0
  110. package/data/attributes.d.ts +121 -0
  111. package/data/attributes.js +145 -0
  112. package/data/autoStruct.d.ts +1 -0
  113. package/data/autoStruct.js +81 -0
  114. package/data/compiledIO.js +228 -0
  115. package/data/dataIO.js +556 -0
  116. package/data/dataTypes.d.ts +115 -0
  117. package/data/dataTypes.js +100 -0
  118. package/data/deepEqual.d.ts +25 -0
  119. package/data/deepEqual.js +56 -0
  120. package/data/disarray.d.ts +32 -0
  121. package/data/disarray.js +50 -0
  122. package/data/getLongestContiguousPrefix.d.ts +9 -0
  123. package/data/getLongestContiguousPrefix.js +13 -0
  124. package/data/index.d.ts +26 -4
  125. package/data/index.js +36 -9
  126. package/data/instanceToSchema.d.ts +33 -0
  127. package/data/isContiguous.d.ts +9 -0
  128. package/data/isContiguous.js +13 -0
  129. package/data/matrix.d.ts +124 -0
  130. package/data/matrix.js +531 -0
  131. package/data/numberOps.js +23 -0
  132. package/data/numeric.d.ts +81 -0
  133. package/data/numeric.js +221 -0
  134. package/data/offsetUtils.d.ts +33 -0
  135. package/data/offsetUtils.js +165 -0
  136. package/data/offsets.js +34 -0
  137. package/data/partialIO.js +113 -0
  138. package/data/ptr.d.ts +11 -0
  139. package/data/ptr.js +44 -0
  140. package/data/ref.d.ts +34 -0
  141. package/data/ref.js +94 -0
  142. package/data/sampler.d.ts +107 -0
  143. package/data/sampler.js +24 -0
  144. package/data/schemaCallWrapper.js +30 -0
  145. package/data/schemaMemoryLayout.js +198 -0
  146. package/data/sizeOf.d.ts +9 -0
  147. package/data/sizeOf.js +13 -0
  148. package/data/snippet.d.ts +26 -0
  149. package/data/snippet.js +70 -0
  150. package/data/struct.d.ts +17 -0
  151. package/data/struct.js +44 -0
  152. package/data/texture.d.ts +292 -0
  153. package/{texture-BagDrrks.js → data/texture.js} +6 -5
  154. package/data/unstruct.d.ts +24 -0
  155. package/data/unstruct.js +41 -0
  156. package/data/vector.d.ts +191 -0
  157. package/data/vector.js +239 -0
  158. package/data/vectorImpl.js +515 -0
  159. package/data/vectorOps.js +681 -0
  160. package/data/vertexFormatData.d.ts +190 -0
  161. package/data/vertexFormatData.js +109 -0
  162. package/data/wgslTypes.d.ts +924 -0
  163. package/data/wgslTypes.js +222 -0
  164. package/errors.d.ts +44 -0
  165. package/errors.js +131 -0
  166. package/execMode.js +49 -0
  167. package/extension.d.ts +11 -0
  168. package/extension.js +16 -0
  169. package/getGPUValue.js +7 -0
  170. package/index.d.ts +42 -243
  171. package/index.js +21 -6320
  172. package/indexNamedExports.d.ts +40 -0
  173. package/mathUtils.js +12 -0
  174. package/memo.js +22 -0
  175. package/nameRegistry.d.ts +30 -0
  176. package/nameRegistry.js +447 -0
  177. package/package.js +4 -0
  178. package/package.json +26 -26
  179. package/resolutionCtx.d.ts +19 -0
  180. package/resolutionCtx.js +612 -0
  181. package/shared/env.js +12 -0
  182. package/shared/generators.js +13 -0
  183. package/shared/meta.d.ts +39 -0
  184. package/shared/meta.js +61 -0
  185. package/shared/repr.d.ts +138 -0
  186. package/shared/stringify.js +20 -0
  187. package/shared/symbols.d.ts +70 -0
  188. package/shared/symbols.js +48 -0
  189. package/shared/utilityTypes.d.ts +33 -0
  190. package/shared/utilityTypes.js +6 -0
  191. package/shared/vertexFormat.d.ts +70 -0
  192. package/shared/vertexFormat.js +63 -0
  193. package/std/array.d.ts +7 -0
  194. package/std/array.js +25 -0
  195. package/std/atomic.d.ts +19 -0
  196. package/std/atomic.js +111 -0
  197. package/std/bitcast.d.ts +10 -0
  198. package/std/bitcast.js +41 -0
  199. package/std/boolean.d.ts +141 -0
  200. package/std/boolean.js +299 -0
  201. package/std/derivative.d.ts +16 -0
  202. package/std/derivative.js +87 -0
  203. package/std/discard.d.ts +6 -0
  204. package/std/discard.js +14 -0
  205. package/std/extensions.d.ts +6 -0
  206. package/std/extensions.js +12 -0
  207. package/std/index.d.ts +17 -4
  208. package/std/index.js +21 -7
  209. package/std/matrix.d.ts +41 -0
  210. package/std/matrix.js +85 -0
  211. package/std/numeric.d.ts +200 -0
  212. package/std/numeric.js +845 -0
  213. package/std/operators.d.ts +56 -0
  214. package/std/operators.js +227 -0
  215. package/std/packing.d.ts +26 -0
  216. package/std/packing.js +84 -0
  217. package/std/range.d.ts +24 -0
  218. package/std/range.js +38 -0
  219. package/std/subgroup.d.ts +47 -0
  220. package/std/subgroup.js +218 -0
  221. package/std/texture.d.ts +117 -0
  222. package/std/texture.js +207 -0
  223. package/tgpu.js +42 -0
  224. package/tgpuBindGroupLayout.d.ts +161 -0
  225. package/tgpuBindGroupLayout.js +272 -0
  226. package/tgpuUnstable.d.ts +48 -0
  227. package/tgpuUnstable.js +64 -0
  228. package/tgsl/accessIndex.js +43 -0
  229. package/tgsl/accessProp.js +115 -0
  230. package/tgsl/consoleLog/deserializers.js +115 -0
  231. package/tgsl/consoleLog/logGenerator.js +84 -0
  232. package/tgsl/consoleLog/serializers.js +223 -0
  233. package/tgsl/consoleLog/types.d.ts +52 -0
  234. package/tgsl/consoleLog/types.js +11 -0
  235. package/tgsl/conversion.js +198 -0
  236. package/tgsl/forOfUtils.js +71 -0
  237. package/tgsl/generationHelpers.d.ts +37 -0
  238. package/tgsl/generationHelpers.js +67 -0
  239. package/tgsl/math.js +43 -0
  240. package/tgsl/shaderGenerator.d.ts +20 -0
  241. package/tgsl/shaderGenerator_members.d.ts +2 -0
  242. package/tgsl/shaderGenerator_members.js +6 -0
  243. package/tgsl/shellless.d.ts +11 -0
  244. package/tgsl/shellless.js +46 -0
  245. package/tgsl/wgslGenerator.d.ts +36 -0
  246. package/tgsl/wgslGenerator.js +639 -0
  247. package/types.d.ts +265 -0
  248. package/types.js +43 -0
  249. package/unwrapper.d.ts +27 -0
  250. package/wgslExtensions.d.ts +5 -0
  251. package/wgslExtensions.js +17 -0
  252. package/builtin-DdtWpk2t.js +0 -818
  253. package/builtin-DdtWpk2t.js.map +0 -1
  254. package/chunk-BYypO7fO.js +0 -18
  255. package/common/index.d.ts.map +0 -1
  256. package/common/index.js.map +0 -1
  257. package/data/index.d.ts.map +0 -1
  258. package/data/index.js.map +0 -1
  259. package/deepEqual-DQxK4vdp.js +0 -413
  260. package/deepEqual-DQxK4vdp.js.map +0 -1
  261. package/extensions-DIVuAfBM.js +0 -2032
  262. package/extensions-DIVuAfBM.js.map +0 -1
  263. package/fullScreenTriangle-CfFyQd_0.js +0 -543
  264. package/fullScreenTriangle-CfFyQd_0.js.map +0 -1
  265. package/index.d.ts.map +0 -1
  266. package/index.js.map +0 -1
  267. package/indexNamedExports-oL6tyaJ9.d.ts +0 -5697
  268. package/indexNamedExports-oL6tyaJ9.d.ts.map +0 -1
  269. package/operators-d-PMVTo7.js +0 -4158
  270. package/operators-d-PMVTo7.js.map +0 -1
  271. package/std/index.d.ts.map +0 -1
  272. package/std/index.js.map +0 -1
  273. package/texture-BagDrrks.js.map +0 -1
@@ -0,0 +1,612 @@
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, undecorate } 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 { coerceToSnippet, concretize, numericLiteralToSnippet } from "./tgsl/generationHelpers.js";
15
+ import { getAttributesString } from "./data/attributes.js";
16
+ import { createIoSchema } from "./core/function/ioSchema.js";
17
+ import { AutoStruct } from "./data/autoStruct.js";
18
+ import { EntryInputRouter } from "./core/function/entryInputRouter.js";
19
+ import { accessProp } from "./tgsl/accessProp.js";
20
+ import { isTgpuFn } from "./core/function/tgpuFn.js";
21
+ import { getUniqueName } from "./core/resolve/namespace.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
+ //#region src/resolutionCtx.ts
29
+ /**
30
+ * Inserted into bind group entry definitions that belong
31
+ * to the automatically generated catch-all bind group.
32
+ *
33
+ * A non-occupied group index can only be determined after
34
+ * every resource has been resolved, so this acts as a placeholder
35
+ * to be replaced with an actual numeric index at the very end
36
+ * of the resolution process.
37
+ */
38
+ const CATCHALL_BIND_GROUP_IDX_MARKER = "#CATCHALL#";
39
+ var ItemStateStackImpl = class {
40
+ _stack = [];
41
+ _itemDepth = 0;
42
+ get itemDepth() {
43
+ return this._itemDepth;
44
+ }
45
+ get topItem() {
46
+ const state = this._stack[this._stack.length - 1];
47
+ if (!state || state.type !== "item") throw new Error("Internal error, expected item layer to be on top.");
48
+ return state;
49
+ }
50
+ get topFunctionScope() {
51
+ return this._stack.findLast((e) => e.type === "functionScope");
52
+ }
53
+ pushItem() {
54
+ this._itemDepth++;
55
+ this._stack.push({
56
+ type: "item",
57
+ usedSlots: /* @__PURE__ */ new Set()
58
+ });
59
+ }
60
+ pushSlotBindings(pairs) {
61
+ this._stack.push({
62
+ type: "slotBinding",
63
+ bindingMap: new WeakMap(pairs)
64
+ });
65
+ }
66
+ pushFunctionScope(functionType, args, argAliases, returnType, externalMap) {
67
+ const scope = {
68
+ type: "functionScope",
69
+ functionType,
70
+ args,
71
+ argAliases,
72
+ returnType,
73
+ externalMap,
74
+ reportedReturnTypes: /* @__PURE__ */ new Set()
75
+ };
76
+ this._stack.push(scope);
77
+ return scope;
78
+ }
79
+ pushBlockScope() {
80
+ this._stack.push({
81
+ type: "blockScope",
82
+ declarations: /* @__PURE__ */ new Map(),
83
+ externals: /* @__PURE__ */ new Map()
84
+ });
85
+ }
86
+ pop(type) {
87
+ const layer = this._stack[this._stack.length - 1];
88
+ if (!layer || type && layer.type !== type) throw new Error(`Internal error, expected a ${type} layer to be on top.`);
89
+ const poppedValue = this._stack.pop();
90
+ if (type === "item") this._itemDepth--;
91
+ return poppedValue;
92
+ }
93
+ readSlot(slot) {
94
+ for (let i = this._stack.length - 1; i >= 0; --i) {
95
+ const layer = this._stack[i];
96
+ if (layer?.type === "item") layer.usedSlots.add(slot);
97
+ else if (layer?.type === "slotBinding") {
98
+ const boundValue = layer.bindingMap.get(slot);
99
+ if (boundValue !== void 0) return boundValue;
100
+ } else if (layer?.type === "functionScope" || layer?.type === "blockScope") {} else throw new Error("Unknown layer type.");
101
+ }
102
+ return slot.defaultValue;
103
+ }
104
+ getSnippetById(id) {
105
+ for (let i = this._stack.length - 1; i >= 0; --i) {
106
+ const layer = this._stack[i];
107
+ if (layer?.type === "functionScope") {
108
+ const arg = layer.args.find((a) => a.value === id);
109
+ if (arg !== void 0) return arg;
110
+ if (layer.argAliases[id]) return layer.argAliases[id];
111
+ const external = layer.externalMap[id];
112
+ if (external !== void 0 && external !== null) return coerceToSnippet(external);
113
+ return;
114
+ }
115
+ if (layer?.type === "blockScope") {
116
+ const snippet = layer.declarations.get(id) ?? layer.externals.get(id);
117
+ if (snippet !== void 0) return snippet;
118
+ }
119
+ }
120
+ }
121
+ defineBlockVariable(id, snippet) {
122
+ if (snippet.dataType === UnknownData) throw Error(`Tried to define variable '${id}' of unknown type`);
123
+ for (let i = this._stack.length - 1; i >= 0; --i) {
124
+ const layer = this._stack[i];
125
+ if (layer?.type === "blockScope") {
126
+ layer.declarations.set(id, snippet);
127
+ return;
128
+ }
129
+ }
130
+ throw new Error("No block scope found to define a variable in.");
131
+ }
132
+ setBlockExternals(externals) {
133
+ for (let i = this._stack.length - 1; i >= 0; --i) {
134
+ const layer = this._stack[i];
135
+ if (layer?.type === "blockScope") {
136
+ Object.entries(externals).forEach(([id, snippet]) => {
137
+ layer.externals.set(id, snippet);
138
+ });
139
+ return;
140
+ }
141
+ }
142
+ throw new Error("No block scope found to set externals in.");
143
+ }
144
+ clearBlockExternals() {
145
+ for (let i = this._stack.length - 1; i >= 0; --i) {
146
+ const layer = this._stack[i];
147
+ if (layer?.type === "blockScope") {
148
+ layer.externals.clear();
149
+ return;
150
+ }
151
+ }
152
+ throw new Error("No block scope found to clear externals in.");
153
+ }
154
+ };
155
+ const INDENT = [
156
+ "",
157
+ " ",
158
+ " ",
159
+ " ",
160
+ " ",
161
+ " ",
162
+ " ",
163
+ " ",
164
+ " "
165
+ ];
166
+ const N = INDENT.length - 1;
167
+ var IndentController = class {
168
+ identLevel = 0;
169
+ get pre() {
170
+ return INDENT[this.identLevel] ?? INDENT[N].repeat(this.identLevel / N) + INDENT[this.identLevel % N];
171
+ }
172
+ indent() {
173
+ const str = this.pre;
174
+ this.identLevel++;
175
+ return str;
176
+ }
177
+ dedent() {
178
+ this.identLevel--;
179
+ return this.pre;
180
+ }
181
+ withResetLevel(callback) {
182
+ const savedLevel = this.identLevel;
183
+ this.identLevel = 0;
184
+ try {
185
+ return callback();
186
+ } finally {
187
+ this.identLevel = savedLevel;
188
+ }
189
+ }
190
+ };
191
+ var ResolutionCtxImpl = class {
192
+ #namespaceInternal;
193
+ _indentController = new IndentController();
194
+ _itemStateStack = new ItemStateStackImpl();
195
+ #modeStack = [];
196
+ _declarations = [];
197
+ _varyingLocations;
198
+ #currentlyResolvedItems = /* @__PURE__ */ new WeakSet();
199
+ #logGenerator;
200
+ gen;
201
+ get varyingLocations() {
202
+ return this._varyingLocations;
203
+ }
204
+ [$internal] = { itemStateStack: this._itemStateStack };
205
+ /**
206
+ * A map from registered bind group layouts to random strings put in
207
+ * place of their group index. The whole tree has to be traversed to
208
+ * collect every use of a typed bind group layout, since they can be
209
+ * explicitly imposed group indices, and they cannot collide.
210
+ */
211
+ bindGroupLayoutsToPlaceholderMap = /* @__PURE__ */ new Map();
212
+ _nextFreeLayoutPlaceholderIdx = 0;
213
+ fixedBindings = [];
214
+ enableExtensions;
215
+ expectedType;
216
+ constructor(opts) {
217
+ this.enableExtensions = opts.enableExtensions;
218
+ this.gen = opts.shaderGenerator ?? wgslGenerator;
219
+ this.#logGenerator = opts.root ? new LogGeneratorImpl(opts.root) : new LogGeneratorNullImpl();
220
+ this.#namespaceInternal = opts.namespace[$internal];
221
+ }
222
+ getUniqueName(resource) {
223
+ return getUniqueName(this.#namespaceInternal, resource);
224
+ }
225
+ makeNameValid(name) {
226
+ return this.#namespaceInternal.nameRegistry.makeValid(name);
227
+ }
228
+ get pre() {
229
+ return this._indentController.pre;
230
+ }
231
+ get topFunctionScope() {
232
+ return this._itemStateStack.topFunctionScope;
233
+ }
234
+ get topFunctionReturnType() {
235
+ const scope = this._itemStateStack.topFunctionScope;
236
+ invariant(scope, "Internal error, expected function scope to be present.");
237
+ return scope.returnType;
238
+ }
239
+ get shelllessRepo() {
240
+ return this.#namespaceInternal.shelllessRepo;
241
+ }
242
+ indent() {
243
+ return this._indentController.indent();
244
+ }
245
+ dedent() {
246
+ return this._indentController.dedent();
247
+ }
248
+ withResetIndentLevel(callback) {
249
+ return this._indentController.withResetLevel(callback);
250
+ }
251
+ getById(id) {
252
+ const item = this._itemStateStack.getSnippetById(id);
253
+ if (item === void 0) return null;
254
+ return item;
255
+ }
256
+ defineVariable(id, snippet) {
257
+ this._itemStateStack.defineBlockVariable(id, snippet);
258
+ }
259
+ reportReturnType(dataType) {
260
+ const scope = this._itemStateStack.topFunctionScope;
261
+ invariant(scope, "Internal error, expected function scope to be present.");
262
+ scope.reportedReturnTypes.add(dataType);
263
+ }
264
+ pushBlockScope() {
265
+ this.#namespaceInternal.nameRegistry.pushBlockScope();
266
+ this._itemStateStack.pushBlockScope();
267
+ }
268
+ popBlockScope() {
269
+ this.#namespaceInternal.nameRegistry.popBlockScope();
270
+ this._itemStateStack.pop("blockScope");
271
+ }
272
+ setBlockExternals(externals) {
273
+ this._itemStateStack.setBlockExternals(externals);
274
+ }
275
+ clearBlockExternals() {
276
+ this._itemStateStack.clearBlockExternals();
277
+ }
278
+ generateLog(op, args) {
279
+ return this.#logGenerator.generateLog(this, op, args);
280
+ }
281
+ get logResources() {
282
+ return this.#logGenerator.logResources;
283
+ }
284
+ fnToWgsl(options) {
285
+ let fnScopePushed = false;
286
+ try {
287
+ this.#namespaceInternal.nameRegistry.pushFunctionScope();
288
+ const args = [];
289
+ const argAliases = [];
290
+ const pendingHeaderEntries = [];
291
+ if (options.entryInput) {
292
+ const { dataSchema, positionalArgs } = options.entryInput;
293
+ const firstParam = options.params[0];
294
+ const structArgName = this.makeNameValid("_arg_0");
295
+ const structArg = dataSchema ? snip(structArgName, dataSchema, "argument") : void 0;
296
+ if (structArg) {
297
+ args.push(structArg);
298
+ pendingHeaderEntries.push({
299
+ argName: structArgName,
300
+ header: `${structArgName}: ${this.resolve(dataSchema).value}`
301
+ });
302
+ }
303
+ if (firstParam?.type === FuncParameterType.destructuredObject) for (const { name, alias } of firstParam.props) {
304
+ const argInfo = positionalArgs.find((a) => a.schemaKey === name);
305
+ if (argInfo) {
306
+ const argName = this.makeNameValid(alias);
307
+ const argSnippet = snip(argName, argInfo.type, "argument");
308
+ args.push(argSnippet);
309
+ argAliases.push([alias, argSnippet]);
310
+ pendingHeaderEntries.push({
311
+ argName,
312
+ header: `${getAttributesString(argInfo.type)}${argName}: ${this.resolve(undecorate(argInfo.type)).value}`
313
+ });
314
+ } else if (structArg) {
315
+ const propSnippet = accessProp(structArg, name);
316
+ if (propSnippet) argAliases.push([alias, propSnippet]);
317
+ }
318
+ }
319
+ else if (firstParam?.type === FuncParameterType.identifier) {
320
+ const proxyEntries = [];
321
+ for (const a of positionalArgs) {
322
+ const argName = this.makeNameValid(`_arg_${a.schemaKey}`);
323
+ const s = snip(argName, a.type, "argument");
324
+ args.push(s);
325
+ proxyEntries.push({
326
+ schemaKey: a.schemaKey,
327
+ argName,
328
+ type: a.type
329
+ });
330
+ pendingHeaderEntries.push({
331
+ argName,
332
+ header: `${getAttributesString(a.type)}${argName}: ${this.resolve(undecorate(a.type)).value}`
333
+ });
334
+ }
335
+ const router = new EntryInputRouter(structArgName, dataSchema, proxyEntries);
336
+ argAliases.push([firstParam.name, snip(firstParam.name, router, "argument")]);
337
+ } else for (const a of positionalArgs) {
338
+ const argName = this.makeNameValid(`_arg_${a.schemaKey}`);
339
+ args.push(snip(argName, a.type, "argument"));
340
+ pendingHeaderEntries.push({
341
+ argName,
342
+ header: `${getAttributesString(a.type)}${argName}: ${this.resolve(undecorate(a.type)).value}`
343
+ });
344
+ }
345
+ } else for (const [i, argType] of options.argTypes.entries()) {
346
+ const astParam = options.params[i];
347
+ const origin = isPtr(argType) ? argType.addressSpace === "storage" ? argType.access === "read" ? "readonly" : "mutable" : argType.addressSpace : "argument";
348
+ switch (astParam?.type) {
349
+ case FuncParameterType.identifier: {
350
+ const rawName = astParam.name;
351
+ const snippet = snip(this.makeNameValid(rawName), argType, origin);
352
+ args.push(snippet);
353
+ if (snippet.value !== rawName) argAliases.push([rawName, snippet]);
354
+ break;
355
+ }
356
+ case FuncParameterType.destructuredObject: {
357
+ const objSnippet = snip(`_arg_${i}`, argType, origin);
358
+ args.push(objSnippet);
359
+ argAliases.push(...astParam.props.map(({ name, alias }) => [alias, accessProp(objSnippet, name)]));
360
+ break;
361
+ }
362
+ case void 0: if (!(argType instanceof AutoStruct)) args.push(snip(`_arg_${i}`, argType, origin));
363
+ }
364
+ }
365
+ const scope = this._itemStateStack.pushFunctionScope(options.functionType, args, Object.fromEntries(argAliases), options.returnType, options.externalMap);
366
+ fnScopePushed = true;
367
+ const body = this.gen.functionDefinition(options.body);
368
+ let returnType = options.returnType;
369
+ if (returnType instanceof AutoStruct) if (isWgslStruct(scope.reportedReturnTypes.values().next().value)) returnType = returnType.completeStruct;
370
+ else returnType = void 0;
371
+ if (!returnType) {
372
+ const returnTypes = [...scope.reportedReturnTypes];
373
+ if (returnTypes.length === 0) returnType = Void;
374
+ else {
375
+ const conversion = getBestConversion(returnTypes);
376
+ if (conversion && !conversion.hasImplicitConversions) returnType = conversion.targetType;
377
+ }
378
+ if (!returnType) throw new Error(`Expected function to have a single return type, got [${returnTypes.join(", ")}]. Cast explicitly to the desired type.`);
379
+ returnType = concretize(returnType);
380
+ if (options.functionType === "vertex" || options.functionType === "fragment") returnType = createIoSchema(returnType);
381
+ }
382
+ if (options.entryInput) return {
383
+ head: `(${pendingHeaderEntries.filter(({ argName }) => isArgUsedInBody(argName, body)).map(({ header }) => header).join(", ")}) ${returnType.type !== "void" ? `-> ${getAttributesString(returnType)}${this.resolve(returnType).value} ` : ""}`,
384
+ body,
385
+ returnType
386
+ };
387
+ return {
388
+ head: resolveFunctionHeader(this, args, returnType),
389
+ body,
390
+ returnType
391
+ };
392
+ } finally {
393
+ if (fnScopePushed) this._itemStateStack.pop("functionScope");
394
+ this.#namespaceInternal.nameRegistry.popFunctionScope();
395
+ }
396
+ }
397
+ addDeclaration(declaration) {
398
+ this._declarations.push(declaration);
399
+ }
400
+ allocateLayoutEntry(layout) {
401
+ const memoMap = this.bindGroupLayoutsToPlaceholderMap;
402
+ let placeholderKey = memoMap.get(layout);
403
+ if (!placeholderKey) {
404
+ placeholderKey = `#BIND_GROUP_LAYOUT_${this._nextFreeLayoutPlaceholderIdx++}#`;
405
+ memoMap.set(layout, placeholderKey);
406
+ }
407
+ return placeholderKey;
408
+ }
409
+ allocateFixedEntry(layoutEntry, resource) {
410
+ const binding = this.fixedBindings.length;
411
+ this.fixedBindings.push({
412
+ layoutEntry,
413
+ resource
414
+ });
415
+ return {
416
+ group: CATCHALL_BIND_GROUP_IDX_MARKER,
417
+ binding
418
+ };
419
+ }
420
+ readSlot(slot) {
421
+ const value = this._itemStateStack.readSlot(slot);
422
+ if (value === void 0) throw new MissingSlotValueError(slot);
423
+ return value;
424
+ }
425
+ withSlots(pairs, callback) {
426
+ if (pairs.length === 0) return callback();
427
+ this._itemStateStack.pushSlotBindings(pairs);
428
+ try {
429
+ return callback();
430
+ } finally {
431
+ this._itemStateStack.pop("slotBinding");
432
+ }
433
+ }
434
+ withVaryingLocations(locations, callback) {
435
+ this._varyingLocations = locations;
436
+ try {
437
+ return callback();
438
+ } finally {
439
+ this._varyingLocations = void 0;
440
+ }
441
+ }
442
+ withRenamed(item, name, callback) {
443
+ if (!name) return callback();
444
+ const oldName = getName(item);
445
+ try {
446
+ setName(item, name);
447
+ return callback();
448
+ } finally {
449
+ setName(item, oldName);
450
+ }
451
+ }
452
+ unwrap(eventual) {
453
+ if (isProviding(eventual)) return this.withRenamed(eventual[$providing].inner, getName(eventual), () => this.withSlots(eventual[$providing].pairs, () => this.unwrap(eventual[$providing].inner)));
454
+ let maybeEventual = eventual;
455
+ while (true) if (isSlot(maybeEventual)) maybeEventual = this.readSlot(maybeEventual);
456
+ else if (isLazy(maybeEventual)) maybeEventual = this._getOrCompute(maybeEventual);
457
+ else break;
458
+ return maybeEventual;
459
+ }
460
+ _getOrCompute(lazy) {
461
+ const instances = this.#namespaceInternal.memoizedLazy.get(lazy) ?? [];
462
+ this._itemStateStack.pushItem();
463
+ try {
464
+ for (const instance of instances) if ([...instance.slotToValueMap.entries()].every(([slot, expectedValue]) => slot.areEqual(this._itemStateStack.readSlot(slot), expectedValue))) return instance.result;
465
+ this.pushMode(new NormalState());
466
+ let result;
467
+ try {
468
+ result = lazy[$internal].compute();
469
+ } finally {
470
+ this.popMode("normal");
471
+ }
472
+ const slotToValueMap = /* @__PURE__ */ new Map();
473
+ for (const usedSlot of this._itemStateStack.topItem.usedSlots) slotToValueMap.set(usedSlot, this._itemStateStack.readSlot(usedSlot));
474
+ instances.push({
475
+ slotToValueMap,
476
+ result
477
+ });
478
+ this.#namespaceInternal.memoizedLazy.set(lazy, instances);
479
+ return result;
480
+ } catch (err) {
481
+ if (err instanceof ResolutionError) throw err.appendToTrace(lazy);
482
+ throw new ResolutionError(err, [lazy]);
483
+ } finally {
484
+ this._itemStateStack.pop("item");
485
+ }
486
+ }
487
+ /**
488
+ * @param item The item whose resolution should be either retrieved from the cache (if there is a cache hit), or resolved.
489
+ */
490
+ _getOrInstantiate(item) {
491
+ const instances = this.#namespaceInternal.memoizedResolves.get(item) ?? [];
492
+ this._itemStateStack.pushItem();
493
+ try {
494
+ for (const instance of instances) if ([...instance.slotToValueMap.entries()].every(([slot, expectedValue]) => slot.areEqual(this._itemStateStack.readSlot(slot), expectedValue))) return instance.result;
495
+ let result;
496
+ if (isData(item)) result = snip(this.gen.typeAnnotation(item), Void, "runtime");
497
+ else if (isLazy(item) || isSlot(item)) result = this.resolve(this.unwrap(item));
498
+ else if (isSelfResolvable(item)) result = item[$resolve](this);
499
+ else if (hasTinyestMetadata(item)) {
500
+ const shellless = this.#namespaceInternal.shelllessRepo.get(item, void 0);
501
+ 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.`);
502
+ return this.withResetIndentLevel(() => this.resolve(shellless));
503
+ } else throw new TypeError(`Unresolvable internal value: ${safeStringify(item)}`);
504
+ const slotToValueMap = /* @__PURE__ */ new Map();
505
+ for (const usedSlot of this._itemStateStack.topItem.usedSlots) slotToValueMap.set(usedSlot, this._itemStateStack.readSlot(usedSlot));
506
+ instances.push({
507
+ slotToValueMap,
508
+ result
509
+ });
510
+ this.#namespaceInternal.memoizedResolves.set(item, instances);
511
+ return result;
512
+ } catch (err) {
513
+ if (err instanceof ResolutionError) throw err.appendToTrace(item);
514
+ throw new ResolutionError(err, [item]);
515
+ } finally {
516
+ this._itemStateStack.pop("item");
517
+ }
518
+ }
519
+ resolve(item, schema) {
520
+ if (isTgpuFn(item) || hasTinyestMetadata(item)) {
521
+ if (this.#currentlyResolvedItems.has(item) && !this.#namespaceInternal.memoizedResolves.has(item)) throw new Error(`Recursive function ${item} detected. Recursion is not allowed on the GPU.`);
522
+ this.#currentlyResolvedItems.add(item);
523
+ }
524
+ if (isProviding(item)) return this.withRenamed(item[$providing].inner, getName(item), () => this.withSlots(item[$providing].pairs, () => this.resolve(item[$providing].inner, schema)));
525
+ if (isMarkedInternal(item) || hasTinyestMetadata(item)) {
526
+ if (this._itemStateStack.itemDepth === 0) {
527
+ this.gen.initGenerator(this);
528
+ try {
529
+ this.pushMode(new CodegenState());
530
+ const result = provideCtx(this, () => this._getOrInstantiate(item));
531
+ return snip(`${[...this._declarations].join("\n\n")}${result.value}`, Void, "runtime");
532
+ } finally {
533
+ this.popMode("codegen");
534
+ }
535
+ }
536
+ return this._getOrInstantiate(item);
537
+ }
538
+ if (typeof item === "number") {
539
+ const realSchema = schema ?? numericLiteralToSnippet(item).dataType;
540
+ invariant(realSchema !== UnknownData, "Schema has to be known for resolving numbers");
541
+ if (realSchema.type === "abstractInt") return snip(`${item}`, realSchema, "constant");
542
+ if (realSchema.type === "u32") return snip(`${item}u`, realSchema, "constant");
543
+ if (realSchema.type === "i32") return snip(`${item}i`, realSchema, "constant");
544
+ const exp = item.toExponential();
545
+ const decimal = realSchema.type === "abstractFloat" && Number.isInteger(item) ? `${item}.` : `${item}`;
546
+ const base = exp.length < decimal.length ? exp : decimal;
547
+ if (realSchema.type === "f32") return snip(`${base}f`, realSchema, "constant");
548
+ if (realSchema.type === "f16") return snip(`${base}h`, realSchema, "constant");
549
+ return snip(base, realSchema, "constant");
550
+ }
551
+ if (typeof item === "boolean") return snip(item ? "true" : "false", bool, "constant");
552
+ if (typeof item === "string") return snip(item, Void, "runtime");
553
+ if (schema && isWgslArray(schema)) {
554
+ if (!Array.isArray(item)) throw new WgslTypeError(`Cannot coerce ${item} into value of type '${schema}'`);
555
+ if (schema.elementCount !== item.length) throw new WgslTypeError(`Cannot create value of type '${schema}' from an array of length: ${item.length}`);
556
+ return snip(stitch`array<${this.resolve(schema.elementType)}, ${schema.elementCount}>(${item.map((element) => snip(element, schema.elementType, "runtime"))})`, schema, "runtime");
557
+ }
558
+ if (Array.isArray(item)) return snip(stitch`array(${item.map((element) => this.resolve(element))})`, UnknownData, "runtime");
559
+ if (schema && isWgslStruct(schema)) return snip(stitch`${this.resolve(schema)}(${Object.entries(schema.propTypes).map(([key, propType]) => snip(item[key], propType, "runtime"))})`, schema, "runtime");
560
+ throw new WgslTypeError(`Value ${item} (as json: ${safeStringify(item)}) is not resolvable${schema ? ` to type ${safeStringify(schema)}` : ""}`);
561
+ }
562
+ resolveSnippet(snippet) {
563
+ return snip(this.resolve(snippet.value, snippet.dataType).value, snippet.dataType, snippet.origin);
564
+ }
565
+ pushMode(mode) {
566
+ this.#modeStack.push(mode);
567
+ }
568
+ popMode(expected) {
569
+ const mode = this.#modeStack.pop();
570
+ if (expected !== void 0) invariant(mode?.type === expected, "Unexpected mode");
571
+ }
572
+ get mode() {
573
+ return this.#modeStack[this.#modeStack.length - 1] ?? topLevelState;
574
+ }
575
+ };
576
+ function resolve(item, options) {
577
+ const ctx = new ResolutionCtxImpl(options);
578
+ let code = (options.config ? ctx.withSlots(options.config(new ConfigurableImpl([])).bindings, () => ctx.resolve(item)) : ctx.resolve(item)).value;
579
+ const memoMap = ctx.bindGroupLayoutsToPlaceholderMap;
580
+ const usedBindGroupLayouts = [];
581
+ const automaticIds = naturalsExcept(new Set([...memoMap.keys()].map((layout) => layout.index).filter((v) => v !== void 0)));
582
+ const layoutEntries = ctx.fixedBindings.map((binding, idx) => [String(idx), binding.layoutEntry]);
583
+ const createCatchallGroup = () => {
584
+ const catchallIdx = automaticIds.next().value;
585
+ const catchallLayout = bindGroupLayout(Object.fromEntries(layoutEntries));
586
+ usedBindGroupLayouts[catchallIdx] = catchallLayout;
587
+ code = code.replaceAll(CATCHALL_BIND_GROUP_IDX_MARKER, String(catchallIdx));
588
+ return [catchallIdx, new TgpuBindGroupImpl(catchallLayout, Object.fromEntries(ctx.fixedBindings.map((binding, idx) => [String(idx), binding.resource])))];
589
+ };
590
+ const catchall = layoutEntries.length > 0 ? createCatchallGroup() : void 0;
591
+ for (const [layout, placeholder] of memoMap.entries()) {
592
+ const idx = layout.index ?? automaticIds.next().value;
593
+ usedBindGroupLayouts[idx] = layout;
594
+ code = code.replaceAll(placeholder, String(idx));
595
+ }
596
+ if (options.enableExtensions && options.enableExtensions.length > 0) code = `${options.enableExtensions.map((ext) => `enable ${ext};`).join("\n")}\n\n${code}`;
597
+ return {
598
+ code,
599
+ usedBindGroupLayouts,
600
+ catchall,
601
+ logResources: ctx.logResources
602
+ };
603
+ }
604
+ function isArgUsedInBody(argName, body) {
605
+ return new RegExp(`\\b${argName}\\b`).test(body);
606
+ }
607
+ function resolveFunctionHeader(ctx, args, returnType) {
608
+ const argList = args.map((arg) => `${arg.value}: ${ctx.resolve(arg.dataType).value}`).join(", ");
609
+ return returnType.type !== "void" ? `(${argList}) -> ${getAttributesString(returnType)}${ctx.resolve(returnType).value} ` : `(${argList}) `;
610
+ }
611
+ //#endregion
612
+ export { ResolutionCtxImpl, resolve };
package/shared/env.js ADDED
@@ -0,0 +1,12 @@
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
+ //#endregion
12
+ export { DEV, TEST };
@@ -0,0 +1,13 @@
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
+ //#endregion
13
+ 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 };