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.
- package/_virtual/_rolldown/runtime.js +13 -0
- package/builtin.d.ts +50 -0
- package/builtin.js +35 -0
- package/common/fullScreenTriangle.d.ts +22 -0
- package/common/fullScreenTriangle.js +34 -0
- package/common/index.d.ts +4 -4
- package/common/index.js +8 -7
- package/common/writeSoA.d.ts +16 -0
- package/common/writeSoA.js +90 -0
- package/core/buffer/buffer.d.ts +79 -0
- package/core/buffer/buffer.js +246 -0
- package/core/buffer/bufferShorthand.d.ts +48 -0
- package/core/buffer/bufferShorthand.js +53 -0
- package/core/buffer/bufferUsage.d.ts +43 -0
- package/core/buffer/bufferUsage.js +165 -0
- package/core/constant/tgpuConstant.d.ts +29 -0
- package/core/constant/tgpuConstant.js +68 -0
- package/core/declare/tgpuDeclare.d.ts +18 -0
- package/core/declare/tgpuDeclare.js +39 -0
- package/core/function/autoIO.d.ts +38 -0
- package/core/function/autoIO.js +85 -0
- package/core/function/comptime.d.ts +39 -0
- package/core/function/comptime.js +49 -0
- package/core/function/createCallableSchema.js +40 -0
- package/core/function/dualImpl.js +52 -0
- package/core/function/entryInputRouter.js +39 -0
- package/core/function/extractArgs.js +204 -0
- package/core/function/fnCore.js +90 -0
- package/core/function/fnTypes.d.ts +40 -0
- package/core/function/ioSchema.d.ts +10 -0
- package/core/function/ioSchema.js +51 -0
- package/core/function/shelllessImpl.d.ts +28 -0
- package/core/function/shelllessImpl.js +21 -0
- package/core/function/templateUtils.js +12 -0
- package/core/function/tgpuComputeFn.d.ts +48 -0
- package/core/function/tgpuComputeFn.js +55 -0
- package/core/function/tgpuFn.d.ts +52 -0
- package/core/function/tgpuFn.js +168 -0
- package/core/function/tgpuFragmentFn.d.ts +72 -0
- package/core/function/tgpuFragmentFn.js +63 -0
- package/core/function/tgpuVertexFn.d.ts +59 -0
- package/core/function/tgpuVertexFn.js +59 -0
- package/core/pipeline/applyPipelineState.js +35 -0
- package/core/pipeline/computePipeline.d.ts +54 -0
- package/core/pipeline/computePipeline.js +227 -0
- package/core/pipeline/connectAttachmentToShader.js +24 -0
- package/core/pipeline/connectTargetsToShader.js +27 -0
- package/core/pipeline/limitsOverflow.js +12 -0
- package/core/pipeline/pipelineUtils.js +29 -0
- package/core/pipeline/renderPipeline.d.ts +284 -0
- package/core/pipeline/renderPipeline.js +489 -0
- package/core/pipeline/timeable.d.ts +20 -0
- package/core/pipeline/timeable.js +55 -0
- package/core/pipeline/typeGuards.js +27 -0
- package/core/querySet/querySet.d.ts +20 -0
- package/core/querySet/querySet.js +104 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +94 -0
- package/core/resolve/externals.d.ts +8 -0
- package/core/resolve/externals.js +56 -0
- package/core/resolve/namespace.d.ts +38 -0
- package/core/resolve/namespace.js +39 -0
- package/core/resolve/resolveData.js +144 -0
- package/core/resolve/stitch.js +23 -0
- package/core/resolve/tgpuResolve.d.ts +153 -0
- package/core/resolve/tgpuResolve.js +66 -0
- package/core/root/configurableImpl.js +17 -0
- package/core/root/init.d.ts +64 -0
- package/core/root/init.js +464 -0
- package/core/root/rootTypes.d.ts +642 -0
- package/core/sampler/sampler.d.ts +31 -0
- package/core/sampler/sampler.js +116 -0
- package/core/simulate/tgpuSimulate.d.ts +36 -0
- package/core/simulate/tgpuSimulate.js +74 -0
- package/core/slot/accessor.d.ts +9 -0
- package/core/slot/accessor.js +95 -0
- package/core/slot/internalSlots.js +5 -0
- package/core/slot/lazy.d.ts +6 -0
- package/core/slot/lazy.js +40 -0
- package/core/slot/slot.d.ts +6 -0
- package/core/slot/slot.js +39 -0
- package/core/slot/slotTypes.d.ts +92 -0
- package/core/slot/slotTypes.js +19 -0
- package/core/texture/externalTexture.d.ts +6 -0
- package/core/texture/externalTexture.js +47 -0
- package/core/texture/texture.d.ts +114 -0
- package/core/texture/texture.js +314 -0
- package/core/texture/textureFormats.d.ts +29 -0
- package/core/texture/textureFormats.js +97 -0
- package/core/texture/textureProps.d.ts +11 -0
- package/core/texture/textureUtils.js +222 -0
- package/core/texture/usageExtension.d.ts +21 -0
- package/core/texture/usageExtension.js +19 -0
- package/core/unroll/tgpuUnroll.d.ts +68 -0
- package/core/unroll/tgpuUnroll.js +94 -0
- package/core/valueProxyUtils.js +42 -0
- package/core/variable/tgpuVariable.d.ts +38 -0
- package/core/variable/tgpuVariable.js +99 -0
- package/core/vertexLayout/connectAttributesToShader.js +57 -0
- package/core/vertexLayout/vertexAttribute.d.ts +29 -0
- package/core/vertexLayout/vertexLayout.d.ts +19 -0
- package/core/vertexLayout/vertexLayout.js +103 -0
- package/data/alignIO.js +14 -0
- package/data/alignmentOf.d.ts +9 -0
- package/data/alignmentOf.js +86 -0
- package/data/array.d.ts +26 -0
- package/data/array.js +46 -0
- package/data/atomic.d.ts +15 -0
- package/data/atomic.js +24 -0
- package/data/attributes.d.ts +121 -0
- package/data/attributes.js +145 -0
- package/data/autoStruct.d.ts +1 -0
- package/data/autoStruct.js +81 -0
- package/data/compiledIO.js +228 -0
- package/data/dataIO.js +556 -0
- package/data/dataTypes.d.ts +115 -0
- package/data/dataTypes.js +100 -0
- package/data/deepEqual.d.ts +25 -0
- package/data/deepEqual.js +56 -0
- package/data/disarray.d.ts +32 -0
- package/data/disarray.js +50 -0
- package/data/getLongestContiguousPrefix.d.ts +9 -0
- package/data/getLongestContiguousPrefix.js +13 -0
- package/data/index.d.ts +26 -4
- package/data/index.js +36 -9
- package/data/instanceToSchema.d.ts +33 -0
- package/data/isContiguous.d.ts +9 -0
- package/data/isContiguous.js +13 -0
- package/data/matrix.d.ts +124 -0
- package/data/matrix.js +531 -0
- package/data/numberOps.js +23 -0
- package/data/numeric.d.ts +81 -0
- package/data/numeric.js +221 -0
- package/data/offsetUtils.d.ts +33 -0
- package/data/offsetUtils.js +165 -0
- package/data/offsets.js +34 -0
- package/data/partialIO.js +113 -0
- package/data/ptr.d.ts +11 -0
- package/data/ptr.js +44 -0
- package/data/ref.d.ts +34 -0
- package/data/ref.js +94 -0
- package/data/sampler.d.ts +107 -0
- package/data/sampler.js +24 -0
- package/data/schemaCallWrapper.js +30 -0
- package/data/schemaMemoryLayout.js +198 -0
- package/data/sizeOf.d.ts +9 -0
- package/data/sizeOf.js +13 -0
- package/data/snippet.d.ts +26 -0
- package/data/snippet.js +70 -0
- package/data/struct.d.ts +17 -0
- package/data/struct.js +44 -0
- package/data/texture.d.ts +292 -0
- package/{texture-BagDrrks.js → data/texture.js} +6 -5
- package/data/unstruct.d.ts +24 -0
- package/data/unstruct.js +41 -0
- package/data/vector.d.ts +191 -0
- package/data/vector.js +239 -0
- package/data/vectorImpl.js +515 -0
- package/data/vectorOps.js +681 -0
- package/data/vertexFormatData.d.ts +190 -0
- package/data/vertexFormatData.js +109 -0
- package/data/wgslTypes.d.ts +924 -0
- package/data/wgslTypes.js +222 -0
- package/errors.d.ts +44 -0
- package/errors.js +131 -0
- package/execMode.js +49 -0
- package/extension.d.ts +11 -0
- package/extension.js +16 -0
- package/getGPUValue.js +7 -0
- package/index.d.ts +42 -243
- package/index.js +21 -6320
- package/indexNamedExports.d.ts +40 -0
- package/mathUtils.js +12 -0
- package/memo.js +22 -0
- package/nameRegistry.d.ts +30 -0
- package/nameRegistry.js +447 -0
- package/package.js +4 -0
- package/package.json +26 -26
- package/resolutionCtx.d.ts +19 -0
- package/resolutionCtx.js +612 -0
- package/shared/env.js +12 -0
- package/shared/generators.js +13 -0
- package/shared/meta.d.ts +39 -0
- package/shared/meta.js +61 -0
- package/shared/repr.d.ts +138 -0
- package/shared/stringify.js +20 -0
- package/shared/symbols.d.ts +70 -0
- package/shared/symbols.js +48 -0
- package/shared/utilityTypes.d.ts +33 -0
- package/shared/utilityTypes.js +6 -0
- package/shared/vertexFormat.d.ts +70 -0
- package/shared/vertexFormat.js +63 -0
- package/std/array.d.ts +7 -0
- package/std/array.js +25 -0
- package/std/atomic.d.ts +19 -0
- package/std/atomic.js +111 -0
- package/std/bitcast.d.ts +10 -0
- package/std/bitcast.js +41 -0
- package/std/boolean.d.ts +141 -0
- package/std/boolean.js +299 -0
- package/std/derivative.d.ts +16 -0
- package/std/derivative.js +87 -0
- package/std/discard.d.ts +6 -0
- package/std/discard.js +14 -0
- package/std/extensions.d.ts +6 -0
- package/std/extensions.js +12 -0
- package/std/index.d.ts +17 -4
- package/std/index.js +21 -7
- package/std/matrix.d.ts +41 -0
- package/std/matrix.js +85 -0
- package/std/numeric.d.ts +200 -0
- package/std/numeric.js +845 -0
- package/std/operators.d.ts +56 -0
- package/std/operators.js +227 -0
- package/std/packing.d.ts +26 -0
- package/std/packing.js +84 -0
- package/std/range.d.ts +24 -0
- package/std/range.js +38 -0
- package/std/subgroup.d.ts +47 -0
- package/std/subgroup.js +218 -0
- package/std/texture.d.ts +117 -0
- package/std/texture.js +207 -0
- package/tgpu.js +42 -0
- package/tgpuBindGroupLayout.d.ts +161 -0
- package/tgpuBindGroupLayout.js +272 -0
- package/tgpuUnstable.d.ts +48 -0
- package/tgpuUnstable.js +64 -0
- package/tgsl/accessIndex.js +43 -0
- package/tgsl/accessProp.js +115 -0
- package/tgsl/consoleLog/deserializers.js +115 -0
- package/tgsl/consoleLog/logGenerator.js +84 -0
- package/tgsl/consoleLog/serializers.js +223 -0
- package/tgsl/consoleLog/types.d.ts +52 -0
- package/tgsl/consoleLog/types.js +11 -0
- package/tgsl/conversion.js +198 -0
- package/tgsl/forOfUtils.js +71 -0
- package/tgsl/generationHelpers.d.ts +37 -0
- package/tgsl/generationHelpers.js +67 -0
- package/tgsl/math.js +43 -0
- package/tgsl/shaderGenerator.d.ts +20 -0
- package/tgsl/shaderGenerator_members.d.ts +2 -0
- package/tgsl/shaderGenerator_members.js +6 -0
- package/tgsl/shellless.d.ts +11 -0
- package/tgsl/shellless.js +46 -0
- package/tgsl/wgslGenerator.d.ts +36 -0
- package/tgsl/wgslGenerator.js +639 -0
- package/types.d.ts +265 -0
- package/types.js +43 -0
- package/unwrapper.d.ts +27 -0
- package/wgslExtensions.d.ts +5 -0
- package/wgslExtensions.js +17 -0
- package/builtin-DdtWpk2t.js +0 -818
- package/builtin-DdtWpk2t.js.map +0 -1
- package/chunk-BYypO7fO.js +0 -18
- package/common/index.d.ts.map +0 -1
- package/common/index.js.map +0 -1
- package/data/index.d.ts.map +0 -1
- package/data/index.js.map +0 -1
- package/deepEqual-DQxK4vdp.js +0 -413
- package/deepEqual-DQxK4vdp.js.map +0 -1
- package/extensions-DIVuAfBM.js +0 -2032
- package/extensions-DIVuAfBM.js.map +0 -1
- package/fullScreenTriangle-CfFyQd_0.js +0 -543
- package/fullScreenTriangle-CfFyQd_0.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/indexNamedExports-oL6tyaJ9.d.ts +0 -5697
- package/indexNamedExports-oL6tyaJ9.d.ts.map +0 -1
- package/operators-d-PMVTo7.js +0 -4158
- package/operators-d-PMVTo7.js.map +0 -1
- package/std/index.d.ts.map +0 -1
- package/std/index.js.map +0 -1
- package/texture-BagDrrks.js.map +0 -1
package/data/numeric.js
ADDED
|
@@ -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 };
|
package/data/offsets.js
ADDED
|
@@ -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 };
|