typegpu 0.11.8 → 0.12.0

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 (362) hide show
  1. package/builtin.d.ts +51 -53
  2. package/builtin.js +30 -34
  3. package/common/fullScreenTriangle.d.ts +2 -10
  4. package/common/fullScreenTriangle.js +20 -28
  5. package/common/index.d.ts +2 -9
  6. package/common/index.js +3 -12
  7. package/common/writeSoA.d.ts +11 -12
  8. package/common/writeSoA.js +88 -76
  9. package/core/buffer/buffer.d.ts +79 -62
  10. package/core/buffer/buffer.js +279 -205
  11. package/core/buffer/bufferBinding.d.ts +71 -0
  12. package/core/buffer/bufferBinding.js +154 -0
  13. package/core/buffer/bufferUsage.d.ts +14 -45
  14. package/core/buffer/bufferUsage.js +1 -171
  15. package/core/buffer/laidOutBuffer.d.ts +25 -0
  16. package/core/buffer/laidOutBuffer.js +55 -0
  17. package/core/commandEncoder/attachments.d.ts +125 -0
  18. package/core/commandEncoder/attachments.js +29 -0
  19. package/core/commandEncoder/commandEncoder.d.ts +53 -0
  20. package/core/commandEncoder/commandEncoder.js +56 -0
  21. package/core/commandEncoder/computePass.d.ts +58 -0
  22. package/core/commandEncoder/computePass.js +63 -0
  23. package/core/commandEncoder/renderPass.d.ts +121 -0
  24. package/core/commandEncoder/renderPass.js +196 -0
  25. package/core/constant/tgpuConstant.d.ts +26 -26
  26. package/core/constant/tgpuConstant.js +76 -65
  27. package/core/declare/tgpuDeclare.d.ts +3 -6
  28. package/core/declare/tgpuDeclare.js +37 -38
  29. package/core/function/autoIO.d.ts +61 -33
  30. package/core/function/autoIO.js +68 -73
  31. package/core/function/comptime.d.ts +11 -13
  32. package/core/function/comptime.js +60 -52
  33. package/core/function/createCallableSchema.d.ts +16 -0
  34. package/core/function/createCallableSchema.js +50 -40
  35. package/core/function/dualImpl.d.ts +44 -0
  36. package/core/function/dualImpl.js +71 -50
  37. package/core/function/entryInputRouter.d.ts +26 -0
  38. package/core/function/entryInputRouter.js +31 -33
  39. package/core/function/extractArgs.d.ts +38 -0
  40. package/core/function/extractArgs.js +202 -200
  41. package/core/function/fnCore.d.ts +44 -0
  42. package/core/function/fnCore.js +148 -92
  43. package/core/function/fnTypes.d.ts +31 -29
  44. package/core/function/fnTypes.js +1 -0
  45. package/core/function/ioSchema.d.ts +12 -10
  46. package/core/function/ioSchema.js +65 -47
  47. package/core/function/shelllessImpl.d.ts +9 -12
  48. package/core/function/shelllessImpl.js +18 -20
  49. package/core/function/templateUtils.d.ts +2 -0
  50. package/core/function/templateUtils.js +9 -8
  51. package/core/function/tgpuComputeFn.d.ts +26 -28
  52. package/core/function/tgpuComputeFn.js +47 -48
  53. package/core/function/tgpuFn.d.ts +34 -37
  54. package/core/function/tgpuFn.js +179 -153
  55. package/core/function/tgpuFragmentFn.d.ts +52 -53
  56. package/core/function/tgpuFragmentFn.js +63 -56
  57. package/core/function/tgpuVertexFn.d.ts +36 -39
  58. package/core/function/tgpuVertexFn.js +56 -53
  59. package/core/pipeline/computePipeline.d.ts +141 -53
  60. package/core/pipeline/computePipeline.js +291 -225
  61. package/core/pipeline/connectAttachmentToShader.d.ts +4 -0
  62. package/core/pipeline/connectAttachmentToShader.js +25 -22
  63. package/core/pipeline/connectTargetsToShader.d.ts +3 -0
  64. package/core/pipeline/connectTargetsToShader.js +29 -27
  65. package/core/pipeline/drawState.d.ts +52 -0
  66. package/core/pipeline/drawState.js +225 -0
  67. package/core/pipeline/limitsOverflow.d.ts +2 -0
  68. package/core/pipeline/limitsOverflow.js +13 -10
  69. package/core/pipeline/performanceTracker.d.ts +14 -0
  70. package/core/pipeline/performanceTracker.js +34 -0
  71. package/core/pipeline/pipelineUtils.d.ts +18 -0
  72. package/core/pipeline/pipelineUtils.js +54 -25
  73. package/core/pipeline/priors.d.ts +1 -0
  74. package/core/pipeline/priors.js +12 -0
  75. package/core/pipeline/renderPipeline.d.ts +246 -261
  76. package/core/pipeline/renderPipeline.js +487 -480
  77. package/core/pipeline/timeable.d.ts +28 -18
  78. package/core/pipeline/timeable.js +90 -52
  79. package/core/pipeline/typeGuards.d.ts +17 -0
  80. package/core/pipeline/typeGuards.js +52 -22
  81. package/core/querySet/querySet.d.ts +26 -21
  82. package/core/querySet/querySet.js +127 -103
  83. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +13 -18
  84. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +90 -93
  85. package/core/resolve/externals.d.ts +25 -7
  86. package/core/resolve/externals.js +79 -62
  87. package/core/resolve/namespace.d.ts +22 -25
  88. package/core/resolve/namespace.js +16 -21
  89. package/core/resolve/resolvableString.d.ts +7 -0
  90. package/core/resolve/resolvableString.js +13 -0
  91. package/core/resolve/resolveData.d.ts +10 -0
  92. package/core/resolve/resolveData.js +162 -121
  93. package/core/resolve/stitch.d.ts +8 -0
  94. package/core/resolve/stitch.js +23 -21
  95. package/core/resolve/tgpuResolve.d.ts +55 -53
  96. package/core/resolve/tgpuResolve.js +106 -55
  97. package/core/root/configurableImpl.d.ts +10 -0
  98. package/core/root/configurableImpl.js +17 -19
  99. package/core/root/init.d.ts +76 -38
  100. package/core/root/init.js +346 -454
  101. package/core/root/rootTypes.d.ts +461 -627
  102. package/core/root/rootTypes.js +1 -0
  103. package/core/sampler/sampler.d.ts +50 -31
  104. package/core/sampler/sampler.js +120 -113
  105. package/core/simulate/tgpuSimulate.d.ts +9 -12
  106. package/core/simulate/tgpuSimulate.js +68 -71
  107. package/core/slot/accessor.d.ts +36 -13
  108. package/core/slot/accessor.js +138 -91
  109. package/core/slot/internalSlots.d.ts +2 -0
  110. package/core/slot/internalSlots.js +1 -6
  111. package/core/slot/lazy.d.ts +2 -6
  112. package/core/slot/lazy.js +71 -39
  113. package/core/slot/slot.d.ts +2 -6
  114. package/core/slot/slot.js +45 -38
  115. package/core/slot/slotTypes.d.ts +78 -80
  116. package/core/slot/slotTypes.js +11 -16
  117. package/core/texture/externalTexture.d.ts +20 -11
  118. package/core/texture/externalTexture.js +46 -46
  119. package/core/texture/texture.d.ts +152 -97
  120. package/core/texture/texture.js +407 -314
  121. package/core/texture/textureFormats.d.ts +42 -23
  122. package/core/texture/textureFormats.js +104 -75
  123. package/core/texture/textureProps.d.ts +7 -10
  124. package/core/texture/textureProps.js +1 -0
  125. package/core/texture/textureUtils.d.ts +8 -0
  126. package/core/texture/textureUtils.js +185 -179
  127. package/core/texture/usageExtension.d.ts +21 -18
  128. package/core/texture/usageExtension.js +13 -17
  129. package/core/unroll/tgpuUnroll.d.ts +20 -19
  130. package/core/unroll/tgpuUnroll.js +82 -91
  131. package/core/valueProxyUtils.d.ts +3 -0
  132. package/core/valueProxyUtils.js +52 -41
  133. package/core/variable/tgpuVariable.d.ts +26 -27
  134. package/core/variable/tgpuVariable.js +93 -96
  135. package/core/vertexLayout/connectAttributesToShader.d.ts +9 -0
  136. package/core/vertexLayout/connectAttributesToShader.js +61 -56
  137. package/core/vertexLayout/vertexAttribute.d.ts +21 -17
  138. package/core/vertexLayout/vertexAttribute.js +1 -0
  139. package/core/vertexLayout/vertexLayout.d.ts +24 -18
  140. package/core/vertexLayout/vertexLayout.js +130 -99
  141. package/core/whitespaces.d.ts +2 -0
  142. package/core/whitespaces.js +16 -0
  143. package/data/alignIO.d.ts +7 -0
  144. package/data/alignIO.js +13 -13
  145. package/data/alignmentOf.d.ts +5 -8
  146. package/data/alignmentOf.js +90 -75
  147. package/data/array.d.ts +6 -9
  148. package/data/array.js +48 -40
  149. package/data/atomic.d.ts +2 -7
  150. package/data/atomic.js +26 -23
  151. package/data/attributes.d.ts +19 -21
  152. package/data/attributes.js +192 -132
  153. package/data/autoStruct.d.ts +36 -3
  154. package/data/autoStruct.js +84 -81
  155. package/data/compiledIO.d.ts +5 -0
  156. package/data/compiledIO.js +231 -214
  157. package/data/dataIO.d.ts +13 -11
  158. package/data/dataIO.js +643 -589
  159. package/data/dataTypes.d.ts +83 -65
  160. package/data/dataTypes.js +66 -68
  161. package/data/deepEqual.d.ts +2 -7
  162. package/data/deepEqual.js +80 -55
  163. package/data/disarray.d.ts +6 -10
  164. package/data/disarray.js +52 -46
  165. package/data/float16Conversion.d.ts +4 -0
  166. package/data/float16Conversion.js +7 -0
  167. package/data/getLongestContiguousPrefix.d.ts +4 -8
  168. package/data/getLongestContiguousPrefix.js +6 -11
  169. package/data/index.d.ts +30 -31
  170. package/data/index.js +39 -172
  171. package/data/instanceToSchema.d.ts +24 -27
  172. package/data/instanceToSchema.js +1 -0
  173. package/data/isContiguous.d.ts +4 -8
  174. package/data/isContiguous.js +6 -11
  175. package/data/matrix.d.ts +21 -21
  176. package/data/matrix.js +513 -505
  177. package/data/numberOps.d.ts +6 -0
  178. package/data/numberOps.js +26 -20
  179. package/data/numeric.d.ts +21 -12
  180. package/data/numeric.js +287 -192
  181. package/data/offsetUtils.d.ts +9 -13
  182. package/data/offsetUtils.js +204 -144
  183. package/data/offsets.d.ts +8 -0
  184. package/data/offsets.js +33 -33
  185. package/data/partialIO.d.ts +13 -8
  186. package/data/partialIO.js +124 -113
  187. package/data/ptr.d.ts +12 -12
  188. package/data/ptr.js +42 -44
  189. package/data/ref.d.ts +40 -27
  190. package/data/ref.js +125 -95
  191. package/data/sampler.d.ts +99 -101
  192. package/data/sampler.js +17 -21
  193. package/data/schemaCallWrapper.d.ts +19 -0
  194. package/data/schemaCallWrapper.js +31 -26
  195. package/data/schemaMemoryLayout.d.ts +8 -0
  196. package/data/schemaMemoryLayout.js +213 -185
  197. package/data/sizeOf.d.ts +4 -8
  198. package/data/sizeOf.js +6 -11
  199. package/data/snippet.d.ts +96 -20
  200. package/data/snippet.js +75 -86
  201. package/data/struct.d.ts +4 -7
  202. package/data/struct.js +51 -39
  203. package/data/texture.d.ts +253 -250
  204. package/data/texture.js +238 -200
  205. package/data/unstruct.d.ts +2 -7
  206. package/data/unstruct.js +43 -37
  207. package/data/vector.d.ts +33 -21
  208. package/data/vector.js +234 -221
  209. package/data/vectorImpl.d.ts +231 -0
  210. package/data/vectorImpl.js +563 -515
  211. package/data/vectorOps.d.ts +63 -0
  212. package/data/vectorOps.js +642 -630
  213. package/data/vertexFormatData.d.ts +181 -184
  214. package/data/vertexFormatData.js +104 -106
  215. package/data/wgslTypes.d.ts +665 -600
  216. package/data/wgslTypes.js +220 -198
  217. package/errors.d.ts +50 -24
  218. package/errors.js +146 -120
  219. package/execMode.d.ts +16 -0
  220. package/execMode.js +47 -40
  221. package/extension.d.ts +13 -8
  222. package/extension.js +10 -16
  223. package/getGPUValue.d.ts +1 -0
  224. package/getGPUValue.js +2 -7
  225. package/index.d.ts +28 -68
  226. package/index.js +8 -28
  227. package/indexNamedExports.d.ts +69 -42
  228. package/indexNamedExports.js +25 -0
  229. package/internal.d.ts +16 -0
  230. package/internal.js +12 -0
  231. package/mathUtils.d.ts +5 -0
  232. package/mathUtils.js +7 -11
  233. package/memo.d.ts +11 -0
  234. package/memo.js +20 -22
  235. package/minify.d.ts +5 -0
  236. package/minify.js +93 -0
  237. package/nameUtils.d.ts +29 -0
  238. package/nameUtils.js +428 -398
  239. package/package.json +9 -3
  240. package/resolutionCtx.d.ts +162 -22
  241. package/resolutionCtx.js +911 -624
  242. package/serial/registry.d.ts +15 -0
  243. package/serial/registry.js +106 -0
  244. package/serial/restore.d.ts +49 -0
  245. package/serial/restore.js +68 -0
  246. package/serial/schema.d.ts +58 -0
  247. package/serial/schema.js +209 -0
  248. package/serial/types.d.ts +5 -0
  249. package/serial/types.js +1 -0
  250. package/shared/env.d.ts +9 -0
  251. package/shared/env.js +9 -12
  252. package/shared/generators.d.ts +4 -0
  253. package/shared/generators.js +10 -12
  254. package/shared/meta.d.ts +29 -14
  255. package/shared/meta.js +71 -55
  256. package/shared/normalizeMetadata.d.ts +32 -27
  257. package/shared/normalizeMetadata.js +23 -36
  258. package/shared/repr.d.ts +73 -55
  259. package/shared/repr.js +1 -0
  260. package/shared/soul.d.ts +17 -0
  261. package/shared/soul.js +1 -0
  262. package/shared/stringify.d.ts +2 -0
  263. package/shared/stringify.js +29 -20
  264. package/shared/symbols.d.ts +26 -20
  265. package/shared/symbols.js +79 -79
  266. package/shared/tseynit.d.ts +2 -0
  267. package/shared/tseynit.js +160 -75
  268. package/shared/utilityTypes.d.ts +30 -14
  269. package/shared/utilityTypes.js +2 -6
  270. package/shared/vertexFormat.d.ts +41 -43
  271. package/shared/vertexFormat.js +59 -62
  272. package/std/array.d.ts +2 -7
  273. package/std/array.js +18 -23
  274. package/std/atomic.d.ts +14 -18
  275. package/std/atomic.js +96 -95
  276. package/std/bitcast.d.ts +193 -10
  277. package/std/bitcast.js +309 -39
  278. package/std/boolean.d.ts +19 -33
  279. package/std/boolean.js +296 -288
  280. package/std/copy.d.ts +2 -7
  281. package/std/copy.js +27 -24
  282. package/std/derivative.d.ts +11 -15
  283. package/std/derivative.js +56 -79
  284. package/std/discard.d.ts +1 -6
  285. package/std/discard.js +7 -14
  286. package/std/environment.d.ts +19 -14
  287. package/std/environment.js +71 -51
  288. package/std/extensions.d.ts +2 -8
  289. package/std/extensions.js +10 -11
  290. package/std/index.d.ts +20 -24
  291. package/std/index.js +32 -187
  292. package/std/matrix.d.ts +6 -12
  293. package/std/matrix.js +60 -69
  294. package/std/numeric.d.ts +143 -146
  295. package/std/numeric.js +858 -749
  296. package/std/operators.d.ts +19 -27
  297. package/std/operators.js +227 -193
  298. package/std/packing.d.ts +5 -11
  299. package/std/packing.js +67 -75
  300. package/std/range.d.ts +6 -11
  301. package/std/range.js +48 -36
  302. package/std/subgroup.d.ts +33 -37
  303. package/std/subgroup.js +180 -217
  304. package/std/texture.d.ts +70 -38
  305. package/std/texture.js +176 -172
  306. package/taskQueue.d.ts +6 -0
  307. package/taskQueue.js +30 -0
  308. package/tgpu.d.ts +16 -0
  309. package/tgpu.js +17 -44
  310. package/tgpuBindGroupLayout.d.ts +132 -152
  311. package/tgpuBindGroupLayout.js +346 -268
  312. package/tgpuLogger.d.ts +34 -0
  313. package/tgpuLogger.js +63 -0
  314. package/tgpuUnstable.d.ts +16 -22
  315. package/tgpuUnstable.js +13 -35
  316. package/tgsl/accessIndex.d.ts +2 -0
  317. package/tgsl/accessIndex.js +76 -33
  318. package/tgsl/accessProp.d.ts +2 -0
  319. package/tgsl/accessProp.js +142 -100
  320. package/tgsl/accessStructProp.d.ts +5 -0
  321. package/tgsl/accessStructProp.js +18 -0
  322. package/tgsl/consoleLog/deserializers.d.ts +13 -0
  323. package/tgsl/consoleLog/deserializers.js +119 -103
  324. package/tgsl/consoleLog/logGenerator.d.ts +21 -0
  325. package/tgsl/consoleLog/logGenerator.js +85 -80
  326. package/tgsl/consoleLog/serializers.d.ts +21 -0
  327. package/tgsl/consoleLog/serializers.js +119 -100
  328. package/tgsl/consoleLog/types.d.ts +40 -39
  329. package/tgsl/consoleLog/types.js +1 -0
  330. package/tgsl/conversion.d.ts +33 -0
  331. package/tgsl/conversion.js +272 -193
  332. package/tgsl/forOfUtils.d.ts +15 -0
  333. package/tgsl/forOfUtils.js +85 -70
  334. package/tgsl/generationHelpers.d.ts +22 -39
  335. package/tgsl/generationHelpers.js +85 -58
  336. package/tgsl/infixDispatch.d.ts +70 -0
  337. package/tgsl/infixDispatch.js +48 -46
  338. package/tgsl/jsPolyfills.d.ts +16 -19
  339. package/tgsl/jsPolyfills.js +44 -42
  340. package/tgsl/makeDereferenceable.d.ts +48 -0
  341. package/tgsl/makeDereferenceable.js +86 -0
  342. package/tgsl/makeResolvable.d.ts +22 -0
  343. package/tgsl/makeResolvable.js +33 -0
  344. package/tgsl/shaderGenerator.d.ts +77 -17
  345. package/tgsl/shaderGenerator.js +1 -0
  346. package/tgsl/shellless.d.ts +6 -9
  347. package/tgsl/shellless.js +73 -43
  348. package/tgsl/wgslGenerator.d.ts +66 -59
  349. package/tgsl/wgslGenerator.js +1344 -747
  350. package/types.d.ts +287 -221
  351. package/types.js +61 -44
  352. package/unwrapper.d.ts +31 -26
  353. package/unwrapper.js +1 -0
  354. package/wgslExtensions.d.ts +3 -5
  355. package/wgslExtensions.js +12 -16
  356. package/_virtual/rolldown_runtime.js +0 -13
  357. package/core/buffer/bufferShorthand.d.ts +0 -50
  358. package/core/buffer/bufferShorthand.js +0 -55
  359. package/core/pipeline/applyPipelineState.js +0 -37
  360. package/package.js +0 -5
  361. package/tgsl/shaderGenerator_members.d.ts +0 -33
  362. package/tgsl/shaderGenerator_members.js +0 -12
