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