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,115 @@
1
+ import { $gpuCallable } from "../shared/symbols.js";
2
+ import { isMat, isNaturallyEphemeral, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
3
+ import { InfixDispatch, MatrixColumnsAccess, UnknownData, isUnstruct, undecorate } from "../data/dataTypes.js";
4
+ import { isEphemeralSnippet, snip } from "../data/snippet.js";
5
+ import { isKnownAtComptime } from "../types.js";
6
+ import { stitch } from "../core/resolve/stitch.js";
7
+ import { derefSnippet } from "../data/ref.js";
8
+ import { abstractInt, bool, f16, f32, i32, u32 } from "../data/numeric.js";
9
+ import { coerceToSnippet } from "./generationHelpers.js";
10
+ import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
11
+ import { AutoStruct } from "../data/autoStruct.js";
12
+ import { EntryInputRouter } from "../core/function/entryInputRouter.js";
13
+ import { add, bitShiftLeft, bitShiftRight, div, mod, mul, sub } from "../std/operators.js";
14
+ //#region src/tgsl/accessProp.ts
15
+ const infixKinds = [
16
+ "vec2f",
17
+ "vec3f",
18
+ "vec4f",
19
+ "vec2h",
20
+ "vec3h",
21
+ "vec4h",
22
+ "vec2i",
23
+ "vec3i",
24
+ "vec4i",
25
+ "vec2u",
26
+ "vec3u",
27
+ "vec4u",
28
+ "mat2x2f",
29
+ "mat3x3f",
30
+ "mat4x4f"
31
+ ];
32
+ const infixOperators = {
33
+ add,
34
+ sub,
35
+ mul,
36
+ div,
37
+ mod,
38
+ bitShiftLeft,
39
+ bitShiftRight
40
+ };
41
+ const swizzleLenToType = {
42
+ f: {
43
+ 1: f32,
44
+ 2: vec2f,
45
+ 3: vec3f,
46
+ 4: vec4f
47
+ },
48
+ h: {
49
+ 1: f16,
50
+ 2: vec2h,
51
+ 3: vec3h,
52
+ 4: vec4h
53
+ },
54
+ i: {
55
+ 1: i32,
56
+ 2: vec2i,
57
+ 3: vec3i,
58
+ 4: vec4i
59
+ },
60
+ u: {
61
+ 1: u32,
62
+ 2: vec2u,
63
+ 3: vec3u,
64
+ 4: vec4u
65
+ },
66
+ b: {
67
+ 1: bool,
68
+ 2: vec2b,
69
+ 3: vec3b,
70
+ 4: vec4b
71
+ }
72
+ };
73
+ function accessProp(target, propName) {
74
+ if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
75
+ const operator = infixOperators[propName];
76
+ return snip(new InfixDispatch(propName, target, operator[$gpuCallable].call.bind(operator)), UnknownData, target.origin);
77
+ }
78
+ if (isWgslArray(target.dataType) && propName === "length") {
79
+ if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
80
+ return snip(target.dataType.elementCount, abstractInt, "constant");
81
+ }
82
+ if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
83
+ if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
84
+ let propType = target.dataType.propTypes[propName];
85
+ if (!propType) return;
86
+ propType = undecorate(propType);
87
+ return snip(stitch`${target}.${propName}`, propType, target.origin === "argument" ? "argument" : !isEphemeralSnippet(target) && !isNaturallyEphemeral(propType) ? target.origin : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
88
+ }
89
+ if (target.dataType instanceof AutoStruct) {
90
+ const result = target.dataType.accessProp(propName);
91
+ if (!result) return;
92
+ return snip(stitch`${target}.${result.prop}`, result.type, "argument");
93
+ }
94
+ if (target.dataType instanceof EntryInputRouter) return target.dataType.accessProp(propName);
95
+ if (isPtr(target.dataType)) {
96
+ const derefed = derefSnippet(target);
97
+ if (propName === "$") return derefed;
98
+ return accessProp(derefed, propName);
99
+ }
100
+ if (isVec(target.dataType)) {
101
+ if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
102
+ }
103
+ const propLength = propName.length;
104
+ if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
105
+ const isXYZW = /^[xyzw]+$/.test(propName);
106
+ const isRGBA = /^[rgba]+$/.test(propName);
107
+ if (!isXYZW && !isRGBA) return;
108
+ const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
109
+ if (!swizzleType) return;
110
+ return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, target.origin === "argument" && propLength === 1 ? "argument" : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
111
+ }
112
+ if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
113
+ }
114
+ //#endregion
115
+ export { accessProp, infixOperators };
@@ -0,0 +1,115 @@
1
+ import { isWgslArray, isWgslData, isWgslStruct } from "../../data/wgslTypes.js";
2
+ import { niceStringify } from "../../shared/stringify.js";
3
+ import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
4
+ import { sizeOf } from "../../data/sizeOf.js";
5
+ import { mat2x2f, mat3x3f, mat4x4f } from "../../data/matrix.js";
6
+ import { bitcastU32toF32, bitcastU32toI32 } from "../../std/bitcast.js";
7
+ import { unpack2x16float } from "../../std/packing.js";
8
+ //#region src/tgsl/consoleLog/deserializers.ts
9
+ const toF = (n) => bitcastU32toF32(n ?? 0);
10
+ const toI = (n) => bitcastU32toI32(n ?? 0);
11
+ const unpack = (n) => unpack2x16float(n ?? 0);
12
+ const deserializerMap = {
13
+ f32: (d) => toF(d[0]),
14
+ f16: (d) => unpack(d[0]).x,
15
+ i32: (d) => toI(d[0]),
16
+ u32: (d) => d[0] ?? 0,
17
+ bool: (d) => !!d[0],
18
+ vec2f: (d) => vec2f(toF(d[0]), toF(d[1])),
19
+ vec3f: (d) => vec3f(toF(d[0]), toF(d[1]), toF(d[2])),
20
+ vec4f: (d) => vec4f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3])),
21
+ vec2h(d) {
22
+ const xyVec = unpack(d[0]);
23
+ return vec2h(xyVec.x, xyVec.y);
24
+ },
25
+ vec3h(d) {
26
+ const xyVec = unpack(d[0]);
27
+ const zVec = unpack(d[1]);
28
+ return vec3h(xyVec.x, xyVec.y, zVec.x);
29
+ },
30
+ vec4h(d) {
31
+ const xyVec = unpack(d[0]);
32
+ const zwVec = unpack(d[1]);
33
+ return vec4h(xyVec.x, xyVec.y, zwVec.x, zwVec.y);
34
+ },
35
+ vec2i: (d) => vec2i(toI(d[0]), toI(d[1])),
36
+ vec3i: (d) => vec3i(toI(d[0]), toI(d[1]), toI(d[2])),
37
+ vec4i: (d) => vec4i(toI(d[0]), toI(d[1]), toI(d[2]), toI(d[3])),
38
+ vec2u: (d) => vec2u(d[0] ?? 0, d[1] ?? 0),
39
+ vec3u: (d) => vec3u(d[0] ?? 0, d[1] ?? 0, d[2] ?? 0),
40
+ vec4u: (d) => vec4u(d[0] ?? 0, d[1] ?? 0, d[2] ?? 0, d[3] ?? 0),
41
+ "vec2<bool>": (d) => vec2b(!!d[0], !!d[1]),
42
+ "vec3<bool>": (d) => vec3b(!!d[0], !!d[1], !!d[2]),
43
+ "vec4<bool>": (d) => vec4b(!!d[0], !!d[1], !!d[2], !!d[3]),
44
+ mat2x2f: (d) => mat2x2f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3])),
45
+ mat3x3f: (d) => mat3x3f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[4]), toF(d[5]), toF(d[6]), toF(d[8]), toF(d[9]), toF(d[10])),
46
+ mat4x4f: (d) => mat4x4f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3]), toF(d[4]), toF(d[5]), toF(d[6]), toF(d[7]), toF(d[8]), toF(d[9]), toF(d[10]), toF(d[11]), toF(d[12]), toF(d[13]), toF(d[14]), toF(d[15]))
47
+ };
48
+ /**
49
+ * Deserializes binary data from a Uint32Array into a JavaScript value based on the provided WGSL data type.
50
+ *
51
+ * @param data - The binary data as a Uint32Array to be deserialized
52
+ * @param dataType - The WGSL data type specification that determines how to interpret the binary data
53
+ */
54
+ function deserialize(data, dataType) {
55
+ const maybeDeserializer = deserializerMap[dataType.type];
56
+ if (maybeDeserializer) return maybeDeserializer(data);
57
+ if (isWgslStruct(dataType)) {
58
+ const props = Object.keys(dataType.propTypes);
59
+ const decodedProps = deserializeCompound(data, Object.values(dataType.propTypes));
60
+ return Object.fromEntries(props.map((key, index) => [key, decodedProps[index]]));
61
+ }
62
+ if (isWgslArray(dataType)) {
63
+ const elementType = dataType.elementType;
64
+ const length = dataType.elementCount;
65
+ return deserializeCompound(data, Array.from({ length }, () => elementType));
66
+ }
67
+ throw new Error(`Cannot deserialize data of type ${dataType.type}`);
68
+ }
69
+ /**
70
+ * Deserializes a list of elements from a Uint32Array buffer using provided type information.
71
+ * If there is a string value among the type information, it is returned as is.
72
+ *
73
+ * @param data - The Uint32Array buffer containing the serialized data
74
+ * @param dataTypes - The WGSL data type specification that determines how to interpret the binary data, or string literals
75
+ */
76
+ function deserializeCompound(data, dataTypes) {
77
+ let index = 0;
78
+ return dataTypes.map((info) => {
79
+ if (!isWgslData(info)) return info;
80
+ const size = Math.ceil(sizeOf(info) / 4);
81
+ const value = deserialize(data.subarray(index, index + size), info);
82
+ index += size;
83
+ return value;
84
+ });
85
+ }
86
+ function deserializeAndStringify(serializedData, argTypes) {
87
+ return deserializeCompound(serializedData, argTypes).map(niceStringify);
88
+ }
89
+ /**
90
+ * Reads and deserializes log data from GPU buffers, logging results to the console.
91
+ *
92
+ * @remarks
93
+ * - Log entries with IDs equal to 0 are filtered out.
94
+ * - Console messages are prepended with options.messagePrefix styled with purple background and white text.
95
+ * - A warning is displayed if the log count exceeds the limit passed in options.
96
+ * - After processing, the index buffer and the data buffer are cleared.
97
+ */
98
+ function logDataFromGPU(resources) {
99
+ const { indexBuffer, dataBuffer, logIdToMeta, options } = resources;
100
+ dataBuffer.read().then((data) => {
101
+ data.filter((e) => e.id).forEach(({ id, serializedData }) => {
102
+ const { argTypes, op } = logIdToMeta.get(id);
103
+ const results = deserializeAndStringify(new Uint32Array(serializedData), argTypes);
104
+ if (results.length === 0) results.push("");
105
+ console[op](`%c${options.messagePrefix}%c ${results[0]}`, "background: #936ff5; color: white;", "color: inherit; background: none", ...results.slice(1));
106
+ });
107
+ });
108
+ indexBuffer.read().then((totalCalls) => {
109
+ if (totalCalls > options.logCountLimit) console.warn(`Log count limit per dispatch (${options.logCountLimit}) exceeded by ${totalCalls - options.logCountLimit} calls. Consider increasing the limit by passing appropriate options to tgpu.init().`);
110
+ });
111
+ dataBuffer.buffer.clear();
112
+ indexBuffer.buffer.clear();
113
+ }
114
+ //#endregion
115
+ export { logDataFromGPU };
@@ -0,0 +1,84 @@
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 { concretizeSnippets } from "../generationHelpers.js";
8
+ import { struct } from "../../data/struct.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
+ //#region src/tgsl/consoleLog/logGenerator.ts
15
+ const defaultOptions = {
16
+ logCountLimit: 64,
17
+ logSizeLimit: 252,
18
+ messagePrefix: " GPU "
19
+ };
20
+ const fallbackSnippet = snip("/* console.log() */", Void, "runtime");
21
+ var LogGeneratorNullImpl = class {
22
+ get logResources() {}
23
+ generateLog() {
24
+ console.warn("'console.log' is only supported when resolving pipelines.");
25
+ return fallbackSnippet;
26
+ }
27
+ };
28
+ var LogGeneratorImpl = class {
29
+ #options;
30
+ #logIdToMeta;
31
+ #firstUnusedId = 1;
32
+ #indexBuffer;
33
+ #dataBuffer;
34
+ constructor(root) {
35
+ this.#options = {
36
+ ...defaultOptions,
37
+ ...root[$internal].logOptions
38
+ };
39
+ this.#logIdToMeta = /* @__PURE__ */ new Map();
40
+ const SerializedLogData = struct({
41
+ id: u32,
42
+ serializedData: arrayOf(u32, Math.ceil(this.#options.logSizeLimit / 4))
43
+ }).$name("SerializedLogData");
44
+ this.#dataBuffer = root.createMutable(arrayOf(SerializedLogData, this.#options.logCountLimit)).$name("dataBuffer");
45
+ this.#indexBuffer = root.createMutable(atomic(u32)).$name("indexBuffer");
46
+ }
47
+ /**
48
+ * Generates all necessary resources for serializing arguments for logging purposes.
49
+ *
50
+ * @param ctx Resolution context.
51
+ * @param args Argument snippets. Snippets of UnknownType will be treated as string literals.
52
+ * @returns A snippet containing the call to the logging function.
53
+ */
54
+ generateLog(ctx, op, args) {
55
+ if (shaderStageSlot.$ === "vertex") {
56
+ console.warn(`'console.${op}' is not supported in vertex shaders.`);
57
+ return fallbackSnippet;
58
+ }
59
+ if (!supportedLogOps.includes(op)) {
60
+ console.warn(`Unsupported log method '${op}'.`);
61
+ return fallbackSnippet;
62
+ }
63
+ const concreteArgs = concretizeSnippets(args);
64
+ const id = this.#firstUnusedId++;
65
+ const nonStringArgs = concreteArgs.filter((e) => e.dataType !== UnknownData);
66
+ const logFn = createLoggingFunction(id, nonStringArgs.map((e) => e.dataType), this.#dataBuffer, this.#indexBuffer, this.#options);
67
+ const argTypes = concreteArgs.map((e) => e.dataType === UnknownData ? e.value : e.dataType);
68
+ this.#logIdToMeta.set(id, {
69
+ op,
70
+ argTypes
71
+ });
72
+ return snip(stitch`${ctx.resolve(logFn).value}(${nonStringArgs})`, Void, "runtime");
73
+ }
74
+ get logResources() {
75
+ return this.#firstUnusedId === 1 ? void 0 : {
76
+ dataBuffer: this.#dataBuffer,
77
+ indexBuffer: this.#indexBuffer,
78
+ options: this.#options,
79
+ logIdToMeta: this.#logIdToMeta
80
+ };
81
+ }
82
+ };
83
+ //#endregion
84
+ export { LogGeneratorImpl, LogGeneratorNullImpl };
@@ -0,0 +1,223 @@
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
+ //#region src/tgsl/consoleLog/serializers.ts
11
+ const dataBlockIndex = privateVar(u32, 0).$name("dataBlockIndex");
12
+ const dataByteIndex = privateVar(u32, 0).$name("dataByteIndex");
13
+ const dataBufferSlot = slot().$name("dataBuffer");
14
+ const nextByteIndex = fn([], u32)`() {
15
+ let i = dataByteIndex;
16
+ dataByteIndex = dataByteIndex + 1u;
17
+ return i;
18
+ }`.$uses({ dataByteIndex }).$name("nextByteIndex");
19
+ const nextU32 = "dataBuffer[dataBlockIndex].serializedData[nextByteIndex()]";
20
+ const serializerMap = {
21
+ f32: fn([f32])`(n) {
22
+ ${nextU32} = bitcast<u32>(n);
23
+ }`,
24
+ f16: fn([f16])`(n) {
25
+ ${nextU32} = pack2x16float(vec2f(f32(n), 0.0));
26
+ }`,
27
+ i32: fn([i32])`(n) {
28
+ ${nextU32} = bitcast<u32>(n);
29
+ }`,
30
+ u32: fn([u32])`(n) {
31
+ ${nextU32} = n;
32
+ }`,
33
+ bool: fn([bool])`(b) {
34
+ ${nextU32} = u32(b);
35
+ }`,
36
+ vec2f: fn([vec2f])`(v) {
37
+ ${nextU32} = bitcast<u32>(v.x);
38
+ ${nextU32} = bitcast<u32>(v.y);
39
+ }`,
40
+ vec3f: fn([vec3f])`(v) {
41
+ ${nextU32} = bitcast<u32>(v.x);
42
+ ${nextU32} = bitcast<u32>(v.y);
43
+ ${nextU32} = bitcast<u32>(v.z);
44
+ }`,
45
+ vec4f: fn([vec4f])`(v) {
46
+ ${nextU32} = bitcast<u32>(v.x);
47
+ ${nextU32} = bitcast<u32>(v.y);
48
+ ${nextU32} = bitcast<u32>(v.z);
49
+ ${nextU32} = bitcast<u32>(v.w);
50
+ }`,
51
+ vec2h: fn([vec2h])`(v) {
52
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
53
+ }`,
54
+ vec3h: fn([vec3h])`(v) {
55
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
56
+ ${nextU32} = pack2x16float(vec2f(f32(v.z), 0.0));
57
+ }`,
58
+ vec4h: fn([vec4h])`(v) {
59
+ ${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
60
+ ${nextU32} = pack2x16float(vec2f(f32(v.z), f32(v.w)));
61
+ }`,
62
+ vec2i: fn([vec2i])`(v) {
63
+ ${nextU32} = bitcast<u32>(v.x);
64
+ ${nextU32} = bitcast<u32>(v.y);
65
+ }`,
66
+ vec3i: fn([vec3i])`(v) {
67
+ ${nextU32} = bitcast<u32>(v.x);
68
+ ${nextU32} = bitcast<u32>(v.y);
69
+ ${nextU32} = bitcast<u32>(v.z);
70
+ }`,
71
+ vec4i: fn([vec4i])`(v) {
72
+ ${nextU32} = bitcast<u32>(v.x);
73
+ ${nextU32} = bitcast<u32>(v.y);
74
+ ${nextU32} = bitcast<u32>(v.z);
75
+ ${nextU32} = bitcast<u32>(v.w);
76
+ }`,
77
+ vec2u: fn([vec2u])`(v) {
78
+ ${nextU32} = v.x;
79
+ ${nextU32} = v.y;
80
+ }`,
81
+ vec3u: fn([vec3u])`(v) {
82
+ ${nextU32} = v.x;
83
+ ${nextU32} = v.y;
84
+ ${nextU32} = v.z;
85
+ }`,
86
+ vec4u: fn([vec4u])`(v) {
87
+ ${nextU32} = v.x;
88
+ ${nextU32} = v.y;
89
+ ${nextU32} = v.z;
90
+ ${nextU32} = v.w;
91
+ }`,
92
+ "vec2<bool>": fn([vec2b])`(v) {
93
+ ${nextU32} = u32(v.x);
94
+ ${nextU32} = u32(v.y);
95
+ }`,
96
+ "vec3<bool>": fn([vec3b])`(v) {
97
+ ${nextU32} = u32(v.x);
98
+ ${nextU32} = u32(v.y);
99
+ ${nextU32} = u32(v.z);
100
+ }`,
101
+ "vec4<bool>": fn([vec4b])`(v) {
102
+ ${nextU32} = u32(v.x);
103
+ ${nextU32} = u32(v.y);
104
+ ${nextU32} = u32(v.z);
105
+ ${nextU32} = u32(v.w);
106
+ }`,
107
+ mat2x2f: fn([mat2x2f])`(m) {
108
+ ${nextU32} = bitcast<u32>(m[0][0]);
109
+ ${nextU32} = bitcast<u32>(m[0][1]);
110
+ ${nextU32} = bitcast<u32>(m[1][0]);
111
+ ${nextU32} = bitcast<u32>(m[1][1]);
112
+ }`,
113
+ mat3x3f: fn([mat3x3f])`(m) {
114
+ ${nextU32} = bitcast<u32>(m[0][0]);
115
+ ${nextU32} = bitcast<u32>(m[0][1]);
116
+ ${nextU32} = bitcast<u32>(m[0][2]);
117
+ ${nextU32} = 0u;
118
+ ${nextU32} = bitcast<u32>(m[1][0]);
119
+ ${nextU32} = bitcast<u32>(m[1][1]);
120
+ ${nextU32} = bitcast<u32>(m[1][2]);
121
+ ${nextU32} = 0u;
122
+ ${nextU32} = bitcast<u32>(m[2][0]);
123
+ ${nextU32} = bitcast<u32>(m[2][1]);
124
+ ${nextU32} = bitcast<u32>(m[2][2]);
125
+ ${nextU32} = 0u;
126
+ }`,
127
+ mat4x4f: fn([mat4x4f])`(m) {
128
+ ${nextU32} = bitcast<u32>(m[0][0]);
129
+ ${nextU32} = bitcast<u32>(m[0][1]);
130
+ ${nextU32} = bitcast<u32>(m[0][2]);
131
+ ${nextU32} = bitcast<u32>(m[0][3]);
132
+ ${nextU32} = bitcast<u32>(m[1][0]);
133
+ ${nextU32} = bitcast<u32>(m[1][1]);
134
+ ${nextU32} = bitcast<u32>(m[1][2]);
135
+ ${nextU32} = bitcast<u32>(m[1][3]);
136
+ ${nextU32} = bitcast<u32>(m[2][0]);
137
+ ${nextU32} = bitcast<u32>(m[2][1]);
138
+ ${nextU32} = bitcast<u32>(m[2][2]);
139
+ ${nextU32} = bitcast<u32>(m[2][3]);
140
+ ${nextU32} = bitcast<u32>(m[3][0]);
141
+ ${nextU32} = bitcast<u32>(m[3][1]);
142
+ ${nextU32} = bitcast<u32>(m[3][2]);
143
+ ${nextU32} = bitcast<u32>(m[3][3]);
144
+ }`
145
+ };
146
+ for (const [name, serializer] of Object.entries(serializerMap)) serializer.$name(`serialize${name[0].toLocaleUpperCase()}${name.slice(1)}`).$uses({
147
+ dataBlockIndex,
148
+ nextByteIndex,
149
+ dataBuffer: dataBufferSlot
150
+ });
151
+ function generateHeader(argTypes) {
152
+ return `(${argTypes.map((_, i) => `_arg_${i}`).join(", ")})`;
153
+ }
154
+ /**
155
+ * Returns a serializer TGPU function for a given WGSL data type.
156
+ * If the data type is a base type, one of the preexisting functions (with the `dataBufferSlot` filled) is returned.
157
+ * Otherwise, a new function is generated.
158
+ *
159
+ * @param dataType - The WGSL data type descriptor to return a serializer for
160
+ * @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
161
+ */
162
+ function getSerializer(dataType, dataBuffer) {
163
+ const maybeSerializer = serializerMap[dataType.type];
164
+ if (maybeSerializer) return maybeSerializer.with(dataBufferSlot, dataBuffer);
165
+ if (isWgslStruct(dataType)) {
166
+ const props = Object.keys(dataType.propTypes);
167
+ const propsSerializer = createCompoundSerializer(Object.values(dataType.propTypes), dataBuffer);
168
+ return fn([dataType])`(arg) {\n propsSerializer(${props.map((prop) => `arg.${prop}`).join(", ")});\n}`.$uses({ propsSerializer }).$name(`${getName(dataType) ?? "struct"}Serializer`);
169
+ }
170
+ if (isWgslArray(dataType)) {
171
+ const elementType = dataType.elementType;
172
+ const length = dataType.elementCount;
173
+ const elementSerializer = getSerializer(elementType, dataBuffer);
174
+ return fn([dataType])`(arg) {\n${Array.from({ length }, (_, i) => ` elementSerializer(arg[${i}]);`).join("\n")}\n}`.$uses({ elementSerializer }).$name("arraySerializer");
175
+ }
176
+ throw new Error(`Cannot serialize data of type ${dataType.type}`);
177
+ }
178
+ /**
179
+ * Creates a compound serializer TGPU function that serializes multiple arguments of different types to the data buffer.
180
+ *
181
+ * @param dataTypes - Array of WGSL data types that define the types of arguments to be serialized
182
+ * @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
183
+ */
184
+ function createCompoundSerializer(dataTypes, dataBuffer) {
185
+ const usedSerializers = {};
186
+ return fn(dataTypes)`${generateHeader(dataTypes)} {\n${dataTypes.map((arg, i) => {
187
+ usedSerializers[`serializer${i}`] = getSerializer(arg, dataBuffer);
188
+ return ` serializer${i}(_arg_${i});`;
189
+ }).join("\n")}\n}`.$uses(usedSerializers).$name("compoundSerializer");
190
+ }
191
+ /**
192
+ * Creates a TGPU function that serializes data to the log buffer.
193
+ *
194
+ * @param id - Identifier for this logging function instance
195
+ * @param dataTypes - Array of WGSL data types that will be logged by this function
196
+ * @param dataBuffer - Mutable buffer array to store serialized log call data
197
+ * @param indexBuffer - Atomic counter buffer to track the next available log data slot
198
+ * @param logOptions - Configuration options
199
+ */
200
+ function createLoggingFunction(id, dataTypes, dataBuffer, indexBuffer, logOptions) {
201
+ const serializedSize = dataTypes.map(sizeOf).reduce((a, b) => a + b, 0);
202
+ 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().`);
203
+ const compoundSerializer = createCompoundSerializer(dataTypes, dataBuffer).$name(`log${id}serializer`);
204
+ const header = generateHeader(dataTypes);
205
+ return fn(dataTypes)`${header} {
206
+ dataBlockIndex = atomicAdd(&indexBuffer, 1);
207
+ if (dataBlockIndex >= ${logOptions.logCountLimit}) {
208
+ return;
209
+ }
210
+ dataBuffer[dataBlockIndex].id = ${id};
211
+ dataByteIndex = 0;
212
+
213
+ compoundSerializer${header};
214
+ }`.$uses({
215
+ indexBuffer,
216
+ dataBuffer,
217
+ dataBlockIndex,
218
+ dataByteIndex,
219
+ compoundSerializer
220
+ }).$name(`log${id}`);
221
+ }
222
+ //#endregion
223
+ export { createLoggingFunction };
@@ -0,0 +1,52 @@
1
+ import { TgpuMutable } from "../../core/buffer/bufferShorthand.js";
2
+ import { AnyWgslData, Atomic, U32, WgslArray, WgslStruct } from "../../data/wgslTypes.js";
3
+
4
+ //#region src/tgsl/consoleLog/types.d.ts
5
+ /**
6
+ * Options for configuring GPU log generation.
7
+ */
8
+ interface LogGeneratorOptions {
9
+ /**
10
+ * The maximum number of logs that appear during a single draw/dispatch call.
11
+ * If this number is exceeded, a warning containing the total number of calls is logged and further logs are dropped.
12
+ * @default 64
13
+ */
14
+ logCountLimit?: number;
15
+ /**
16
+ * The total number of bytes reserved for each log call.
17
+ * If this number is exceeded, an exception is thrown during resolution.
18
+ * @default 252
19
+ */
20
+ logSizeLimit?: number;
21
+ /**
22
+ * The prefix attached to each log call.
23
+ * @default ' GPU '
24
+ */
25
+ messagePrefix?: string;
26
+ }
27
+ type SerializedLogCallData = WgslStruct<{
28
+ id: U32;
29
+ serializedData: WgslArray<U32>;
30
+ }>;
31
+ interface LogMeta {
32
+ op: SupportedLogOps;
33
+ argTypes: (string | AnyWgslData)[];
34
+ }
35
+ /**
36
+ * The resources required for logging via console.log within TypeGPU functions.
37
+ *
38
+ * @property indexBuffer - A buffer used for indexing log entries. Needs to be cleared after each dispatch/draw.
39
+ * @property dataBuffer - A buffer containing an array of serialized log call data.
40
+ * @property options - The configuration options for the LogGenerator.
41
+ * @property logIdToMeta - A mapping from log identifiers to an object containing the corresponding log op and argument types.
42
+ */
43
+ interface LogResources {
44
+ indexBuffer: TgpuMutable<Atomic<U32>>;
45
+ dataBuffer: TgpuMutable<WgslArray<SerializedLogCallData>>;
46
+ options: Required<LogGeneratorOptions>;
47
+ logIdToMeta: Map<number, LogMeta>;
48
+ }
49
+ declare const supportedLogOps: readonly ["log", "debug", "info", "warn", "error", "clear"];
50
+ type SupportedLogOps = (typeof supportedLogOps)[number];
51
+ //#endregion
52
+ export { LogGeneratorOptions, LogResources };
@@ -0,0 +1,11 @@
1
+ //#region src/tgsl/consoleLog/types.ts
2
+ const supportedLogOps = [
3
+ "log",
4
+ "debug",
5
+ "info",
6
+ "warn",
7
+ "error",
8
+ "clear"
9
+ ];
10
+ //#endregion
11
+ export { supportedLogOps };