@@ -1,213 +1,292 @@
1
- import { DEV, TEST } from "../shared/env.js";
2
- import { isMat, isPtr, isVec } from "../data/wgslTypes.js";
3
- import { safeStringify } from "../shared/stringify.js";
4
- import { UnknownData, undecorate } from "../data/dataTypes.js";
5
- import { snip, withDataType } from "../data/snippet.js";
6
- import { WgslTypeError, invariant } from "../errors.js";
7
- import { stitch } from "../core/resolve/stitch.js";
8
- import { RefOperator, derefSnippet } from "../data/ref.js";
1
+ import { UnknownData } from "../data/dataTypes.js";
2
+ import { undecorate } from "../data/dataTypes.js";
3
+ import { derefSnippet, RefOperator } from "../data/ref.js";
9
4
  import { schemaCallWrapperGPU } from "../data/schemaCallWrapper.js";
5
+ import { snip, withDataType } from "../data/snippet.js";
6
+ import { isMat, isPtr, isVec, isWgslStruct, } from "../data/wgslTypes.js";
7
+ import { invariant, WgslTypeError } from "../errors.js";
8
+ import { getName } from "../shared/meta.js";
9
+ import { safeStringify } from "../shared/stringify.js";
10
10
  import { assertExhaustive } from "../shared/utilityTypes.js";
