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,221 @@
1
+ import { $internal } from "../shared/symbols.js";
2
+ import { callableSchema } from "../core/function/createCallableSchema.js";
3
+ //#region src/data/numeric.ts
4
+ const abstractInt = {
5
+ [$internal]: {},
6
+ type: "abstractInt",
7
+ toString() {
8
+ return "abstractInt";
9
+ }
10
+ };
11
+ const abstractFloat = {
12
+ [$internal]: {},
13
+ type: "abstractFloat",
14
+ toString() {
15
+ return "abstractFloat";
16
+ }
17
+ };
18
+ const boolCast = callableSchema({
19
+ name: "bool",
20
+ schema: () => bool,
21
+ argTypes: (arg) => arg ? [arg] : [],
22
+ normalImpl(v) {
23
+ if (v === void 0) return false;
24
+ if (typeof v === "boolean") return v;
25
+ return !!v;
26
+ },
27
+ codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(bool, args)
28
+ });
29
+ /**
30
+ * A schema that represents a boolean value. (equivalent to `bool` in WGSL)
31
+ *
32
+ * Can also be called to cast a value to a bool in accordance with WGSL casting rules.
33
+ *
34
+ * @example
35
+ * const value = bool(); // false
36
+ * @example
37
+ * const value = bool(0); // false
38
+ * @example
39
+ * const value = bool(-0); // false
40
+ * @example
41
+ * const value = bool(21.37); // true
42
+ */
43
+ const bool = Object.assign(boolCast, {
44
+ [$internal]: {},
45
+ type: "bool"
46
+ });
47
+ const u32Cast = callableSchema({
48
+ name: "u32",
49
+ schema: () => u32,
50
+ argTypes: (arg) => arg ? [arg] : [],
51
+ normalImpl(v) {
52
+ if (v === void 0) return 0;
53
+ if (typeof v === "boolean") return v ? 1 : 0;
54
+ if (!Number.isInteger(v)) {
55
+ const truncated = Math.trunc(v);
56
+ if (truncated < 0) return 0;
57
+ if (truncated > 4294967295) return 4294967295;
58
+ return truncated;
59
+ }
60
+ return (v & 4294967295) >>> 0;
61
+ },
62
+ codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(u32, args)
63
+ });
64
+ /**
65
+ * A schema that represents an unsigned 32-bit integer value. (equivalent to `u32` in WGSL)
66
+ *
67
+ * Can also be called to cast a value to an u32 in accordance with WGSL casting rules.
68
+ *
69
+ * @example
70
+ * const value = u32(); // 0
71
+ * @example
72
+ * const value = u32(7); // 7
73
+ * @example
74
+ * const value = u32(3.14); // 3
75
+ * @example
76
+ * const value = u32(-1); // 4294967295
77
+ * @example
78
+ * const value = u32(-3.1); // 0
79
+ */
80
+ const u32 = Object.assign(u32Cast, {
81
+ [$internal]: {},
82
+ type: "u32"
83
+ });
84
+ const i32Cast = callableSchema({
85
+ name: "i32",
86
+ schema: () => i32,
87
+ argTypes: (arg) => arg ? [arg] : [],
88
+ normalImpl(v) {
89
+ if (v === void 0) return 0;
90
+ if (typeof v === "boolean") return v ? 1 : 0;
91
+ return v | 0;
92
+ },
93
+ codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(i32, args)
94
+ });
95
+ const u16 = {
96
+ [$internal]: {},
97
+ type: "u16"
98
+ };
99
+ /**
100
+ * A schema that represents a signed 32-bit integer value. (equivalent to `i32` in WGSL)
101
+ *
102
+ * Can also be called to cast a value to an i32 in accordance with WGSL casting rules.
103
+ *
104
+ * @example
105
+ * const value = i32(); // 0
106
+ * @example
107
+ * const value = i32(3.14); // 3
108
+ * @example
109
+ * const value = i32(-3.9); // -3
110
+ * @example
111
+ * const value = i32(10000000000) // 1410065408
112
+ */
113
+ const i32 = Object.assign(i32Cast, {
114
+ [$internal]: {},
115
+ type: "i32"
116
+ });
117
+ const f32Cast = callableSchema({
118
+ name: "f32",
119
+ schema: () => f32,
120
+ argTypes: (arg) => arg ? [arg] : [],
121
+ normalImpl(v) {
122
+ if (v === void 0) return 0;
123
+ if (typeof v === "boolean") return v ? 1 : 0;
124
+ return Math.fround(v);
125
+ },
126
+ codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(f32, args)
127
+ });
128
+ /**
129
+ * A schema that represents a 32-bit float value. (equivalent to `f32` in WGSL)
130
+ *
131
+ * Can also be called to cast a value to an f32.
132
+ *
133
+ * @example
134
+ * const value = f32(); // 0
135
+ * @example
136
+ * const value = f32(1.23); // 1.23
137
+ * @example
138
+ * const value = f32(true); // 1
139
+ */
140
+ const f32 = Object.assign(f32Cast, {
141
+ [$internal]: {},
142
+ type: "f32"
143
+ });
144
+ const buf32 = /* @__PURE__ */ new ArrayBuffer(4);
145
+ const f32arr = new Float32Array(buf32);
146
+ const u32arr = new Uint32Array(buf32);
147
+ /**
148
+ * Convert a JavaScript number (treated as float32) to **binary16** bit pattern.
149
+ * @param x 32-bit floating-point value
150
+ * @returns 16-bit half-precision encoding (stored in a JS number)
151
+ */
152
+ function toHalfBits(x) {
153
+ f32arr[0] = x;
154
+ const bits = u32arr[0];
155
+ const sign = bits >>> 31 & 1;
156
+ let exp = bits >>> 23 & 255;
157
+ let mant = bits & 8388607;
158
+ if (exp === 255) return sign << 15 | 31744 | (mant ? 512 : 0);
159
+ exp = exp - 127 + 15;
160
+ if (exp <= 0) {
161
+ if (exp < -10) return sign << 15;
162
+ mant = (mant | 8388608) >> 1 - exp;
163
+ mant = mant + 4096 >> 13;
164
+ return sign << 15 | mant;
165
+ }
166
+ if (exp >= 31) return sign << 15 | 31744;
167
+ mant = mant + 4096;
168
+ if (mant & 8388608) {
169
+ mant = 0;
170
+ ++exp;
171
+ if (exp >= 31) return sign << 15 | 31744;
172
+ }
173
+ return sign << 15 | exp << 10 | mant >> 13;
174
+ }
175
+ /**
176
+ * Convert a **binary16** encoded bit pattern back to JavaScript number.
177
+ * @param h 16-bit half-precision bits
178
+ * @returns JavaScript number (64-bit float) with same numerical value
179
+ */
180
+ function fromHalfBits(h) {
181
+ const sign = h & 32768 ? -1 : 1;
182
+ const exp = h >> 10 & 31;
183
+ const mant = h & 1023;
184
+ if (exp === 0) return mant ? sign * mant * 2 ** -24 : sign * 0;
185
+ if (exp === 31) return mant ? NaN : sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
186
+ return sign * (1 + mant / 1024) * 2 ** (exp - 15);
187
+ }
188
+ function roundToF16(x) {
189
+ return fromHalfBits(toHalfBits(x));
190
+ }
191
+ const f16Cast = callableSchema({
192
+ name: "f16",
193
+ schema: () => f16,
194
+ argTypes: (arg) => arg ? [arg] : [],
195
+ normalImpl(v) {
196
+ if (v === void 0) return 0;
197
+ if (typeof v === "boolean") return v ? 1 : 0;
198
+ return roundToF16(v);
199
+ },
200
+ codegenImpl: (ctx, args) => ctx.gen.typeInstantiation(f16, args)
201
+ });
202
+ /**
203
+ * A schema that represents a 16-bit float value. (equivalent to `f16` in WGSL)
204
+ *
205
+ * Can also be called to cast a value to an f16.
206
+ *
207
+ * @example
208
+ * const value = f16(); // 0
209
+ * @example
210
+ * const value = f32(1.23); // 1.23
211
+ * @example
212
+ * const value = f16(true); // 1
213
+ * @example
214
+ * const value = f16(21877.5); // 21872
215
+ */
216
+ const f16 = Object.assign(f16Cast, {
217
+ [$internal]: {},
218
+ type: "f16"
219
+ });
220
+ //#endregion
221
+ export { abstractFloat, abstractInt, bool, f16, f32, i32, u16, u32 };
@@ -0,0 +1,33 @@
1
+ import { BaseData } from "./wgslTypes.js";
2
+ import { Infer } from "../shared/repr.js";
3
+
4
+ //#region src/data/offsetUtils.d.ts
5
+ /**
6
+ * Interface containing information about the offset and the available contiguous after a selected primitive.
7
+ */
8
+ interface PrimitiveOffsetInfo {
9
+ /** The byte offset of the primitive within the buffer. */
10
+ offset: number;
11
+ /** The number of contiguous bytes available from the offset. */
12
+ contiguous: number;
13
+ }
14
+ /**
15
+ * A function that retrieves offset and information for a specific primitive within a data schema.
16
+ * Example usage:
17
+ * ```ts
18
+ * const Boid = d.struct({
19
+ * position: d.vec3f,
20
+ * velocity: d.vec3f,
21
+ * });
22
+ * const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);
23
+ * console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)
24
+ * console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)
25
+ * ```
26
+ *
27
+ * @param schema - The data schema to analyze.
28
+ * @param accessor - Optional function that accesses a specific element within the schema. If omitted, uses the root offset (0).
29
+ * @returns An object containing the offset and contiguous byte information.
30
+ */
31
+ declare function memoryLayoutOf<T extends BaseData>(schema: T, accessor?: (proxy: Infer<T>) => unknown): PrimitiveOffsetInfo;
32
+ //#endregion
33
+ export { PrimitiveOffsetInfo, memoryLayoutOf };
@@ -0,0 +1,165 @@
1
+ import { isVec, isWgslArray, isWgslStruct } from "./wgslTypes.js";
2
+ import { undecorate } from "./dataTypes.js";
3
+ import { alignmentOf } from "./alignmentOf.js";
4
+ import { roundUp } from "../mathUtils.js";
5
+ import { sizeOf } from "./sizeOf.js";
6
+ import { offsetsForProps } from "./offsets.js";
7
+ import { isContiguous } from "./isContiguous.js";
8
+ import { getLongestContiguousPrefix } from "./getLongestContiguousPrefix.js";
9
+ //#region src/data/offsetUtils.ts
10
+ const OFFSET_MARKER = Symbol("indirectOffset");
11
+ const CONTIGUOUS_MARKER = Symbol("indirectContiguous");
12
+ function isOffsetProxy(value) {
13
+ return typeof value === "object" && value !== null && OFFSET_MARKER in value && CONTIGUOUS_MARKER in value;
14
+ }
15
+ function scalarNode(offset, contiguous) {
16
+ return {
17
+ [OFFSET_MARKER]: offset,
18
+ [CONTIGUOUS_MARKER]: contiguous
19
+ };
20
+ }
21
+ function getMarker(target, prop) {
22
+ if (prop === OFFSET_MARKER) return target[OFFSET_MARKER];
23
+ if (prop === CONTIGUOUS_MARKER) return target[CONTIGUOUS_MARKER];
24
+ }
25
+ function makeProxy(schema, baseOffset, contiguous = sizeOf(schema)) {
26
+ const unwrapped = undecorate(schema);
27
+ const vecComponentCount = isVec(unwrapped) ? unwrapped.componentCount : void 0;
28
+ if (vecComponentCount !== void 0) {
29
+ const componentSize = sizeOf(unwrapped.primitive);
30
+ return makeVecProxy(scalarNode(baseOffset, contiguous), componentSize, vecComponentCount);
31
+ }
32
+ if (isWgslStruct(unwrapped)) return makeStructProxy(unwrapped, scalarNode(baseOffset, contiguous));
33
+ if (isWgslArray(unwrapped)) return makeArrayProxy(unwrapped, scalarNode(baseOffset, contiguous));
34
+ return scalarNode(baseOffset, contiguous);
35
+ }
36
+ function createOffsetProxy(schema, baseOffset = 0) {
37
+ return makeProxy(schema, baseOffset, sizeOf(schema));
38
+ }
39
+ function makeVecProxy(target, componentSize, componentCount) {
40
+ const baseOffset = target[OFFSET_MARKER];
41
+ return new Proxy(target, { get(t, prop) {
42
+ const marker = getMarker(t, prop);
43
+ if (marker !== void 0) return marker;
44
+ const idx = prop === "x" || prop === "0" ? 0 : prop === "y" || prop === "1" ? 1 : prop === "z" || prop === "2" ? 2 : prop === "w" || prop === "3" ? 3 : -1;
45
+ if (idx < 0 || idx >= componentCount) return;
46
+ const byteOffset = idx * componentSize;
47
+ const contiguous = Math.max(0, t[CONTIGUOUS_MARKER] - byteOffset);
48
+ return scalarNode(baseOffset + byteOffset, contiguous);
49
+ } });
50
+ }
51
+ function makeArrayProxy(array, target) {
52
+ const elementType = array.elementType;
53
+ const elementSize = sizeOf(elementType);
54
+ const stride = roundUp(elementSize, alignmentOf(elementType));
55
+ const hasPadding = stride > elementSize;
56
+ return new Proxy(target, { get(t, prop) {
57
+ const marker = getMarker(t, prop);
58
+ if (marker !== void 0) return marker;
59
+ if (prop === "length") return array.elementCount;
60
+ if (typeof prop !== "string") return;
61
+ const index = Number(prop);
62
+ if (!Number.isInteger(index) || index < 0 || index >= array.elementCount) return;
63
+ const elementOffset = index * stride;
64
+ const remainingFromHere = !isContiguous(elementType) ? elementSize + getLongestContiguousPrefix(elementType) : Math.max(0, t[CONTIGUOUS_MARKER] - elementOffset);
65
+ const childContiguous = hasPadding ? Math.min(remainingFromHere, elementSize) : remainingFromHere;
66
+ return makeProxy(elementType, t[OFFSET_MARKER] + elementOffset, childContiguous);
67
+ } });
68
+ }
69
+ function makeStructProxy(struct, target) {
70
+ const offsets = offsetsForProps(struct);
71
+ const propTypes = struct.propTypes;
72
+ const propNames = Object.keys(propTypes);
73
+ const meta = /* @__PURE__ */ new Map();
74
+ let runStart = 0;
75
+ for (let i = 0; i < propNames.length; i++) {
76
+ const name = propNames[i];
77
+ if (!name) continue;
78
+ const type = propTypes[name];
79
+ if (!type) continue;
80
+ const info = offsets[name];
81
+ const padding = info.padding ?? 0;
82
+ const typeContiguous = isContiguous(type);
83
+ if (!(i === propNames.length - 1 || padding > 0 || !typeContiguous)) continue;
84
+ const runEnd = info.offset + (typeContiguous ? info.size : getLongestContiguousPrefix(type));
85
+ for (let j = runStart; j <= i; j++) {
86
+ const runName = propNames[j];
87
+ if (!runName) continue;
88
+ const runInfo = offsets[runName];
89
+ meta.set(runName, {
90
+ offset: runInfo.offset,
91
+ runEnd
92
+ });
93
+ }
94
+ runStart = i + 1;
95
+ }
96
+ return new Proxy(target, { get(t, prop) {
97
+ const marker = getMarker(t, prop);
98
+ if (marker !== void 0) return marker;
99
+ if (typeof prop !== "string") return;
100
+ const m = meta.get(prop);
101
+ if (!m) return;
102
+ const remainingFromHere = Math.max(0, t[CONTIGUOUS_MARKER] - m.offset);
103
+ const localLimit = Math.max(0, m.runEnd - m.offset);
104
+ const propSchema = propTypes[prop];
105
+ if (!propSchema) return;
106
+ return makeProxy(propSchema, t[OFFSET_MARKER] + m.offset, sizeOf(struct) === m.runEnd ? remainingFromHere : localLimit);
107
+ } });
108
+ }
109
+ function getRootContiguous(schema) {
110
+ const unwrapped = undecorate(schema);
111
+ if (isWgslStruct(unwrapped)) {
112
+ const offsets = offsetsForProps(unwrapped);
113
+ const propTypes = unwrapped.propTypes;
114
+ const propNames = Object.keys(propTypes);
115
+ for (let i = 0; i < propNames.length; i++) {
116
+ const name = propNames[i];
117
+ if (!name) continue;
118
+ const info = offsets[name];
119
+ const padding = info.padding ?? 0;
120
+ const runEnd = info.offset + info.size;
121
+ if (i === propNames.length - 1 || padding > 0) return runEnd;
122
+ }
123
+ return 0;
124
+ }
125
+ if (isWgslArray(unwrapped)) {
126
+ const elementType = unwrapped.elementType;
127
+ const elementSize = sizeOf(elementType);
128
+ const stride = roundUp(elementSize, alignmentOf(elementType));
129
+ const totalSize = sizeOf(schema);
130
+ if (!Number.isFinite(totalSize)) return elementSize;
131
+ return stride > elementSize ? elementSize : totalSize;
132
+ }
133
+ return sizeOf(schema);
134
+ }
135
+ /**
136
+ * A function that retrieves offset and information for a specific primitive within a data schema.
137
+ * Example usage:
138
+ * ```ts
139
+ * const Boid = d.struct({
140
+ * position: d.vec3f,
141
+ * velocity: d.vec3f,
142
+ * });
143
+ * const memLayout = d.memoryLayoutOf(Boid, (b) => b.velocity.y);
144
+ * console.log(memLayout.offset); // Byte offset of velocity.y within Boid (here 20 bytes)
145
+ * console.log(memLayout.contiguous); // Contiguous bytes available from that offset (here 8 bytes)
146
+ * ```
147
+ *
148
+ * @param schema - The data schema to analyze.
149
+ * @param accessor - Optional function that accesses a specific element within the schema. If omitted, uses the root offset (0).
150
+ * @returns An object containing the offset and contiguous byte information.
151
+ */
152
+ function memoryLayoutOf(schema, accessor) {
153
+ if (!accessor) return {
154
+ offset: 0,
155
+ contiguous: getRootContiguous(schema)
156
+ };
157
+ const result = accessor(createOffsetProxy(schema));
158
+ if (isOffsetProxy(result)) return {
159
+ offset: result[OFFSET_MARKER],
160
+ contiguous: result[CONTIGUOUS_MARKER]
161
+ };
162
+ throw new Error("memoryLayoutOf: accessor did not return a schema element. Make sure the accessor navigates to a field or element of the schema (e.g. `(s) => s.position.x`).");
163
+ }
164
+ //#endregion
165
+ export { memoryLayoutOf };
@@ -0,0 +1,34 @@
1
+ import { isUnstruct } from "./dataTypes.js";
2
+ import { alignmentOf, customAlignmentOf } from "./alignmentOf.js";
3
+ import { roundUp } from "../mathUtils.js";
4
+ import { sizeOf } from "./sizeOf.js";
5
+ import alignIO from "./alignIO.js";
6
+ import { Measurer } from "typed-binary";
7
+ //#region src/data/offsets.ts
8
+ const cachedOffsets = /* @__PURE__ */ new WeakMap();
9
+ function offsetsForProps(struct) {
10
+ const cached = cachedOffsets.get(struct);
11
+ if (cached) return cached;
12
+ const measurer = new Measurer();
13
+ const offsets = {};
14
+ let lastEntry;
15
+ for (const key in struct.propTypes) {
16
+ const prop = struct.propTypes[key];
17
+ if (prop === void 0) throw new Error(`Property ${key} is undefined in struct`);
18
+ const beforeAlignment = measurer.size;
19
+ alignIO(measurer, isUnstruct(struct) ? customAlignmentOf(prop) : alignmentOf(prop));
20
+ if (lastEntry) lastEntry.padding = measurer.size - beforeAlignment;
21
+ const propSize = sizeOf(prop);
22
+ offsets[key] = {
23
+ offset: measurer.size,
24
+ size: propSize
25
+ };
26
+ lastEntry = offsets[key];
27
+ measurer.add(propSize);
28
+ }
29
+ if (lastEntry) lastEntry.padding = roundUp(sizeOf(struct), alignmentOf(struct)) - measurer.size;
30
+ cachedOffsets.set(struct, offsets);
31
+ return offsets;
32
+ }
33
+ //#endregion
34
+ export { offsetsForProps };
@@ -0,0 +1,113 @@
1
+ import { isWgslArray, isWgslStruct } from "./wgslTypes.js";
2
+ import { isDisarray, isUnstruct } from "./dataTypes.js";
3
+ import { alignmentOf } from "./alignmentOf.js";
4
+ import { roundUp } from "../mathUtils.js";
5
+ import { sizeOf } from "./sizeOf.js";
6
+ import { offsetsForProps } from "./offsets.js";
7
+ import { getCompiledWriter } from "./compiledIO.js";
8
+ import { writeData } from "./dataIO.js";
9
+ import { BufferWriter, getSystemEndianness } from "typed-binary";
10
+ //#region src/data/partialIO.ts
11
+ /**
12
+ * Converts `{idx, value}[]` sparse arrays into `Record<number, T>` format.
13
+ */
14
+ function convertPartialToPatch(schema, data) {
15
+ if (data === void 0 || data === null) return data;
16
+ if (isWgslStruct(schema) || isUnstruct(schema)) {
17
+ const result = {};
18
+ const record = data;
19
+ for (const key of Object.keys(schema.propTypes)) {
20
+ const subSchema = schema.propTypes[key];
21
+ const value = record[key];
22
+ if (value !== void 0 && subSchema) result[key] = convertPartialToPatch(subSchema, value);
23
+ }
24
+ return result;
25
+ }
26
+ if (isWgslArray(schema) || isDisarray(schema)) {
27
+ const arrSchema = schema;
28
+ const result = {};
29
+ for (const { idx, value } of data) result[idx] = convertPartialToPatch(arrSchema.elementType, value);
30
+ return result;
31
+ }
32
+ return data;
33
+ }
34
+ const isLittleEndian = getSystemEndianness() === "little";
35
+ function getPatchInstructions(schema, data, targetBuffer) {
36
+ const totalSize = sizeOf(schema);
37
+ if (totalSize === 0 || data === void 0 || data === null) return [];
38
+ const buf = targetBuffer ?? new ArrayBuffer(totalSize);
39
+ const writer = new BufferWriter(buf);
40
+ const compiledView = new DataView(buf);
41
+ const segments = [];
42
+ function collect(node, value, offset, padding) {
43
+ if (value === void 0 || value === null) return;
44
+ if (isWgslStruct(node) || isUnstruct(node)) {
45
+ const propOffsets = offsetsForProps(node);
46
+ for (const [key, propOffset] of Object.entries(propOffsets)) {
47
+ const childValue = value[key];
48
+ const subSchema = node.propTypes[key];
49
+ if (childValue !== void 0 && subSchema) collect(subSchema, childValue, offset + propOffset.offset, propOffset.padding ?? padding);
50
+ }
51
+ return;
52
+ }
53
+ if (isWgslArray(node) || isDisarray(node)) {
54
+ const arrSchema = node;
55
+ const elementSize = roundUp(sizeOf(arrSchema.elementType), alignmentOf(arrSchema.elementType));
56
+ const elementPadding = elementSize - sizeOf(arrSchema.elementType);
57
+ if (ArrayBuffer.isView(value)) {
58
+ const copyLen = Math.min(value.byteLength, arrSchema.elementCount * elementSize);
59
+ new Uint8Array(buf, offset, copyLen).set(new Uint8Array(value.buffer, value.byteOffset, copyLen));
60
+ segments.push({
61
+ start: offset,
62
+ end: offset + copyLen,
63
+ padding
64
+ });
65
+ return;
66
+ }
67
+ if (Array.isArray(value)) {
68
+ for (let i = 0; i < Math.min(arrSchema.elementCount, value.length); i++) collect(arrSchema.elementType, value[i], offset + i * elementSize, elementPadding);
69
+ return;
70
+ }
71
+ const sparse = value;
72
+ for (const key of Object.keys(sparse)) {
73
+ const idx = Number(key);
74
+ if (!Number.isNaN(idx)) collect(arrSchema.elementType, sparse[key], offset + idx * elementSize, elementPadding);
75
+ }
76
+ return;
77
+ }
78
+ const leafSize = sizeOf(node);
79
+ const compiledWriter = getCompiledWriter(node);
80
+ if (compiledWriter) compiledWriter(compiledView, offset, value, isLittleEndian, offset + leafSize);
81
+ else {
82
+ writer.seekTo(offset);
83
+ writeData(writer, node, value);
84
+ }
85
+ segments.push({
86
+ start: offset,
87
+ end: offset + leafSize,
88
+ padding
89
+ });
90
+ }
91
+ collect(schema, data, 0);
92
+ const instructions = [];
93
+ let run = null;
94
+ for (const seg of segments) if (run && seg.start === run.end + (run.padding ?? 0)) run = {
95
+ start: run.start,
96
+ end: seg.end,
97
+ padding: seg.padding
98
+ };
99
+ else {
100
+ if (run) instructions.push({
101
+ gpuOffset: run.start,
102
+ data: new Uint8Array(buf, run.start, run.end - run.start).slice()
103
+ });
104
+ run = seg;
105
+ }
106
+ if (run) instructions.push({
107
+ gpuOffset: run.start,
108
+ data: new Uint8Array(buf, run.start, run.end - run.start).slice()
109
+ });
110
+ return instructions;
111
+ }
112
+ //#endregion
113
+ export { convertPartialToPatch, getPatchInstructions };
package/data/ptr.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { Ptr, StorableData } from "./wgslTypes.js";
2
+
3
+ //#region src/data/ptr.d.ts
4
+ declare function ptrFn<T extends StorableData>(inner: T): Ptr<'function', T, 'read-write'>;
5
+ declare function ptrPrivate<T extends StorableData>(inner: T): Ptr<'private', T, 'read-write'>;
6
+ declare function ptrWorkgroup<T extends StorableData>(inner: T): Ptr<'workgroup', T, 'read-write'>;
7
+ declare function ptrStorage<T extends StorableData, TAccess extends 'read' | 'read-write' = 'read'>(inner: T, access?: TAccess): Ptr<'storage', T, TAccess>;
8
+ declare function ptrUniform<T extends StorableData>(inner: T): Ptr<'uniform', T, 'read'>;
9
+ declare function ptrHandle<T extends StorableData>(inner: T): Ptr<'handle', T, 'read'>;
10
+ //#endregion
11
+ export { ptrFn, ptrHandle, ptrPrivate, ptrStorage, ptrUniform, ptrWorkgroup };
package/data/ptr.js ADDED
@@ -0,0 +1,44 @@
1
+ import { $internal } from "../shared/symbols.js";
2
+ import { originToPtrParams } from "./snippet.js";
3
+ //#region src/data/ptr.ts
4
+ function ptrFn(inner) {
5
+ return INTERNAL_createPtr("function", inner, "read-write");
6
+ }
7
+ function ptrPrivate(inner) {
8
+ return INTERNAL_createPtr("private", inner, "read-write");
9
+ }
10
+ function ptrWorkgroup(inner) {
11
+ return INTERNAL_createPtr("workgroup", inner, "read-write");
12
+ }
13
+ function ptrStorage(inner, access = "read") {
14
+ return INTERNAL_createPtr("storage", inner, access);
15
+ }
16
+ function ptrUniform(inner) {
17
+ return INTERNAL_createPtr("uniform", inner, "read");
18
+ }
19
+ function ptrHandle(inner) {
20
+ return INTERNAL_createPtr("handle", inner, "read");
21
+ }
22
+ function INTERNAL_createPtr(addressSpace, inner, access, implicit = false) {
23
+ return {
24
+ [$internal]: {},
25
+ type: "ptr",
26
+ addressSpace,
27
+ inner,
28
+ access,
29
+ implicit,
30
+ toString: () => `ptr<${addressSpace}, ${inner}, ${access}>`
31
+ };
32
+ }
33
+ function createPtrFromOrigin(origin, innerDataType) {
34
+ const ptrParams = originToPtrParams[origin];
35
+ if (ptrParams) return INTERNAL_createPtr(ptrParams.space, innerDataType, ptrParams.access);
36
+ }
37
+ function implicitFrom(ptr) {
38
+ return INTERNAL_createPtr(ptr.addressSpace, ptr.inner, ptr.access, true);
39
+ }
40
+ function explicitFrom(ptr) {
41
+ return INTERNAL_createPtr(ptr.addressSpace, ptr.inner, ptr.access, false);
42
+ }
43
+ //#endregion
44
+ export { createPtrFromOrigin, explicitFrom, implicitFrom, ptrFn, ptrHandle, ptrPrivate, ptrStorage, ptrUniform, ptrWorkgroup };
package/data/ref.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { $internal } from "../shared/symbols.js";
2
+ import { DualFn } from "../types.js";
3
+ //#region src/data/ref.d.ts
4
+ interface ref<T> {
5
+ readonly [$internal]: {
6
+ type: 'ref';
7
+ };
8
+ /**
9
+ * Derefences the reference, and gives access to the underlying value.
10
+ *
11
+ * @example ```ts
12
+ * const boid = Boid({ pos: d.vec3f(3, 2, 1) });
13
+ * const posRef = d.ref(boid.pos);
14
+ *
15
+ * // Actually updates `boid.pos`
16
+ * posRef.$ = d.vec3f(1, 2, 3);
17
+ * console.log(boid.pos); // Output: vec3f(1, 2, 3)
18
+ * ```
19
+ */
20
+ $: T;
21
+ }
22
+ /**
23
+ * A reference to a value `T`. Can be passed to other functions to give them
24
+ * mutable access to the underlying value.
25
+ *
26
+ * Conceptually, it represents a WGSL pointer.
27
+ */
28
+ type _ref<T> = T extends object ? T & ref<T> : ref<T>;
29
+ type RefFn = DualFn<(<T>(value: T) => _ref<T>)> & {
30
+ [$internal]: true;
31
+ };
32
+ declare const _ref: RefFn;
33
+ //#endregion
34
+ export { _ref };