typegpu 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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-BagDrrks.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-DdtWpk2t.js +0 -818
- package/builtin-DdtWpk2t.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-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,86 @@
|
|
|
1
|
+
import { $internal } from "../../shared/symbols.js";
|
|
2
|
+
import { Void } from "../../data/wgslTypes.js";
|
|
3
|
+
import { UnknownData } from "../../data/dataTypes.js";
|
|
4
|
+
import { snip } from "../../data/snippet.js";
|
|
5
|
+
import { stitch } from "../../core/resolve/stitch.js";
|
|
6
|
+
import { u32 } from "../../data/numeric.js";
|
|
7
|
+
import { struct } from "../../data/struct.js";
|
|
8
|
+
import { concretizeSnippets } from "../generationHelpers.js";
|
|
9
|
+
import { shaderStageSlot } from "../../core/slot/internalSlots.js";
|
|
10
|
+
import { arrayOf } from "../../data/array.js";
|
|
11
|
+
import { atomic } from "../../data/atomic.js";
|
|
12
|
+
import { createLoggingFunction } from "./serializers.js";
|
|
13
|
+
import { supportedLogOps } from "./types.js";
|
|
14
|
+
|
|
15
|
+
//#region src/tgsl/consoleLog/logGenerator.ts
|
|
16
|
+
const defaultOptions = {
|
|
17
|
+
logCountLimit: 64,
|
|
18
|
+
logSizeLimit: 252,
|
|
19
|
+
messagePrefix: " GPU "
|
|
20
|
+
};
|
|
21
|
+
const fallbackSnippet = snip("/* console.log() */", Void, "runtime");
|
|
22
|
+
var LogGeneratorNullImpl = class {
|
|
23
|
+
get logResources() {}
|
|
24
|
+
generateLog() {
|
|
25
|
+
console.warn("'console.log' is only supported when resolving pipelines.");
|
|
26
|
+
return fallbackSnippet;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var LogGeneratorImpl = class {
|
|
30
|
+
#options;
|
|
31
|
+
#logIdToMeta;
|
|
32
|
+
#firstUnusedId = 1;
|
|
33
|
+
#indexBuffer;
|
|
34
|
+
#dataBuffer;
|
|
35
|
+
constructor(root) {
|
|
36
|
+
this.#options = {
|
|
37
|
+
...defaultOptions,
|
|
38
|
+
...root[$internal].logOptions
|
|
39
|
+
};
|
|
40
|
+
this.#logIdToMeta = /* @__PURE__ */ new Map();
|
|
41
|
+
const SerializedLogData = struct({
|
|
42
|
+
id: u32,
|
|
43
|
+
serializedData: arrayOf(u32, Math.ceil(this.#options.logSizeLimit / 4))
|
|
44
|
+
}).$name("SerializedLogData");
|
|
45
|
+
this.#dataBuffer = root.createMutable(arrayOf(SerializedLogData, this.#options.logCountLimit)).$name("dataBuffer");
|
|
46
|
+
this.#indexBuffer = root.createMutable(atomic(u32)).$name("indexBuffer");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Generates all necessary resources for serializing arguments for logging purposes.
|
|
50
|
+
*
|
|
51
|
+
* @param ctx Resolution context.
|
|
52
|
+
* @param args Argument snippets. Snippets of UnknownType will be treated as string literals.
|
|
53
|
+
* @returns A snippet containing the call to the logging function.
|
|
54
|
+
*/
|
|
55
|
+
generateLog(ctx, op, args) {
|
|
56
|
+
if (shaderStageSlot.$ === "vertex") {
|
|
57
|
+
console.warn(`'console.${op}' is not supported in vertex shaders.`);
|
|
58
|
+
return fallbackSnippet;
|
|
59
|
+
}
|
|
60
|
+
if (!supportedLogOps.includes(op)) {
|
|
61
|
+
console.warn(`Unsupported log method '${op}'.`);
|
|
62
|
+
return fallbackSnippet;
|
|
63
|
+
}
|
|
64
|
+
const concreteArgs = concretizeSnippets(args);
|
|
65
|
+
const id = this.#firstUnusedId++;
|
|
66
|
+
const nonStringArgs = concreteArgs.filter((e) => e.dataType !== UnknownData);
|
|
67
|
+
const logFn = createLoggingFunction(id, nonStringArgs.map((e) => e.dataType), this.#dataBuffer, this.#indexBuffer, this.#options);
|
|
68
|
+
const argTypes = concreteArgs.map((e) => e.dataType === UnknownData ? e.value : e.dataType);
|
|
69
|
+
this.#logIdToMeta.set(id, {
|
|
70
|
+
op,
|
|
71
|
+
argTypes
|
|
72
|
+
});
|
|
73
|
+
return snip(stitch`${ctx.resolve(logFn).value}(${nonStringArgs})`, Void, "runtime");
|
|
74
|
+
}
|
|
75
|
+
get logResources() {
|
|
76
|
+
return this.#firstUnusedId === 1 ? void 0 : {
|
|
77
|
+
dataBuffer: this.#dataBuffer,
|
|
78
|
+
indexBuffer: this.#indexBuffer,
|
|
79
|
+
options: this.#options,
|
|
80
|
+
logIdToMeta: this.#logIdToMeta
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { LogGeneratorImpl, LogGeneratorNullImpl };
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { getName } from "../../shared/meta.js";
|
|
2
|
+
import { isWgslArray, isWgslStruct } from "../../data/wgslTypes.js";
|
|
3
|
+
import { bool, f16, f32, i32, u32 } from "../../data/numeric.js";
|
|
4
|
+
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
|
|
5
|
+
import { sizeOf } from "../../data/sizeOf.js";
|
|
6
|
+
import { mat2x2f, mat3x3f, mat4x4f } from "../../data/matrix.js";
|
|
7
|
+
import { fn } from "../../core/function/tgpuFn.js";
|
|
8
|
+
import { slot } from "../../core/slot/slot.js";
|
|
9
|
+
import { privateVar } from "../../core/variable/tgpuVariable.js";
|
|
10
|
+
|
|
11
|
+
//#region src/tgsl/consoleLog/serializers.ts
|
|
12
|
+
const dataBlockIndex = privateVar(u32, 0).$name("dataBlockIndex");
|
|
13
|
+
const dataByteIndex = privateVar(u32, 0).$name("dataByteIndex");
|
|
14
|
+
const dataBufferSlot = slot().$name("dataBuffer");
|
|
15
|
+
const nextByteIndex = fn([], u32)`() {
|
|
16
|
+
let i = dataByteIndex;
|
|
17
|
+
dataByteIndex = dataByteIndex + 1u;
|
|
18
|
+
return i;
|
|
19
|
+
}`.$uses({ dataByteIndex }).$name("nextByteIndex");
|
|
20
|
+
const nextU32 = "dataBuffer[dataBlockIndex].serializedData[nextByteIndex()]";
|
|
21
|
+
const serializerMap = {
|
|
22
|
+
f32: fn([f32])`(n) => {
|
|
23
|
+
${nextU32} = bitcast<u32>(n);
|
|
24
|
+
}`,
|
|
25
|
+
f16: fn([f16])`(n) => {
|
|
26
|
+
${nextU32} = pack2x16float(vec2f(f32(n), 0.0));
|
|
27
|
+
}`,
|
|
28
|
+
i32: fn([i32])`(n) => {
|
|
29
|
+
${nextU32} = bitcast<u32>(n);
|
|
30
|
+
}`,
|
|
31
|
+
u32: fn([u32])`(n) => {
|
|
32
|
+
${nextU32} = n;
|
|
33
|
+
}`,
|
|
34
|
+
bool: fn([bool])`(b) => {
|
|
35
|
+
${nextU32} = u32(b);
|
|
36
|
+
}`,
|
|
37
|
+
vec2f: fn([vec2f])`(v) => {
|
|
38
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
39
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
40
|
+
}`,
|
|
41
|
+
vec3f: fn([vec3f])`(v) => {
|
|
42
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
43
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
44
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
45
|
+
}`,
|
|
46
|
+
vec4f: fn([vec4f])`(v) => {
|
|
47
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
48
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
49
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
50
|
+
${nextU32} = bitcast<u32>(v.w);
|
|
51
|
+
}`,
|
|
52
|
+
vec2h: fn([vec2h])`(v) => {
|
|
53
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
54
|
+
}`,
|
|
55
|
+
vec3h: fn([vec3h])`(v) => {
|
|
56
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
57
|
+
${nextU32} = pack2x16float(vec2f(f32(v.z), 0.0));
|
|
58
|
+
}`,
|
|
59
|
+
vec4h: fn([vec4h])`(v) => {
|
|
60
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
61
|
+
${nextU32} = pack2x16float(vec2f(f32(v.z), f32(v.w)));
|
|
62
|
+
}`,
|
|
63
|
+
vec2i: fn([vec2i])`(v) => {
|
|
64
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
65
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
66
|
+
}`,
|
|
67
|
+
vec3i: fn([vec3i])`(v) => {
|
|
68
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
69
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
70
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
71
|
+
}`,
|
|
72
|
+
vec4i: fn([vec4i])`(v) => {
|
|
73
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
74
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
75
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
76
|
+
${nextU32} = bitcast<u32>(v.w);
|
|
77
|
+
}`,
|
|
78
|
+
vec2u: fn([vec2u])`(v) => {
|
|
79
|
+
${nextU32} = v.x;
|
|
80
|
+
${nextU32} = v.y;
|
|
81
|
+
}`,
|
|
82
|
+
vec3u: fn([vec3u])`(v) => {
|
|
83
|
+
${nextU32} = v.x;
|
|
84
|
+
${nextU32} = v.y;
|
|
85
|
+
${nextU32} = v.z;
|
|
86
|
+
}`,
|
|
87
|
+
vec4u: fn([vec4u])`(v) => {
|
|
88
|
+
${nextU32} = v.x;
|
|
89
|
+
${nextU32} = v.y;
|
|
90
|
+
${nextU32} = v.z;
|
|
91
|
+
${nextU32} = v.w;
|
|
92
|
+
}`,
|
|
93
|
+
"vec2<bool>": fn([vec2b])`(v) => {
|
|
94
|
+
${nextU32} = u32(v.x);
|
|
95
|
+
${nextU32} = u32(v.y);
|
|
96
|
+
}`,
|
|
97
|
+
"vec3<bool>": fn([vec3b])`(v) => {
|
|
98
|
+
${nextU32} = u32(v.x);
|
|
99
|
+
${nextU32} = u32(v.y);
|
|
100
|
+
${nextU32} = u32(v.z);
|
|
101
|
+
}`,
|
|
102
|
+
"vec4<bool>": fn([vec4b])`(v) => {
|
|
103
|
+
${nextU32} = u32(v.x);
|
|
104
|
+
${nextU32} = u32(v.y);
|
|
105
|
+
${nextU32} = u32(v.z);
|
|
106
|
+
${nextU32} = u32(v.w);
|
|
107
|
+
}`,
|
|
108
|
+
mat2x2f: fn([mat2x2f])`(m) => {
|
|
109
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
110
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
111
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
112
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
113
|
+
}`,
|
|
114
|
+
mat3x3f: fn([mat3x3f])`(m) => {
|
|
115
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
116
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
117
|
+
${nextU32} = bitcast<u32>(m[0][2]);
|
|
118
|
+
${nextU32} = 0u;
|
|
119
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
120
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
121
|
+
${nextU32} = bitcast<u32>(m[1][2]);
|
|
122
|
+
${nextU32} = 0u;
|
|
123
|
+
${nextU32} = bitcast<u32>(m[2][0]);
|
|
124
|
+
${nextU32} = bitcast<u32>(m[2][1]);
|
|
125
|
+
${nextU32} = bitcast<u32>(m[2][2]);
|
|
126
|
+
${nextU32} = 0u;
|
|
127
|
+
}`,
|
|
128
|
+
mat4x4f: fn([mat4x4f])`(m) => {
|
|
129
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
130
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
131
|
+
${nextU32} = bitcast<u32>(m[0][2]);
|
|
132
|
+
${nextU32} = bitcast<u32>(m[0][3]);
|
|
133
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
134
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
135
|
+
${nextU32} = bitcast<u32>(m[1][2]);
|
|
136
|
+
${nextU32} = bitcast<u32>(m[1][3]);
|
|
137
|
+
${nextU32} = bitcast<u32>(m[2][0]);
|
|
138
|
+
${nextU32} = bitcast<u32>(m[2][1]);
|
|
139
|
+
${nextU32} = bitcast<u32>(m[2][2]);
|
|
140
|
+
${nextU32} = bitcast<u32>(m[2][3]);
|
|
141
|
+
${nextU32} = bitcast<u32>(m[3][0]);
|
|
142
|
+
${nextU32} = bitcast<u32>(m[3][1]);
|
|
143
|
+
${nextU32} = bitcast<u32>(m[3][2]);
|
|
144
|
+
${nextU32} = bitcast<u32>(m[3][3]);
|
|
145
|
+
}`
|
|
146
|
+
};
|
|
147
|
+
for (const [name, serializer] of Object.entries(serializerMap)) serializer.$name(`serialize${name[0].toLocaleUpperCase()}${name.slice(1)}`).$uses({
|
|
148
|
+
dataBlockIndex,
|
|
149
|
+
nextByteIndex,
|
|
150
|
+
dataBuffer: dataBufferSlot
|
|
151
|
+
});
|
|
152
|
+
function generateHeader(argTypes) {
|
|
153
|
+
return `(${argTypes.map((_, i) => `_arg_${i}`).join(", ")})`;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Returns a serializer TGPU function for a given WGSL data type.
|
|
157
|
+
* If the data type is a base type, one of the preexisting functions (with the `dataBufferSlot` filled) is returned.
|
|
158
|
+
* Otherwise, a new function is generated.
|
|
159
|
+
*
|
|
160
|
+
* @param dataType - The WGSL data type descriptor to return a serializer for
|
|
161
|
+
* @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
|
|
162
|
+
*/
|
|
163
|
+
function getSerializer(dataType, dataBuffer) {
|
|
164
|
+
const maybeSerializer = serializerMap[dataType.type];
|
|
165
|
+
if (maybeSerializer) return maybeSerializer.with(dataBufferSlot, dataBuffer);
|
|
166
|
+
if (isWgslStruct(dataType)) {
|
|
167
|
+
const props = Object.keys(dataType.propTypes);
|
|
168
|
+
const propsSerializer = createCompoundSerializer(Object.values(dataType.propTypes), dataBuffer);
|
|
169
|
+
return fn([dataType])`(arg) {\n propsSerializer(${props.map((prop) => `arg.${prop}`).join(", ")});\n}`.$uses({ propsSerializer }).$name(`${getName(dataType) ?? "struct"}Serializer`);
|
|
170
|
+
}
|
|
171
|
+
if (isWgslArray(dataType)) {
|
|
172
|
+
const elementType = dataType.elementType;
|
|
173
|
+
const length = dataType.elementCount;
|
|
174
|
+
const elementSerializer = getSerializer(elementType, dataBuffer);
|
|
175
|
+
return fn([dataType])`(arg) {\n${Array.from({ length }, (_, i) => ` elementSerializer(arg[${i}]);`).join("\n")}\n}`.$uses({ elementSerializer }).$name("arraySerializer");
|
|
176
|
+
}
|
|
177
|
+
throw new Error(`Cannot serialize data of type ${dataType.type}`);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Creates a compound serializer TGPU function that serializes multiple arguments of different types to the data buffer.
|
|
181
|
+
*
|
|
182
|
+
* @param dataTypes - Array of WGSL data types that define the types of arguments to be serialized
|
|
183
|
+
* @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
|
|
184
|
+
*/
|
|
185
|
+
function createCompoundSerializer(dataTypes, dataBuffer) {
|
|
186
|
+
const usedSerializers = {};
|
|
187
|
+
return fn(dataTypes)`${generateHeader(dataTypes)} {\n${dataTypes.map((arg, i) => {
|
|
188
|
+
usedSerializers[`serializer${i}`] = getSerializer(arg, dataBuffer);
|
|
189
|
+
return ` serializer${i}(_arg_${i});`;
|
|
190
|
+
}).join("\n")}\n}`.$uses(usedSerializers).$name("compoundSerializer");
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Creates a TGPU function that serializes data to the log buffer.
|
|
194
|
+
*
|
|
195
|
+
* @param id - Identifier for this logging function instance
|
|
196
|
+
* @param dataTypes - Array of WGSL data types that will be logged by this function
|
|
197
|
+
* @param dataBuffer - Mutable buffer array to store serialized log call data
|
|
198
|
+
* @param indexBuffer - Atomic counter buffer to track the next available log data slot
|
|
199
|
+
* @param logOptions - Configuration options
|
|
200
|
+
*/
|
|
201
|
+
function createLoggingFunction(id, dataTypes, dataBuffer, indexBuffer, logOptions) {
|
|
202
|
+
const serializedSize = dataTypes.map(sizeOf).reduce((a, b) => a + b, 0);
|
|
203
|
+
if (serializedSize > logOptions.logSizeLimit) throw new Error(`Logged data needs to fit in ${logOptions.logSizeLimit} bytes (one of the logs requires ${serializedSize} bytes). Consider increasing the limit by passing appropriate options to tgpu.init().`);
|
|
204
|
+
const compoundSerializer = createCompoundSerializer(dataTypes, dataBuffer).$name(`log${id}serializer`);
|
|
205
|
+
const header = generateHeader(dataTypes);
|
|
206
|
+
return fn(dataTypes)`${header} {
|
|
207
|
+
dataBlockIndex = atomicAdd(&indexBuffer, 1);
|
|
208
|
+
if (dataBlockIndex >= ${logOptions.logCountLimit}) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
dataBuffer[dataBlockIndex].id = ${id};
|
|
212
|
+
dataByteIndex = 0;
|
|
213
|
+
|
|
214
|
+
compoundSerializer${header};
|
|
215
|
+
}`.$uses({
|
|
216
|
+
indexBuffer,
|
|
217
|
+
dataBuffer,
|
|
218
|
+
dataBlockIndex,
|
|
219
|
+
dataByteIndex,
|
|
220
|
+
compoundSerializer
|
|
221
|
+
}).$name(`log${id}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
export { createLoggingFunction };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import "../../data/snippet.js";
|
|
2
|
+
import { TgpuMutable } from "../../core/buffer/bufferShorthand.js";
|
|
3
|
+
import "../generationHelpers.js";
|
|
4
|
+
import { AnyWgslData, Atomic, U32, WgslArray, WgslStruct } from "../../data/wgslTypes.js";
|
|
5
|
+
|
|
6
|
+
//#region src/tgsl/consoleLog/types.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Options for configuring GPU log generation.
|
|
9
|
+
*/
|
|
10
|
+
interface LogGeneratorOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The maximum number of logs that appear during a single draw/dispatch call.
|
|
13
|
+
* If this number is exceeded, a warning containing the total number of calls is logged and further logs are dropped.
|
|
14
|
+
* @default 64
|
|
15
|
+
*/
|
|
16
|
+
logCountLimit?: number;
|
|
17
|
+
/**
|
|
18
|
+
* The total number of bytes reserved for each log call.
|
|
19
|
+
* If this number is exceeded, an exception is thrown during resolution.
|
|
20
|
+
* @default 252
|
|
21
|
+
*/
|
|
22
|
+
logSizeLimit?: number;
|
|
23
|
+
/**
|
|
24
|
+
* The prefix attached to each log call.
|
|
25
|
+
* @default ' GPU '
|
|
26
|
+
*/
|
|
27
|
+
messagePrefix?: string;
|
|
28
|
+
}
|
|
29
|
+
type SerializedLogCallData = WgslStruct<{
|
|
30
|
+
id: U32;
|
|
31
|
+
serializedData: WgslArray<U32>;
|
|
32
|
+
}>;
|
|
33
|
+
interface LogMeta {
|
|
34
|
+
op: SupportedLogOps;
|
|
35
|
+
argTypes: (string | AnyWgslData)[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The resources required for logging via console.log within TypeGPU functions.
|
|
39
|
+
*
|
|
40
|
+
* @property indexBuffer - A buffer used for indexing log entries. Needs to be cleared after each dispatch/draw.
|
|
41
|
+
* @property dataBuffer - A buffer containing an array of serialized log call data.
|
|
42
|
+
* @property options - The configuration options for the LogGenerator.
|
|
43
|
+
* @property logIdToMeta - A mapping from log identifiers to an object containing the corresponding log op and argument types.
|
|
44
|
+
*/
|
|
45
|
+
interface LogResources {
|
|
46
|
+
indexBuffer: TgpuMutable<Atomic<U32>>;
|
|
47
|
+
dataBuffer: TgpuMutable<WgslArray<SerializedLogCallData>>;
|
|
48
|
+
options: Required<LogGeneratorOptions>;
|
|
49
|
+
logIdToMeta: Map<number, LogMeta>;
|
|
50
|
+
}
|
|
51
|
+
declare const supportedLogOps: readonly ["log", "debug", "info", "warn", "error", "clear"];
|
|
52
|
+
type SupportedLogOps = (typeof supportedLogOps)[number];
|
|
53
|
+
//#endregion
|
|
54
|
+
export { LogGeneratorOptions, LogResources };
|
|
@@ -0,0 +1,200 @@
|
|
|
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
|
+
|
|
12
|
+
//#region src/tgsl/conversion.ts
|
|
13
|
+
const INFINITE_RANK = {
|
|
14
|
+
rank: Number.POSITIVE_INFINITY,
|
|
15
|
+
action: "none"
|
|
16
|
+
};
|
|
17
|
+
function getAutoConversionRank(src, dest) {
|
|
18
|
+
const trueSrc = undecorate(src);
|
|
19
|
+
const trueDst = undecorate(dest);
|
|
20
|
+
if (trueSrc.type === trueDst.type) return {
|
|
21
|
+
rank: 0,
|
|
22
|
+
action: "none"
|
|
23
|
+
};
|
|
24
|
+
if (trueSrc.type === "abstractFloat") {
|
|
25
|
+
if (trueDst.type === "f32") return {
|
|
26
|
+
rank: 1,
|
|
27
|
+
action: "none"
|
|
28
|
+
};
|
|
29
|
+
if (trueDst.type === "f16") return {
|
|
30
|
+
rank: 2,
|
|
31
|
+
action: "none"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
if (trueSrc.type === "abstractInt") {
|
|
35
|
+
if (trueDst.type === "i32") return {
|
|
36
|
+
rank: 3,
|
|
37
|
+
action: "none"
|
|
38
|
+
};
|
|
39
|
+
if (trueDst.type === "u32") return {
|
|
40
|
+
rank: 4,
|
|
41
|
+
action: "none"
|
|
42
|
+
};
|
|
43
|
+
if (trueDst.type === "abstractFloat") return {
|
|
44
|
+
rank: 5,
|
|
45
|
+
action: "none"
|
|
46
|
+
};
|
|
47
|
+
if (trueDst.type === "f32") return {
|
|
48
|
+
rank: 6,
|
|
49
|
+
action: "none"
|
|
50
|
+
};
|
|
51
|
+
if (trueDst.type === "f16") return {
|
|
52
|
+
rank: 7,
|
|
53
|
+
action: "none"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (isVec(trueSrc) && isVec(trueDst) && trueSrc.type[3] === trueDst.type[3]) return getAutoConversionRank(trueSrc.primitive, trueDst.primitive);
|
|
57
|
+
if (isMat(trueSrc) && isMat(trueDst) && trueSrc.type[3] === trueDst.type[3]) return {
|
|
58
|
+
rank: 0,
|
|
59
|
+
action: "none"
|
|
60
|
+
};
|
|
61
|
+
return INFINITE_RANK;
|
|
62
|
+
}
|
|
63
|
+
function getImplicitConversionRank(src, dest) {
|
|
64
|
+
const trueSrc = undecorate(src);
|
|
65
|
+
const trueDst = undecorate(dest);
|
|
66
|
+
if (isPtr(trueSrc) && trueSrc.implicit && getAutoConversionRank(trueSrc.inner, trueDst).rank < Number.POSITIVE_INFINITY) return {
|
|
67
|
+
rank: 0,
|
|
68
|
+
action: "deref"
|
|
69
|
+
};
|
|
70
|
+
if (isPtr(trueDst) && getAutoConversionRank(trueSrc, trueDst.inner).rank < Number.POSITIVE_INFINITY) return {
|
|
71
|
+
rank: 1,
|
|
72
|
+
action: "ref"
|
|
73
|
+
};
|
|
74
|
+
const primitivePreference = {
|
|
75
|
+
f32: 0,
|
|
76
|
+
f16: 1,
|
|
77
|
+
i32: 2,
|
|
78
|
+
u32: 3,
|
|
79
|
+
bool: 4
|
|
80
|
+
};
|
|
81
|
+
if (trueSrc.type in primitivePreference && trueDst.type in primitivePreference) {
|
|
82
|
+
const srcType = trueSrc.type;
|
|
83
|
+
const destType = trueDst.type;
|
|
84
|
+
if (srcType !== destType) {
|
|
85
|
+
const srcPref = primitivePreference[srcType];
|
|
86
|
+
return {
|
|
87
|
+
rank: primitivePreference[destType] < srcPref ? 10 : 20,
|
|
88
|
+
action: "cast",
|
|
89
|
+
targetType: trueDst
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (trueSrc.type === "abstractFloat") {
|
|
94
|
+
if (trueDst.type === "u32") return {
|
|
95
|
+
rank: 2,
|
|
96
|
+
action: "cast",
|
|
97
|
+
targetType: trueDst
|
|
98
|
+
};
|
|
99
|
+
if (trueDst.type === "i32") return {
|
|
100
|
+
rank: 1,
|
|
101
|
+
action: "cast",
|
|
102
|
+
targetType: trueDst
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return INFINITE_RANK;
|
|
106
|
+
}
|
|
107
|
+
function getConversionRank(src, dest, allowImplicit) {
|
|
108
|
+
const autoRank = getAutoConversionRank(src, dest);
|
|
109
|
+
if (autoRank.rank < Number.POSITIVE_INFINITY) return autoRank;
|
|
110
|
+
if (allowImplicit) return getImplicitConversionRank(src, dest);
|
|
111
|
+
return INFINITE_RANK;
|
|
112
|
+
}
|
|
113
|
+
function findBestType(types, uniqueTypes, allowImplicit) {
|
|
114
|
+
let bestResult;
|
|
115
|
+
for (const targetType of uniqueTypes) {
|
|
116
|
+
const details = [];
|
|
117
|
+
let sum = 0;
|
|
118
|
+
for (const sourceType of types) {
|
|
119
|
+
const conversion = getConversionRank(sourceType, targetType, allowImplicit);
|
|
120
|
+
sum += conversion.rank;
|
|
121
|
+
if (conversion.rank === Number.POSITIVE_INFINITY) break;
|
|
122
|
+
details.push(conversion);
|
|
123
|
+
}
|
|
124
|
+
if (sum < (bestResult?.sum ?? Number.POSITIVE_INFINITY)) bestResult = {
|
|
125
|
+
type: targetType,
|
|
126
|
+
details,
|
|
127
|
+
sum
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (!bestResult) return;
|
|
131
|
+
const actions = bestResult.details.map((detail, index) => ({
|
|
132
|
+
sourceIndex: index,
|
|
133
|
+
action: detail.action,
|
|
134
|
+
...detail.action === "cast" && { targetType: detail.targetType }
|
|
135
|
+
}));
|
|
136
|
+
return {
|
|
137
|
+
targetType: bestResult.type,
|
|
138
|
+
actions,
|
|
139
|
+
hasImplicitConversions: actions.some((action) => action.action === "cast")
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function getBestConversion(types, targetTypes) {
|
|
143
|
+
if (types.length === 0) return void 0;
|
|
144
|
+
const uniqueTargetTypes = [...new Set((targetTypes || types).map(undecorate))];
|
|
145
|
+
const explicitResult = findBestType(types, uniqueTargetTypes, false);
|
|
146
|
+
if (explicitResult) return explicitResult;
|
|
147
|
+
const implicitResult = findBestType(types, uniqueTargetTypes, true);
|
|
148
|
+
if (implicitResult) return implicitResult;
|
|
149
|
+
}
|
|
150
|
+
function applyActionToSnippet(ctx, snippet, action, targetType) {
|
|
151
|
+
if (action.action === "none") return snip(snippet.value, targetType, snippet.origin);
|
|
152
|
+
switch (action.action) {
|
|
153
|
+
case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
|
|
154
|
+
case "deref": return derefSnippet(snippet);
|
|
155
|
+
case "cast": return schemaCallWrapperGPU(ctx, targetType, snippet);
|
|
156
|
+
default: assertExhaustive(action.action, "applyActionToSnippet");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function unify(inTypes, restrictTo) {
|
|
160
|
+
if (inTypes.some((type) => type === UnknownData)) return;
|
|
161
|
+
const conversion = getBestConversion(inTypes, restrictTo);
|
|
162
|
+
if (!conversion) return;
|
|
163
|
+
return inTypes.map((type) => isVec(type) || isMat(type) ? type : conversion.targetType);
|
|
164
|
+
}
|
|
165
|
+
function convertToCommonType(ctx, values, restrictTo, verbose = true) {
|
|
166
|
+
const types = values.map((value) => value.dataType);
|
|
167
|
+
if (types.some((type) => type === UnknownData)) return;
|
|
168
|
+
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.");
|
|
169
|
+
const conversion = getBestConversion(types, restrictTo);
|
|
170
|
+
if (!conversion) return;
|
|
171
|
+
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.
|
|
172
|
+
Consider using explicit conversions instead.`);
|
|
173
|
+
return values.map((value, index) => {
|
|
174
|
+
const action = conversion.actions[index];
|
|
175
|
+
invariant(action, "Action should not be undefined");
|
|
176
|
+
return applyActionToSnippet(ctx, value, action, conversion.targetType);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function tryConvertSnippet(ctx, snippet, targetDataTypes, verbose = true) {
|
|
180
|
+
const targets = Array.isArray(targetDataTypes) ? targetDataTypes : [targetDataTypes];
|
|
181
|
+
const { value, dataType, origin } = snippet;
|
|
182
|
+
if (targets.length === 1) {
|
|
183
|
+
const target = targets[0];
|
|
184
|
+
if (target === dataType) return snip(value, target, origin);
|
|
185
|
+
if (dataType === UnknownData) return snip(stitch`${snip(value, target, origin)}`, target, origin);
|
|
186
|
+
}
|
|
187
|
+
const converted = convertToCommonType(ctx, [snippet], targets, verbose);
|
|
188
|
+
if (converted) return converted[0];
|
|
189
|
+
throw new WgslTypeError(`Cannot convert value of type '${String(dataType)}' to any of the target types: [${targets.map((t) => t.type).join(", ")}]`);
|
|
190
|
+
}
|
|
191
|
+
function convertStructValues(ctx, structType, values) {
|
|
192
|
+
return Object.entries(structType.propTypes).map(([key, targetType]) => {
|
|
193
|
+
const val = values[key];
|
|
194
|
+
if (!val) throw new Error(`Missing property ${key}`);
|
|
195
|
+
return convertToCommonType(ctx, [val], [targetType])?.[0] ?? val;
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
//#endregion
|
|
200
|
+
export { convertStructValues, convertToCommonType, getBestConversion, tryConvertSnippet, unify };
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { 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
|
+
|
|
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 getElementCountSnippet(ctx, iterableSnippet, unroll = false) {
|
|
34
|
+
const { value, dataType } = iterableSnippet;
|
|
35
|
+
if (isWgslArray(dataType)) return dataType.elementCount > 0 ? snip(dataType.elementCount, u32, "constant") : arrayLength[$gpuCallable].call(ctx, [iterableSnippet]);
|
|
36
|
+
if (isVec(dataType)) return snip(dataType.componentCount, u32, "constant");
|
|
37
|
+
if (unroll) {
|
|
38
|
+
if (Array.isArray(value)) return snip(value.length, u32, "constant");
|
|
39
|
+
if (value instanceof ArrayExpression) return snip(value.elements.length, u32, "constant");
|
|
40
|
+
}
|
|
41
|
+
throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
export { getElementCountSnippet, getElementSnippet, getElementType, getLoopVarKind };
|
|
@@ -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 };
|