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,198 @@
1
+ import { DEV, TEST } from "../shared/env.js";
2
+ import { isMat, isPtr, isVec } from "../data/wgslTypes.js";
3
+ import { UnknownData, undecorate } from "../data/dataTypes.js";
4
+ import { snip } from "../data/snippet.js";
5
+ import { WgslTypeError, invariant } from "../errors.js";
6
+ import { stitch } from "../core/resolve/stitch.js";
7
+ import { RefOperator, derefSnippet } from "../data/ref.js";
8
+ import { schemaCallWrapperGPU } from "../data/schemaCallWrapper.js";
9
+ import { safeStringify } from "../shared/stringify.js";
10
+ import { assertExhaustive } from "../shared/utilityTypes.js";
11
+ //#region src/tgsl/conversion.ts
12
+ const INFINITE_RANK = {
13
+ rank: Number.POSITIVE_INFINITY,
14
+ action: "none"
15
+ };
16
+ function getAutoConversionRank(src, dest) {
17
+ const trueSrc = undecorate(src);
18
+ const trueDst = undecorate(dest);
19
+ if (trueSrc.type === trueDst.type) return {
20
+ rank: 0,
21
+ action: "none"
22
+ };
23
+ if (trueSrc.type === "abstractFloat") {
24
+ if (trueDst.type === "f32") return {
25
+ rank: 1,
26
+ action: "none"
27
+ };
28
+ if (trueDst.type === "f16") return {
29
+ rank: 2,
30
+ action: "none"
31
+ };
32
+ }
33
+ if (trueSrc.type === "abstractInt") {
34
+ if (trueDst.type === "i32") return {
35
+ rank: 3,
36
+ action: "none"
37
+ };
38
+ if (trueDst.type === "u32") return {
39
+ rank: 4,
40
+ action: "none"
41
+ };
42
+ if (trueDst.type === "abstractFloat") return {
43
+ rank: 5,
44
+ action: "none"
45
+ };
46
+ if (trueDst.type === "f32") return {
47
+ rank: 6,
48
+ action: "none"
49
+ };
50
+ if (trueDst.type === "f16") return {
51
+ rank: 7,
52
+ action: "none"
53
+ };
54
+ }
55
+ if (isVec(trueSrc) && isVec(trueDst) && trueSrc.type[3] === trueDst.type[3]) return getAutoConversionRank(trueSrc.primitive, trueDst.primitive);
56
+ if (isMat(trueSrc) && isMat(trueDst) && trueSrc.type[3] === trueDst.type[3]) return {
57
+ rank: 0,
58
+ action: "none"
59
+ };
60
+ return INFINITE_RANK;
61
+ }
62
+ function getImplicitConversionRank(src, dest) {
63
+ const trueSrc = undecorate(src);
64
+ const trueDst = undecorate(dest);
65
+ if (isPtr(trueSrc) && trueSrc.implicit && getAutoConversionRank(trueSrc.inner, trueDst).rank < Number.POSITIVE_INFINITY) return {
66
+ rank: 0,
67
+ action: "deref"
68
+ };
69
+ if (isPtr(trueDst) && getAutoConversionRank(trueSrc, trueDst.inner).rank < Number.POSITIVE_INFINITY) return {
70
+ rank: 1,
71
+ action: "ref"
72
+ };
73
+ const primitivePreference = {
74
+ f32: 0,
75
+ f16: 1,
76
+ i32: 2,
77
+ u32: 3,
78
+ bool: 4
79
+ };
80
+ if (trueSrc.type in primitivePreference && trueDst.type in primitivePreference) {
81
+ const srcType = trueSrc.type;
82
+ const destType = trueDst.type;
83
+ if (srcType !== destType) {
84
+ const srcPref = primitivePreference[srcType];
85
+ return {
86
+ rank: primitivePreference[destType] < srcPref ? 10 : 20,
87
+ action: "cast",
88
+ targetType: trueDst
89
+ };
90
+ }
91
+ }
92
+ if (trueSrc.type === "abstractFloat") {
93
+ if (trueDst.type === "u32") return {
94
+ rank: 2,
95
+ action: "cast",
96
+ targetType: trueDst
97
+ };
98
+ if (trueDst.type === "i32") return {
99
+ rank: 1,
100
+ action: "cast",
101
+ targetType: trueDst
102
+ };
103
+ }
104
+ return INFINITE_RANK;
105
+ }
106
+ function getConversionRank(src, dest, allowImplicit) {
107
+ const autoRank = getAutoConversionRank(src, dest);
108
+ if (autoRank.rank < Number.POSITIVE_INFINITY) return autoRank;
109
+ if (allowImplicit) return getImplicitConversionRank(src, dest);
110
+ return INFINITE_RANK;
111
+ }
112
+ function findBestType(types, uniqueTypes, allowImplicit) {
113
+ let bestResult;
114
+ for (const targetType of uniqueTypes) {
115
+ const details = [];
116
+ let sum = 0;
117
+ for (const sourceType of types) {
118
+ const conversion = getConversionRank(sourceType, targetType, allowImplicit);
119
+ sum += conversion.rank;
120
+ if (conversion.rank === Number.POSITIVE_INFINITY) break;
121
+ details.push(conversion);
122
+ }
123
+ if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) bestResult = {
124
+ type: targetType,
125
+ details,
126
+ sum
127
+ };
128
+ }
129
+ if (!bestResult) return;
130
+ const actions = bestResult.details.map((detail, index) => ({
131
+ sourceIndex: index,
132
+ action: detail.action,
133
+ ...detail.action === "cast" && { targetType: detail.targetType }
134
+ }));
135
+ return {
136
+ targetType: bestResult.type,
137
+ actions,
138
+ hasImplicitConversions: actions.some((action) => action.action === "cast")
139
+ };
140
+ }
141
+ function getBestConversion(types, targetTypes) {
142
+ if (types.length === 0) return void 0;
143
+ const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
144
+ const explicitResult = findBestType(types, uniqueTargetTypes, false);
145
+ if (explicitResult) return explicitResult;
146
+ const implicitResult = findBestType(types, uniqueTargetTypes, true);
147
+ if (implicitResult) return implicitResult;
148
+ }
149
+ function applyActionToSnippet(ctx, snippet, action, targetType) {
150
+ if (action.action === "none") return snip(snippet.value, targetType, snippet.origin);
151
+ switch (action.action) {
152
+ case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
153
+ case "deref": return derefSnippet(snippet);
154
+ case "cast": return schemaCallWrapperGPU(ctx, targetType, snippet);
155
+ default: assertExhaustive(action.action, "applyActionToSnippet");
156
+ }
157
+ }
158
+ function unify(inTypes, restrictTo) {
159
+ if (inTypes.some((type) => type === UnknownData)) return;
160
+ const conversion = getBestConversion(inTypes, restrictTo);
161
+ if (!conversion) return;
162
+ return inTypes.map((type) => isVec(type) || isMat(type) ? type : conversion.targetType);
163
+ }
164
+ function convertToCommonType(ctx, values, restrictTo, verbose = true) {
165
+ const types = values.map((value) => value.dataType);
166
+ if (types.some((type) => type === UnknownData)) return;
167
+ if (DEV && Array.isArray(restrictTo) && restrictTo.length === 0) console.warn("convertToCommonType was called with an empty restrictTo array, which prevents any conversions from being made. If you intend to allow all conversions, pass undefined instead. If this was intended call the function conditionally since the result will always be undefined.");
168
+ const conversion = getBestConversion(types, restrictTo);
169
+ if (!conversion) return;
170
+ if ((TEST || DEV) && verbose && conversion.hasImplicitConversions) console.warn(`Implicit conversions from [\n${values.map((v) => ` ${v.value}: ${safeStringify(v.dataType)}`).join(",\n")}\n] to ${conversion.targetType.type} are supported, but not recommended.
171
+ Consider using explicit conversions instead.`);
172
+ return values.map((value, index) => {
173
+ const action = conversion.actions[index];
174
+ invariant(action, "Action should not be undefined");
175
+ return applyActionToSnippet(ctx, value, action, conversion.targetType);
176
+ });
177
+ }
178
+ function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
179
+ const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
180
+ const { value, dataType, origin } = snippet;
181
+ if (targets.length === 1) {
182
+ const target = targets[0];
183
+ if (target === dataType) return snip(value, target, origin);
184
+ if (dataType === UnknownData) return snip(stitch`${snip(value, target, origin)}`, target, origin);
185
+ }
186
+ const converted = convertToCommonType(ctx, [snippet], targets, verbose);
187
+ if (converted) return converted[0];
188
+ throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(", ")}]`);
189
+ }
190
+ function convertStructValues(ctx, structType, values) {
191
+ return Object.entries(structType.propTypes).map(([key, targetType]) => {
192
+ const val = values[key];
193
+ if (!val) throw new Error(`Missing property ${key}`);
194
+ return convertToCommonType(ctx, [val], [targetType])?.[0] ?? val;
195
+ });
196
+ }
197
+ //#endregion
198
+ export { convertStructValues, convertToCommonType, getBestConversion, tryConvertSnippet, unify };
@@ -0,0 +1,71 @@
1
+ import { $gpuCallable } from "../shared/symbols.js";
2
+ import { isPtr, isVec, isWgslArray } from "../data/wgslTypes.js";
3
+ import { UnknownData } from "../data/dataTypes.js";
4
+ import { isEphemeralSnippet, snip } from "../data/snippet.js";
5
+ import { WgslTypeError, invariant } from "../errors.js";
6
+ import { stitch } from "../core/resolve/stitch.js";
7
+ import { createPtrFromOrigin, implicitFrom } from "../data/ptr.js";
8
+ import { i32, u32 } from "../data/numeric.js";
9
+ import { ArrayExpression, concretize } from "./generationHelpers.js";
10
+ import { accessIndex } from "./accessIndex.js";
11
+ import { arrayLength } from "../std/array.js";
12
+ import { isTgpuRange } from "../std/range.js";
13
+ //#region src/tgsl/forOfUtils.ts
14
+ function getLoopVarKind(elementSnippet) {
15
+ return elementSnippet.origin === "constant-tgpu-const-ref" ? "const" : "let";
16
+ }
17
+ function getElementSnippet(iterableSnippet, index) {
18
+ const elementSnippet = accessIndex(iterableSnippet, index);
19
+ if (!elementSnippet) throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
20
+ return elementSnippet;
21
+ }
22
+ function getElementType(elementSnippet, iterableSnippet) {
23
+ let elementType = elementSnippet.dataType;
24
+ if (elementType === UnknownData) throw new WgslTypeError(stitch`The elements in iterable ${iterableSnippet} are of unknown type`);
25
+ if (isEphemeralSnippet(elementSnippet) || elementSnippet.origin === "constant-tgpu-const-ref" || elementSnippet.origin === "runtime-tgpu-const-ref") return elementType;
26
+ if (!isPtr(elementType)) {
27
+ const ptrType = createPtrFromOrigin(elementSnippet.origin, concretize(elementType));
28
+ invariant(ptrType !== void 0, `Creating pointer type from origin ${elementSnippet.origin}`);
29
+ elementType = ptrType;
30
+ }
31
+ return implicitFrom(elementType);
32
+ }
33
+ function getRangeSnippets(ctx, iterableSnippet, unroll = false) {
34
+ const { value, dataType } = iterableSnippet;
35
+ if (isTgpuRange(value)) return {
36
+ start: snip(value.start, i32, "constant"),
37
+ end: snip(value.end, i32, "constant"),
38
+ step: snip(value.step, i32, "constant"),
39
+ comparison: value.step < 0 ? ">" : "<"
40
+ };
41
+ if (!unroll && isEphemeralSnippet(iterableSnippet)) throw new Error(`\`for ... of ...\` loops only support std.range or iterables stored in variables.
42
+ -----
43
+ You can wrap iterable with \`tgpu.unroll(...)\`. If iterable is known at comptime, the loop will be unrolled.
44
+ -----`);
45
+ const defaults = {
46
+ start: snip(0, u32, "constant"),
47
+ step: snip(1, u32, "constant"),
48
+ comparison: "<"
49
+ };
50
+ if (isWgslArray(dataType)) return {
51
+ ...defaults,
52
+ end: dataType.elementCount > 0 ? snip(dataType.elementCount, u32, "constant") : arrayLength[$gpuCallable].call(ctx, [iterableSnippet])
53
+ };
54
+ if (isVec(dataType)) return {
55
+ ...defaults,
56
+ end: snip(dataType.componentCount, u32, "constant")
57
+ };
58
+ if (unroll) {
59
+ if (Array.isArray(value)) return {
60
+ ...defaults,
61
+ end: snip(value.length, u32, "constant")
62
+ };
63
+ if (value instanceof ArrayExpression) return {
64
+ ...defaults,
65
+ end: snip(value.elements.length, u32, "constant")
66
+ };
67
+ }
68
+ throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
69
+ }
70
+ //#endregion
71
+ export { getElementSnippet, getElementType, getLoopVarKind, getRangeSnippets };
@@ -0,0 +1,37 @@
1
+ import { Snippet } from "../data/snippet.js";
2
+ import { ShelllessRepository } from "./shellless.js";
3
+ import { FunctionScopeLayer, ResolutionCtx } from "../types.js";
4
+ import { BaseData } from "../data/wgslTypes.js";
5
+
6
+ //#region src/tgsl/generationHelpers.d.ts
7
+ type GenerationCtx = ResolutionCtx & {
8
+ readonly pre: string;
9
+ /**
10
+ * Used by `typedExpression` to signal downstream
11
+ * expression resolution what type is expected of them.
12
+ *
13
+ * It is used exclusively for inferring the types of structs and arrays.
14
+ * It is modified exclusively by `typedExpression` function.
15
+ */
16
+ expectedType: (BaseData | BaseData[]) | undefined;
17
+ readonly topFunctionScope: FunctionScopeLayer | undefined;
18
+ readonly topFunctionReturnType: BaseData | undefined;
19
+ indent(): string;
20
+ dedent(): string;
21
+ pushBlockScope(): void;
22
+ popBlockScope(): void;
23
+ generateLog(op: string, args: Snippet[]): Snippet;
24
+ getById(id: string): Snippet | null;
25
+ defineVariable(id: string, snippet: Snippet): void;
26
+ setBlockExternals(externals: Record<string, Snippet>): void;
27
+ clearBlockExternals(): void;
28
+ /**
29
+ * Types that are used in `return` statements are
30
+ * reported using this function, and used to infer
31
+ * the return type of the owning function.
32
+ */
33
+ reportReturnType(dataType: BaseData): void;
34
+ readonly shelllessRepo: ShelllessRepository;
35
+ };
36
+ //#endregion
37
+ export { GenerationCtx };
@@ -0,0 +1,67 @@
1
+ import { $internal, $resolve } from "../shared/symbols.js";
2
+ import { WORKAROUND_getSchema, isMatInstance, isNaturallyEphemeral, isVecInstance } from "../data/wgslTypes.js";
3
+ import { UnknownData } from "../data/dataTypes.js";
4
+ import { isEphemeralSnippet, isSnippet, snip } from "../data/snippet.js";
5
+ import { WgslTypeError } from "../errors.js";
6
+ import { getOwnSnippet } from "../types.js";
7
+ import { stitch } from "../core/resolve/stitch.js";
8
+ import { isRef } from "../data/ref.js";
9
+ import { abstractFloat, abstractInt, bool, f32, i32 } from "../data/numeric.js";
10
+ //#region src/tgsl/generationHelpers.ts
11
+ function numericLiteralToSnippet(value) {
12
+ if (value >= 2 ** 63 || value < -(2 ** 63)) return snip(value, abstractFloat, "constant");
13
+ if (Number.isInteger(value)) {
14
+ if (!Number.isSafeInteger(value)) console.warn(`The integer ${value} exceeds the safe integer range and may have lost precision.`);
15
+ return snip(value, abstractInt, "constant");
16
+ }
17
+ return snip(value, abstractFloat, "constant");
18
+ }
19
+ function concretize(type) {
20
+ if (type.type === "abstractFloat") return f32;
21
+ if (type.type === "abstractInt") return i32;
22
+ return type;
23
+ }
24
+ function concretizeSnippet(snippet) {
25
+ return snip(snippet.value, concretize(snippet.dataType), snippet.origin);
26
+ }
27
+ function concretizeSnippets(args) {
28
+ return args.map(concretizeSnippet);
29
+ }
30
+ function coerceToSnippet(value) {
31
+ if (isSnippet(value)) return value;
32
+ if (isRef(value)) throw new Error("Cannot use refs (d.ref(...)) from the outer scope.");
33
+ const ownSnippet = getOwnSnippet(value);
34
+ if (ownSnippet) return ownSnippet;
35
+ if (isVecInstance(value) || isMatInstance(value)) return snip(value, WORKAROUND_getSchema(value), "constant");
36
+ if (typeof value === "string" || typeof value === "function" || typeof value === "object" || typeof value === "symbol" || typeof value === "undefined" || value === null) return snip(value, UnknownData, "constant");
37
+ if (typeof value === "number") return numericLiteralToSnippet(value);
38
+ if (typeof value === "boolean") return snip(value, bool, "constant");
39
+ return snip(value, UnknownData, "constant");
40
+ }
41
+ /**
42
+ * Intermediate representation for WGSL array expressions.
43
+ * Defers resolution. Stores array elements as snippets so the
44
+ * generator can access them when needed.
45
+ */
46
+ var ArrayExpression = class {
47
+ [$internal] = true;
48
+ type;
49
+ elements;
50
+ constructor(type, elements) {
51
+ this.type = type;
52
+ this.elements = elements;
53
+ }
54
+ toString() {
55
+ return "ArrayExpression";
56
+ }
57
+ [$resolve](ctx) {
58
+ for (const elem of this.elements) if (elem.origin === "argument" && !isNaturallyEphemeral(elem.dataType) || !isEphemeralSnippet(elem)) {
59
+ const snippetStr = ctx.resolve(elem.value, elem.dataType).value;
60
+ const snippetType = ctx.resolve(concretize(elem.dataType)).value;
61
+ throw new WgslTypeError(`'${snippetStr}' reference cannot be used in an array constructor.\n-----\nTry '${snippetType}(${snippetStr})' or 'arrayOf(${snippetType}, count)([...])' to copy the value instead.\n-----`);
62
+ }
63
+ return snip(stitch`${`array<${ctx.resolve(this.type.elementType).value}, ${this.elements.length}>`}(${this.elements})`, this.type, "runtime");
64
+ }
65
+ };
66
+ //#endregion
67
+ export { ArrayExpression, coerceToSnippet, concretize, concretizeSnippets, numericLiteralToSnippet };
package/tgsl/math.js ADDED
@@ -0,0 +1,43 @@
1
+ import { f32 } from "../data/numeric.js";
2
+ import { abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, cos, cosh, countLeadingZeros, exp, floor, log, log2, max, min, pow, sign, sin, sinh, sqrt, tan, tanh, trunc } from "../std/numeric.js";
3
+ //#region src/tgsl/math.ts
4
+ const mathToStd = {
5
+ abs,
6
+ acos,
7
+ acosh,
8
+ asin,
9
+ asinh,
10
+ atan,
11
+ atan2,
12
+ atanh,
13
+ ceil,
14
+ cos,
15
+ cosh,
16
+ exp,
17
+ floor,
18
+ fround: f32,
19
+ clz32: countLeadingZeros,
20
+ trunc,
21
+ log,
22
+ log2,
23
+ pow,
24
+ sign,
25
+ sin,
26
+ sinh,
27
+ sqrt,
28
+ tan,
29
+ tanh,
30
+ max,
31
+ min,
32
+ cbrt: void 0,
33
+ log10: void 0,
34
+ log1p: void 0,
35
+ f16round: void 0,
36
+ hypot: void 0,
37
+ expm1: void 0,
38
+ random: void 0,
39
+ imul: void 0,
40
+ round: void 0
41
+ };
42
+ //#endregion
43
+ export { mathToStd };
@@ -0,0 +1,20 @@
1
+ import { ResolvedSnippet, Snippet } from "../data/snippet.js";
2
+ import { GenerationCtx } from "./generationHelpers.js";
3
+ import { BaseData } from "../data/wgslTypes.js";
4
+ import { Block } from "tinyest";
5
+
6
+ //#region src/tgsl/shaderGenerator.d.ts
7
+ /**
8
+ * **NOTE: This is an unstable API and may change in the future.**
9
+ *
10
+ * An interface meant to be used by other systems to generate snippets of
11
+ * shader code in the target language (WGSL, GLSL, etc.).
12
+ */
13
+ interface ShaderGenerator {
14
+ initGenerator(ctx: GenerationCtx): void;
15
+ functionDefinition(body: Block): string;
16
+ typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
17
+ typeAnnotation(schema: BaseData): string;
18
+ }
19
+ //#endregion
20
+ export { ShaderGenerator };
@@ -0,0 +1,2 @@
1
+ import { ResolutionCtx } from "../types.js";
2
+ import { UnknownData } from "../data/dataTypes.js";
@@ -0,0 +1,6 @@
1
+ import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
+ import { UnknownData } from "../data/dataTypes.js";
3
+ //#region src/tgsl/shaderGenerator_members.ts
4
+ var shaderGenerator_members_exports = /* @__PURE__ */ __exportAll({ UnknownData: () => UnknownData });
5
+ //#endregion
6
+ export { shaderGenerator_members_exports };
@@ -0,0 +1,11 @@
1
+ import { Snippet } from "../data/snippet.js";
2
+ import { ShelllessImpl } from "../core/function/shelllessImpl.js";
3
+
4
+ //#region src/tgsl/shellless.d.ts
5
+ type AnyFn = (...args: never[]) => unknown;
6
+ declare class ShelllessRepository {
7
+ cache: Map<AnyFn, ShelllessImpl[]>;
8
+ get(fn: AnyFn, argSnippets: Snippet[] | undefined): ShelllessImpl | undefined;
9
+ }
10
+ //#endregion
11
+ export { ShelllessRepository };
@@ -0,0 +1,46 @@
1
+ import { getMetaData, getName } from "../shared/meta.js";
2
+ import { isPtr, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
3
+ import { UnknownData } from "../data/dataTypes.js";
4
+ import { WgslTypeError } from "../errors.js";
5
+ import { RefOperator } from "../data/ref.js";
6
+ import { concretize } from "./generationHelpers.js";
7
+ import { createShelllessImpl } from "../core/function/shelllessImpl.js";
8
+ //#region src/tgsl/shellless.ts
9
+ function shallowEqualSchemas(a, b) {
10
+ if (a.type !== b.type) return false;
11
+ if (isPtr(a) && isPtr(b)) return a.access === b.access && a.addressSpace === b.addressSpace && a.implicit === b.implicit && shallowEqualSchemas(a.inner, b.inner);
12
+ if (isWgslArray(a) && isWgslArray(b)) return a.elementCount === b.elementCount && shallowEqualSchemas(a.elementType, b.elementType);
13
+ if (isWgslStruct(a) && isWgslStruct(b)) return a === b;
14
+ return true;
15
+ }
16
+ var ShelllessRepository = class {
17
+ cache = /* @__PURE__ */ new Map();
18
+ get(fn, argSnippets) {
19
+ const meta = getMetaData(fn);
20
+ if (!meta?.ast) return void 0;
21
+ if (!argSnippets && meta.ast.params.length > 0) throw new Error(`Cannot resolve '${getName(fn)}' directly, because it expects arguments. Either call it from another function, or wrap it in a shell`);
22
+ const argTypes = (argSnippets ?? []).map((s, index) => {
23
+ if (s.value instanceof RefOperator) {
24
+ if (s.dataType === UnknownData) throw new WgslTypeError(`d.ref() created with primitive types must be stored in a variable before use`);
25
+ return s.dataType;
26
+ }
27
+ if (s.dataType === UnknownData) throw new Error(`Passed illegal value ${s.value} as the #${index} argument to ${meta.name}(...)\nShellless functions can only accept arguments representing WGSL resources: constructible WGSL types, d.refs, samplers or texture views.\nRemember, that arguments such as samplers, texture views, accessors, slots etc. should be dereferenced via '.$' first.`);
28
+ let type = concretize(s.dataType);
29
+ if (isPtr(type) && type.implicit) type = type.inner;
30
+ return type;
31
+ });
32
+ let cache = this.cache.get(fn);
33
+ if (cache) {
34
+ const variant = cache.find((v) => v.argTypes.length === argTypes.length && v.argTypes.every((t, i) => shallowEqualSchemas(t, argTypes[i])));
35
+ if (variant) return variant;
36
+ } else {
37
+ cache = [];
38
+ this.cache.set(fn, cache);
39
+ }
40
+ const shellless = createShelllessImpl(argTypes, fn);
41
+ cache.push(shellless);
42
+ return shellless;
43
+ }
44
+ };
45
+ //#endregion
46
+ export { ShelllessRepository };
@@ -0,0 +1,36 @@
1
+ import { Origin, ResolvedSnippet, Snippet } from "../data/snippet.js";
2
+ import { GenerationCtx } from "./generationHelpers.js";
3
+ import { ShaderGenerator } from "./shaderGenerator.js";
4
+ import { BaseData, StorableData } from "../data/wgslTypes.js";
5
+ import { UnknownData } from "../data/dataTypes.js";
6
+ import { ExternalMap } from "../core/resolve/externals.js";
7
+ import * as tinyest from "tinyest";
8
+
9
+ //#region src/tgsl/wgslGenerator.d.ts
10
+ declare class WgslGenerator implements ShaderGenerator {
11
+ #private;
12
+ initGenerator(ctx: GenerationCtx): void;
13
+ protected get ctx(): GenerationCtx;
14
+ _block([_, statements]: tinyest.Block, externalMap?: ExternalMap): string;
15
+ refVariable(id: string, dataType: StorableData): string;
16
+ blockVariable(varType: 'var' | 'let' | 'const', id: string, dataType: BaseData | UnknownData, origin: Origin): Snippet;
17
+ protected emitVarDecl(pre: string, keyword: 'var' | 'let' | 'const', name: string, _dataType: BaseData | UnknownData, rhsStr: string): string;
18
+ _identifier(id: string): Snippet;
19
+ /**
20
+ * A wrapper for `generateExpression` that updates `ctx.expectedType`
21
+ * and tries to convert the result when it does not match the expected type.
22
+ */
23
+ _typedExpression(expression: tinyest.Expression, expectedType: BaseData | BaseData[]): Snippet;
24
+ _expression(expression: tinyest.Expression): Snippet;
25
+ functionDefinition(body: tinyest.Block): string;
26
+ /**
27
+ * Generates a WGSL type string for the given data type, and adds necessary
28
+ * definitions to the shader preamble. This shouldn't be called directly, only
29
+ * through `ctx.resolve` to properly cache the result.
30
+ */
31
+ typeAnnotation(data: BaseData): string;
32
+ typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
33
+ _statement(statement: tinyest.Statement): string;
34
+ }
35
+ //#endregion
36
+ export { WgslGenerator };