11
-
12
- //#region src/tgsl/conversion.ts
11
+ import { logger } from "../tgpuLogger.js";
12
+ import { accessStructProp } from "./accessStructProp.js";
13
13
  const INFINITE_RANK = {
14
- rank: Number.POSITIVE_INFINITY,
15
- action: "none"
14
+ rank: Number.POSITIVE_INFINITY,
15
+ action: 'none',
16
16
  };
17
17
  function getAutoConversionRank(src, dest) {
18
- const trueSrc = undecorate(src);
19
- const trueDst = undecorate(dest);
20
- if (trueSrc.type === trueDst.type) return {
21
- rank: 0,
22
- action: "none"
23
- };
24
- if (trueSrc.type === "abstractFloat") {
25
- if (trueDst.type === "f32") return {
26
- rank: 1,
27
- action: "none"
28
- };
29
- if (trueDst.type === "f16") return {
30
- rank: 2,
31
- action: "none"
32
- };
33
- }
34
- if (trueSrc.type === "abstractInt") {
35
- if (trueDst.type === "i32") return {
36
- rank: 3,
37
- action: "none"
38
- };
39
- if (trueDst.type === "u32") return {
40
- rank: 4,
41
- action: "none"
42
- };
43
- if (trueDst.type === "abstractFloat") return {
44
- rank: 5,
45
- action: "none"
46
- };
47
- if (trueDst.type === "f32") return {
48
- rank: 6,
49
- action: "none"
50
- };
51
- if (trueDst.type === "f16") return {
52
- rank: 7,
53
- action: "none"
54
- };
55
- }
56
- if (isVec(trueSrc) && isVec(trueDst) && trueSrc.type[3] === trueDst.type[3]) return getAutoConversionRank(trueSrc.primitive, trueDst.primitive);
57
- if (isMat(trueSrc) && isMat(trueDst) && trueSrc.type[3] === trueDst.type[3]) return {
58
- rank: 0,
59
- action: "none"
60
- };
61
- return INFINITE_RANK;
18
+ const trueSrc = undecorate(src);
19
+ const trueDst = undecorate(dest);
20
+ if (trueSrc.type === trueDst.type) {
21
+ if (trueSrc.type === 'struct' && trueSrc !== trueDst) {
22
+ return { rank: 1, action: 'cast', targetType: dest };
23
+ }
24
+ return { rank: 0, action: 'none' };
25
+ }
26
+ if (trueSrc.type === 'abstractFloat') {
27
+ if (trueDst.type === 'f32')
28
+ return { rank: 1, action: 'none' };
29
+ if (trueDst.type === 'f16')
30
+ return { rank: 2, action: 'none' };
31
+ }
32
+ if (trueSrc.type === 'abstractInt') {
33
+ if (trueDst.type === 'i32')
34
+ return { rank: 3, action: 'none' };
35
+ if (trueDst.type === 'u32')
36
+ return { rank: 4, action: 'none' };
37
+ if (trueDst.type === 'abstractFloat')
38
+ return { rank: 5, action: 'none' };
39
+ if (trueDst.type === 'f32')
40
+ return { rank: 6, action: 'none' };
41
+ if (trueDst.type === 'f16')
42
+ return { rank: 7, action: 'none' };
43
+ }
44
+ if (isVec(trueSrc) &&
45
+ isVec(trueDst) &&
46
+ // Same length vectors
47
+ trueSrc.type[3] === trueDst.type[3]) {
48
+ return getAutoConversionRank(trueSrc.primitive, trueDst.primitive);
49
+ }
50
+ if (isMat(trueSrc) &&
51
+ isMat(trueDst) &&
52
+ // Same dimensions
53
+ trueSrc.type[3] === trueDst.type[3]) {
54
+ // Matrix conversion rank depends only on component type (always f32 for now)
55
+ return { rank: 0, action: 'none' };
56
+ }
57
+ return INFINITE_RANK;
62
58
  }
