typegpu 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/{chunk-BYypO7fO.js → _virtual/_rolldown/runtime.js} +1 -1
  2. package/builtin.d.ts +50 -0
  3. package/builtin.js +37 -0
  4. package/common/fullScreenTriangle.d.ts +26 -0
  5. package/common/fullScreenTriangle.js +36 -0
  6. package/common/index.d.ts +2 -3
  7. package/common/index.js +3 -4
  8. package/core/buffer/buffer.d.ts +74 -0
  9. package/core/buffer/buffer.js +197 -0
  10. package/core/buffer/bufferShorthand.d.ts +48 -0
  11. package/core/buffer/bufferShorthand.js +49 -0
  12. package/core/buffer/bufferUsage.d.ts +45 -0
  13. package/core/buffer/bufferUsage.js +163 -0
  14. package/core/constant/tgpuConstant.d.ts +28 -0
  15. package/core/constant/tgpuConstant.js +67 -0
  16. package/core/declare/tgpuDeclare.d.ts +18 -0
  17. package/core/declare/tgpuDeclare.js +40 -0
  18. package/core/function/autoIO.d.ts +37 -0
  19. package/core/function/autoIO.js +87 -0
  20. package/core/function/comptime.d.ts +39 -0
  21. package/core/function/comptime.js +51 -0
  22. package/core/function/createCallableSchema.js +42 -0
  23. package/core/function/dualImpl.js +54 -0
  24. package/core/function/extractArgs.js +204 -0
  25. package/core/function/fnCore.js +79 -0
  26. package/core/function/fnTypes.d.ts +34 -0
  27. package/core/function/ioSchema.d.ts +10 -0
  28. package/core/function/ioSchema.js +30 -0
  29. package/core/function/shelllessImpl.d.ts +28 -0
  30. package/core/function/shelllessImpl.js +23 -0
  31. package/core/function/templateUtils.js +13 -0
  32. package/core/function/tgpuComputeFn.d.ts +49 -0
  33. package/core/function/tgpuComputeFn.js +62 -0
  34. package/core/function/tgpuFn.d.ts +52 -0
  35. package/core/function/tgpuFn.js +170 -0
  36. package/core/function/tgpuFragmentFn.d.ts +68 -0
  37. package/core/function/tgpuFragmentFn.js +68 -0
  38. package/core/function/tgpuVertexFn.d.ts +55 -0
  39. package/core/function/tgpuVertexFn.js +65 -0
  40. package/core/pipeline/applyPipelineState.js +37 -0
  41. package/core/pipeline/computePipeline.d.ts +58 -0
  42. package/core/pipeline/computePipeline.js +226 -0
  43. package/core/pipeline/connectAttachmentToShader.js +26 -0
  44. package/core/pipeline/connectTargetsToShader.js +29 -0
  45. package/core/pipeline/limitsOverflow.js +13 -0
  46. package/core/pipeline/renderPipeline.d.ts +266 -0
  47. package/core/pipeline/renderPipeline.js +471 -0
  48. package/core/pipeline/timeable.d.ts +23 -0
  49. package/core/pipeline/timeable.js +61 -0
  50. package/core/pipeline/typeGuards.js +29 -0
  51. package/core/querySet/querySet.d.ts +22 -0
  52. package/core/querySet/querySet.js +103 -0
  53. package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
  54. package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +96 -0
  55. package/core/resolve/externals.d.ts +10 -0
  56. package/core/resolve/externals.js +58 -0
  57. package/core/resolve/namespace.d.ts +38 -0
  58. package/core/resolve/namespace.js +41 -0
  59. package/core/resolve/resolveData.js +146 -0
  60. package/core/resolve/stitch.js +25 -0
  61. package/core/resolve/tgpuResolve.d.ts +151 -0
  62. package/core/resolve/tgpuResolve.js +68 -0
  63. package/core/root/configurableImpl.js +18 -0
  64. package/core/root/init.d.ts +69 -0
  65. package/core/root/init.js +457 -0
  66. package/core/root/rootTypes.d.ts +622 -0
  67. package/core/sampler/sampler.d.ts +35 -0
  68. package/core/sampler/sampler.js +116 -0
  69. package/core/simulate/tgpuSimulate.d.ts +36 -0
  70. package/core/simulate/tgpuSimulate.js +76 -0
  71. package/core/slot/accessor.d.ts +13 -0
  72. package/core/slot/accessor.js +97 -0
  73. package/core/slot/internalSlots.js +7 -0
  74. package/core/slot/lazy.d.ts +6 -0
  75. package/core/slot/lazy.js +42 -0
  76. package/core/slot/slot.d.ts +6 -0
  77. package/core/slot/slot.js +40 -0
  78. package/core/slot/slotTypes.d.ts +92 -0
  79. package/core/slot/slotTypes.js +21 -0
  80. package/core/texture/externalTexture.d.ts +12 -0
  81. package/core/texture/externalTexture.js +48 -0
  82. package/core/texture/texture.d.ts +118 -0
  83. package/core/texture/texture.js +312 -0
  84. package/core/texture/textureFormats.d.ts +29 -0
  85. package/core/texture/textureFormats.js +99 -0
  86. package/core/texture/textureProps.d.ts +11 -0
  87. package/core/texture/textureUtils.js +224 -0
  88. package/core/texture/usageExtension.d.ts +21 -0
  89. package/core/texture/usageExtension.js +21 -0
  90. package/core/unroll/tgpuUnroll.d.ts +13 -0
  91. package/core/unroll/tgpuUnroll.js +36 -0
  92. package/core/valueProxyUtils.js +44 -0
  93. package/core/variable/tgpuVariable.d.ts +38 -0
  94. package/core/variable/tgpuVariable.js +101 -0
  95. package/core/vertexLayout/connectAttributesToShader.js +59 -0
  96. package/core/vertexLayout/vertexAttribute.d.ts +29 -0
  97. package/core/vertexLayout/vertexLayout.d.ts +19 -0
  98. package/core/vertexLayout/vertexLayout.js +103 -0
  99. package/data/alignIO.js +15 -0
  100. package/data/alignmentOf.d.ts +10 -0
  101. package/data/alignmentOf.js +88 -0
  102. package/data/array.d.ts +28 -0
  103. package/data/array.js +48 -0
  104. package/data/atomic.d.ts +15 -0
  105. package/data/atomic.js +25 -0
  106. package/data/attributes.d.ts +121 -0
  107. package/data/attributes.js +145 -0
  108. package/data/autoStruct.d.ts +3 -0
  109. package/data/autoStruct.js +83 -0
  110. package/data/compiledIO.js +231 -0
  111. package/data/dataIO.js +549 -0
  112. package/data/dataTypes.d.ts +115 -0
  113. package/data/dataTypes.js +97 -0
  114. package/data/deepEqual.d.ts +25 -0
  115. package/data/deepEqual.js +58 -0
  116. package/data/disarray.d.ts +34 -0
  117. package/data/disarray.js +52 -0
  118. package/data/getLongestContiguousPrefix.d.ts +10 -0
  119. package/data/getLongestContiguousPrefix.js +15 -0
  120. package/data/index.d.ts +26 -4
  121. package/data/index.js +27 -7
  122. package/data/instanceToSchema.d.ts +33 -0
  123. package/data/isContiguous.d.ts +10 -0
  124. package/data/isContiguous.js +15 -0
  125. package/data/matrix.d.ts +126 -0
  126. package/data/matrix.js +517 -0
  127. package/data/numberOps.js +24 -0
  128. package/data/numeric.d.ts +81 -0
  129. package/data/numeric.js +234 -0
  130. package/data/offsetUtils.d.ts +33 -0
  131. package/data/offsetUtils.js +167 -0
  132. package/data/offsets.js +36 -0
  133. package/data/partialIO.js +68 -0
  134. package/data/ptr.d.ts +12 -0
  135. package/data/ptr.js +46 -0
  136. package/data/ref.d.ts +37 -0
  137. package/data/ref.js +96 -0
  138. package/data/sampler.d.ts +107 -0
  139. package/data/sampler.js +26 -0
  140. package/data/schemaCallWrapper.js +32 -0
  141. package/data/schemaMemoryLayout.js +200 -0
  142. package/data/sizeOf.d.ts +10 -0
  143. package/data/sizeOf.js +15 -0
  144. package/data/snippet.d.ts +26 -0
  145. package/data/snippet.js +61 -0
  146. package/data/struct.d.ts +17 -0
  147. package/data/struct.js +46 -0
  148. package/data/texture.d.ts +292 -0
  149. package/{texture-Dg5ybJro.js → data/texture.js} +6 -3
  150. package/data/unstruct.d.ts +24 -0
  151. package/data/unstruct.js +43 -0
  152. package/data/vector.d.ts +191 -0
  153. package/data/vector.js +247 -0
  154. package/data/vectorImpl.js +516 -0
  155. package/data/vectorOps.js +664 -0
  156. package/data/vertexFormatData.d.ts +190 -0
  157. package/data/vertexFormatData.js +110 -0
  158. package/data/wgslTypes.d.ts +896 -0
  159. package/data/wgslTypes.js +215 -0
  160. package/errors.d.ts +44 -0
  161. package/errors.js +128 -0
  162. package/execMode.js +51 -0
  163. package/extension.d.ts +11 -0
  164. package/extension.js +18 -0
  165. package/getGPUValue.js +9 -0
  166. package/index.d.ts +40 -243
  167. package/index.js +19 -6318
  168. package/indexNamedExports.d.ts +38 -0
  169. package/mathUtils.js +13 -0
  170. package/memo.js +22 -0
  171. package/nameRegistry.d.ts +30 -0
  172. package/nameRegistry.js +449 -0
  173. package/package.js +5 -0
  174. package/package.json +23 -23
  175. package/resolutionCtx.d.ts +29 -0
  176. package/resolutionCtx.js +546 -0
  177. package/shared/env.js +13 -0
  178. package/shared/generators.js +14 -0
  179. package/shared/meta.d.ts +39 -0
  180. package/shared/meta.js +63 -0
  181. package/shared/repr.d.ts +108 -0
  182. package/shared/stringify.js +22 -0
  183. package/shared/symbols.d.ts +61 -0
  184. package/shared/symbols.js +71 -0
  185. package/shared/utilityTypes.d.ts +29 -0
  186. package/shared/utilityTypes.js +7 -0
  187. package/shared/vertexFormat.d.ts +70 -0
  188. package/shared/vertexFormat.js +64 -0
  189. package/std/array.d.ts +7 -0
  190. package/std/array.js +27 -0
  191. package/std/atomic.d.ts +19 -0
  192. package/std/atomic.js +113 -0
  193. package/std/bitcast.d.ts +10 -0
  194. package/std/bitcast.js +43 -0
  195. package/std/boolean.d.ts +127 -0
  196. package/std/boolean.js +274 -0
  197. package/std/derivative.d.ts +16 -0
  198. package/std/derivative.js +89 -0
  199. package/std/discard.d.ts +6 -0
  200. package/std/discard.js +16 -0
  201. package/std/extensions.d.ts +8 -0
  202. package/std/extensions.js +14 -0
  203. package/std/index.d.ts +15 -3
  204. package/std/index.js +16 -5
  205. package/std/matrix.d.ts +41 -0
  206. package/std/matrix.js +87 -0
  207. package/std/numeric.d.ts +254 -0
  208. package/std/numeric.js +847 -0
  209. package/std/operators.d.ts +48 -0
  210. package/std/operators.js +153 -0
  211. package/std/packing.d.ts +26 -0
  212. package/std/packing.js +86 -0
  213. package/std/subgroup.d.ts +47 -0
  214. package/std/subgroup.js +220 -0
  215. package/std/texture.d.ts +108 -0
  216. package/std/texture.js +197 -0
  217. package/tgpu.js +44 -0
  218. package/tgpuBindGroupLayout.d.ts +161 -0
  219. package/tgpuBindGroupLayout.js +271 -0
  220. package/tgpuUnstable.d.ts +48 -0
  221. package/tgpuUnstable.js +66 -0
  222. package/tgsl/accessIndex.js +45 -0
  223. package/tgsl/accessProp.js +113 -0
  224. package/tgsl/consoleLog/deserializers.js +117 -0
  225. package/tgsl/consoleLog/logGenerator.js +86 -0
  226. package/tgsl/consoleLog/serializers.js +225 -0
  227. package/tgsl/consoleLog/types.d.ts +54 -0
  228. package/tgsl/consoleLog/types.js +12 -0
  229. package/tgsl/conversion.js +200 -0
  230. package/tgsl/forOfUtils.js +45 -0
  231. package/tgsl/generationHelpers.d.ts +37 -0
  232. package/tgsl/generationHelpers.js +67 -0
  233. package/tgsl/math.js +45 -0
  234. package/tgsl/shaderGenerator.d.ts +18 -0
  235. package/tgsl/shellless.d.ts +11 -0
  236. package/tgsl/shellless.js +53 -0
  237. package/tgsl/wgslGenerator.js +585 -0
  238. package/types.d.ts +255 -0
  239. package/types.js +43 -0
  240. package/unwrapper.d.ts +27 -0
  241. package/wgslExtensions.d.ts +5 -0
  242. package/wgslExtensions.js +18 -0
  243. package/builtin-ClEnM-Ye.js +0 -818
  244. package/builtin-ClEnM-Ye.js.map +0 -1
  245. package/common/index.d.ts.map +0 -1
  246. package/common/index.js.map +0 -1
  247. package/data/index.d.ts.map +0 -1
  248. package/data/index.js.map +0 -1
  249. package/deepEqual-yZXvaV2C.js +0 -413
  250. package/deepEqual-yZXvaV2C.js.map +0 -1
  251. package/extensions-0SFbU9FH.js +0 -2032
  252. package/extensions-0SFbU9FH.js.map +0 -1
  253. package/fullScreenTriangle-MdLGaAMR.js +0 -543
  254. package/fullScreenTriangle-MdLGaAMR.js.map +0 -1
  255. package/index.d.ts.map +0 -1
  256. package/index.js.map +0 -1
  257. package/indexNamedExports-Cdy7USiY.d.ts +0 -5696
  258. package/indexNamedExports-Cdy7USiY.d.ts.map +0 -1
  259. package/operators-HTxa_0k9.js +0 -4156
  260. package/operators-HTxa_0k9.js.map +0 -1
  261. package/std/index.d.ts.map +0 -1
  262. package/std/index.js.map +0 -1
  263. package/texture-Dg5ybJro.js.map +0 -1
