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,115 @@
|
|
|
1
|
+
import { $gpuCallable } from "../shared/symbols.js";
|
|
2
|
+
import { isMat, isNaturallyEphemeral, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
|
|
3
|
+
import { InfixDispatch, MatrixColumnsAccess, UnknownData, isUnstruct, undecorate } from "../data/dataTypes.js";
|
|
4
|
+
import { isEphemeralSnippet, snip } from "../data/snippet.js";
|
|
5
|
+
import { isKnownAtComptime } from "../types.js";
|
|
6
|
+
import { stitch } from "../core/resolve/stitch.js";
|
|
7
|
+
import { derefSnippet } from "../data/ref.js";
|
|
8
|
+
import { abstractInt, bool, f16, f32, i32, u32 } from "../data/numeric.js";
|
|
9
|
+
import { coerceToSnippet } from "./generationHelpers.js";
|
|
10
|
+
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
|
|
11
|
+
import { AutoStruct } from "../data/autoStruct.js";
|
|
12
|
+
import { EntryInputRouter } from "../core/function/entryInputRouter.js";
|
|
13
|
+
import { add, bitShiftLeft, bitShiftRight, div, mod, mul, sub } from "../std/operators.js";
|
|
14
|
+
//#region src/tgsl/accessProp.ts
|
|
15
|
+
const infixKinds = [
|
|
16
|
+
"vec2f",
|
|
17
|
+
"vec3f",
|
|
18
|
+
"vec4f",
|
|
19
|
+
"vec2h",
|
|
20
|
+
"vec3h",
|
|
21
|
+
"vec4h",
|
|
22
|
+
"vec2i",
|
|
23
|
+
"vec3i",
|
|
24
|
+
"vec4i",
|
|
25
|
+
"vec2u",
|
|
26
|
+
"vec3u",
|
|
27
|
+
"vec4u",
|
|
28
|
+
"mat2x2f",
|
|
29
|
+
"mat3x3f",
|
|
30
|
+
"mat4x4f"
|
|
31
|
+
];
|
|
32
|
+
const infixOperators = {
|
|
33
|
+
add,
|
|
34
|
+
sub,
|
|
35
|
+
mul,
|
|
36
|
+
div,
|
|
37
|
+
mod,
|
|
38
|
+
bitShiftLeft,
|
|
39
|
+
bitShiftRight
|
|
40
|
+
};
|
|
41
|
+
const swizzleLenToType = {
|
|
42
|
+
f: {
|
|
43
|
+
1: f32,
|
|
44
|
+
2: vec2f,
|
|
45
|
+
3: vec3f,
|
|
46
|
+
4: vec4f
|
|
47
|
+
},
|
|
48
|
+
h: {
|
|
49
|
+
1: f16,
|
|
50
|
+
2: vec2h,
|
|
51
|
+
3: vec3h,
|
|
52
|
+
4: vec4h
|
|
53
|
+
},
|
|
54
|
+
i: {
|
|
55
|
+
1: i32,
|
|
56
|
+
2: vec2i,
|
|
57
|
+
3: vec3i,
|
|
58
|
+
4: vec4i
|
|
59
|
+
},
|
|
60
|
+
u: {
|
|
61
|
+
1: u32,
|
|
62
|
+
2: vec2u,
|
|
63
|
+
3: vec3u,
|
|
64
|
+
4: vec4u
|
|
65
|
+
},
|
|
66
|
+
b: {
|
|
67
|
+
1: bool,
|
|
68
|
+
2: vec2b,
|
|
69
|
+
3: vec3b,
|
|
70
|
+
4: vec4b
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
function accessProp(target, propName) {
|
|
74
|
+
if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
|
|
75
|
+
const operator = infixOperators[propName];
|
|
76
|
+
return snip(new InfixDispatch(propName, target, operator[$gpuCallable].call.bind(operator)), UnknownData, target.origin);
|
|
77
|
+
}
|
|
78
|
+
if (isWgslArray(target.dataType) && propName === "length") {
|
|
79
|
+
if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
|
|
80
|
+
return snip(target.dataType.elementCount, abstractInt, "constant");
|
|
81
|
+
}
|
|
82
|
+
if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
|
|
83
|
+
if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
|
|
84
|
+
let propType = target.dataType.propTypes[propName];
|
|
85
|
+
if (!propType) return;
|
|
86
|
+
propType = undecorate(propType);
|
|
87
|
+
return snip(stitch`${target}.${propName}`, propType, target.origin === "argument" ? "argument" : !isEphemeralSnippet(target) && !isNaturallyEphemeral(propType) ? target.origin : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
|
|
88
|
+
}
|
|
89
|
+
if (target.dataType instanceof AutoStruct) {
|
|
90
|
+
const result = target.dataType.accessProp(propName);
|
|
91
|
+
if (!result) return;
|
|
92
|
+
return snip(stitch`${target}.${result.prop}`, result.type, "argument");
|
|
93
|
+
}
|
|
94
|
+
if (target.dataType instanceof EntryInputRouter) return target.dataType.accessProp(propName);
|
|
95
|
+
if (isPtr(target.dataType)) {
|
|
96
|
+
const derefed = derefSnippet(target);
|
|
97
|
+
if (propName === "$") return derefed;
|
|
98
|
+
return accessProp(derefed, propName);
|
|
99
|
+
}
|
|
100
|
+
if (isVec(target.dataType)) {
|
|
101
|
+
if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
|
|
102
|
+
}
|
|
103
|
+
const propLength = propName.length;
|
|
104
|
+
if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
|
|
105
|
+
const isXYZW = /^[xyzw]+$/.test(propName);
|
|
106
|
+
const isRGBA = /^[rgba]+$/.test(propName);
|
|
107
|
+
if (!isXYZW && !isRGBA) return;
|
|
108
|
+
const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
|
|
109
|
+
if (!swizzleType) return;
|
|
110
|
+
return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, target.origin === "argument" && propLength === 1 ? "argument" : target.origin === "constant" || target.origin === "constant-tgpu-const-ref" ? "constant" : "runtime");
|
|
111
|
+
}
|
|
112
|
+
if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { accessProp, infixOperators };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { isWgslArray, isWgslData, isWgslStruct } from "../../data/wgslTypes.js";
|
|
2
|
+
import { niceStringify } from "../../shared/stringify.js";
|
|
3
|
+
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
|
|
4
|
+
import { sizeOf } from "../../data/sizeOf.js";
|
|
5
|
+
import { mat2x2f, mat3x3f, mat4x4f } from "../../data/matrix.js";
|
|
6
|
+
import { bitcastU32toF32, bitcastU32toI32 } from "../../std/bitcast.js";
|
|
7
|
+
import { unpack2x16float } from "../../std/packing.js";
|
|
8
|
+
//#region src/tgsl/consoleLog/deserializers.ts
|
|
9
|
+
const toF = (n) => bitcastU32toF32(n ?? 0);
|
|
10
|
+
const toI = (n) => bitcastU32toI32(n ?? 0);
|
|
11
|
+
const unpack = (n) => unpack2x16float(n ?? 0);
|
|
12
|
+
const deserializerMap = {
|
|
13
|
+
f32: (d) => toF(d[0]),
|
|
14
|
+
f16: (d) => unpack(d[0]).x,
|
|
15
|
+
i32: (d) => toI(d[0]),
|
|
16
|
+
u32: (d) => d[0] ?? 0,
|
|
17
|
+
bool: (d) => !!d[0],
|
|
18
|
+
vec2f: (d) => vec2f(toF(d[0]), toF(d[1])),
|
|
19
|
+
vec3f: (d) => vec3f(toF(d[0]), toF(d[1]), toF(d[2])),
|
|
20
|
+
vec4f: (d) => vec4f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3])),
|
|
21
|
+
vec2h(d) {
|
|
22
|
+
const xyVec = unpack(d[0]);
|
|
23
|
+
return vec2h(xyVec.x, xyVec.y);
|
|
24
|
+
},
|
|
25
|
+
vec3h(d) {
|
|
26
|
+
const xyVec = unpack(d[0]);
|
|
27
|
+
const zVec = unpack(d[1]);
|
|
28
|
+
return vec3h(xyVec.x, xyVec.y, zVec.x);
|
|
29
|
+
},
|
|
30
|
+
vec4h(d) {
|
|
31
|
+
const xyVec = unpack(d[0]);
|
|
32
|
+
const zwVec = unpack(d[1]);
|
|
33
|
+
return vec4h(xyVec.x, xyVec.y, zwVec.x, zwVec.y);
|
|
34
|
+
},
|
|
35
|
+
vec2i: (d) => vec2i(toI(d[0]), toI(d[1])),
|
|
36
|
+
vec3i: (d) => vec3i(toI(d[0]), toI(d[1]), toI(d[2])),
|
|
37
|
+
vec4i: (d) => vec4i(toI(d[0]), toI(d[1]), toI(d[2]), toI(d[3])),
|
|
38
|
+
vec2u: (d) => vec2u(d[0] ?? 0, d[1] ?? 0),
|
|
39
|
+
vec3u: (d) => vec3u(d[0] ?? 0, d[1] ?? 0, d[2] ?? 0),
|
|
40
|
+
vec4u: (d) => vec4u(d[0] ?? 0, d[1] ?? 0, d[2] ?? 0, d[3] ?? 0),
|
|
41
|
+
"vec2<bool>": (d) => vec2b(!!d[0], !!d[1]),
|
|
42
|
+
"vec3<bool>": (d) => vec3b(!!d[0], !!d[1], !!d[2]),
|
|
43
|
+
"vec4<bool>": (d) => vec4b(!!d[0], !!d[1], !!d[2], !!d[3]),
|
|
44
|
+
mat2x2f: (d) => mat2x2f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3])),
|
|
45
|
+
mat3x3f: (d) => mat3x3f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[4]), toF(d[5]), toF(d[6]), toF(d[8]), toF(d[9]), toF(d[10])),
|
|
46
|
+
mat4x4f: (d) => mat4x4f(toF(d[0]), toF(d[1]), toF(d[2]), toF(d[3]), toF(d[4]), toF(d[5]), toF(d[6]), toF(d[7]), toF(d[8]), toF(d[9]), toF(d[10]), toF(d[11]), toF(d[12]), toF(d[13]), toF(d[14]), toF(d[15]))
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Deserializes binary data from a Uint32Array into a JavaScript value based on the provided WGSL data type.
|
|
50
|
+
*
|
|
51
|
+
* @param data - The binary data as a Uint32Array to be deserialized
|
|
52
|
+
* @param dataType - The WGSL data type specification that determines how to interpret the binary data
|
|
53
|
+
*/
|
|
54
|
+
function deserialize(data, dataType) {
|
|
55
|
+
const maybeDeserializer = deserializerMap[dataType.type];
|
|
56
|
+
if (maybeDeserializer) return maybeDeserializer(data);
|
|
57
|
+
if (isWgslStruct(dataType)) {
|
|
58
|
+
const props = Object.keys(dataType.propTypes);
|
|
59
|
+
const decodedProps = deserializeCompound(data, Object.values(dataType.propTypes));
|
|
60
|
+
return Object.fromEntries(props.map((key, index) => [key, decodedProps[index]]));
|
|
61
|
+
}
|
|
62
|
+
if (isWgslArray(dataType)) {
|
|
63
|
+
const elementType = dataType.elementType;
|
|
64
|
+
const length = dataType.elementCount;
|
|
65
|
+
return deserializeCompound(data, Array.from({ length }, () => elementType));
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Cannot deserialize data of type ${dataType.type}`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Deserializes a list of elements from a Uint32Array buffer using provided type information.
|
|
71
|
+
* If there is a string value among the type information, it is returned as is.
|
|
72
|
+
*
|
|
73
|
+
* @param data - The Uint32Array buffer containing the serialized data
|
|
74
|
+
* @param dataTypes - The WGSL data type specification that determines how to interpret the binary data, or string literals
|
|
75
|
+
*/
|
|
76
|
+
function deserializeCompound(data, dataTypes) {
|
|
77
|
+
let index = 0;
|
|
78
|
+
return dataTypes.map((info) => {
|
|
79
|
+
if (!isWgslData(info)) return info;
|
|
80
|
+
const size = Math.ceil(sizeOf(info) / 4);
|
|
81
|
+
const value = deserialize(data.subarray(index, index + size), info);
|
|
82
|
+
index += size;
|
|
83
|
+
return value;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function deserializeAndStringify(serializedData, argTypes) {
|
|
87
|
+
return deserializeCompound(serializedData, argTypes).map(niceStringify);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Reads and deserializes log data from GPU buffers, logging results to the console.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* - Log entries with IDs equal to 0 are filtered out.
|
|
94
|
+
* - Console messages are prepended with options.messagePrefix styled with purple background and white text.
|
|
95
|
+
* - A warning is displayed if the log count exceeds the limit passed in options.
|
|
96
|
+
* - After processing, the index buffer and the data buffer are cleared.
|
|
97
|
+
*/
|
|
98
|
+
function logDataFromGPU(resources) {
|
|
99
|
+
const { indexBuffer, dataBuffer, logIdToMeta, options } = resources;
|
|
100
|
+
dataBuffer.read().then((data) => {
|
|
101
|
+
data.filter((e) => e.id).forEach(({ id, serializedData }) => {
|
|
102
|
+
const { argTypes, op } = logIdToMeta.get(id);
|
|
103
|
+
const results = deserializeAndStringify(new Uint32Array(serializedData), argTypes);
|
|
104
|
+
if (results.length === 0) results.push("");
|
|
105
|
+
console[op](`%c${options.messagePrefix}%c ${results[0]}`, "background: #936ff5; color: white;", "color: inherit; background: none", ...results.slice(1));
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
indexBuffer.read().then((totalCalls) => {
|
|
109
|
+
if (totalCalls > options.logCountLimit) console.warn(`Log count limit per dispatch (${options.logCountLimit}) exceeded by ${totalCalls - options.logCountLimit} calls. Consider increasing the limit by passing appropriate options to tgpu.init().`);
|
|
110
|
+
});
|
|
111
|
+
dataBuffer.buffer.clear();
|
|
112
|
+
indexBuffer.buffer.clear();
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { logDataFromGPU };
|
|
@@ -0,0 +1,84 @@
|
|
|
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 { concretizeSnippets } from "../generationHelpers.js";
|
|
8
|
+
import { struct } from "../../data/struct.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
|
+
//#region src/tgsl/consoleLog/logGenerator.ts
|
|
15
|
+
const defaultOptions = {
|
|
16
|
+
logCountLimit: 64,
|
|
17
|
+
logSizeLimit: 252,
|
|
18
|
+
messagePrefix: " GPU "
|
|
19
|
+
};
|
|
20
|
+
const fallbackSnippet = snip("/* console.log() */", Void, "runtime");
|
|
21
|
+
var LogGeneratorNullImpl = class {
|
|
22
|
+
get logResources() {}
|
|
23
|
+
generateLog() {
|
|
24
|
+
console.warn("'console.log' is only supported when resolving pipelines.");
|
|
25
|
+
return fallbackSnippet;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var LogGeneratorImpl = class {
|
|
29
|
+
#options;
|
|
30
|
+
#logIdToMeta;
|
|
31
|
+
#firstUnusedId = 1;
|
|
32
|
+
#indexBuffer;
|
|
33
|
+
#dataBuffer;
|
|
34
|
+
constructor(root) {
|
|
35
|
+
this.#options = {
|
|
36
|
+
...defaultOptions,
|
|
37
|
+
...root[$internal].logOptions
|
|
38
|
+
};
|
|
39
|
+
this.#logIdToMeta = /* @__PURE__ */ new Map();
|
|
40
|
+
const SerializedLogData = struct({
|
|
41
|
+
id: u32,
|
|
42
|
+
serializedData: arrayOf(u32, Math.ceil(this.#options.logSizeLimit / 4))
|
|
43
|
+
}).$name("SerializedLogData");
|
|
44
|
+
this.#dataBuffer = root.createMutable(arrayOf(SerializedLogData, this.#options.logCountLimit)).$name("dataBuffer");
|
|
45
|
+
this.#indexBuffer = root.createMutable(atomic(u32)).$name("indexBuffer");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generates all necessary resources for serializing arguments for logging purposes.
|
|
49
|
+
*
|
|
50
|
+
* @param ctx Resolution context.
|
|
51
|
+
* @param args Argument snippets. Snippets of UnknownType will be treated as string literals.
|
|
52
|
+
* @returns A snippet containing the call to the logging function.
|
|
53
|
+
*/
|
|
54
|
+
generateLog(ctx, op, args) {
|
|
55
|
+
if (shaderStageSlot.$ === "vertex") {
|
|
56
|
+
console.warn(`'console.${op}' is not supported in vertex shaders.`);
|
|
57
|
+
return fallbackSnippet;
|
|
58
|
+
}
|
|
59
|
+
if (!supportedLogOps.includes(op)) {
|
|
60
|
+
console.warn(`Unsupported log method '${op}'.`);
|
|
61
|
+
return fallbackSnippet;
|
|
62
|
+
}
|
|
63
|
+
const concreteArgs = concretizeSnippets(args);
|
|
64
|
+
const id = this.#firstUnusedId++;
|
|
65
|
+
const nonStringArgs = concreteArgs.filter((e) => e.dataType !== UnknownData);
|
|
66
|
+
const logFn = createLoggingFunction(id, nonStringArgs.map((e) => e.dataType), this.#dataBuffer, this.#indexBuffer, this.#options);
|
|
67
|
+
const argTypes = concreteArgs.map((e) => e.dataType === UnknownData ? e.value : e.dataType);
|
|
68
|
+
this.#logIdToMeta.set(id, {
|
|
69
|
+
op,
|
|
70
|
+
argTypes
|
|
71
|
+
});
|
|
72
|
+
return snip(stitch`${ctx.resolve(logFn).value}(${nonStringArgs})`, Void, "runtime");
|
|
73
|
+
}
|
|
74
|
+
get logResources() {
|
|
75
|
+
return this.#firstUnusedId === 1 ? void 0 : {
|
|
76
|
+
dataBuffer: this.#dataBuffer,
|
|
77
|
+
indexBuffer: this.#indexBuffer,
|
|
78
|
+
options: this.#options,
|
|
79
|
+
logIdToMeta: this.#logIdToMeta
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
export { LogGeneratorImpl, LogGeneratorNullImpl };
|
|
@@ -0,0 +1,223 @@
|
|
|
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
|
+
//#region src/tgsl/consoleLog/serializers.ts
|
|
11
|
+
const dataBlockIndex = privateVar(u32, 0).$name("dataBlockIndex");
|
|
12
|
+
const dataByteIndex = privateVar(u32, 0).$name("dataByteIndex");
|
|
13
|
+
const dataBufferSlot = slot().$name("dataBuffer");
|
|
14
|
+
const nextByteIndex = fn([], u32)`() {
|
|
15
|
+
let i = dataByteIndex;
|
|
16
|
+
dataByteIndex = dataByteIndex + 1u;
|
|
17
|
+
return i;
|
|
18
|
+
}`.$uses({ dataByteIndex }).$name("nextByteIndex");
|
|
19
|
+
const nextU32 = "dataBuffer[dataBlockIndex].serializedData[nextByteIndex()]";
|
|
20
|
+
const serializerMap = {
|
|
21
|
+
f32: fn([f32])`(n) {
|
|
22
|
+
${nextU32} = bitcast<u32>(n);
|
|
23
|
+
}`,
|
|
24
|
+
f16: fn([f16])`(n) {
|
|
25
|
+
${nextU32} = pack2x16float(vec2f(f32(n), 0.0));
|
|
26
|
+
}`,
|
|
27
|
+
i32: fn([i32])`(n) {
|
|
28
|
+
${nextU32} = bitcast<u32>(n);
|
|
29
|
+
}`,
|
|
30
|
+
u32: fn([u32])`(n) {
|
|
31
|
+
${nextU32} = n;
|
|
32
|
+
}`,
|
|
33
|
+
bool: fn([bool])`(b) {
|
|
34
|
+
${nextU32} = u32(b);
|
|
35
|
+
}`,
|
|
36
|
+
vec2f: fn([vec2f])`(v) {
|
|
37
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
38
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
39
|
+
}`,
|
|
40
|
+
vec3f: fn([vec3f])`(v) {
|
|
41
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
42
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
43
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
44
|
+
}`,
|
|
45
|
+
vec4f: fn([vec4f])`(v) {
|
|
46
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
47
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
48
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
49
|
+
${nextU32} = bitcast<u32>(v.w);
|
|
50
|
+
}`,
|
|
51
|
+
vec2h: fn([vec2h])`(v) {
|
|
52
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
53
|
+
}`,
|
|
54
|
+
vec3h: fn([vec3h])`(v) {
|
|
55
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
56
|
+
${nextU32} = pack2x16float(vec2f(f32(v.z), 0.0));
|
|
57
|
+
}`,
|
|
58
|
+
vec4h: fn([vec4h])`(v) {
|
|
59
|
+
${nextU32} = pack2x16float(vec2f(f32(v.x), f32(v.y)));
|
|
60
|
+
${nextU32} = pack2x16float(vec2f(f32(v.z), f32(v.w)));
|
|
61
|
+
}`,
|
|
62
|
+
vec2i: fn([vec2i])`(v) {
|
|
63
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
64
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
65
|
+
}`,
|
|
66
|
+
vec3i: fn([vec3i])`(v) {
|
|
67
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
68
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
69
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
70
|
+
}`,
|
|
71
|
+
vec4i: fn([vec4i])`(v) {
|
|
72
|
+
${nextU32} = bitcast<u32>(v.x);
|
|
73
|
+
${nextU32} = bitcast<u32>(v.y);
|
|
74
|
+
${nextU32} = bitcast<u32>(v.z);
|
|
75
|
+
${nextU32} = bitcast<u32>(v.w);
|
|
76
|
+
}`,
|
|
77
|
+
vec2u: fn([vec2u])`(v) {
|
|
78
|
+
${nextU32} = v.x;
|
|
79
|
+
${nextU32} = v.y;
|
|
80
|
+
}`,
|
|
81
|
+
vec3u: fn([vec3u])`(v) {
|
|
82
|
+
${nextU32} = v.x;
|
|
83
|
+
${nextU32} = v.y;
|
|
84
|
+
${nextU32} = v.z;
|
|
85
|
+
}`,
|
|
86
|
+
vec4u: fn([vec4u])`(v) {
|
|
87
|
+
${nextU32} = v.x;
|
|
88
|
+
${nextU32} = v.y;
|
|
89
|
+
${nextU32} = v.z;
|
|
90
|
+
${nextU32} = v.w;
|
|
91
|
+
}`,
|
|
92
|
+
"vec2<bool>": fn([vec2b])`(v) {
|
|
93
|
+
${nextU32} = u32(v.x);
|
|
94
|
+
${nextU32} = u32(v.y);
|
|
95
|
+
}`,
|
|
96
|
+
"vec3<bool>": fn([vec3b])`(v) {
|
|
97
|
+
${nextU32} = u32(v.x);
|
|
98
|
+
${nextU32} = u32(v.y);
|
|
99
|
+
${nextU32} = u32(v.z);
|
|
100
|
+
}`,
|
|
101
|
+
"vec4<bool>": fn([vec4b])`(v) {
|
|
102
|
+
${nextU32} = u32(v.x);
|
|
103
|
+
${nextU32} = u32(v.y);
|
|
104
|
+
${nextU32} = u32(v.z);
|
|
105
|
+
${nextU32} = u32(v.w);
|
|
106
|
+
}`,
|
|
107
|
+
mat2x2f: fn([mat2x2f])`(m) {
|
|
108
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
109
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
110
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
111
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
112
|
+
}`,
|
|
113
|
+
mat3x3f: fn([mat3x3f])`(m) {
|
|
114
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
115
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
116
|
+
${nextU32} = bitcast<u32>(m[0][2]);
|
|
117
|
+
${nextU32} = 0u;
|
|
118
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
119
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
120
|
+
${nextU32} = bitcast<u32>(m[1][2]);
|
|
121
|
+
${nextU32} = 0u;
|
|
122
|
+
${nextU32} = bitcast<u32>(m[2][0]);
|
|
123
|
+
${nextU32} = bitcast<u32>(m[2][1]);
|
|
124
|
+
${nextU32} = bitcast<u32>(m[2][2]);
|
|
125
|
+
${nextU32} = 0u;
|
|
126
|
+
}`,
|
|
127
|
+
mat4x4f: fn([mat4x4f])`(m) {
|
|
128
|
+
${nextU32} = bitcast<u32>(m[0][0]);
|
|
129
|
+
${nextU32} = bitcast<u32>(m[0][1]);
|
|
130
|
+
${nextU32} = bitcast<u32>(m[0][2]);
|
|
131
|
+
${nextU32} = bitcast<u32>(m[0][3]);
|
|
132
|
+
${nextU32} = bitcast<u32>(m[1][0]);
|
|
133
|
+
${nextU32} = bitcast<u32>(m[1][1]);
|
|
134
|
+
${nextU32} = bitcast<u32>(m[1][2]);
|
|
135
|
+
${nextU32} = bitcast<u32>(m[1][3]);
|
|
136
|
+
${nextU32} = bitcast<u32>(m[2][0]);
|
|
137
|
+
${nextU32} = bitcast<u32>(m[2][1]);
|
|
138
|
+
${nextU32} = bitcast<u32>(m[2][2]);
|
|
139
|
+
${nextU32} = bitcast<u32>(m[2][3]);
|
|
140
|
+
${nextU32} = bitcast<u32>(m[3][0]);
|
|
141
|
+
${nextU32} = bitcast<u32>(m[3][1]);
|
|
142
|
+
${nextU32} = bitcast<u32>(m[3][2]);
|
|
143
|
+
${nextU32} = bitcast<u32>(m[3][3]);
|
|
144
|
+
}`
|
|
145
|
+
};
|
|
146
|
+
for (const [name, serializer] of Object.entries(serializerMap)) serializer.$name(`serialize${name[0].toLocaleUpperCase()}${name.slice(1)}`).$uses({
|
|
147
|
+
dataBlockIndex,
|
|
148
|
+
nextByteIndex,
|
|
149
|
+
dataBuffer: dataBufferSlot
|
|
150
|
+
});
|
|
151
|
+
function generateHeader(argTypes) {
|
|
152
|
+
return `(${argTypes.map((_, i) => `_arg_${i}`).join(", ")})`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Returns a serializer TGPU function for a given WGSL data type.
|
|
156
|
+
* If the data type is a base type, one of the preexisting functions (with the `dataBufferSlot` filled) is returned.
|
|
157
|
+
* Otherwise, a new function is generated.
|
|
158
|
+
*
|
|
159
|
+
* @param dataType - The WGSL data type descriptor to return a serializer for
|
|
160
|
+
* @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
|
|
161
|
+
*/
|
|
162
|
+
function getSerializer(dataType, dataBuffer) {
|
|
163
|
+
const maybeSerializer = serializerMap[dataType.type];
|
|
164
|
+
if (maybeSerializer) return maybeSerializer.with(dataBufferSlot, dataBuffer);
|
|
165
|
+
if (isWgslStruct(dataType)) {
|
|
166
|
+
const props = Object.keys(dataType.propTypes);
|
|
167
|
+
const propsSerializer = createCompoundSerializer(Object.values(dataType.propTypes), dataBuffer);
|
|
168
|
+
return fn([dataType])`(arg) {\n propsSerializer(${props.map((prop) => `arg.${prop}`).join(", ")});\n}`.$uses({ propsSerializer }).$name(`${getName(dataType) ?? "struct"}Serializer`);
|
|
169
|
+
}
|
|
170
|
+
if (isWgslArray(dataType)) {
|
|
171
|
+
const elementType = dataType.elementType;
|
|
172
|
+
const length = dataType.elementCount;
|
|
173
|
+
const elementSerializer = getSerializer(elementType, dataBuffer);
|
|
174
|
+
return fn([dataType])`(arg) {\n${Array.from({ length }, (_, i) => ` elementSerializer(arg[${i}]);`).join("\n")}\n}`.$uses({ elementSerializer }).$name("arraySerializer");
|
|
175
|
+
}
|
|
176
|
+
throw new Error(`Cannot serialize data of type ${dataType.type}`);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Creates a compound serializer TGPU function that serializes multiple arguments of different types to the data buffer.
|
|
180
|
+
*
|
|
181
|
+
* @param dataTypes - Array of WGSL data types that define the types of arguments to be serialized
|
|
182
|
+
* @param dataBuffer - A buffer to store serialized log call data (a necessary external for the returned function)
|
|
183
|
+
*/
|
|
184
|
+
function createCompoundSerializer(dataTypes, dataBuffer) {
|
|
185
|
+
const usedSerializers = {};
|
|
186
|
+
return fn(dataTypes)`${generateHeader(dataTypes)} {\n${dataTypes.map((arg, i) => {
|
|
187
|
+
usedSerializers[`serializer${i}`] = getSerializer(arg, dataBuffer);
|
|
188
|
+
return ` serializer${i}(_arg_${i});`;
|
|
189
|
+
}).join("\n")}\n}`.$uses(usedSerializers).$name("compoundSerializer");
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Creates a TGPU function that serializes data to the log buffer.
|
|
193
|
+
*
|
|
194
|
+
* @param id - Identifier for this logging function instance
|
|
195
|
+
* @param dataTypes - Array of WGSL data types that will be logged by this function
|
|
196
|
+
* @param dataBuffer - Mutable buffer array to store serialized log call data
|
|
197
|
+
* @param indexBuffer - Atomic counter buffer to track the next available log data slot
|
|
198
|
+
* @param logOptions - Configuration options
|
|
199
|
+
*/
|
|
200
|
+
function createLoggingFunction(id, dataTypes, dataBuffer, indexBuffer, logOptions) {
|
|
201
|
+
const serializedSize = dataTypes.map(sizeOf).reduce((a, b) => a + b, 0);
|
|
202
|
+
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().`);
|
|
203
|
+
const compoundSerializer = createCompoundSerializer(dataTypes, dataBuffer).$name(`log${id}serializer`);
|
|
204
|
+
const header = generateHeader(dataTypes);
|
|
205
|
+
return fn(dataTypes)`${header} {
|
|
206
|
+
dataBlockIndex = atomicAdd(&indexBuffer, 1);
|
|
207
|
+
if (dataBlockIndex >= ${logOptions.logCountLimit}) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
dataBuffer[dataBlockIndex].id = ${id};
|
|
211
|
+
dataByteIndex = 0;
|
|
212
|
+
|
|
213
|
+
compoundSerializer${header};
|
|
214
|
+
}`.$uses({
|
|
215
|
+
indexBuffer,
|
|
216
|
+
dataBuffer,
|
|
217
|
+
dataBlockIndex,
|
|
218
|
+
dataByteIndex,
|
|
219
|
+
compoundSerializer
|
|
220
|
+
}).$name(`log${id}`);
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
export { createLoggingFunction };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { TgpuMutable } from "../../core/buffer/bufferShorthand.js";
|
|
2
|
+
import { AnyWgslData, Atomic, U32, WgslArray, WgslStruct } from "../../data/wgslTypes.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tgsl/consoleLog/types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Options for configuring GPU log generation.
|
|
7
|
+
*/
|
|
8
|
+
interface LogGeneratorOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The maximum number of logs that appear during a single draw/dispatch call.
|
|
11
|
+
* If this number is exceeded, a warning containing the total number of calls is logged and further logs are dropped.
|
|
12
|
+
* @default 64
|
|
13
|
+
*/
|
|
14
|
+
logCountLimit?: number;
|
|
15
|
+
/**
|
|
16
|
+
* The total number of bytes reserved for each log call.
|
|
17
|
+
* If this number is exceeded, an exception is thrown during resolution.
|
|
18
|
+
* @default 252
|
|
19
|
+
*/
|
|
20
|
+
logSizeLimit?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The prefix attached to each log call.
|
|
23
|
+
* @default ' GPU '
|
|
24
|
+
*/
|
|
25
|
+
messagePrefix?: string;
|
|
26
|
+
}
|
|
27
|
+
type SerializedLogCallData = WgslStruct<{
|
|
28
|
+
id: U32;
|
|
29
|
+
serializedData: WgslArray<U32>;
|
|
30
|
+
}>;
|
|
31
|
+
interface LogMeta {
|
|
32
|
+
op: SupportedLogOps;
|
|
33
|
+
argTypes: (string | AnyWgslData)[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The resources required for logging via console.log within TypeGPU functions.
|
|
37
|
+
*
|
|
38
|
+
* @property indexBuffer - A buffer used for indexing log entries. Needs to be cleared after each dispatch/draw.
|
|
39
|
+
* @property dataBuffer - A buffer containing an array of serialized log call data.
|
|
40
|
+
* @property options - The configuration options for the LogGenerator.
|
|
41
|
+
* @property logIdToMeta - A mapping from log identifiers to an object containing the corresponding log op and argument types.
|
|
42
|
+
*/
|
|
43
|
+
interface LogResources {
|
|
44
|
+
indexBuffer: TgpuMutable<Atomic<U32>>;
|
|
45
|
+
dataBuffer: TgpuMutable<WgslArray<SerializedLogCallData>>;
|
|
46
|
+
options: Required<LogGeneratorOptions>;
|
|
47
|
+
logIdToMeta: Map<number, LogMeta>;
|
|
48
|
+
}
|
|
49
|
+
declare const supportedLogOps: readonly ["log", "debug", "info", "warn", "error", "clear"];
|
|
50
|
+
type SupportedLogOps = (typeof supportedLogOps)[number];
|
|
51
|
+
//#endregion
|
|
52
|
+
export { LogGeneratorOptions, LogResources };
|