63
59
  function getImplicitConversionRank(src, dest) {
64
- const trueSrc = undecorate(src);
65
- const trueDst = undecorate(dest);
66
- if (isPtr(trueSrc) && trueSrc.implicit && getAutoConversionRank(trueSrc.inner, trueDst).rank < Number.POSITIVE_INFINITY) return {
67
- rank: 0,
68
- action: "deref"
69
- };
70
- if (isPtr(trueDst) && getAutoConversionRank(trueSrc, trueDst.inner).rank < Number.POSITIVE_INFINITY) return {
71
- rank: 1,
72
- action: "ref"
73
- };
74
- const primitivePreference = {
75
- f32: 0,
76
- f16: 1,
77
- i32: 2,
78
- u32: 3,
79
- bool: 4
80
- };
81
- if (trueSrc.type in primitivePreference && trueDst.type in primitivePreference) {
82
- const srcType = trueSrc.type;
83
- const destType = trueDst.type;
84
- if (srcType !== destType) {
85
- const srcPref = primitivePreference[srcType];
86
- return {
87
- rank: primitivePreference[destType] < srcPref ? 10 : 20,
88
- action: "cast",
89
- targetType: trueDst
90
- };
91
- }
92
- }
93
- if ((trueSrc.type === "u32" || trueSrc.type === "i32") && trueDst.type === "abstractFloat") return {
94
- rank: 1,
95
- action: "cast",
96
- targetType: trueDst.concretized
97
- };
98
- if (trueSrc.type === "abstractFloat") {
99
- if (trueDst.type === "i32") return {
100
- rank: 2,
101
- action: "cast",
102
- targetType: trueDst
103
- };
104
- if (trueDst.type === "u32") return {
105
- rank: 3,
106
- action: "cast",
107
- targetType: trueDst
108
- };
109
- }
110
- return INFINITE_RANK;
60
+ const trueSrc = undecorate(src);
61
+ const trueDst = undecorate(dest);
62
+ if (isPtr(trueSrc) &&
63
+ // Only dereferencing implicit pointers, otherwise we'd have a types mismatch between TS and WGSL
64
+ trueSrc.implicit &&
65
+ getAutoConversionRank(trueSrc.inner, trueDst).rank < Number.POSITIVE_INFINITY) {
66
+ return { rank: 0, action: 'deref' };
67
+ }
68
+ if (isPtr(trueDst) &&
69
+ getAutoConversionRank(trueSrc, trueDst.inner).rank < Number.POSITIVE_INFINITY) {
70
+ return { rank: 1, action: 'ref' };
71
+ }
72
+ const primitivePreference = {
73
+ f32: 0,
74
+ f16: 1,
75
+ i32: 2,
76
+ u32: 3,
77
+ bool: 4,
78
+ };
79
+ if (trueSrc.type in primitivePreference && trueDst.type in primitivePreference) {
80
+ const srcType = trueSrc.type;
81
+ const destType = trueDst.type;
82
+ if (srcType !== destType) {
83
+ const srcPref = primitivePreference[srcType];
84
+ const destPref = primitivePreference[destType];
85
+ const rank = destPref < srcPref ? 10 : 20;
86
+ return { rank: rank, action: 'cast', targetType: trueDst };
87
+ }
88
+ }
89
+ if ((trueSrc.type === 'u32' || trueSrc.type === 'i32') && trueDst.type === 'abstractFloat') {
90
+ // When one of the types is a float (abstract or not), we don't want to cast it to a non-float type,
91
+ // which would cause it to lose precision. We instead choose the common type to be f32.
92
+ return { rank: 1, action: 'cast', targetType: trueDst.concretized };
93
+ }
94
+ if (trueSrc.type === 'abstractFloat') {
95
+ if (trueDst.type === 'i32') {
96
+ return { rank: 2, action: 'cast', targetType: trueDst };
97
+ }
98
+ if (trueDst.type === 'u32') {
99
+ return { rank: 3, action: 'cast', targetType: trueDst };
100
+ }
101
+ }
102
+ return INFINITE_RANK;
111
103
  }