@@ -0,0 +1,86 @@
1
+ import { $internal } from "../../shared/symbols.js";
2
+ import { Void } from "../../data/wgslTypes.js";
3
+ import { UnknownData } from "../../data/dataTypes.js";
4
+ import { snip } from "../../data/snippet.js";
5
+ import { stitch } from "../../core/resolve/stitch.js";
6
+ import { u32 } from "../../data/numeric.js";
7
+ import { struct } from "../../data/struct.js";
8
+ import { concretizeSnippets } from "../generationHelpers.js";
9
+ import { shaderStageSlot } from "../../core/slot/internalSlots.js";
10
+ import { arrayOf } from "../../data/array.js";
11
+ import { atomic } from "../../data/atomic.js";
12
+ import { createLoggingFunction } from "./serializers.js";
13
+ import { supportedLogOps } from "./types.js";
14
+
15
+ //#region src/tgsl/consoleLog/logGenerator.ts
16
+ const defaultOptions = {
17
+ logCountLimit: 64,
18
+ logSizeLimit: 252,
19
+ messagePrefix: " GPU "
20
+ };
21
+ const fallbackSnippet = snip("/* console.log() */", Void, "runtime");
22
+ var LogGeneratorNullImpl = class {
23
+ get logResources() {}
24
+ generateLog() {
25
+ console.warn("'console.log' is only supported when resolving pipelines.");
26
+ return fallbackSnippet;
27
+ }
28
+ };
29
+ var LogGeneratorImpl = class {
30
+ #options;
31
+ #logIdToMeta;
32
+ #firstUnusedId = 1;
33
+ #indexBuffer;
34
+ #dataBuffer;
35
+ constructor(root) {
36
+ this.#options = {
37
+ ...defaultOptions,
38
+ ...root[$internal].logOptions
39
+ };
40
+ this.#logIdToMeta = /* @__PURE__ */ new Map();
41
+ const SerializedLogData = struct({
42
+ id: u32,
43
+ serializedData: arrayOf(u32, Math.ceil(this.#options.logSizeLimit / 4))
44
+ }).$name("SerializedLogData");
45
+ this.#dataBuffer = root.createMutable(arrayOf(SerializedLogData, this.#options.logCountLimit)).$name("dataBuffer");
46
+ this.#indexBuffer = root.createMutable(atomic(u32)).$name("indexBuffer");
47
+ }
48
+ /**
49
+ * Generates all necessary resources for serializing arguments for logging purposes.
50
+ *
51
+ * @param ctx Resolution context.
52
+ * @param args Argument snippets. Snippets of UnknownType will be treated as string literals.
53
+ * @returns A snippet containing the call to the logging function.
54
+ */
55
+ generateLog(ctx, op, args) {
56
+ if (shaderStageSlot.$ === "vertex") {
57
+ console.warn(`'console.${op}' is not supported in vertex shaders.`);
58
+ return fallbackSnippet;
59
+ }
60
+ if (!supportedLogOps.includes(op)) {
61
+ console.warn(`Unsupported log method '${op}'.`);
62
+ return fallbackSnippet;
63
+ }
64
+ const concreteArgs = concretizeSnippets(args);
65
+ const id = this.#firstUnusedId++;
66
+ const nonStringArgs = concreteArgs.filter((e) => e.dataType !== UnknownData);
67
+ const logFn = createLoggingFunction(id, nonStringArgs.map((e) => e.dataType), this.#dataBuffer, this.#indexBuffer, this.#options);
68
+ const argTypes = concreteArgs.map((e) => e.dataType === UnknownData ? e.value : e.dataType);
69
+ this.#logIdToMeta.set(id, {
70
+ op,
71
+ argTypes
72
+ });
73
+ return snip(stitch`${ctx.resolve(logFn).value}(${nonStringArgs})`, Void, "runtime");
74
+ }
75
+ get logResources() {
76
+ return this.#firstUnusedId === 1 ? void 0 : {
77
+ dataBuffer: this.#dataBuffer,
78
+ indexBuffer: this.#indexBuffer,
79
+ options: this.#options,
80
+ logIdToMeta: this.#logIdToMeta
81
+ };
82
+ }
83
+ };
84
+
85
+ //#endregion
86
+ export { LogGeneratorImpl, LogGeneratorNullImpl };
@@ -0,0 +1,225 @@
1
+ import { getName } from "../../shared/meta.js";
2
+ import { isWgslArray, isWgslStruct } from "../../data/wgslTypes.js";
3
+ import { bool, f16, f32, i32, u32 } from "../../data/numeric.js";
4
+ import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
5
+ import { sizeOf } from "../../data/sizeOf.js";
6
+ import { mat2x2f, mat3x3f, mat4x4f } from "../../data/matrix.js";
7
+ import { fn } from "../../core/function/tgpuFn.js";
8
+ import { slot } from "../../core/slot/slot.js";
9
+ import { privateVar } from "../../core/variable/tgpuVariable.js";
10
+
11
+ //#region src/tgsl/consoleLog/serializers.ts
12
+ const dataBlockIndex = privateVar(u32, 0).$name("dataBlockIndex");
13
+ const dataByteIndex = privateVar(u32, 0).$name("dataByteIndex");
14
+ const dataBufferSlot = slot().$name("dataBuffer");
15
+ const nextByteIndex = fn([], u32)`() {
16
+ let i = dataByteIndex;
17
+ dataByteIndex = dataByteIndex + 1u;
18
+ return i;
19
+ }`.$uses({ dataByteIndex }).$name("nextByteIndex");
20
+ const nextU32 = "dataBuffer[dataBlockIndex].serializedData[nextByteIndex()]";
21
+ const serializerMap = {
22
+ f32: fn([f32])`(n) => {
23
+ ${nextU32} = bitcast<u32>(n);
24
+ }`,
25
+ f16: fn([f16])`(n) => {
26
+ ${nextU32} = pack2x16float(vec2f(f32(n), 0.0));
27
+ }`,
28
+ i32: fn([i32])`(n) => {
29
+ ${nextU32} = bitcast<u32>(n);
30
+ }`,
31
+ u32: fn([u32])`(n) => {
32
+ ${nextU32} = n;
33
+ }`,
34
+ bool: fn([bool])`(b) => {
35
+ ${nextU32} = u32(b);
36
+ }`,
37
+ vec2f: fn([vec2f])`(v) => {
38
+ ${nextU32} = bitcast<u32>(v.x);
39
+ ${nextU32} = bitcast<u32>(v.y);
40
+ }`,
41
+ vec3f: fn([vec3f])`(v) => {
42
+ ${nextU32} = bitcast<u32>(v.x);
43
+ ${nextU32} = bitcast<u32>(v.y);
44
+ ${nextU32} = bitcast<u32>(v.z);
45
+ }`,
46
+ vec4f: fn([vec4f])`(v) => {
47
+ ${nextU32} = bitcast<u32>(v.x);
48
+ ${nextU32} = bitcast<u32>(v.y);
49
+ ${nextU32} = bitcast<u32>(v.z);
50
+ ${nextU32} = bitcast<u32>(v.w);
51
+ }`,
52
+ vec2h: fn([vec2h])`(v) => {
53
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
54
+ }`,
55
+ vec3h: fn([vec3h])`(v) => {
56
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
57
+ ${nextU32} = pack2x16float(vec2f(f32(v.z), 0.0));
58
+ }`,
59
+ vec4h: fn([vec4h])`(v) => {
60
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
61
+ ${nextU32} = pack2x16float(vec2f(f32(v.z), f32(v.w)));
62
+ }`,
63
+ vec2i: fn([vec2i])`(v) => {
64
+ ${nextU32} = bitcast<u32>(v.x);
65
+ ${nextU32} = bitcast<u32>(v.y);
66
+ }`,
67
+ vec3i: fn([vec3i])`(v) => {
68
+ ${nextU32} = bitcast<u32>(v.x);
69
+ ${nextU32} = bitcast<u32>(v.y);
70
+ ${nextU32} = bitcast<u32>(v.z);
71
+ }`,
72
+ vec4i: fn([vec4i])`(v) => {
73
+ ${nextU32} = bitcast<u32>(v.x);
74
+ ${nextU32} = bitcast<u32>(v.y);
75
+ ${nextU32} = bitcast<u32>(v.z);
76
+ ${nextU32} = bitcast<u32>(v.w);
77
+ }`,
78
+ vec2u: fn([vec2u])`(v) => {
79
+ ${nextU32} = v.x;
80
+ ${nextU32} = v.y;
81
+ }`,
82
+ vec3u: fn([vec3u])`(v) => {
83
+ ${nextU32} = v.x;
84
+ ${nextU32} = v.y;
85
+ ${nextU32} = v.z;
86
+ }`,
87
+ vec4u: fn([vec4u])`(v) => {
88
+ ${nextU32} = v.x;
89
+ ${nextU32} = v.y;
90
+ ${nextU32} = v.z;
91
+ ${nextU32} = v.w;
92
+ }`,
93
+ "vec2<bool>": fn([vec2b])`(v) => {
94
+ ${nextU32} = u32(v.x);
95
+ ${nextU32} = u32(v.y);
96
+ }`,
97
+ "vec3<bool>": fn([vec3b])`(v) => {
98
+ ${nextU32} = u32(v.x);
99
+ ${nextU32} = u32(v.y);
100
+ ${nextU32} = u32(v.z);
101
+ }`,
102
+ "vec4<bool>": fn([vec4b])`(v) => {
103
+ ${nextU32} = u32(v.x);
104
+ ${nextU32} = u32(v.y);
105
+ ${nextU32} = u32(v.z);
106
+ ${nextU32} = u32(v.w);
107
+ }`,
108
+ mat2x2f: fn([mat2x2f])`(m) => {
109
+ ${nextU32} = bitcast<u32>(m[0][0]);
110
+ ${nextU32} = bitcast<u32>(m[0][1]);
111
+ ${nextU32} = bitcast<u32>(m[1][0]);
112
+ ${nextU32} = bitcast<u32>(m[1][1]);
113
+ }`,
114
+ mat3x3f: fn([mat3x3f])`(m) => {
115
+ ${nextU32} = bitcast<u32>(m[0][0]);
116
+ ${nextU32} = bitcast<u32>(m[0][1]);
117
+ ${nextU32} = bitcast<u32>(m[0][2]);
118
+ ${nextU32} = 0u;
119
+ ${nextU32} = bitcast<u32>(m[1][0]);
120
+ ${nextU32} = bitcast<u32>(m[1][1]);
121
+ ${nextU32} = bitcast<u32>(m[1][2]);
122
+ ${nextU32} = 0u;
123
+ ${nextU32} = bitcast<u32>(m[2][0]);
124
+ ${nextU32} = bitcast<u32>(m[2][1]);
125
+ ${nextU32} = bitcast<u32>(m[2][2]);
126
+ ${nextU32} = 0u;
127
+ }`,
128
+ mat4x4f: fn([mat4x4f])`(m) => {
129
+ ${nextU32} = bitcast<u32>(m[0][0]);
130
+ ${nextU32} = bitcast<u32>(m[0][1]);
131
+ ${nextU32} = bitcast<u32>(m[0][2]);
132
+ ${nextU32} = bitcast<u32>(m[0][3]);
133
+ ${nextU32} = bitcast<u32>(m[1][0]);
134
+ ${nextU32} = bitcast<u32>(m[1][1]);
135
+ ${nextU32} = bitcast<u32>(m[1][2]);
136
+ ${nextU32} = bitcast<u32>(m[1][3]);
137
+ ${nextU32} = bitcast<u32>(m[2][0]);
138
+ ${nextU32} = bitcast<u32>(m[2][1]);
139
+ ${nextU32} = bitcast<u32>(m[2][2]);
140
+ ${nextU32} = bitcast<u32>(m[2][3]);
141
+ ${nextU32} = bitcast<u32>(m[3][0]);
142
+ ${nextU32} = bitcast<u32>(m[3][1]);
143
+ ${nextU32} = bitcast<u32>(m[3][2]);
144
+ ${nextU32} = bitcast<u32>(m[3][3]);
145
+ }`
146
+ };
147
+ for (const [name, serializer] of Object.entries(serializerMap)) serializer.$name(`serialize${name[0].toLocaleUpperCase()}${name.slice(1)}`).$uses({
148
+ dataBlockIndex,
149
+ nextByteIndex,
150
+ dataBuffer: dataBufferSlot
151
+ });
152
+ function generateHeader(argTypes) {
153
+ return `(${argTypes.map((_, i) => `_arg_${i}`).join(", ")})`;
154
+ }
155
+ /**
156
+ * Returns a serializer TGPU function for a given WGSL data type.
157
+ * If the data type is a base type, one of the preexisting functions (with the `dataBufferSlot` filled) is returned.
158
+ * Otherwise, a new function is generated.
159
+ *
160
+ * @param dataType - The WGSL data type descriptor to return a serializer for
161
+ * @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
162
+ */
163
+ function getSerializer(dataType, dataBuffer) {
164
+ const maybeSerializer = serializerMap[dataType.type];
165
+ if (maybeSerializer) return maybeSerializer.with(dataBufferSlot, dataBuffer);
166
+ if (isWgslStruct(dataType)) {
167
+ const props = Object.keys(dataType.propTypes);
168
+ const propsSerializer = createCompoundSerializer(Object.values(dataType.propTypes), dataBuffer);
169
+ return fn([dataType])`(arg) {\n propsSerializer(${props.map((prop) => `arg.${prop}`).join(", ")});\n}`.$uses({ propsSerializer }).$name(`${getName(dataType) ?? "struct"}Serializer`);
170
+ }
171
+ if (isWgslArray(dataType)) {
172
+ const elementType = dataType.elementType;
173
+ const length = dataType.elementCount;
174
+ const elementSerializer = getSerializer(elementType, dataBuffer);
175
+ return fn([dataType])`(arg) {\n${Array.from({ length }, (_, i) => ` elementSerializer(arg[${i}]);`).join("\n")}\n}`.$uses({ elementSerializer }).$name("arraySerializer");
176
+ }
177
+ throw new Error(`Cannot serialize data of type ${dataType.type}`);
178
+ }
179
+ /**
180
+ * Creates a compound serializer TGPU function that serializes multiple arguments of different types to the data buffer.
181
+ *
182
+ * @param dataTypes - Array of WGSL data types that define the types of arguments to be serialized
183
+ * @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
184
+ */
185
+ function createCompoundSerializer(dataTypes, dataBuffer) {
186
+ const usedSerializers = {};
187
+ return fn(dataTypes)`${generateHeader(dataTypes)} {\n${dataTypes.map((arg, i) => {
188
+ usedSerializers[`serializer${i}`] = getSerializer(arg, dataBuffer);
189
+ return ` serializer${i}(_arg_${i});`;
190
+ }).join("\n")}\n}`.$uses(usedSerializers).$name("compoundSerializer");
191
+ }
192
+ /**
193
+ * Creates a TGPU function that serializes data to the log buffer.
194
+ *
195
+ * @param id - Identifier for this logging function instance
196
+ * @param dataTypes - Array of WGSL data types that will be logged by this function
197
+ * @param dataBuffer - Mutable buffer array to store serialized log call data
198
+ * @param indexBuffer - Atomic counter buffer to track the next available log data slot
199
+ * @param logOptions - Configuration options
200
+ */
201
+ function createLoggingFunction(id, dataTypes, dataBuffer, indexBuffer, logOptions) {
202
+ const serializedSize = dataTypes.map(sizeOf).reduce((a, b) => a + b, 0);
203
+ if (serializedSize > logOptions.logSizeLimit) throw new Error(`Logged data needs to fit in ${logOptions.logSizeLimit} bytes (one of the logs requires ${serializedSize} bytes). Consider increasing the limit by passing appropriate options to tgpu.init().`);
204
+ const compoundSerializer = createCompoundSerializer(dataTypes, dataBuffer).$name(`log${id}serializer`);
205
+ const header = generateHeader(dataTypes);
206
+ return fn(dataTypes)`${header} {
207
+ dataBlockIndex = atomicAdd(&indexBuffer, 1);
208
+ if (dataBlockIndex >= ${logOptions.logCountLimit}) {
209
+ return;
210
+ }
211
+ dataBuffer[dataBlockIndex].id = ${id};
212
+ dataByteIndex = 0;
213
+
214
+ compoundSerializer${header};
215
+ }`.$uses({
216
+ indexBuffer,
217
+ dataBuffer,
218
+ dataBlockIndex,
219
+ dataByteIndex,
220
+ compoundSerializer
221
+ }).$name(`log${id}`);
222
+ }
223
+
224
+ //#endregion
225
+ export { createLoggingFunction };
@@ -0,0 +1,54 @@
1
+ import "../../data/snippet.js";
2
+ import { TgpuMutable } from "../../core/buffer/bufferShorthand.js";
3
+ import "../generationHelpers.js";
4
+ import { AnyWgslData, Atomic, U32, WgslArray, WgslStruct } from "../../data/wgslTypes.js";
5
+
6
+ //#region src/tgsl/consoleLog/types.d.ts
7
+ /**
8
+ * Options for configuring GPU log generation.
9
+ */
10
+ interface LogGeneratorOptions {
11
+ /**
12
+ * The maximum number of logs that appear during a single draw/dispatch call.
13
+ * If this number is exceeded, a warning containing the total number of calls is logged and further logs are dropped.
14
+ * @default 64
15
+ */
16
+ logCountLimit?: number;
17
+ /**
18
+ * The total number of bytes reserved for each log call.
19
+ * If this number is exceeded, an exception is thrown during resolution.
20
+ * @default 252
21
+ */
22
+ logSizeLimit?: number;
23
+ /**
24
+ * The prefix attached to each log call.
25
+ * @default ' GPU '
26
+ */
27
+ messagePrefix?: string;
28
+ }
29
+ type SerializedLogCallData = WgslStruct<{
30
+ id: U32;
31
+ serializedData: WgslArray<U32>;
32
+ }>;
33
+ interface LogMeta {
34
+ op: SupportedLogOps;
35
+ argTypes: (string | AnyWgslData)[];
36
+ }
37
+ /**
38
+ * The resources required for logging via console.log within TypeGPU functions.
39
+ *
40
+ * @property indexBuffer - A buffer used for indexing log entries. Needs to be cleared after each dispatch/draw.
41
+ * @property dataBuffer - A buffer containing an array of serialized log call data.
42
+ * @property options - The configuration options for the LogGenerator.
43
+ * @property logIdToMeta - A mapping from log identifiers to an object containing the corresponding log op and argument types.
44
+ */
45
+ interface LogResources {
46
+ indexBuffer: TgpuMutable<Atomic<U32>>;
47
+ dataBuffer: TgpuMutable<WgslArray<SerializedLogCallData>>;
48
+ options: Required<LogGeneratorOptions>;
49
+ logIdToMeta: Map<number, LogMeta>;
50
+ }
51
+ declare const supportedLogOps: readonly ["log", "debug", "info", "warn", "error", "clear"];
52
+ type SupportedLogOps = (typeof supportedLogOps)[number];
53
+ //#endregion
54
+ export { LogGeneratorOptions, LogResources };
@@ -0,0 +1,12 @@
1
+ //#region src/tgsl/consoleLog/types.ts
2
+ const supportedLogOps = [
3
+ "log",
4
+ "debug",
5
+ "info",
6
+ "warn",
7
+ "error",
8
+ "clear"
9
+ ];
10
+
11
+ //#endregion
12
+ export { supportedLogOps };
@@ -0,0 +1,200 @@
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
+
12
+ //#region src/tgsl/conversion.ts
13
+ const INFINITE_RANK = {
14
+ rank: Number.POSITIVE_INFINITY,
15
+ action: "none"
16
+ };
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;
62
+ }
63
+ 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 === "abstractFloat") {
94
+ if (trueDst.type === "u32") return {
95
+ rank: 2,
96
+ action: "cast",
97
+ targetType: trueDst
98
+ };
99
+ if (trueDst.type === "i32") return {
100
+ rank: 1,
101
+ action: "cast",
102
+ targetType: trueDst
103
+ };
104
+ }
105
+ return INFINITE_RANK;
106
+ }
107
+ function getConversionRank(src, dest, allowImplicit) {
108
+ const autoRank = getAutoConversionRank(src, dest);
109
+ if (autoRank.rank < Number.POSITIVE_INFINITY) return autoRank;
110
+ if (allowImplicit) return getImplicitConversionRank(src, dest);
111
+ return INFINITE_RANK;
112
+ }
113
+ function findBestType(types, uniqueTypes, allowImplicit) {
114
+ let bestResult;
115
+ for (const targetType of uniqueTypes) {
116
+ const details = [];
117
+ let sum = 0;
118
+ for (const sourceType of types) {
119
+ const conversion = getConversionRank(sourceType, targetType, allowImplicit);
120
+ sum += conversion.rank;
121
+ if (conversion.rank === Number.POSITIVE_INFINITY) break;
122
+ details.push(conversion);
123
+ }
124
+ if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) bestResult = {
125
+ type: targetType,
126
+ details,
127
+ sum
128
+ };
129
+ }
130
+ if (!bestResult) return;
131
+ const actions = bestResult.details.map((detail, index) => ({
132
+ sourceIndex: index,
133
+ action: detail.action,
134
+ ...detail.action === "cast" && { targetType: detail.targetType }
135
+ }));
136
+ return {
137
+ targetType: bestResult.type,
138
+ actions,
139
+ hasImplicitConversions: actions.some((action) => action.action === "cast")
140
+ };
141
+ }
142
+ function getBestConversion(types, targetTypes) {
143
+ if (types.length === 0) return void 0;
144
+ const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
145
+ const explicitResult = findBestType(types, uniqueTargetTypes, false);
146
+ if (explicitResult) return explicitResult;
147
+ const implicitResult = findBestType(types, uniqueTargetTypes, true);
148
+ if (implicitResult) return implicitResult;
149
+ }
150
+ function applyActionToSnippet(ctx, snippet, action, targetType) {
151
+ if (action.action === "none") return snip(snippet.value, targetType, snippet.origin);
152
+ switch (action.action) {
153
+ case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
154
+ case "deref": return derefSnippet(snippet);
155
+ case "cast": return schemaCallWrapperGPU(ctx, targetType, snippet);
156
+ default: assertExhaustive(action.action, "applyActionToSnippet");
157
+ }
158
+ }
159
+ function unify(inTypes, restrictTo) {
160
+ if (inTypes.some((type) => type === UnknownData)) return;
161
+ const conversion = getBestConversion(inTypes, restrictTo);
162
+ if (!conversion) return;
163
+ return inTypes.map((type) => isVec(type) || isMat(type) ? type : conversion.targetType);
164
+ }
165
+ function convertToCommonType(ctx, values, restrictTo, verbose = true) {
166
+ const types = values.map((value) => value.dataType);
167
+ if (types.some((type) => type === UnknownData)) return;
168
+ 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.");
169
+ const conversion = getBestConversion(types, restrictTo);
170
+ if (!conversion) return;
171
+ 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.
172
+ Consider using explicit conversions instead.`);
173
+ return values.map((value, index) => {
174
+ const action = conversion.actions[index];
175
+ invariant(action, "Action should not be undefined");
176
+ return applyActionToSnippet(ctx, value, action, conversion.targetType);
177
+ });
178
+ }
179
+ function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
180
+ const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
181
+ const { value, dataType, origin } = snippet;
182
+ if (targets.length === 1) {
183
+ const target = targets[0];
184
+ if (target === dataType) return snip(value, target, origin);
185
+ if (dataType === UnknownData) return snip(stitch`${snip(value, target, origin)}`, target, origin);
186
+ }
187
+ const converted = convertToCommonType(ctx, [snippet], targets, verbose);
188
+ if (converted) return converted[0];
189
+ throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(", ")}]`);
190
+ }
191
+ function convertStructValues(ctx, structType, values) {
192
+ return Object.entries(structType.propTypes).map(([key, targetType]) => {
193
+ const val = values[key];
194
+ if (!val) throw new Error(`Missing property ${key}`);
195
+ return convertToCommonType(ctx, [val], [targetType])?.[0] ?? val;
196
+ });
197
+ }
198
+
199
+ //#endregion
200
+ export { convertStructValues, convertToCommonType, getBestConversion, tryConvertSnippet, unify };
@@ -0,0 +1,45 @@
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 { 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
+
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 getElementCountSnippet(ctx, iterableSnippet, unroll = false) {
34
+ const { value, dataType } = iterableSnippet;
35
+ if (isWgslArray(dataType)) return dataType.elementCount > 0 ? snip(dataType.elementCount, u32, "constant") : arrayLength[$gpuCallable].call(ctx, [iterableSnippet]);
36
+ if (isVec(dataType)) return snip(dataType.componentCount, u32, "constant");
37
+ if (unroll) {
38
+ if (Array.isArray(value)) return snip(value.length, u32, "constant");
39
+ if (value instanceof ArrayExpression) return snip(value.elements.length, u32, "constant");
40
+ }
41
+ throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
42
+ }
43
+
44
+ //#endregion
45
+ export { getElementCountSnippet, getElementSnippet, getElementType, getLoopVarKind };
@@ -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 };