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
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { DEV, TEST } from "../shared/env.js";
|
|
2
|
+
import { isMat, isPtr, isVec } from "../data/wgslTypes.js";
|
|
3
|
+
import { UnknownData, undecorate } from "../data/dataTypes.js";
|
|
4
|
+
import { snip } from "../data/snippet.js";
|
|
5
|
+
import { WgslTypeError, invariant } from "../errors.js";
|
|
6
|
+
import { stitch } from "../core/resolve/stitch.js";
|
|
7
|
+
import { RefOperator, derefSnippet } from "../data/ref.js";
|
|
8
|
+
import { schemaCallWrapperGPU } from "../data/schemaCallWrapper.js";
|
|
9
|
+
import { safeStringify } from "../shared/stringify.js";
|
|
10
|
+
import { assertExhaustive } from "../shared/utilityTypes.js";
|
|
11
|
+
//#region src/tgsl/conversion.ts
|
|
12
|
+
const INFINITE_RANK = {
|
|
13
|
+
rank: Number.POSITIVE_INFINITY,
|
|
14
|
+
action: "none"
|
|
15
|
+
};
|
|
16
|
+
function getAutoConversionRank(src, dest) {
|
|
17
|
+
const trueSrc = undecorate(src);
|
|
18
|
+
const trueDst = undecorate(dest);
|
|
19
|
+
if (trueSrc.type === trueDst.type) return {
|
|
20
|
+
rank: 0,
|
|
21
|
+
action: "none"
|
|
22
|
+
};
|
|
23
|
+
if (trueSrc.type === "abstractFloat") {
|
|
24
|
+
if (trueDst.type === "f32") return {
|
|
25
|
+
rank: 1,
|
|
26
|
+
action: "none"
|
|
27
|
+
};
|
|
28
|
+
if (trueDst.type === "f16") return {
|
|
29
|
+
rank: 2,
|
|
30
|
+
action: "none"
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (trueSrc.type === "abstractInt") {
|
|
34
|
+
if (trueDst.type === "i32") return {
|
|
35
|
+
rank: 3,
|
|
36
|
+
action: "none"
|
|
37
|
+
};
|
|
38
|
+
if (trueDst.type === "u32") return {
|
|
39
|
+
rank: 4,
|
|
40
|
+
action: "none"
|
|
41
|
+
};
|
|
42
|
+
if (trueDst.type === "abstractFloat") return {
|
|
43
|
+
rank: 5,
|
|
44
|
+
action: "none"
|
|
45
|
+
};
|
|
46
|
+
if (trueDst.type === "f32") return {
|
|
47
|
+
rank: 6,
|
|
48
|
+
action: "none"
|
|
49
|
+
};
|
|
50
|
+
if (trueDst.type === "f16") return {
|
|
51
|
+
rank: 7,
|
|
52
|
+
action: "none"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (isVec(trueSrc) && isVec(trueDst) && trueSrc.type[3] === trueDst.type[3]) return getAutoConversionRank(trueSrc.primitive, trueDst.primitive);
|
|
56
|
+
if (isMat(trueSrc) && isMat(trueDst) && trueSrc.type[3] === trueDst.type[3]) return {
|
|
57
|
+
rank: 0,
|
|
58
|
+
action: "none"
|
|
59
|
+
};
|
|
60
|
+
return INFINITE_RANK;
|
|
61
|
+
}
|
|
62
|
+
function getImplicitConversionRank(src, dest) {
|
|
63
|
+
const trueSrc = undecorate(src);
|
|
64
|
+
const trueDst = undecorate(dest);
|
|
65
|
+
if (isPtr(trueSrc) && trueSrc.implicit && getAutoConversionRank(trueSrc.inner, trueDst).rank < Number.POSITIVE_INFINITY) return {
|
|
66
|
+
rank: 0,
|
|
67
|
+
action: "deref"
|
|
68
|
+
};
|
|
69
|
+
if (isPtr(trueDst) && getAutoConversionRank(trueSrc, trueDst.inner).rank < Number.POSITIVE_INFINITY) return {
|
|
70
|
+
rank: 1,
|
|
71
|
+
action: "ref"
|
|
72
|
+
};
|
|
73
|
+
const primitivePreference = {
|
|
74
|
+
f32: 0,
|
|
75
|
+
f16: 1,
|
|
76
|
+
i32: 2,
|
|
77
|
+
u32: 3,
|
|
78
|
+
bool: 4
|
|
79
|
+
};
|
|
80
|
+
if (trueSrc.type in primitivePreference && trueDst.type in primitivePreference) {
|
|
81
|
+
const srcType = trueSrc.type;
|
|
82
|
+
const destType = trueDst.type;
|
|
83
|
+
if (srcType !== destType) {
|
|
84
|
+
const srcPref = primitivePreference[srcType];
|
|
85
|
+
return {
|
|
86
|
+
rank: primitivePreference[destType] < srcPref ? 10 : 20,
|
|
87
|
+
action: "cast",
|
|
88
|
+
targetType: trueDst
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (trueSrc.type === "abstractFloat") {
|
|
93
|
+
if (trueDst.type === "u32") return {
|
|
94
|
+
rank: 2,
|
|
95
|
+
action: "cast",
|
|
96
|
+
targetType: trueDst
|
|
97
|
+
};
|
|
98
|
+
if (trueDst.type === "i32") return {
|
|
99
|
+
rank: 1,
|
|
100
|
+
action: "cast",
|
|
101
|
+
targetType: trueDst
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return INFINITE_RANK;
|
|
105
|
+
}
|
|
106
|
+
function getConversionRank(src, dest, allowImplicit) {
|
|
107
|
+
const autoRank = getAutoConversionRank(src, dest);
|
|
108
|
+
if (autoRank.rank < Number.POSITIVE_INFINITY) return autoRank;
|
|
109
|
+
if (allowImplicit) return getImplicitConversionRank(src, dest);
|
|
110
|
+
return INFINITE_RANK;
|
|
111
|
+
}
|
|
112
|
+
function findBestType(types, uniqueTypes, allowImplicit) {
|
|
113
|
+
let bestResult;
|
|
114
|
+
for (const targetType of uniqueTypes) {
|
|
115
|
+
const details = [];
|
|
116
|
+
let sum = 0;
|
|
117
|
+
for (const sourceType of types) {
|
|
118
|
+
const conversion = getConversionRank(sourceType, targetType, allowImplicit);
|
|
119
|
+
sum += conversion.rank;
|
|
120
|
+
if (conversion.rank === Number.POSITIVE_INFINITY) break;
|
|
121
|
+
details.push(conversion);
|
|
122
|
+
}
|
|
123
|
+
if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) bestResult = {
|
|
124
|
+
type: targetType,
|
|
125
|
+
details,
|
|
126
|
+
sum
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
if (!bestResult) return;
|
|
130
|
+
const actions = bestResult.details.map((detail, index) => ({
|
|
131
|
+
sourceIndex: index,
|
|
132
|
+
action: detail.action,
|
|
133
|
+
...detail.action === "cast" && { targetType: detail.targetType }
|
|
134
|
+
}));
|
|
135
|
+
return {
|
|
136
|
+
targetType: bestResult.type,
|
|
137
|
+
actions,
|
|
138
|
+
hasImplicitConversions: actions.some((action) => action.action === "cast")
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function getBestConversion(types, targetTypes) {
|
|
142
|
+
if (types.length === 0) return void 0;
|
|
143
|
+
const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
|
|
144
|
+
const explicitResult = findBestType(types, uniqueTargetTypes, false);
|
|
145
|
+
if (explicitResult) return explicitResult;
|
|
146
|
+
const implicitResult = findBestType(types, uniqueTargetTypes, true);
|
|
147
|
+
if (implicitResult) return implicitResult;
|
|
148
|
+
}
|
|
149
|
+
function applyActionToSnippet(ctx, snippet, action, targetType) {
|
|
150
|
+
if (action.action === "none") return snip(snippet.value, targetType, snippet.origin);
|
|
151
|
+
switch (action.action) {
|
|
152
|
+
case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
|
|
153
|
+
case "deref": return derefSnippet(snippet);
|
|
154
|
+
case "cast": return schemaCallWrapperGPU(ctx, targetType, snippet);
|
|
155
|
+
default: assertExhaustive(action.action, "applyActionToSnippet");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function unify(inTypes, restrictTo) {
|
|
159
|
+
if (inTypes.some((type) => type === UnknownData)) return;
|
|
160
|
+
const conversion = getBestConversion(inTypes, restrictTo);
|
|
161
|
+
if (!conversion) return;
|
|
162
|
+
return inTypes.map((type) => isVec(type) || isMat(type) ? type : conversion.targetType);
|
|
163
|
+
}
|
|
164
|
+
function convertToCommonType(ctx, values, restrictTo, verbose = true) {
|
|
165
|
+
const types = values.map((value) => value.dataType);
|
|
166
|
+
if (types.some((type) => type === UnknownData)) return;
|
|
167
|
+
if (DEV && Array.isArray(restrictTo) && restrictTo.length === 0) console.warn("convertToCommonType was called with an empty restrictTo array, which prevents any conversions from being made. If you intend to allow all conversions, pass undefined instead. If this was intended call the function conditionally since the result will always be undefined.");
|
|
168
|
+
const conversion = getBestConversion(types, restrictTo);
|
|
169
|
+
if (!conversion) return;
|
|
170
|
+
if ((TEST || DEV) && verbose && conversion.hasImplicitConversions) console.warn(`Implicit conversions from [\n${values.map((v) => ` ${v.value}: ${safeStringify(v.dataType)}`).join(",\n")}\n] to ${conversion.targetType.type} are supported, but not recommended.
|
|
171
|
+
Consider using explicit conversions instead.`);
|
|
172
|
+
return values.map((value, index) => {
|
|
173
|
+
const action = conversion.actions[index];
|
|
174
|
+
invariant(action, "Action should not be undefined");
|
|
175
|
+
return applyActionToSnippet(ctx, value, action, conversion.targetType);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
|
|
179
|
+
const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
|
|
180
|
+
const { value, dataType, origin } = snippet;
|
|
181
|
+
if (targets.length === 1) {
|
|
182
|
+
const target = targets[0];
|
|
183
|
+
if (target === dataType) return snip(value, target, origin);
|
|
184
|
+
if (dataType === UnknownData) return snip(stitch`${snip(value, target, origin)}`, target, origin);
|
|
185
|
+
}
|
|
186
|
+
const converted = convertToCommonType(ctx, [snippet], targets, verbose);
|
|
187
|
+
if (converted) return converted[0];
|
|
188
|
+
throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(", ")}]`);
|
|
189
|
+
}
|
|
190
|
+
function convertStructValues(ctx, structType, values) {
|
|
191
|
+
return Object.entries(structType.propTypes).map(([key, targetType]) => {
|
|
192
|
+
const val = values[key];
|
|
193
|
+
if (!val) throw new Error(`Missing property ${key}`);
|
|
194
|
+
return convertToCommonType(ctx, [val], [targetType])?.[0] ?? val;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
export { convertStructValues, convertToCommonType, getBestConversion, tryConvertSnippet, unify };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { $gpuCallable } from "../shared/symbols.js";
|
|
2
|
+
import { isPtr, isVec, isWgslArray } from "../data/wgslTypes.js";
|
|
3
|
+
import { UnknownData } from "../data/dataTypes.js";
|
|
4
|
+
import { isEphemeralSnippet, snip } from "../data/snippet.js";
|
|
5
|
+
import { WgslTypeError, invariant } from "../errors.js";
|
|
6
|
+
import { stitch } from "../core/resolve/stitch.js";
|
|
7
|
+
import { createPtrFromOrigin, implicitFrom } from "../data/ptr.js";
|
|
8
|
+
import { i32, u32 } from "../data/numeric.js";
|
|
9
|
+
import { ArrayExpression, concretize } from "./generationHelpers.js";
|
|
10
|
+
import { accessIndex } from "./accessIndex.js";
|
|
11
|
+
import { arrayLength } from "../std/array.js";
|
|
12
|
+
import { isTgpuRange } from "../std/range.js";
|
|
13
|
+
//#region src/tgsl/forOfUtils.ts
|
|
14
|
+
function getLoopVarKind(elementSnippet) {
|
|
15
|
+
return elementSnippet.origin === "constant-tgpu-const-ref" ? "const" : "let";
|
|
16
|
+
}
|
|
17
|
+
function getElementSnippet(iterableSnippet, index) {
|
|
18
|
+
const elementSnippet = accessIndex(iterableSnippet, index);
|
|
19
|
+
if (!elementSnippet) throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
|
|
20
|
+
return elementSnippet;
|
|
21
|
+
}
|
|
22
|
+
function getElementType(elementSnippet, iterableSnippet) {
|
|
23
|
+
let elementType = elementSnippet.dataType;
|
|
24
|
+
if (elementType === UnknownData) throw new WgslTypeError(stitch`The elements in iterable ${iterableSnippet} are of unknown type`);
|
|
25
|
+
if (isEphemeralSnippet(elementSnippet) || elementSnippet.origin === "constant-tgpu-const-ref" || elementSnippet.origin === "runtime-tgpu-const-ref") return elementType;
|
|
26
|
+
if (!isPtr(elementType)) {
|
|
27
|
+
const ptrType = createPtrFromOrigin(elementSnippet.origin, concretize(elementType));
|
|
28
|
+
invariant(ptrType !== void 0, `Creating pointer type from origin ${elementSnippet.origin}`);
|
|
29
|
+
elementType = ptrType;
|
|
30
|
+
}
|
|
31
|
+
return implicitFrom(elementType);
|
|
32
|
+
}
|
|
33
|
+
function getRangeSnippets(ctx, iterableSnippet, unroll = false) {
|
|
34
|
+
const { value, dataType } = iterableSnippet;
|
|
35
|
+
if (isTgpuRange(value)) return {
|
|
36
|
+
start: snip(value.start, i32, "constant"),
|
|
37
|
+
end: snip(value.end, i32, "constant"),
|
|
38
|
+
step: snip(value.step, i32, "constant"),
|
|
39
|
+
comparison: value.step < 0 ? ">" : "<"
|
|
40
|
+
};
|
|
41
|
+
if (!unroll && isEphemeralSnippet(iterableSnippet)) throw new Error(`\`for ... of ...\` loops only support std.range or iterables stored in variables.
|
|
42
|
+
-----
|
|
43
|
+
You can wrap iterable with \`tgpu.unroll(...)\`. If iterable is known at comptime, the loop will be unrolled.
|
|
44
|
+
-----`);
|
|
45
|
+
const defaults = {
|
|
46
|
+
start: snip(0, u32, "constant"),
|
|
47
|
+
step: snip(1, u32, "constant"),
|
|
48
|
+
comparison: "<"
|
|
49
|
+
};
|
|
50
|
+
if (isWgslArray(dataType)) return {
|
|
51
|
+
...defaults,
|
|
52
|
+
end: dataType.elementCount > 0 ? snip(dataType.elementCount, u32, "constant") : arrayLength[$gpuCallable].call(ctx, [iterableSnippet])
|
|
53
|
+
};
|
|
54
|
+
if (isVec(dataType)) return {
|
|
55
|
+
...defaults,
|
|
56
|
+
end: snip(dataType.componentCount, u32, "constant")
|
|
57
|
+
};
|
|
58
|
+
if (unroll) {
|
|
59
|
+
if (Array.isArray(value)) return {
|
|
60
|
+
...defaults,
|
|
61
|
+
end: snip(value.length, u32, "constant")
|
|
62
|
+
};
|
|
63
|
+
if (value instanceof ArrayExpression) return {
|
|
64
|
+
...defaults,
|
|
65
|
+
end: snip(value.elements.length, u32, "constant")
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { getElementSnippet, getElementType, getLoopVarKind, getRangeSnippets };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Snippet } from "../data/snippet.js";
|
|
2
|
+
import { ShelllessRepository } from "./shellless.js";
|
|
3
|
+
import { FunctionScopeLayer, ResolutionCtx } from "../types.js";
|
|
4
|
+
import { BaseData } from "../data/wgslTypes.js";
|
|
5
|
+
|
|
6
|
+
//#region src/tgsl/generationHelpers.d.ts
|
|
7
|
+
type GenerationCtx = ResolutionCtx & {
|
|
8
|
+
readonly pre: string;
|
|
9
|
+
/**
|
|
10
|
+
* Used by `typedExpression` to signal downstream
|
|
11
|
+
* expression resolution what type is expected of them.
|
|
12
|
+
*
|
|
13
|
+
* It is used exclusively for inferring the types of structs and arrays.
|
|
14
|
+
* It is modified exclusively by `typedExpression` function.
|
|
15
|
+
*/
|
|
16
|
+
expectedType: (BaseData | BaseData[]) | undefined;
|
|
17
|
+
readonly topFunctionScope: FunctionScopeLayer | undefined;
|
|
18
|
+
readonly topFunctionReturnType: BaseData | undefined;
|
|
19
|
+
indent(): string;
|
|
20
|
+
dedent(): string;
|
|
21
|
+
pushBlockScope(): void;
|
|
22
|
+
popBlockScope(): void;
|
|
23
|
+
generateLog(op: string, args: Snippet[]): Snippet;
|
|
24
|
+
getById(id: string): Snippet | null;
|
|
25
|
+
defineVariable(id: string, snippet: Snippet): void;
|
|
26
|
+
setBlockExternals(externals: Record<string, Snippet>): void;
|
|
27
|
+
clearBlockExternals(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Types that are used in `return` statements are
|
|
30
|
+
* reported using this function, and used to infer
|
|
31
|
+
* the return type of the owning function.
|
|
32
|
+
*/
|
|
33
|
+
reportReturnType(dataType: BaseData): void;
|
|
34
|
+
readonly shelllessRepo: ShelllessRepository;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { GenerationCtx };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { $internal, $resolve } from "../shared/symbols.js";
|
|
2
|
+
import { WORKAROUND_getSchema, isMatInstance, isNaturallyEphemeral, isVecInstance } from "../data/wgslTypes.js";
|
|
3
|
+
import { UnknownData } from "../data/dataTypes.js";
|
|
4
|
+
import { isEphemeralSnippet, isSnippet, snip } from "../data/snippet.js";
|
|
5
|
+
import { WgslTypeError } from "../errors.js";
|
|
6
|
+
import { getOwnSnippet } from "../types.js";
|
|
7
|
+
import { stitch } from "../core/resolve/stitch.js";
|
|
8
|
+
import { isRef } from "../data/ref.js";
|
|
9
|
+
import { abstractFloat, abstractInt, bool, f32, i32 } from "../data/numeric.js";
|
|
10
|
+
//#region src/tgsl/generationHelpers.ts
|
|
11
|
+
function numericLiteralToSnippet(value) {
|
|
12
|
+
if (value >= 2 ** 63 || value < -(2 ** 63)) return snip(value, abstractFloat, "constant");
|
|
13
|
+
if (Number.isInteger(value)) {
|
|
14
|
+
if (!Number.isSafeInteger(value)) console.warn(`The integer ${value} exceeds the safe integer range and may have lost precision.`);
|
|
15
|
+
return snip(value, abstractInt, "constant");
|
|
16
|
+
}
|
|
17
|
+
return snip(value, abstractFloat, "constant");
|
|
18
|
+
}
|
|
19
|
+
function concretize(type) {
|
|
20
|
+
if (type.type === "abstractFloat") return f32;
|
|
21
|
+
if (type.type === "abstractInt") return i32;
|
|
22
|
+
return type;
|
|
23
|
+
}
|
|
24
|
+
function concretizeSnippet(snippet) {
|
|
25
|
+
return snip(snippet.value, concretize(snippet.dataType), snippet.origin);
|
|
26
|
+
}
|
|
27
|
+
function concretizeSnippets(args) {
|
|
28
|
+
return args.map(concretizeSnippet);
|
|
29
|
+
}
|
|
30
|
+
function coerceToSnippet(value) {
|
|
31
|
+
if (isSnippet(value)) return value;
|
|
32
|
+
if (isRef(value)) throw new Error("Cannot use refs (d.ref(...)) from the outer scope.");
|
|
33
|
+
const ownSnippet = getOwnSnippet(value);
|
|
34
|
+
if (ownSnippet) return ownSnippet;
|
|
35
|
+
if (isVecInstance(value) || isMatInstance(value)) return snip(value, WORKAROUND_getSchema(value), "constant");
|
|
36
|
+
if (typeof value === "string" || typeof value === "function" || typeof value === "object" || typeof value === "symbol" || typeof value === "undefined" || value === null) return snip(value, UnknownData, "constant");
|
|
37
|
+
if (typeof value === "number") return numericLiteralToSnippet(value);
|
|
38
|
+
if (typeof value === "boolean") return snip(value, bool, "constant");
|
|
39
|
+
return snip(value, UnknownData, "constant");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Intermediate representation for WGSL array expressions.
|
|
43
|
+
* Defers resolution. Stores array elements as snippets so the
|
|
44
|
+
* generator can access them when needed.
|
|
45
|
+
*/
|
|
46
|
+
var ArrayExpression = class {
|
|
47
|
+
[$internal] = true;
|
|
48
|
+
type;
|
|
49
|
+
elements;
|
|
50
|
+
constructor(type, elements) {
|
|
51
|
+
this.type = type;
|
|
52
|
+
this.elements = elements;
|
|
53
|
+
}
|
|
54
|
+
toString() {
|
|
55
|
+
return "ArrayExpression";
|
|
56
|
+
}
|
|
57
|
+
[$resolve](ctx) {
|
|
58
|
+
for (const elem of this.elements) if (elem.origin === "argument" && !isNaturallyEphemeral(elem.dataType) || !isEphemeralSnippet(elem)) {
|
|
59
|
+
const snippetStr = ctx.resolve(elem.value, elem.dataType).value;
|
|
60
|
+
const snippetType = ctx.resolve(concretize(elem.dataType)).value;
|
|
61
|
+
throw new WgslTypeError(`'${snippetStr}' reference cannot be used in an array constructor.\n-----\nTry '${snippetType}(${snippetStr})' or 'arrayOf(${snippetType}, count)([...])' to copy the value instead.\n-----`);
|
|
62
|
+
}
|
|
63
|
+
return snip(stitch`${`array<${ctx.resolve(this.type.elementType).value}, ${this.elements.length}>`}(${this.elements})`, this.type, "runtime");
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
//#endregion
|
|
67
|
+
export { ArrayExpression, coerceToSnippet, concretize, concretizeSnippets, numericLiteralToSnippet };
|
package/tgsl/math.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { f32 } from "../data/numeric.js";
|
|
2
|
+
import { abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, cos, cosh, countLeadingZeros, exp, floor, log, log2, max, min, pow, sign, sin, sinh, sqrt, tan, tanh, trunc } from "../std/numeric.js";
|
|
3
|
+
//#region src/tgsl/math.ts
|
|
4
|
+
const mathToStd = {
|
|
5
|
+
abs,
|
|
6
|
+
acos,
|
|
7
|
+
acosh,
|
|
8
|
+
asin,
|
|
9
|
+
asinh,
|
|
10
|
+
atan,
|
|
11
|
+
atan2,
|
|
12
|
+
atanh,
|
|
13
|
+
ceil,
|
|
14
|
+
cos,
|
|
15
|
+
cosh,
|
|
16
|
+
exp,
|
|
17
|
+
floor,
|
|
18
|
+
fround: f32,
|
|
19
|
+
clz32: countLeadingZeros,
|
|
20
|
+
trunc,
|
|
21
|
+
log,
|
|
22
|
+
log2,
|
|
23
|
+
pow,
|
|
24
|
+
sign,
|
|
25
|
+
sin,
|
|
26
|
+
sinh,
|
|
27
|
+
sqrt,
|
|
28
|
+
tan,
|
|
29
|
+
tanh,
|
|
30
|
+
max,
|
|
31
|
+
min,
|
|
32
|
+
cbrt: void 0,
|
|
33
|
+
log10: void 0,
|
|
34
|
+
log1p: void 0,
|
|
35
|
+
f16round: void 0,
|
|
36
|
+
hypot: void 0,
|
|
37
|
+
expm1: void 0,
|
|
38
|
+
random: void 0,
|
|
39
|
+
imul: void 0,
|
|
40
|
+
round: void 0
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { mathToStd };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ResolvedSnippet, Snippet } from "../data/snippet.js";
|
|
2
|
+
import { GenerationCtx } from "./generationHelpers.js";
|
|
3
|
+
import { BaseData } from "../data/wgslTypes.js";
|
|
4
|
+
import { Block } from "tinyest";
|
|
5
|
+
|
|
6
|
+
//#region src/tgsl/shaderGenerator.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* **NOTE: This is an unstable API and may change in the future.**
|
|
9
|
+
*
|
|
10
|
+
* An interface meant to be used by other systems to generate snippets of
|
|
11
|
+
* shader code in the target language (WGSL, GLSL, etc.).
|
|
12
|
+
*/
|
|
13
|
+
interface ShaderGenerator {
|
|
14
|
+
initGenerator(ctx: GenerationCtx): void;
|
|
15
|
+
functionDefinition(body: Block): string;
|
|
16
|
+
typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
|
|
17
|
+
typeAnnotation(schema: BaseData): string;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ShaderGenerator };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { UnknownData } from "../data/dataTypes.js";
|
|
3
|
+
//#region src/tgsl/shaderGenerator_members.ts
|
|
4
|
+
var shaderGenerator_members_exports = /* @__PURE__ */ __exportAll({ UnknownData: () => UnknownData });
|
|
5
|
+
//#endregion
|
|
6
|
+
export { shaderGenerator_members_exports };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Snippet } from "../data/snippet.js";
|
|
2
|
+
import { ShelllessImpl } from "../core/function/shelllessImpl.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tgsl/shellless.d.ts
|
|
5
|
+
type AnyFn = (...args: never[]) => unknown;
|
|
6
|
+
declare class ShelllessRepository {
|
|
7
|
+
cache: Map<AnyFn, ShelllessImpl[]>;
|
|
8
|
+
get(fn: AnyFn, argSnippets: Snippet[] | undefined): ShelllessImpl | undefined;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ShelllessRepository };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getMetaData, getName } from "../shared/meta.js";
|
|
2
|
+
import { isPtr, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
|
|
3
|
+
import { UnknownData } from "../data/dataTypes.js";
|
|
4
|
+
import { WgslTypeError } from "../errors.js";
|
|
5
|
+
import { RefOperator } from "../data/ref.js";
|
|
6
|
+
import { concretize } from "./generationHelpers.js";
|
|
7
|
+
import { createShelllessImpl } from "../core/function/shelllessImpl.js";
|
|
8
|
+
//#region src/tgsl/shellless.ts
|
|
9
|
+
function shallowEqualSchemas(a, b) {
|
|
10
|
+
if (a.type !== b.type) return false;
|
|
11
|
+
if (isPtr(a) && isPtr(b)) return a.access === b.access && a.addressSpace === b.addressSpace && a.implicit === b.implicit && shallowEqualSchemas(a.inner, b.inner);
|
|
12
|
+
if (isWgslArray(a) && isWgslArray(b)) return a.elementCount === b.elementCount && shallowEqualSchemas(a.elementType, b.elementType);
|
|
13
|
+
if (isWgslStruct(a) && isWgslStruct(b)) return a === b;
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
var ShelllessRepository = class {
|
|
17
|
+
cache = /* @__PURE__ */ new Map();
|
|
18
|
+
get(fn, argSnippets) {
|
|
19
|
+
const meta = getMetaData(fn);
|
|
20
|
+
if (!meta?.ast) return void 0;
|
|
21
|
+
if (!argSnippets && meta.ast.params.length > 0) throw new Error(`Cannot resolve '${getName(fn)}' directly, because it expects arguments. Either call it from another function, or wrap it in a shell`);
|
|
22
|
+
const argTypes = (argSnippets ?? []).map((s, index) => {
|
|
23
|
+
if (s.value instanceof RefOperator) {
|
|
24
|
+
if (s.dataType === UnknownData) throw new WgslTypeError(`d.ref() created with primitive types must be stored in a variable before use`);
|
|
25
|
+
return s.dataType;
|
|
26
|
+
}
|
|
27
|
+
if (s.dataType === UnknownData) throw new Error(`Passed illegal value ${s.value} as the #${index} argument to ${meta.name}(...)\nShellless functions can only accept arguments representing WGSL resources: constructible WGSL types, d.refs, samplers or texture views.\nRemember, that arguments such as samplers, texture views, accessors, slots etc. should be dereferenced via '.$' first.`);
|
|
28
|
+
let type = concretize(s.dataType);
|
|
29
|
+
if (isPtr(type) && type.implicit) type = type.inner;
|
|
30
|
+
return type;
|
|
31
|
+
});
|
|
32
|
+
let cache = this.cache.get(fn);
|
|
33
|
+
if (cache) {
|
|
34
|
+
const variant = cache.find((v) => v.argTypes.length === argTypes.length && v.argTypes.every((t, i) => shallowEqualSchemas(t, argTypes[i])));
|
|
35
|
+
if (variant) return variant;
|
|
36
|
+
} else {
|
|
37
|
+
cache = [];
|
|
38
|
+
this.cache.set(fn, cache);
|
|
39
|
+
}
|
|
40
|
+
const shellless = createShelllessImpl(argTypes, fn);
|
|
41
|
+
cache.push(shellless);
|
|
42
|
+
return shellless;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ShelllessRepository };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Origin, ResolvedSnippet, Snippet } from "../data/snippet.js";
|
|
2
|
+
import { GenerationCtx } from "./generationHelpers.js";
|
|
3
|
+
import { ShaderGenerator } from "./shaderGenerator.js";
|
|
4
|
+
import { BaseData, StorableData } from "../data/wgslTypes.js";
|
|
5
|
+
import { UnknownData } from "../data/dataTypes.js";
|
|
6
|
+
import { ExternalMap } from "../core/resolve/externals.js";
|
|
7
|
+
import * as tinyest from "tinyest";
|
|
8
|
+
|
|
9
|
+
//#region src/tgsl/wgslGenerator.d.ts
|
|
10
|
+
declare class WgslGenerator implements ShaderGenerator {
|
|
11
|
+
#private;
|
|
12
|
+
initGenerator(ctx: GenerationCtx): void;
|
|
13
|
+
protected get ctx(): GenerationCtx;
|
|
14
|
+
_block([_, statements]: tinyest.Block, externalMap?: ExternalMap): string;
|
|
15
|
+
refVariable(id: string, dataType: StorableData): string;
|
|
16
|
+
blockVariable(varType: 'var' | 'let' | 'const', id: string, dataType: BaseData | UnknownData, origin: Origin): Snippet;
|
|
17
|
+
protected emitVarDecl(pre: string, keyword: 'var' | 'let' | 'const', name: string, _dataType: BaseData | UnknownData, rhsStr: string): string;
|
|
18
|
+
_identifier(id: string): Snippet;
|
|
19
|
+
/**
|
|
20
|
+
* A wrapper for `generateExpression` that updates `ctx.expectedType`
|
|
21
|
+
* and tries to convert the result when it does not match the expected type.
|
|
22
|
+
*/
|
|
23
|
+
_typedExpression(expression: tinyest.Expression, expectedType: BaseData | BaseData[]): Snippet;
|
|
24
|
+
_expression(expression: tinyest.Expression): Snippet;
|
|
25
|
+
functionDefinition(body: tinyest.Block): string;
|
|
26
|
+
/**
|
|
27
|
+
* Generates a WGSL type string for the given data type, and adds necessary
|
|
28
|
+
* definitions to the shader preamble. This shouldn't be called directly, only
|
|
29
|
+
* through `ctx.resolve` to properly cache the result.
|
|
30
|
+
*/
|
|
31
|
+
typeAnnotation(data: BaseData): string;
|
|
32
|
+
typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
|
|
33
|
+
_statement(statement: tinyest.Statement): string;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { WgslGenerator };
|