112
104
  function getConversionRank(src, dest, allowImplicit) {
113
- const autoRank = getAutoConversionRank(src, dest);
114
- if (autoRank.rank < Number.POSITIVE_INFINITY) return autoRank;
115
- if (allowImplicit) return getImplicitConversionRank(src, dest);
116
- return INFINITE_RANK;
105
+ const autoRank = getAutoConversionRank(src, dest);
106
+ if (autoRank.rank < Number.POSITIVE_INFINITY) {
107
+ return autoRank;
108
+ }
109
+ if (allowImplicit) {
110
+ return getImplicitConversionRank(src, dest);
111
+ }
112
+ return INFINITE_RANK;
117
113
  }
118
114
  function findBestType(types, uniqueTypes, allowImplicit) {
119
- let bestResult;
120
- for (const targetType of uniqueTypes) {
121
- /**
122
- * The type we end up converting to. Will be different than `targetType` if `targetType === abstractFloat`
123
- */
124
- let destType = targetType;
125
- const details = [];
126
- let sum = 0;
127
- for (const sourceType of types) {
128
- const conversion = getConversionRank(sourceType, targetType, allowImplicit);
129
- sum += conversion.rank;
130
- if (conversion.rank === Number.POSITIVE_INFINITY) break;
131
- details.push(conversion);
132
- if (conversion.action === "cast") destType = conversion.targetType;
133
- }
134
- if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) bestResult = {
135
- type: destType,
136
- details,
137
- sum
138
- };
139
- }
140
- if (!bestResult) return;
141
- const actions = bestResult.details.map((detail, index) => ({
142
- sourceIndex: index,
143
- action: detail.action,
144
- ...detail.action === "cast" && { targetType: detail.targetType }
145
- }));
146
- return {
147
- targetType: bestResult.type,
148
- actions,
149
- hasImplicitConversions: actions.some((action) => action.action === "cast")
150
- };
115
+ let bestResult;
116
+ for (const targetType of uniqueTypes) {
117
+ /**
118
+ * The type we end up converting to. Will be different than `targetType` if `targetType === abstractFloat`
119
+ */
120
+ let destType = targetType;
121
+ const details = [];
122
+ let sum = 0;
123
+ for (const sourceType of types) {
124
+ const conversion = getConversionRank(sourceType, targetType, allowImplicit);
125
+ sum += conversion.rank;
126
+ if (conversion.rank === Number.POSITIVE_INFINITY) {
127
+ break;
128
+ }
129
+ details.push(conversion);
130
+ if (conversion.action === 'cast') {
131
+ destType = conversion.targetType;
132
+ }
133
+ }
134
+ if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) {
135
+ bestResult = { type: destType, details, sum };
136
+ }
137
+ }
138
+ if (!bestResult) {
139
+ return undefined;
140
+ }
141
+ const actions = bestResult.details.map((detail, index) => ({
142
+ sourceIndex: index,
143
+ action: detail.action,
144
+ ...(detail.action === 'cast' && {
145
+ targetType: detail.targetType,
146
+ }),
147
+ }));
148
+ return {
149
+ targetType: bestResult.type,
150
+ actions,
151
+ hasImplicitConversions: actions.some((action) => action.action === 'cast'),
152
+ };
151
153
  }
