typegpu 0.10.0 → 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.
- package/{chunk-BYypO7fO.js → _virtual/_rolldown/runtime.js} +1 -1
- package/builtin.d.ts +50 -0
- package/builtin.js +37 -0
- package/common/fullScreenTriangle.d.ts +26 -0
- package/common/fullScreenTriangle.js +36 -0
- package/common/index.d.ts +2 -3
- package/common/index.js +3 -4
- package/core/buffer/buffer.d.ts +74 -0
- package/core/buffer/buffer.js +197 -0
- package/core/buffer/bufferShorthand.d.ts +48 -0
- package/core/buffer/bufferShorthand.js +49 -0
- package/core/buffer/bufferUsage.d.ts +45 -0
- package/core/buffer/bufferUsage.js +163 -0
- package/core/constant/tgpuConstant.d.ts +28 -0
- package/core/constant/tgpuConstant.js +67 -0
- package/core/declare/tgpuDeclare.d.ts +18 -0
- package/core/declare/tgpuDeclare.js +40 -0
- package/core/function/autoIO.d.ts +37 -0
- package/core/function/autoIO.js +87 -0
- package/core/function/comptime.d.ts +39 -0
- package/core/function/comptime.js +51 -0
- package/core/function/createCallableSchema.js +42 -0
- package/core/function/dualImpl.js +54 -0
- package/core/function/extractArgs.js +204 -0
- package/core/function/fnCore.js +79 -0
- package/core/function/fnTypes.d.ts +34 -0
- package/core/function/ioSchema.d.ts +10 -0
- package/core/function/ioSchema.js +30 -0
- package/core/function/shelllessImpl.d.ts +28 -0
- package/core/function/shelllessImpl.js +23 -0
- package/core/function/templateUtils.js +13 -0
- package/core/function/tgpuComputeFn.d.ts +49 -0
- package/core/function/tgpuComputeFn.js +62 -0
- package/core/function/tgpuFn.d.ts +52 -0
- package/core/function/tgpuFn.js +170 -0
- package/core/function/tgpuFragmentFn.d.ts +68 -0
- package/core/function/tgpuFragmentFn.js +68 -0
- package/core/function/tgpuVertexFn.d.ts +55 -0
- package/core/function/tgpuVertexFn.js +65 -0
- package/core/pipeline/applyPipelineState.js +37 -0
- package/core/pipeline/computePipeline.d.ts +58 -0
- package/core/pipeline/computePipeline.js +226 -0
- package/core/pipeline/connectAttachmentToShader.js +26 -0
- package/core/pipeline/connectTargetsToShader.js +29 -0
- package/core/pipeline/limitsOverflow.js +13 -0
- package/core/pipeline/renderPipeline.d.ts +266 -0
- package/core/pipeline/renderPipeline.js +471 -0
- package/core/pipeline/timeable.d.ts +23 -0
- package/core/pipeline/timeable.js +61 -0
- package/core/pipeline/typeGuards.js +29 -0
- package/core/querySet/querySet.d.ts +22 -0
- package/core/querySet/querySet.js +103 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +59 -0
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +96 -0
- package/core/resolve/externals.d.ts +10 -0
- package/core/resolve/externals.js +58 -0
- package/core/resolve/namespace.d.ts +38 -0
- package/core/resolve/namespace.js +41 -0
- package/core/resolve/resolveData.js +146 -0
- package/core/resolve/stitch.js +25 -0
- package/core/resolve/tgpuResolve.d.ts +151 -0
- package/core/resolve/tgpuResolve.js +68 -0
- package/core/root/configurableImpl.js +18 -0
- package/core/root/init.d.ts +69 -0
- package/core/root/init.js +457 -0
- package/core/root/rootTypes.d.ts +622 -0
- package/core/sampler/sampler.d.ts +35 -0
- package/core/sampler/sampler.js +116 -0
- package/core/simulate/tgpuSimulate.d.ts +36 -0
- package/core/simulate/tgpuSimulate.js +76 -0
- package/core/slot/accessor.d.ts +13 -0
- package/core/slot/accessor.js +97 -0
- package/core/slot/internalSlots.js +7 -0
- package/core/slot/lazy.d.ts +6 -0
- package/core/slot/lazy.js +42 -0
- package/core/slot/slot.d.ts +6 -0
- package/core/slot/slot.js +40 -0
- package/core/slot/slotTypes.d.ts +92 -0
- package/core/slot/slotTypes.js +21 -0
- package/core/texture/externalTexture.d.ts +12 -0
- package/core/texture/externalTexture.js +48 -0
- package/core/texture/texture.d.ts +118 -0
- package/core/texture/texture.js +312 -0
- package/core/texture/textureFormats.d.ts +29 -0
- package/core/texture/textureFormats.js +99 -0
- package/core/texture/textureProps.d.ts +11 -0
- package/core/texture/textureUtils.js +224 -0
- package/core/texture/usageExtension.d.ts +21 -0
- package/core/texture/usageExtension.js +21 -0
- package/core/unroll/tgpuUnroll.d.ts +13 -0
- package/core/unroll/tgpuUnroll.js +36 -0
- package/core/valueProxyUtils.js +44 -0
- package/core/variable/tgpuVariable.d.ts +38 -0
- package/core/variable/tgpuVariable.js +101 -0
- package/core/vertexLayout/connectAttributesToShader.js +59 -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 +15 -0
- package/data/alignmentOf.d.ts +10 -0
- package/data/alignmentOf.js +88 -0
- package/data/array.d.ts +28 -0
- package/data/array.js +48 -0
- package/data/atomic.d.ts +15 -0
- package/data/atomic.js +25 -0
- package/data/attributes.d.ts +121 -0
- package/data/attributes.js +145 -0
- package/data/autoStruct.d.ts +3 -0
- package/data/autoStruct.js +83 -0
- package/data/compiledIO.js +231 -0
- package/data/dataIO.js +549 -0
- package/data/dataTypes.d.ts +115 -0
- package/data/dataTypes.js +97 -0
- package/data/deepEqual.d.ts +25 -0
- package/data/deepEqual.js +58 -0
- package/data/disarray.d.ts +34 -0
- package/data/disarray.js +52 -0
- package/data/getLongestContiguousPrefix.d.ts +10 -0
- package/data/getLongestContiguousPrefix.js +15 -0
- package/data/index.d.ts +26 -4
- package/data/index.js +27 -7
- package/data/instanceToSchema.d.ts +33 -0
- package/data/isContiguous.d.ts +10 -0
- package/data/isContiguous.js +15 -0
- package/data/matrix.d.ts +126 -0
- package/data/matrix.js +517 -0
- package/data/numberOps.js +24 -0
- package/data/numeric.d.ts +81 -0
- package/data/numeric.js +234 -0
- package/data/offsetUtils.d.ts +33 -0
- package/data/offsetUtils.js +167 -0
- package/data/offsets.js +36 -0
- package/data/partialIO.js +68 -0
- package/data/ptr.d.ts +12 -0
- package/data/ptr.js +46 -0
- package/data/ref.d.ts +37 -0
- package/data/ref.js +96 -0
- package/data/sampler.d.ts +107 -0
- package/data/sampler.js +26 -0
- package/data/schemaCallWrapper.js +32 -0
- package/data/schemaMemoryLayout.js +200 -0
- package/data/sizeOf.d.ts +10 -0
- package/data/sizeOf.js +15 -0
- package/data/snippet.d.ts +26 -0
- package/data/snippet.js +61 -0
- package/data/struct.d.ts +17 -0
- package/data/struct.js +46 -0
- package/data/texture.d.ts +292 -0
- package/{texture-Dg5ybJro.js → data/texture.js} +6 -3
- package/data/unstruct.d.ts +24 -0
- package/data/unstruct.js +43 -0
- package/data/vector.d.ts +191 -0
- package/data/vector.js +247 -0
- package/data/vectorImpl.js +516 -0
- package/data/vectorOps.js +664 -0
- package/data/vertexFormatData.d.ts +190 -0
- package/data/vertexFormatData.js +110 -0
- package/data/wgslTypes.d.ts +896 -0
- package/data/wgslTypes.js +215 -0
- package/errors.d.ts +44 -0
- package/errors.js +128 -0
- package/execMode.js +51 -0
- package/extension.d.ts +11 -0
- package/extension.js +18 -0
- package/getGPUValue.js +9 -0
- package/index.d.ts +40 -243
- package/index.js +19 -6318
- package/indexNamedExports.d.ts +38 -0
- package/mathUtils.js +13 -0
- package/memo.js +22 -0
- package/nameRegistry.d.ts +30 -0
- package/nameRegistry.js +449 -0
- package/package.js +5 -0
- package/package.json +23 -23
- package/resolutionCtx.d.ts +29 -0
- package/resolutionCtx.js +546 -0
- package/shared/env.js +13 -0
- package/shared/generators.js +14 -0
- package/shared/meta.d.ts +39 -0
- package/shared/meta.js +63 -0
- package/shared/repr.d.ts +108 -0
- package/shared/stringify.js +22 -0
- package/shared/symbols.d.ts +61 -0
- package/shared/symbols.js +71 -0
- package/shared/utilityTypes.d.ts +29 -0
- package/shared/utilityTypes.js +7 -0
- package/shared/vertexFormat.d.ts +70 -0
- package/shared/vertexFormat.js +64 -0
- package/std/array.d.ts +7 -0
- package/std/array.js +27 -0
- package/std/atomic.d.ts +19 -0
- package/std/atomic.js +113 -0
- package/std/bitcast.d.ts +10 -0
- package/std/bitcast.js +43 -0
- package/std/boolean.d.ts +127 -0
- package/std/boolean.js +274 -0
- package/std/derivative.d.ts +16 -0
- package/std/derivative.js +89 -0
- package/std/discard.d.ts +6 -0
- package/std/discard.js +16 -0
- package/std/extensions.d.ts +8 -0
- package/std/extensions.js +14 -0
- package/std/index.d.ts +15 -3
- package/std/index.js +16 -5
- package/std/matrix.d.ts +41 -0
- package/std/matrix.js +87 -0
- package/std/numeric.d.ts +254 -0
- package/std/numeric.js +847 -0
- package/std/operators.d.ts +48 -0
- package/std/operators.js +153 -0
- package/std/packing.d.ts +26 -0
- package/std/packing.js +86 -0
- package/std/subgroup.d.ts +47 -0
- package/std/subgroup.js +220 -0
- package/std/texture.d.ts +108 -0
- package/std/texture.js +197 -0
- package/tgpu.js +44 -0
- package/tgpuBindGroupLayout.d.ts +161 -0
- package/tgpuBindGroupLayout.js +271 -0
- package/tgpuUnstable.d.ts +48 -0
- package/tgpuUnstable.js +66 -0
- package/tgsl/accessIndex.js +45 -0
- package/tgsl/accessProp.js +113 -0
- package/tgsl/consoleLog/deserializers.js +117 -0
- package/tgsl/consoleLog/logGenerator.js +86 -0
- package/tgsl/consoleLog/serializers.js +225 -0
- package/tgsl/consoleLog/types.d.ts +54 -0
- package/tgsl/consoleLog/types.js +12 -0
- package/tgsl/conversion.js +200 -0
- package/tgsl/forOfUtils.js +45 -0
- package/tgsl/generationHelpers.d.ts +37 -0
- package/tgsl/generationHelpers.js +67 -0
- package/tgsl/math.js +45 -0
- package/tgsl/shaderGenerator.d.ts +18 -0
- package/tgsl/shellless.d.ts +11 -0
- package/tgsl/shellless.js +53 -0
- package/tgsl/wgslGenerator.js +585 -0
- package/types.d.ts +255 -0
- package/types.js +43 -0
- package/unwrapper.d.ts +27 -0
- package/wgslExtensions.d.ts +5 -0
- package/wgslExtensions.js +18 -0
- package/builtin-ClEnM-Ye.js +0 -818
- package/builtin-ClEnM-Ye.js.map +0 -1
- 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-yZXvaV2C.js +0 -413
- package/deepEqual-yZXvaV2C.js.map +0 -1
- package/extensions-0SFbU9FH.js +0 -2032
- package/extensions-0SFbU9FH.js.map +0 -1
- package/fullScreenTriangle-MdLGaAMR.js +0 -543
- package/fullScreenTriangle-MdLGaAMR.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/indexNamedExports-Cdy7USiY.d.ts +0 -5696
- package/indexNamedExports-Cdy7USiY.d.ts.map +0 -1
- package/operators-HTxa_0k9.js +0 -4156
- package/operators-HTxa_0k9.js.map +0 -1
- package/std/index.d.ts.map +0 -1
- package/std/index.js.map +0 -1
- package/texture-Dg5ybJro.js.map +0 -1
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { $getNameForward, $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
|
|
2
|
+
import { getName, setName } from "../../shared/meta.js";
|
|
3
|
+
import { isNaturallyEphemeral } from "../../data/wgslTypes.js";
|
|
4
|
+
import { snip } from "../../data/snippet.js";
|
|
5
|
+
import { IllegalBufferAccessError } from "../../errors.js";
|
|
6
|
+
import { getExecMode, inCodegenMode, isInsideTgpuFn } from "../../execMode.js";
|
|
7
|
+
import { schemaCallWrapper } from "../../data/schemaCallWrapper.js";
|
|
8
|
+
import { assertExhaustive } from "../../shared/utilityTypes.js";
|
|
9
|
+
import { valueProxyHandler } from "../valueProxyUtils.js";
|
|
10
|
+
import { isUsableAsStorage } from "../../extension.js";
|
|
11
|
+
|
|
12
|
+
//#region src/core/buffer/bufferUsage.ts
|
|
13
|
+
function isUsableAsUniform(buffer) {
|
|
14
|
+
return !!buffer.usableAsUniform;
|
|
15
|
+
}
|
|
16
|
+
const usageToVarTemplateMap = {
|
|
17
|
+
uniform: "uniform",
|
|
18
|
+
mutable: "storage, read_write",
|
|
19
|
+
readonly: "storage, read"
|
|
20
|
+
};
|
|
21
|
+
var TgpuFixedBufferImpl = class {
|
|
22
|
+
resourceType = "buffer-usage";
|
|
23
|
+
[$internal];
|
|
24
|
+
[$getNameForward];
|
|
25
|
+
constructor(usage, buffer) {
|
|
26
|
+
this.usage = usage;
|
|
27
|
+
this.buffer = buffer;
|
|
28
|
+
this[$internal] = { dataType: buffer.dataType };
|
|
29
|
+
this[$getNameForward] = buffer;
|
|
30
|
+
}
|
|
31
|
+
$name(label) {
|
|
32
|
+
setName(this, label);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
[$resolve](ctx) {
|
|
36
|
+
const dataType = this.buffer.dataType;
|
|
37
|
+
const id = ctx.getUniqueName(this);
|
|
38
|
+
const { group, binding } = ctx.allocateFixedEntry(this.usage === "uniform" ? { uniform: dataType } : {
|
|
39
|
+
storage: dataType,
|
|
40
|
+
access: this.usage
|
|
41
|
+
}, this.buffer);
|
|
42
|
+
const usage = usageToVarTemplateMap[this.usage];
|
|
43
|
+
ctx.addDeclaration(`@group(${group}) @binding(${binding}) var<${usage}> ${id}: ${ctx.resolve(dataType).value};`);
|
|
44
|
+
return snip(id, dataType, isNaturallyEphemeral(dataType) ? "runtime" : this.usage);
|
|
45
|
+
}
|
|
46
|
+
toString() {
|
|
47
|
+
return `${this.usage}:${getName(this) ?? "<unnamed>"}`;
|
|
48
|
+
}
|
|
49
|
+
get [$gpuValueOf]() {
|
|
50
|
+
const dataType = this.buffer.dataType;
|
|
51
|
+
const usage = this.usage;
|
|
52
|
+
return new Proxy({
|
|
53
|
+
[$internal]: true,
|
|
54
|
+
get [$ownSnippet]() {
|
|
55
|
+
return snip(this, dataType, isNaturallyEphemeral(dataType) ? "runtime" : usage);
|
|
56
|
+
},
|
|
57
|
+
[$resolve]: (ctx) => ctx.resolve(this),
|
|
58
|
+
toString: () => `${this.usage}:${getName(this) ?? "<unnamed>"}.$`
|
|
59
|
+
}, valueProxyHandler);
|
|
60
|
+
}
|
|
61
|
+
get $() {
|
|
62
|
+
const mode = getExecMode();
|
|
63
|
+
const insideTgpuFn = isInsideTgpuFn();
|
|
64
|
+
if (mode.type === "normal") throw new IllegalBufferAccessError(insideTgpuFn ? `Cannot access ${String(this.buffer)}. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation` : ".$ is inaccessible during normal JS execution. Try `.read()`");
|
|
65
|
+
if (mode.type === "codegen") return this[$gpuValueOf];
|
|
66
|
+
if (mode.type === "simulate") {
|
|
67
|
+
if (!mode.buffers.has(this.buffer)) mode.buffers.set(this.buffer, schemaCallWrapper(this.buffer.dataType, this.buffer.initial));
|
|
68
|
+
return mode.buffers.get(this.buffer);
|
|
69
|
+
}
|
|
70
|
+
return assertExhaustive(mode, "bufferUsage.ts#TgpuFixedBufferImpl/$");
|
|
71
|
+
}
|
|
72
|
+
get value() {
|
|
73
|
+
return this.$;
|
|
74
|
+
}
|
|
75
|
+
set $(value) {
|
|
76
|
+
const mode = getExecMode();
|
|
77
|
+
const insideTgpuFn = isInsideTgpuFn();
|
|
78
|
+
if (mode.type === "normal") throw new IllegalBufferAccessError(insideTgpuFn ? `Cannot access ${String(this.buffer)}. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation` : ".$ is inaccessible during normal JS execution. Try `.write()`");
|
|
79
|
+
if (mode.type === "codegen") throw new Error("Unreachable bufferUsage.ts#TgpuFixedBufferImpl/$");
|
|
80
|
+
if (mode.type === "simulate") {
|
|
81
|
+
mode.buffers.set(this.buffer, value);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
assertExhaustive(mode, "bufferUsage.ts#TgpuFixedBufferImpl/$");
|
|
85
|
+
}
|
|
86
|
+
set value(value) {
|
|
87
|
+
this.$ = value;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var TgpuLaidOutBufferImpl = class {
|
|
91
|
+
[$internal];
|
|
92
|
+
resourceType = "buffer-usage";
|
|
93
|
+
#membership;
|
|
94
|
+
constructor(usage, dataType, membership) {
|
|
95
|
+
this.usage = usage;
|
|
96
|
+
this.dataType = dataType;
|
|
97
|
+
this[$internal] = { dataType };
|
|
98
|
+
this.#membership = membership;
|
|
99
|
+
setName(this, membership.key);
|
|
100
|
+
}
|
|
101
|
+
[$resolve](ctx) {
|
|
102
|
+
const id = ctx.getUniqueName(this);
|
|
103
|
+
const group = ctx.allocateLayoutEntry(this.#membership.layout);
|
|
104
|
+
const usage = usageToVarTemplateMap[this.usage];
|
|
105
|
+
ctx.addDeclaration(`@group(${group}) @binding(${this.#membership.idx}) var<${usage}> ${id}: ${ctx.resolve(this.dataType).value};`);
|
|
106
|
+
return snip(id, this.dataType, isNaturallyEphemeral(this.dataType) ? "runtime" : this.usage);
|
|
107
|
+
}
|
|
108
|
+
toString() {
|
|
109
|
+
return `${this.usage}:${getName(this) ?? "<unnamed>"}`;
|
|
110
|
+
}
|
|
111
|
+
get [$gpuValueOf]() {
|
|
112
|
+
const schema = this.dataType;
|
|
113
|
+
const usage = this.usage;
|
|
114
|
+
return new Proxy({
|
|
115
|
+
[$internal]: true,
|
|
116
|
+
get [$ownSnippet]() {
|
|
117
|
+
return snip(this, schema, isNaturallyEphemeral(schema) ? "runtime" : usage);
|
|
118
|
+
},
|
|
119
|
+
[$resolve]: (ctx) => ctx.resolve(this),
|
|
120
|
+
toString: () => `${this.usage}:${getName(this) ?? "<unnamed>"}.$`
|
|
121
|
+
}, valueProxyHandler);
|
|
122
|
+
}
|
|
123
|
+
get $() {
|
|
124
|
+
if (inCodegenMode()) return this[$gpuValueOf];
|
|
125
|
+
throw new Error("Direct access to buffer values is possible only as part of a compute dispatch or draw call. Try .read() or .write() instead");
|
|
126
|
+
}
|
|
127
|
+
get value() {
|
|
128
|
+
return this.$;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const mutableUsageMap = /* @__PURE__ */ new WeakMap();
|
|
132
|
+
function mutable(buffer) {
|
|
133
|
+
if (!isUsableAsStorage(buffer)) throw new Error(`Cannot call as('mutable') on ${buffer}, as it is not allowed to be used as storage. To allow it, call .$usage('storage') when creating the buffer.`);
|
|
134
|
+
let usage = mutableUsageMap.get(buffer);
|
|
135
|
+
if (!usage) {
|
|
136
|
+
usage = new TgpuFixedBufferImpl("mutable", buffer);
|
|
137
|
+
mutableUsageMap.set(buffer, usage);
|
|
138
|
+
}
|
|
139
|
+
return usage;
|
|
140
|
+
}
|
|
141
|
+
const readonlyUsageMap = /* @__PURE__ */ new WeakMap();
|
|
142
|
+
function readonly(buffer) {
|
|
143
|
+
if (!isUsableAsStorage(buffer)) throw new Error(`Cannot call as('readonly') on ${buffer}, as it is not allowed to be used as storage. To allow it, call .$usage('storage') when creating the buffer.`);
|
|
144
|
+
let usage = readonlyUsageMap.get(buffer);
|
|
145
|
+
if (!usage) {
|
|
146
|
+
usage = new TgpuFixedBufferImpl("readonly", buffer);
|
|
147
|
+
readonlyUsageMap.set(buffer, usage);
|
|
148
|
+
}
|
|
149
|
+
return usage;
|
|
150
|
+
}
|
|
151
|
+
const uniformUsageMap = /* @__PURE__ */ new WeakMap();
|
|
152
|
+
function uniform(buffer) {
|
|
153
|
+
if (!isUsableAsUniform(buffer)) throw new Error(`Cannot call as('uniform') on ${buffer}, as it is not allowed to be used as a uniform. To allow it, call .$usage('uniform') when creating the buffer.`);
|
|
154
|
+
let usage = uniformUsageMap.get(buffer);
|
|
155
|
+
if (!usage) {
|
|
156
|
+
usage = new TgpuFixedBufferImpl("uniform", buffer);
|
|
157
|
+
uniformUsageMap.set(buffer, usage);
|
|
158
|
+
}
|
|
159
|
+
return usage;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
//#endregion
|
|
163
|
+
export { TgpuLaidOutBufferImpl, isUsableAsUniform, mutable, readonly, uniform };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { TgpuNamable } from "../../shared/meta.js";
|
|
2
|
+
import { $gpuValueOf, $internal } from "../../shared/symbols.js";
|
|
3
|
+
import { BaseData } from "../../data/wgslTypes.js";
|
|
4
|
+
import { InferGPU } from "../../shared/repr.js";
|
|
5
|
+
import { AnyData } from "../../data/dataTypes.js";
|
|
6
|
+
|
|
7
|
+
//#region src/core/constant/tgpuConstant.d.ts
|
|
8
|
+
type DeepReadonly<T> = T extends {
|
|
9
|
+
[$internal]: unknown;
|
|
10
|
+
} ? T : T extends unknown[] ? ReadonlyArray<DeepReadonly<T[number]>> : T extends Record<string, unknown> ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;
|
|
11
|
+
interface TgpuConst<TDataType extends BaseData = BaseData> extends TgpuNamable {
|
|
12
|
+
readonly resourceType: 'const';
|
|
13
|
+
readonly [$gpuValueOf]: DeepReadonly<InferGPU<TDataType>>;
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Use `.$` instead, works the same way.
|
|
16
|
+
*/
|
|
17
|
+
readonly value: DeepReadonly<InferGPU<TDataType>>;
|
|
18
|
+
readonly $: DeepReadonly<InferGPU<TDataType>>;
|
|
19
|
+
readonly [$internal]: {
|
|
20
|
+
/** Makes it differentiable on the type level. Does not exist at runtime. */dataType?: TDataType;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a module constant with specified value.
|
|
25
|
+
*/
|
|
26
|
+
declare function constant<TDataType extends AnyData>(dataType: TDataType, value: InferGPU<TDataType>): TgpuConst<TDataType>;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { TgpuConst, constant };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { $gpuValueOf, $internal, $ownSnippet, $resolve } from "../../shared/symbols.js";
|
|
2
|
+
import { getName, setName } from "../../shared/meta.js";
|
|
3
|
+
import { isNaturallyEphemeral } from "../../data/wgslTypes.js";
|
|
4
|
+
import { snip } from "../../data/snippet.js";
|
|
5
|
+
import { inCodegenMode } from "../../execMode.js";
|
|
6
|
+
import { valueProxyHandler } from "../valueProxyUtils.js";
|
|
7
|
+
|
|
8
|
+
//#region src/core/constant/tgpuConstant.ts
|
|
9
|
+
/**
|
|
10
|
+
* Creates a module constant with specified value.
|
|
11
|
+
*/
|
|
12
|
+
function constant(dataType, value) {
|
|
13
|
+
return new TgpuConstImpl(dataType, value);
|
|
14
|
+
}
|
|
15
|
+
function deepFreeze(object) {
|
|
16
|
+
const propNames = Reflect.ownKeys(object);
|
|
17
|
+
for (const name of propNames) {
|
|
18
|
+
const value = object[name];
|
|
19
|
+
if (value && typeof value === "object" || typeof value === "function") deepFreeze(value);
|
|
20
|
+
}
|
|
21
|
+
return Object.freeze(object);
|
|
22
|
+
}
|
|
23
|
+
var TgpuConstImpl = class {
|
|
24
|
+
[$internal] = {};
|
|
25
|
+
resourceType;
|
|
26
|
+
#value;
|
|
27
|
+
constructor(dataType, value) {
|
|
28
|
+
this.dataType = dataType;
|
|
29
|
+
this.resourceType = "const";
|
|
30
|
+
this.#value = value && typeof value === "object" ? deepFreeze(value) : value;
|
|
31
|
+
}
|
|
32
|
+
$name(label) {
|
|
33
|
+
setName(this, label);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
[$resolve](ctx) {
|
|
37
|
+
const id = ctx.getUniqueName(this);
|
|
38
|
+
const resolvedDataType = ctx.resolve(this.dataType).value;
|
|
39
|
+
const resolvedValue = ctx.resolve(this.#value, this.dataType).value;
|
|
40
|
+
ctx.addDeclaration(`const ${id}: ${resolvedDataType} = ${resolvedValue};`);
|
|
41
|
+
return snip(id, this.dataType, isNaturallyEphemeral(this.dataType) ? "constant" : "constant-tgpu-const-ref");
|
|
42
|
+
}
|
|
43
|
+
toString() {
|
|
44
|
+
return `const:${getName(this) ?? "<unnamed>"}`;
|
|
45
|
+
}
|
|
46
|
+
get [$gpuValueOf]() {
|
|
47
|
+
const dataType = this.dataType;
|
|
48
|
+
return new Proxy({
|
|
49
|
+
[$internal]: true,
|
|
50
|
+
get [$ownSnippet]() {
|
|
51
|
+
return snip(this, dataType, isNaturallyEphemeral(dataType) ? "constant" : "constant-tgpu-const-ref");
|
|
52
|
+
},
|
|
53
|
+
[$resolve]: (ctx) => ctx.resolve(this),
|
|
54
|
+
toString: () => `const:${getName(this) ?? "<unnamed>"}.$`
|
|
55
|
+
}, valueProxyHandler);
|
|
56
|
+
}
|
|
57
|
+
get $() {
|
|
58
|
+
if (inCodegenMode()) return this[$gpuValueOf];
|
|
59
|
+
return this.#value;
|
|
60
|
+
}
|
|
61
|
+
get value() {
|
|
62
|
+
return this.$;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { constant };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/core/declare/tgpuDeclare.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extra declaration that shall be included in final WGSL code,
|
|
4
|
+
* when resolving objects that use it.
|
|
5
|
+
*/
|
|
6
|
+
interface TgpuDeclare {
|
|
7
|
+
$uses(dependencyMap: Record<string, unknown>): this;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Allows defining extra declarations that shall be included in the final WGSL code,
|
|
11
|
+
* when resolving objects that use them.
|
|
12
|
+
*
|
|
13
|
+
* Using this API is generally discouraged, as it shouldn't be necessary in any common scenario.
|
|
14
|
+
* It was developed to ensure full compatibility of TypeGPU programs with current and future versions of WGSL.
|
|
15
|
+
*/
|
|
16
|
+
declare function declare(declaration: string): TgpuDeclare;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { TgpuDeclare, declare };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { $internal, $resolve } from "../../shared/symbols.js";
|
|
2
|
+
import { Void } from "../../data/wgslTypes.js";
|
|
3
|
+
import { snip } from "../../data/snippet.js";
|
|
4
|
+
import { applyExternals, replaceExternalsInWgsl } from "../resolve/externals.js";
|
|
5
|
+
|
|
6
|
+
//#region src/core/declare/tgpuDeclare.ts
|
|
7
|
+
/**
|
|
8
|
+
* Allows defining extra declarations that shall be included in the final WGSL code,
|
|
9
|
+
* when resolving objects that use them.
|
|
10
|
+
*
|
|
11
|
+
* Using this API is generally discouraged, as it shouldn't be necessary in any common scenario.
|
|
12
|
+
* It was developed to ensure full compatibility of TypeGPU programs with current and future versions of WGSL.
|
|
13
|
+
*/
|
|
14
|
+
function declare(declaration) {
|
|
15
|
+
return new TgpuDeclareImpl(declaration);
|
|
16
|
+
}
|
|
17
|
+
var TgpuDeclareImpl = class {
|
|
18
|
+
[$internal] = true;
|
|
19
|
+
externalsToApply = [];
|
|
20
|
+
constructor(declaration) {
|
|
21
|
+
this.declaration = declaration;
|
|
22
|
+
}
|
|
23
|
+
$uses(dependencyMap) {
|
|
24
|
+
this.externalsToApply.push(dependencyMap);
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
[$resolve](ctx) {
|
|
28
|
+
const externalMap = {};
|
|
29
|
+
for (const externals of this.externalsToApply) applyExternals(externalMap, externals);
|
|
30
|
+
const replacedDeclaration = replaceExternalsInWgsl(ctx, externalMap, this.declaration);
|
|
31
|
+
ctx.addDeclaration(replacedDeclaration);
|
|
32
|
+
return snip("", Void, "constant");
|
|
33
|
+
}
|
|
34
|
+
toString() {
|
|
35
|
+
return `declare: ${this.declaration}`;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
export { declare };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BuiltinClipDistances, BuiltinFragDepth, BuiltinFrontFacing, BuiltinInstanceIndex, BuiltinPosition, BuiltinPrimitiveIndex, BuiltinSampleIndex, BuiltinSampleMask, BuiltinSubgroupInvocationId, BuiltinSubgroupSize, BuiltinVertexIndex, OmitBuiltins } from "../../builtin.js";
|
|
2
|
+
import "../../data/snippet.js";
|
|
3
|
+
import { BaseIOData } from "./fnTypes.js";
|
|
4
|
+
import "../../data/autoStruct.js";
|
|
5
|
+
import "../../types.js";
|
|
6
|
+
import { v4f } from "../../data/wgslTypes.js";
|
|
7
|
+
import { InferGPU, InferGPURecord, InferRecord } from "../../shared/repr.js";
|
|
8
|
+
|
|
9
|
+
//#region src/core/function/autoIO.d.ts
|
|
10
|
+
type AnyAutoCustoms = Record<string, InferGPU<BaseIOData>>;
|
|
11
|
+
declare const builtinVertexIn: {
|
|
12
|
+
readonly $vertexIndex: BuiltinVertexIndex;
|
|
13
|
+
readonly $instanceIndex: BuiltinInstanceIndex;
|
|
14
|
+
};
|
|
15
|
+
type AutoVertexIn<T extends AnyAutoCustoms> = T & InferRecord<typeof builtinVertexIn>;
|
|
16
|
+
declare const builtinVertexOut: {
|
|
17
|
+
readonly $clipDistances: BuiltinClipDistances;
|
|
18
|
+
readonly $position: BuiltinPosition;
|
|
19
|
+
};
|
|
20
|
+
type AutoVertexOut<T extends AnyAutoCustoms> = OmitBuiltins<T> & Partial<InferGPURecord<typeof builtinVertexOut>>;
|
|
21
|
+
declare const builtinFragmentIn: {
|
|
22
|
+
readonly $position: BuiltinPosition;
|
|
23
|
+
readonly $frontFacing: BuiltinFrontFacing;
|
|
24
|
+
readonly $primitiveIndex: BuiltinPrimitiveIndex;
|
|
25
|
+
readonly $sampleIndex: BuiltinSampleIndex;
|
|
26
|
+
readonly $sampleMask: BuiltinSampleMask;
|
|
27
|
+
readonly $subgroupInvocationId: BuiltinSubgroupInvocationId;
|
|
28
|
+
readonly $subgroupSize: BuiltinSubgroupSize;
|
|
29
|
+
};
|
|
30
|
+
type AutoFragmentIn<T extends AnyAutoCustoms> = T & InferRecord<typeof builtinFragmentIn>;
|
|
31
|
+
declare const builtinFragmentOut: {
|
|
32
|
+
readonly $fragDepth: BuiltinFragDepth;
|
|
33
|
+
readonly $sampleMask: BuiltinSampleMask;
|
|
34
|
+
};
|
|
35
|
+
type AutoFragmentOut<T extends undefined | v4f | AnyAutoCustoms> = T extends undefined | v4f ? T : T & Partial<InferGPURecord<typeof builtinFragmentOut>>;
|
|
36
|
+
//#endregion
|
|
37
|
+
export { AnyAutoCustoms, AutoFragmentIn, AutoFragmentOut, AutoVertexIn, AutoVertexOut };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { $internal, $resolve } from "../../shared/symbols.js";
|
|
2
|
+
import { getName, setName } from "../../shared/meta.js";
|
|
3
|
+
import { vec4f } from "../../data/vector.js";
|
|
4
|
+
import { AutoStruct } from "../../data/autoStruct.js";
|
|
5
|
+
import { createFnCore } from "./fnCore.js";
|
|
6
|
+
import { shaderStageSlot } from "../slot/internalSlots.js";
|
|
7
|
+
import { builtin } from "../../builtin.js";
|
|
8
|
+
|
|
9
|
+
//#region src/core/function/autoIO.ts
|
|
10
|
+
const builtinVertexIn = {
|
|
11
|
+
$vertexIndex: builtin.vertexIndex,
|
|
12
|
+
$instanceIndex: builtin.instanceIndex
|
|
13
|
+
};
|
|
14
|
+
const builtinVertexOut = {
|
|
15
|
+
$clipDistances: builtin.clipDistances,
|
|
16
|
+
$position: builtin.position
|
|
17
|
+
};
|
|
18
|
+
const builtinFragmentIn = {
|
|
19
|
+
$position: builtin.position,
|
|
20
|
+
$frontFacing: builtin.frontFacing,
|
|
21
|
+
$primitiveIndex: builtin.primitiveIndex,
|
|
22
|
+
$sampleIndex: builtin.sampleIndex,
|
|
23
|
+
$sampleMask: builtin.sampleMask,
|
|
24
|
+
$subgroupInvocationId: builtin.subgroupInvocationId,
|
|
25
|
+
$subgroupSize: builtin.subgroupSize
|
|
26
|
+
};
|
|
27
|
+
const builtinFragmentOut = {
|
|
28
|
+
$fragDepth: builtin.fragDepth,
|
|
29
|
+
$sampleMask: builtin.sampleMask
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Only used internally. Meant to be recreated on every resolution.
|
|
33
|
+
*/
|
|
34
|
+
var AutoFragmentFn = class {
|
|
35
|
+
#core;
|
|
36
|
+
autoIn;
|
|
37
|
+
autoOut;
|
|
38
|
+
constructor(impl, varyings, locations) {
|
|
39
|
+
if (!getName(impl)) setName(impl, "fragmentFn");
|
|
40
|
+
this.#core = createFnCore(impl, "@fragment ");
|
|
41
|
+
this.autoIn = new AutoStruct({
|
|
42
|
+
...builtinFragmentIn,
|
|
43
|
+
...varyings
|
|
44
|
+
}, void 0, locations);
|
|
45
|
+
setName(this.autoIn, "FragmentIn");
|
|
46
|
+
this.autoOut = new AutoStruct(builtinFragmentOut, vec4f);
|
|
47
|
+
setName(this.autoOut, "FragmentOut");
|
|
48
|
+
}
|
|
49
|
+
toString() {
|
|
50
|
+
return "autoFragmentFn";
|
|
51
|
+
}
|
|
52
|
+
[$resolve](ctx) {
|
|
53
|
+
return ctx.withSlots([[shaderStageSlot, "fragment"]], () => this.#core.resolve(ctx, [this.autoIn], this.autoOut));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
AutoFragmentFn.prototype[$internal] = true;
|
|
57
|
+
AutoFragmentFn.prototype.resourceType = "auto-fragment-fn";
|
|
58
|
+
/**
|
|
59
|
+
* Only used internally. Meant to be recreated on every resolution.
|
|
60
|
+
*/
|
|
61
|
+
var AutoVertexFn = class {
|
|
62
|
+
#core;
|
|
63
|
+
autoIn;
|
|
64
|
+
autoOut;
|
|
65
|
+
constructor(impl, attribs, locations) {
|
|
66
|
+
if (!getName(impl)) setName(impl, "vertexFn");
|
|
67
|
+
this.#core = createFnCore(impl, "@vertex ");
|
|
68
|
+
this.autoIn = new AutoStruct({
|
|
69
|
+
...builtinVertexIn,
|
|
70
|
+
...attribs
|
|
71
|
+
}, void 0, locations);
|
|
72
|
+
setName(this.autoIn, "VertexIn");
|
|
73
|
+
this.autoOut = new AutoStruct(builtinVertexOut, void 0);
|
|
74
|
+
setName(this.autoOut, "VertexOut");
|
|
75
|
+
}
|
|
76
|
+
toString() {
|
|
77
|
+
return "autoVertexFn";
|
|
78
|
+
}
|
|
79
|
+
[$resolve](ctx) {
|
|
80
|
+
return ctx.withSlots([[shaderStageSlot, "vertex"]], () => this.#core.resolve(ctx, [this.autoIn], this.autoOut));
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
AutoVertexFn.prototype[$internal] = true;
|
|
84
|
+
AutoVertexFn.prototype.resourceType = "auto-vertex-fn";
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
export { AutoFragmentFn, AutoVertexFn };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { TgpuNamable } from "../../shared/meta.js";
|
|
2
|
+
import { $getNameForward, $internal } from "../../shared/symbols.js";
|
|
3
|
+
import { DualFn } from "../../types.js";
|
|
4
|
+
|
|
5
|
+
//#region src/core/function/comptime.d.ts
|
|
6
|
+
type AnyFn = (...args: never[]) => unknown;
|
|
7
|
+
type TgpuComptime<T extends AnyFn = AnyFn> = DualFn<T> & TgpuNamable & {
|
|
8
|
+
[$getNameForward]: unknown;
|
|
9
|
+
[$internal]: {
|
|
10
|
+
isComptime: true;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Creates a version of `func` that can called safely in a TypeGPU function to
|
|
15
|
+
* precompute and inject a value into the final shader code.
|
|
16
|
+
*
|
|
17
|
+
* Note how the function passed into `comptime` doesn't have to be marked with
|
|
18
|
+
* 'use gpu'. That's because the function doesn't execute on the GPU, it gets
|
|
19
|
+
* executed before the shader code gets sent to the GPU.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const color = tgpu.comptime((int: number) => {
|
|
24
|
+
* const r = (int >> 16) & 0xff;
|
|
25
|
+
* const g = (int >> 8) & 0xff;
|
|
26
|
+
* const b = int & 0xff;
|
|
27
|
+
* return d.vec3f(r / 255, g / 255, b / 255);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* const material = (diffuse: d.v3f): d.v3f => {
|
|
31
|
+
* 'use gpu';
|
|
32
|
+
* const albedo = color(0xff00ff);
|
|
33
|
+
* return albedo.mul(diffuse);
|
|
34
|
+
* };
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function comptime<T extends (...args: never[]) => unknown>(func: T): TgpuComptime<T>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { TgpuComptime, comptime };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { $getNameForward, $gpuCallable, $internal } from "../../shared/symbols.js";
|
|
2
|
+
import { setName } from "../../shared/meta.js";
|
|
3
|
+
import { WgslTypeError } from "../../errors.js";
|
|
4
|
+
import { isKnownAtComptime } from "../../types.js";
|
|
5
|
+
import { coerceToSnippet } from "../../tgsl/generationHelpers.js";
|
|
6
|
+
|
|
7
|
+
//#region src/core/function/comptime.ts
|
|
8
|
+
/**
|
|
9
|
+
* Creates a version of `func` that can called safely in a TypeGPU function to
|
|
10
|
+
* precompute and inject a value into the final shader code.
|
|
11
|
+
*
|
|
12
|
+
* Note how the function passed into `comptime` doesn't have to be marked with
|
|
13
|
+
* 'use gpu'. That's because the function doesn't execute on the GPU, it gets
|
|
14
|
+
* executed before the shader code gets sent to the GPU.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const color = tgpu.comptime((int: number) => {
|
|
19
|
+
* const r = (int >> 16) & 0xff;
|
|
20
|
+
* const g = (int >> 8) & 0xff;
|
|
21
|
+
* const b = int & 0xff;
|
|
22
|
+
* return d.vec3f(r / 255, g / 255, b / 255);
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* const material = (diffuse: d.v3f): d.v3f => {
|
|
26
|
+
* 'use gpu';
|
|
27
|
+
* const albedo = color(0xff00ff);
|
|
28
|
+
* return albedo.mul(diffuse);
|
|
29
|
+
* };
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
function comptime(func) {
|
|
33
|
+
const impl = ((...args) => {
|
|
34
|
+
return func(...args);
|
|
35
|
+
});
|
|
36
|
+
impl.toString = () => "comptime";
|
|
37
|
+
impl[$getNameForward] = func;
|
|
38
|
+
impl[$gpuCallable] = { call(_ctx, args) {
|
|
39
|
+
if (!args.every((s) => isKnownAtComptime(s))) throw new WgslTypeError(`Called comptime function with runtime-known values: ${args.filter((s) => !isKnownAtComptime(s)).map((s) => `'${s.value}'`).join(", ")}`);
|
|
40
|
+
return coerceToSnippet(func(...args.map((s) => s.value)));
|
|
41
|
+
} };
|
|
42
|
+
impl.$name = (label) => {
|
|
43
|
+
setName(func, label);
|
|
44
|
+
return impl;
|
|
45
|
+
};
|
|
46
|
+
Object.defineProperty(impl, $internal, { value: { isComptime: true } });
|
|
47
|
+
return impl;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { comptime };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { $gpuCallable } from "../../shared/symbols.js";
|
|
2
|
+
import { setName } from "../../shared/meta.js";
|
|
3
|
+
import { isPtr } from "../../data/wgslTypes.js";
|
|
4
|
+
import { snip } from "../../data/snippet.js";
|
|
5
|
+
import { NormalState, isKnownAtComptime } from "../../types.js";
|
|
6
|
+
import { tryConvertSnippet } from "../../tgsl/conversion.js";
|
|
7
|
+
|
|
8
|
+
//#region src/core/function/createCallableSchema.ts
|
|
9
|
+
function callableSchema(options) {
|
|
10
|
+
const impl = ((...args) => {
|
|
11
|
+
return options.normalImpl(...args);
|
|
12
|
+
});
|
|
13
|
+
setName(impl, options.name);
|
|
14
|
+
impl.toString = () => options.name;
|
|
15
|
+
impl[$gpuCallable] = {
|
|
16
|
+
get strictSignature() {},
|
|
17
|
+
call(ctx, args) {
|
|
18
|
+
const { argTypes, returnType } = options.signature(...args.map((s) => {
|
|
19
|
+
if (isPtr(s.dataType) && s.dataType.implicit) return s.dataType.inner;
|
|
20
|
+
return s.dataType;
|
|
21
|
+
}));
|
|
22
|
+
const converted = args.map((s, idx) => {
|
|
23
|
+
const argType = argTypes[idx];
|
|
24
|
+
if (!argType) throw new Error("Function called with invalid arguments");
|
|
25
|
+
return tryConvertSnippet(ctx, s, argType, false);
|
|
26
|
+
});
|
|
27
|
+
if (converted.every((s) => isKnownAtComptime(s))) {
|
|
28
|
+
ctx.pushMode(new NormalState());
|
|
29
|
+
try {
|
|
30
|
+
return snip(options.normalImpl(...converted.map((s) => s.value)), returnType, "constant");
|
|
31
|
+
} finally {
|
|
32
|
+
ctx.popMode("normal");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return snip(options.codegenImpl(ctx, converted), returnType, "runtime");
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
return impl;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { callableSchema };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { $gpuCallable } from "../../shared/symbols.js";
|
|
2
|
+
import { setName } from "../../shared/meta.js";
|
|
3
|
+
import { isPtr } from "../../data/wgslTypes.js";
|
|
4
|
+
import { snip } from "../../data/snippet.js";
|
|
5
|
+
import { NormalState, isKnownAtComptime } from "../../types.js";
|
|
6
|
+
import { tryConvertSnippet } from "../../tgsl/conversion.js";
|
|
7
|
+
import { concretize } from "../../tgsl/generationHelpers.js";
|
|
8
|
+
|
|
9
|
+
//#region src/core/function/dualImpl.ts
|
|
10
|
+
var MissingCpuImplError = class extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = this.constructor.name;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function dualImpl(options) {
|
|
17
|
+
const impl = ((...args) => {
|
|
18
|
+
if (typeof options.normalImpl === "string") throw new MissingCpuImplError(options.normalImpl);
|
|
19
|
+
return options.normalImpl(...args);
|
|
20
|
+
});
|
|
21
|
+
setName(impl, options.name);
|
|
22
|
+
impl.toString = () => options.name ?? "<unknown>";
|
|
23
|
+
impl[$gpuCallable] = {
|
|
24
|
+
get strictSignature() {
|
|
25
|
+
return typeof options.signature !== "function" ? options.signature : void 0;
|
|
26
|
+
},
|
|
27
|
+
call(ctx, args) {
|
|
28
|
+
const { argTypes, returnType } = typeof options.signature === "function" ? options.signature(...args.map((s) => {
|
|
29
|
+
if (isPtr(s.dataType) && s.dataType.implicit) return s.dataType.inner;
|
|
30
|
+
return s.dataType;
|
|
31
|
+
})) : options.signature;
|
|
32
|
+
const converted = args.map((s, idx) => {
|
|
33
|
+
const argType = argTypes[idx];
|
|
34
|
+
if (!argType) throw new Error("Function called with invalid arguments");
|
|
35
|
+
return tryConvertSnippet(ctx, s, argType, !options.ignoreImplicitCastWarning);
|
|
36
|
+
});
|
|
37
|
+
if (!options.noComptime && converted.every((s) => isKnownAtComptime(s)) && typeof options.normalImpl === "function") {
|
|
38
|
+
ctx.pushMode(new NormalState());
|
|
39
|
+
try {
|
|
40
|
+
return snip(options.normalImpl(...converted.map((s) => s.value)), returnType, "constant");
|
|
41
|
+
} catch (e) {
|
|
42
|
+
if (!(e instanceof MissingCpuImplError)) throw e;
|
|
43
|
+
} finally {
|
|
44
|
+
ctx.popMode("normal");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return snip(options.codegenImpl(ctx, converted), concretize(returnType), "runtime");
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
return impl;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { MissingCpuImplError, dualImpl };
|