152
- function getBestConversion(types, targetTypes) {
153
- if (types.length === 0) return void 0;
154
- const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
155
- const explicitResult = findBestType(types, uniqueTargetTypes, false);
156
- if (explicitResult) return explicitResult;
157
- const implicitResult = findBestType(types, uniqueTargetTypes, true);
158
- if (implicitResult) return implicitResult;
154
+ export function getBestConversion(types, targetTypes) {
155
+ if (types.length === 0)
156
+ return undefined;
157
+ const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
158
+ const explicitResult = findBestType(types, uniqueTargetTypes, false);
159
+ if (explicitResult) {
160
+ return explicitResult;
161
+ }
162
+ const implicitResult = findBestType(types, uniqueTargetTypes, true);
163
+ if (implicitResult) {
164
+ return implicitResult;
165
+ }
166
+ return undefined;
159
167
  }
160
168
  function applyActionToSnippet(ctx, snippet, action, targetType) {
161
- if (action.action === "none") {
162
- if (targetType === snippet.dataType) return snippet;
163
- return withDataType(targetType, snippet);
164
- }
165
- switch (action.action) {
166
- case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
167
- case "deref": return derefSnippet(snippet);
168
- case "cast": return schemaCallWrapperGPU(ctx, targetType, snippet);
169
- default: assertExhaustive(action.action, "applyActionToSnippet");
170
- }
169
+ if (action.action === 'none') {
170
+ if (targetType === snippet.dataType) {
171
+ return snippet;
172
+ }
173
+ return withDataType(targetType, snippet);
174
+ }
175
+ switch (action.action) {
176
+ case 'ref':
177
+ return snip(new RefOperator(snippet, targetType), targetType, snippet.origin, snippet.possibleSideEffects);
178
+ case 'deref':
179
+ return derefSnippet(snippet);
180
+ case 'cast': {
181
+ if (isWgslStruct(snippet.dataType) && isWgslStruct(targetType)) {
182
+ const typeName = getName(snippet.dataType) ?? '<unnamed>';
183
+ const targetName = getName(targetType) ?? '<unnamed>';
184
+ // Struct to struct casting
185
+ if (snippet.possibleSideEffects) {
186
+ throw new Error(`Cannot resolve struct cast from '${typeName}' to '${targetName}'. Store the value to a variable first, then cast it.`);
187
+ }
188
+ const propSnips = Object.entries(targetType.propTypes).map(([key, dataType]) => {
189
+ const accessedProp = accessStructProp(snippet, key);
190
+ if (!accessedProp) {
191
+ throw new Error(`Cannot auto-convert struct '${typeName}' to '${targetName}' because the property '${key}' is missing.`);
192
+ }
193
+ const converted = convertToCommonType(ctx, [accessedProp], [dataType]);
194
+ if (!converted || !converted[0]) {
195
+ throw new Error(`Cannot auto-convert struct '${typeName}' to '${targetName}' because type '${getName(accessedProp.dataType) ?? '<unnamed>'}' is not convertible to '${getName(undecorate(dataType)) ?? '<unnamed>'}'.`);
196
+ }
197
+ return converted[0];
198
+ });
199
+ const targetSnippet = ctx.resolve(targetType).value;
200
+ return snip(`${targetSnippet}(${propSnips.map((snip) => snip.value).join(', ')})`, targetType, 'runtime', false);
201
+ }
202
+ // Casting means calling the schema with the snippet as an argument.
203
+ return schemaCallWrapperGPU(ctx, targetType, snippet);
204
+ }
205
+ default: {
206
+ assertExhaustive(action.action, 'applyActionToSnippet');
207
+ }
208
+ }
209
+ }
210
+ /**
211
+ * Unifies input types to a common type.
212
+ */
213
+ export function unify(inTypes, restrictTo) {
214
+ if (inTypes.some((type) => type === UnknownData)) {
215
+ return undefined;
216
+ }
217
+ const conversion = getBestConversion(inTypes, restrictTo);
218
+ if (!conversion) {
219
+ return undefined;
220
+ }
221
+ return inTypes.map((type) => (isVec(type) || isMat(type) ? type : conversion.targetType));
171
222
  }
172
- function unify(inTypes, restrictTo) {
173
- if (inTypes.some((type) => type === UnknownData)) return;
174
- const conversion = getBestConversion(inTypes, restrictTo);
175
- if (!conversion) return;
176
- return inTypes.map((type) => isVec(type) || isMat(type) ? type : conversion.targetType);
223
+ /**
224
+ * Unifies input types to a common type.
225
+ * Unlike `unify`, it does not allow implicit conversions.
226
+ */
227
+ export function unifyStrict(inTypes, restrictTo) {
228
+ if (inTypes.some((type) => type === UnknownData)) {
229
+ return undefined;
230
+ }
231
+ const uniqueTargetTypes = [...new Set((restrictTo || inTypes).map(undecorate))];
232
+ const conversion = findBestType(inTypes, uniqueTargetTypes, false);
233
+ if (!conversion) {
234
+ return undefined;
235
+ }
236
+ return inTypes.map((type) => (isVec(type) || isMat(type) ? type : conversion.targetType));
177
237
  }
178
- function convertToCommonType(ctx, values, restrictTo, verbose = true) {
179
- const types = values.map((value) => value.dataType);
180
- if (types.some((type) => type === UnknownData)) return;
181
- 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.");
182
- const conversion = getBestConversion(types, restrictTo);
183
- if (!conversion) return;
184
- if ((TEST || DEV) && verbose && conversion.hasImplicitConversions) console.warn(`Implicit conversions from [\n${values.map((v) => ` ${ctx.resolveSnippet(v).value}: ${safeStringify(v.dataType)}`).join(",\n")}\n] to ${conversion.targetType.type} are supported, but not recommended.
238
+ export function convertToCommonType(ctx, values, restrictTo, verbose = true) {
239
+ const types = values.map((value) => value.dataType);
240
+ if (types.some((type) => type === UnknownData)) {
241
+ return undefined;
242
+ }
243
+ // Calling convertToCommonType with an empty restrictTo array
244
+ // prevents any conversions from being made. If you intend to allow
245
+ // all conversions, pass undefined instead. If this was intended call
246
+ // the function conditionally since the result will always be undefined.
247
+ invariant(!(Array.isArray(restrictTo) && restrictTo.length === 0), "Internal error, expected 'restrictTo' to not be an empty array.");
248
+ const conversion = getBestConversion(types, restrictTo);
249
+ if (!conversion) {
250
+ return undefined;
251
+ }
252
+ if (verbose && conversion.hasImplicitConversions) {
253
+ logger.warn('implicit-conversion', `Implicit conversions from [\n${values
254
+ .map((v) => ` ${ctx.resolveSnippet(v).value}: ${safeStringify(v.dataType)}`)
255
+ .join(',\n')}\n] to ${conversion.targetType.type} are supported, but not recommended.
185
256
  Consider using explicit conversions instead.`);
186
- return values.map((value, index) => {
187
- const action = conversion.actions[index];
188
- invariant(action, "Action should not be undefined");
189
- return applyActionToSnippet(ctx, value, action, conversion.targetType);
190
- });
257
+ }
258
+ return values.map((value, index) => {
259
+ const action = conversion.actions[index];
260
+ invariant(action, 'Action should not be undefined');
261
+ return applyActionToSnippet(ctx, value, action, conversion.targetType);
262
+ });
191
263
  }
192
- function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
193
- const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
194
- const { value, dataType, origin } = snippet;
195
- if (targets.length === 1) {
196
- const target = targets[0];
197
- if (target === dataType) return snip(value, target, origin);
198
- if (dataType === UnknownData) return snip(stitch`${snip(value, target, origin)}`, target, origin);
199
- }
200
- const converted = convertToCommonType(ctx, [snippet], targets, verbose);
201
- if (converted) return converted[0];
202
- throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(", ")}]`);
264
+ export function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
265
+ const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
266
+ const { value, dataType, origin, possibleSideEffects } = snippet;
267
+ if (targets.length === 1) {
268
+ const target = targets[0];
269
+ if (target === dataType) {
270
+ return snip(value, target, origin, possibleSideEffects);
271
+ }
272
+ if (dataType === UnknownData) {
273
+ // Commit unknown to the expected type.
274
+ return ctx.resolveSnippet(snip(value, target, origin, possibleSideEffects));
275
+ }
276
+ }
277
+ const converted = convertToCommonType(ctx, [snippet], targets, verbose);
278
+ if (converted) {
279
+ return converted[0];
280
+ }
281
+ throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(', ')}]`);
203
282
  }
204
- function convertStructValues(ctx, structType, values) {
205
- return Object.entries(structType.propTypes).map(([key, targetType]) => {
206
- const val = values[key];
207
- if (!val) throw new Error(`Missing property ${key}`);
208
- return convertToCommonType(ctx, [val], [targetType])?.[0] ?? val;
209
- });
283
+ export function convertStructValues(ctx, structType, values) {
284
+ return Object.entries(structType.propTypes).map(([key, targetType]) => {
285
+ const val = values[key];
286
+ if (!val) {
287
+ throw new Error(`Missing property ${key}`);
288
+ }
289
+ const converted = convertToCommonType(ctx, [val], [targetType]);
290
+ return converted?.[0] ?? val;
291
+ });
210
292
  }
211
-
212
- //#endregion
213
- export { convertStructValues, convertToCommonType, getBestConversion, tryConvertSnippet, unify };
@@ -0,0 +1,15 @@
1
+ import { type Snippet } from '../data/snippet.ts';
2
+ import * as wgsl from '../data/wgslTypes.ts';
3
+ import type { ResolutionCtx } from '../types.ts';
4
+ export declare function getLoopVarKind(elementSnippet: Snippet): "let" | "const";
5
+ export declare function getElementSnippet(iterableSnippet: Snippet, index: Snippet): Snippet;
6
+ /**
7
+ * Determines the type of the element as accessible inside of the `for .. of` loop body
8
+ */
9
+ export declare function getElementType(elementSnippet: Snippet, iterableSnippet: Snippet): wgsl.BaseData;
10
+ export declare function getRangeSnippets(ctx: ResolutionCtx, iterableSnippet: Snippet, unroll?: boolean): {
11
+ start: Snippet;
12
+ end: Snippet;
13
+ step: Snippet;
14
+ comparison: '<' | '>';
15
+ };