typegpu 0.11.5 → 0.11.7
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/bin.mjs +57 -0
- package/builtin.d.ts +5 -1
- package/builtin.js +2 -0
- package/core/buffer/buffer.js +1 -1
- package/core/buffer/bufferUsage.js +18 -14
- package/core/constant/tgpuConstant.js +6 -6
- package/core/function/comptime.js +8 -3
- package/core/function/createCallableSchema.js +7 -5
- package/core/function/dualImpl.js +2 -2
- package/core/function/fnCore.js +7 -8
- package/core/function/tgpuComputeFn.js +1 -1
- package/core/function/tgpuFn.js +3 -2
- package/core/pipeline/computePipeline.js +3 -3
- package/core/pipeline/renderPipeline.js +3 -3
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +1 -1
- package/core/resolve/externals.js +1 -1
- package/core/resolve/tgpuResolve.d.ts +2 -2
- package/core/root/init.js +1 -1
- package/core/slot/accessor.js +1 -1
- package/core/texture/texture.js +8 -2
- package/core/variable/tgpuVariable.js +8 -6
- package/core/vertexLayout/vertexLayout.js +1 -1
- package/data/alignmentOf.js +1 -1
- package/data/attributes.d.ts +1 -1
- package/data/dataIO.js +1 -1
- package/data/dataTypes.d.ts +0 -1
- package/data/dataTypes.js +2 -12
- package/data/index.js +6 -23
- package/data/ref.js +20 -7
- package/data/snippet.d.ts +2 -1
- package/data/snippet.js +37 -10
- package/errors.d.ts +1 -4
- package/errors.js +1 -7
- package/index.d.ts +3 -3
- package/index.js +2 -2
- package/indexNamedExports.d.ts +2 -2
- package/package.js +1 -1
- package/package.json +5 -4
- package/resolutionCtx.js +10 -17
- package/shared/meta.d.ts +6 -15
- package/shared/meta.js +45 -38
- package/shared/normalizeMetadata.d.ts +32 -0
- package/shared/normalizeMetadata.js +40 -0
- package/std/atomic.js +1 -1
- package/std/boolean.js +36 -5
- package/std/environment.d.ts +48 -0
- package/std/environment.js +57 -0
- package/std/extensions.d.ts +2 -2
- package/std/extensions.js +2 -2
- package/std/index.d.ts +3 -2
- package/std/index.js +5 -2
- package/tgpuBindGroupLayout.js +1 -1
- package/tgsl/accessIndex.js +8 -14
- package/tgsl/accessProp.js +16 -29
- package/tgsl/consoleLog/serializers.js +1 -1
- package/tgsl/conversion.js +3 -3
- package/tgsl/forOfUtils.js +8 -5
- package/tgsl/generationHelpers.js +10 -11
- package/tgsl/infixDispatch.js +53 -0
- package/tgsl/shaderGenerator.d.ts +4 -1
- package/tgsl/shaderGenerator_members.d.ts +20 -2
- package/tgsl/shaderGenerator_members.js +5 -1
- package/tgsl/shellless.js +4 -4
- package/tgsl/wgslGenerator.d.ts +15 -11
- package/tgsl/wgslGenerator.js +174 -97
- package/types.d.ts +6 -4
- package/wgslExtensions.d.ts +3 -3
- package/wgslExtensions.js +3 -3
package/std/boolean.js
CHANGED
|
@@ -2,8 +2,8 @@ import { isBool, isNumericSchema, isVec, isVecBool, isVecInstance } from "../dat
|
|
|
2
2
|
import { isSnippetNumeric, snip } from "../data/snippet.js";
|
|
3
3
|
import { stitch } from "../core/resolve/stitch.js";
|
|
4
4
|
import { unify } from "../tgsl/conversion.js";
|
|
5
|
-
import { bool, f32 } from "../data/numeric.js";
|
|
6
|
-
import { vec2b, vec3b, vec4b } from "../data/vector.js";
|
|
5
|
+
import { bool, f16, f32, i32, u32 } from "../data/numeric.js";
|
|
6
|
+
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
|
|
7
7
|
import { dualImpl } from "../core/function/dualImpl.js";
|
|
8
8
|
import { VectorOps } from "../data/vectorOps.js";
|
|
9
9
|
import { sub } from "./operators.js";
|
|
@@ -271,6 +271,28 @@ function cpuSelect(f, t, cond) {
|
|
|
271
271
|
if (typeof cond === "boolean") return cond ? t : f;
|
|
272
272
|
return VectorOps.select[f.kind](f, t, cond);
|
|
273
273
|
}
|
|
274
|
+
const validSelectBranchTypes = [
|
|
275
|
+
f32,
|
|
276
|
+
f16,
|
|
277
|
+
i32,
|
|
278
|
+
u32,
|
|
279
|
+
bool,
|
|
280
|
+
vec2f,
|
|
281
|
+
vec3f,
|
|
282
|
+
vec4f,
|
|
283
|
+
vec2h,
|
|
284
|
+
vec3h,
|
|
285
|
+
vec4h,
|
|
286
|
+
vec2i,
|
|
287
|
+
vec3i,
|
|
288
|
+
vec4i,
|
|
289
|
+
vec2u,
|
|
290
|
+
vec3u,
|
|
291
|
+
vec4u,
|
|
292
|
+
vec2b,
|
|
293
|
+
vec3b,
|
|
294
|
+
vec4b
|
|
295
|
+
];
|
|
274
296
|
/**
|
|
275
297
|
* Returns `t` if `cond` is `true`, and `f` otherwise.
|
|
276
298
|
* Component-wise if `cond` is a vector.
|
|
@@ -283,7 +305,7 @@ function cpuSelect(f, t, cond) {
|
|
|
283
305
|
const select = dualImpl({
|
|
284
306
|
name: "select",
|
|
285
307
|
signature: (f, t, cond) => {
|
|
286
|
-
const [uf, ut] = unify([f, t]) ?? [f, t];
|
|
308
|
+
const [uf, ut] = unify([f, t], validSelectBranchTypes) ?? [f, t];
|
|
287
309
|
return {
|
|
288
310
|
argTypes: [
|
|
289
311
|
uf,
|
|
@@ -294,8 +316,17 @@ const select = dualImpl({
|
|
|
294
316
|
};
|
|
295
317
|
},
|
|
296
318
|
normalImpl: cpuSelect,
|
|
297
|
-
codegenImpl: (
|
|
319
|
+
codegenImpl: (ctx, [f, t, cond]) => {
|
|
320
|
+
const result = stitch`select(${f}, ${t}, ${cond})`;
|
|
321
|
+
if (!validSelectBranchTypes.includes(f.dataType) || !validSelectBranchTypes.includes(t.dataType)) throw new Error(`'${result}' is invalid, std.select requires both branches to be either scalars or vectors.`);
|
|
322
|
+
if (f.dataType !== t.dataType) {
|
|
323
|
+
const fStr = ctx.resolve(f.dataType);
|
|
324
|
+
const tStr = ctx.resolve(t.dataType);
|
|
325
|
+
throw new Error(`'${result}' is invalid, std.select requires both branches to be the same type, got [${fStr.value}, ${tStr.value}].`);
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
298
329
|
});
|
|
299
330
|
|
|
300
331
|
//#endregion
|
|
301
|
-
export { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select };
|
|
332
|
+
export { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select, validSelectBranchTypes };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DualFn } from "../types.js";
|
|
2
|
+
import { TgpuComptime } from "../core/function/comptime.js";
|
|
3
|
+
import "../indexNamedExports.js";
|
|
4
|
+
|
|
5
|
+
//#region src/std/environment.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns `true` when the direct callee is being transpiled for GPU, otherwise `false`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const f = () => {
|
|
12
|
+
* 'use gpu';
|
|
13
|
+
* return isBeingTranspiled() ? 1 : 0;
|
|
14
|
+
* };
|
|
15
|
+
*
|
|
16
|
+
* f(); // returns 0, but resolved WGSL looks like this:
|
|
17
|
+
*
|
|
18
|
+
* fn f() -> i32 {
|
|
19
|
+
* return 1;
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* @note
|
|
23
|
+
* Inside `comptime`, `lazy` or `simulate`, it always returns `false`.
|
|
24
|
+
*/
|
|
25
|
+
declare const isBeingTranspiled: DualFn<() => boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Returns `wgsl` if invoked during the resolution process; otherwise, returns `undefined`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const f = () => {
|
|
31
|
+
* 'use gpu';
|
|
32
|
+
* return getTargetShaderLanguage() === 'wgsl';
|
|
33
|
+
* };
|
|
34
|
+
*
|
|
35
|
+
* f(); // returns false, but resolved WGSL looks like this:
|
|
36
|
+
*
|
|
37
|
+
* fn f() -> bool {
|
|
38
|
+
* return true;
|
|
39
|
+
* }
|
|
40
|
+
*
|
|
41
|
+
* @note
|
|
42
|
+
* Inside `lazy`, it always returns `wgsl`.
|
|
43
|
+
* Inside `simulate`, it always returns `undefined`.
|
|
44
|
+
* Inside `comptime`, it returns `wgsl` if called during the resolution process; otherwise, `undefined`.
|
|
45
|
+
*/
|
|
46
|
+
declare const getTargetShaderLanguage: TgpuComptime<() => string | undefined>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { getTargetShaderLanguage, isBeingTranspiled };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { $gpuCallable } from "../shared/symbols.js";
|
|
2
|
+
import { getExecMode, getResolutionCtx } from "../execMode.js";
|
|
3
|
+
import { coerceToSnippet } from "../tgsl/generationHelpers.js";
|
|
4
|
+
import { comptime } from "../core/function/comptime.js";
|
|
5
|
+
|
|
6
|
+
//#region src/std/environment.ts
|
|
7
|
+
const impl = (() => false);
|
|
8
|
+
impl.toString = () => "isBeingTranspiled";
|
|
9
|
+
impl[$gpuCallable] = { call(_ctx, _args) {
|
|
10
|
+
return coerceToSnippet(true);
|
|
11
|
+
} };
|
|
12
|
+
/**
|
|
13
|
+
* Returns `true` when the direct callee is being transpiled for GPU, otherwise `false`.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const f = () => {
|
|
17
|
+
* 'use gpu';
|
|
18
|
+
* return isBeingTranspiled() ? 1 : 0;
|
|
19
|
+
* };
|
|
20
|
+
*
|
|
21
|
+
* f(); // returns 0, but resolved WGSL looks like this:
|
|
22
|
+
*
|
|
23
|
+
* fn f() -> i32 {
|
|
24
|
+
* return 1;
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* @note
|
|
28
|
+
* Inside `comptime`, `lazy` or `simulate`, it always returns `false`.
|
|
29
|
+
*/
|
|
30
|
+
const isBeingTranspiled = impl;
|
|
31
|
+
/**
|
|
32
|
+
* Returns `wgsl` if invoked during the resolution process; otherwise, returns `undefined`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* const f = () => {
|
|
36
|
+
* 'use gpu';
|
|
37
|
+
* return getTargetShaderLanguage() === 'wgsl';
|
|
38
|
+
* };
|
|
39
|
+
*
|
|
40
|
+
* f(); // returns false, but resolved WGSL looks like this:
|
|
41
|
+
*
|
|
42
|
+
* fn f() -> bool {
|
|
43
|
+
* return true;
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* @note
|
|
47
|
+
* Inside `lazy`, it always returns `wgsl`.
|
|
48
|
+
* Inside `simulate`, it always returns `undefined`.
|
|
49
|
+
* Inside `comptime`, it returns `wgsl` if called during the resolution process; otherwise, `undefined`.
|
|
50
|
+
*/
|
|
51
|
+
const getTargetShaderLanguage = comptime((() => {
|
|
52
|
+
if (!getResolutionCtx()) return;
|
|
53
|
+
return getExecMode().type !== "simulate" ? "wgsl" : void 0;
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { getTargetShaderLanguage, isBeingTranspiled };
|
package/std/extensions.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WgslEnableExtension } from "../wgslExtensions.js";
|
|
2
2
|
import { TgpuComptime } from "../core/function/comptime.js";
|
|
3
3
|
import "../indexNamedExports.js";
|
|
4
4
|
|
|
5
5
|
//#region src/std/extensions.d.ts
|
|
6
|
-
declare const extensionEnabled: TgpuComptime<(extensionName:
|
|
6
|
+
declare const extensionEnabled: TgpuComptime<(extensionName: WgslEnableExtension) => boolean>;
|
|
7
7
|
//#endregion
|
|
8
8
|
export { extensionEnabled };
|
package/std/extensions.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getResolutionCtx } from "../execMode.js";
|
|
2
2
|
import { comptime } from "../core/function/comptime.js";
|
|
3
|
-
import {
|
|
3
|
+
import { wgslEnableExtensions } from "../wgslExtensions.js";
|
|
4
4
|
|
|
5
5
|
//#region src/std/extensions.ts
|
|
6
6
|
const extensionEnabled = comptime((extensionName) => {
|
|
7
7
|
const resolutionCtx = getResolutionCtx();
|
|
8
8
|
if (!resolutionCtx) throw new Error("Functions using `extensionEnabled` cannot be called directly. Either generate WGSL from them, or use tgpu['~unstable'].simulate(...)");
|
|
9
|
-
if (typeof extensionName !== "string" || !
|
|
9
|
+
if (typeof extensionName !== "string" || !wgslEnableExtensions.includes(extensionName)) throw new Error(`extensionEnabled has to be called with a string literal representing a valid WGSL extension name. Got: '${extensionName}'`);
|
|
10
10
|
return (resolutionCtx.enableExtensions ?? []).includes(extensionName);
|
|
11
11
|
});
|
|
12
12
|
|
package/std/index.d.ts
CHANGED
|
@@ -14,10 +14,11 @@ import { subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, sub
|
|
|
14
14
|
import { extensionEnabled } from "./extensions.js";
|
|
15
15
|
import { bitcastU32toF32, bitcastU32toI32 } from "./bitcast.js";
|
|
16
16
|
import { range } from "./range.js";
|
|
17
|
+
import { getTargetShaderLanguage, isBeingTranspiled } from "./environment.js";
|
|
17
18
|
|
|
18
19
|
//#region src/std/index.d.ts
|
|
19
20
|
declare namespace index_d_exports {
|
|
20
|
-
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
|
21
|
+
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, getTargetShaderLanguage, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isBeingTranspiled, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
|
21
22
|
}
|
|
22
23
|
//#endregion
|
|
23
|
-
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, index_d_exports, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
|
24
|
+
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, getTargetShaderLanguage, gt, identity2, identity3, identity4, index_d_exports, insertBits, inverseSqrt, isBeingTranspiled, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
package/std/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { add, bitShiftLeft, bitShiftRight, div, mod, mul, neg, sub } from "./ope
|
|
|
4
4
|
import { abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, clamp, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, distance, dot, dot4I8Packed, dot4U8Packed, exp, exp2, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, insertBits, inverseSqrt, ldexp, length, log, log2, max, min, mix, modf, normalize, pow, quantizeToF16, radians, reflect, refract, reverseBits, round, saturate, sign, sin, sinh, smoothstep, sqrt, step, tan, tanh, transpose, trunc } from "./numeric.js";
|
|
5
5
|
import { arrayLength } from "./array.js";
|
|
6
6
|
import { range } from "./range.js";
|
|
7
|
+
import { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select } from "./boolean.js";
|
|
7
8
|
import { bitcastU32toF32, bitcastU32toI32 } from "./bitcast.js";
|
|
8
9
|
import { pack2x16float, pack4x8unorm, unpack2x16float, unpack4x8unorm } from "./packing.js";
|
|
9
|
-
import { all, allEq, and, any, eq, ge, gt, isCloseTo, le, lt, ne, not, or, select } from "./boolean.js";
|
|
10
10
|
import { copy } from "./copy.js";
|
|
11
11
|
import { discard } from "./discard.js";
|
|
12
12
|
import { rotateX4, rotateY4, rotateZ4, scale4, translate4 } from "./matrix.js";
|
|
@@ -15,6 +15,7 @@ import { dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, fwidth, fwidthC
|
|
|
15
15
|
import { textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore } from "./texture.js";
|
|
16
16
|
import { subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor } from "./subgroup.js";
|
|
17
17
|
import { extensionEnabled } from "./extensions.js";
|
|
18
|
+
import { getTargetShaderLanguage, isBeingTranspiled } from "./environment.js";
|
|
18
19
|
|
|
19
20
|
//#region src/std/index.ts
|
|
20
21
|
var std_exports = /* @__PURE__ */ __export({
|
|
@@ -84,12 +85,14 @@ var std_exports = /* @__PURE__ */ __export({
|
|
|
84
85
|
fwidthCoarse: () => fwidthCoarse,
|
|
85
86
|
fwidthFine: () => fwidthFine,
|
|
86
87
|
ge: () => ge,
|
|
88
|
+
getTargetShaderLanguage: () => getTargetShaderLanguage,
|
|
87
89
|
gt: () => gt,
|
|
88
90
|
identity2: () => identity2,
|
|
89
91
|
identity3: () => identity3,
|
|
90
92
|
identity4: () => identity4,
|
|
91
93
|
insertBits: () => insertBits,
|
|
92
94
|
inverseSqrt: () => inverseSqrt,
|
|
95
|
+
isBeingTranspiled: () => isBeingTranspiled,
|
|
93
96
|
isCloseTo: () => isCloseTo,
|
|
94
97
|
ldexp: () => ldexp,
|
|
95
98
|
le: () => le,
|
|
@@ -181,4 +184,4 @@ var std_exports = /* @__PURE__ */ __export({
|
|
|
181
184
|
});
|
|
182
185
|
|
|
183
186
|
//#endregion
|
|
184
|
-
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, std_exports, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
|
187
|
+
export { abs, acos, acosh, add, all, allEq, and, any, arrayLength, asin, asinh, atan, atan2, atanh, atomicAdd, atomicAnd, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, bitShiftLeft, bitShiftRight, bitcastU32toF32, bitcastU32toI32, ceil, clamp, copy, cos, cosh, countLeadingZeros, countOneBits, countTrailingZeros, cross, degrees, determinant, discard, distance, div, dot, dot4I8Packed, dot4U8Packed, dpdx, dpdxCoarse, dpdxFine, dpdy, dpdyCoarse, dpdyFine, eq, exp, exp2, extensionEnabled, extractBits, faceForward, firstLeadingBit, firstTrailingBit, floor, fma, fract, frexp, fwidth, fwidthCoarse, fwidthFine, ge, getTargetShaderLanguage, gt, identity2, identity3, identity4, insertBits, inverseSqrt, isBeingTranspiled, isCloseTo, ldexp, le, length, log, log2, lt, max, min, mix, mod, modf, mul, ne, neg, normalize, not, or, pack2x16float, pack4x8unorm, pow, quantizeToF16, radians, range, reflect, refract, reverseBits, rotateX4, rotateY4, rotateZ4, rotationX4, rotationY4, rotationZ4, round, saturate, scale4, scaling4, select, sign, sin, sinh, smoothstep, sqrt, std_exports, step, storageBarrier, sub, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupXor, tan, tanh, textureBarrier, textureDimensions, textureGather, textureLoad, textureSample, textureSampleBaseClampToEdge, textureSampleBias, textureSampleCompare, textureSampleCompareLevel, textureSampleGrad, textureSampleLevel, textureStore, translate4, translation4, transpose, trunc, unpack2x16float, unpack4x8unorm, workgroupBarrier };
|
package/tgpuBindGroupLayout.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $gpuValueOf, $internal } from "./shared/symbols.js";
|
|
2
|
+
import { safeStringify } from "./shared/stringify.js";
|
|
2
3
|
import { getName, setName } from "./shared/meta.js";
|
|
3
4
|
import { NotUniformError } from "./errors.js";
|
|
4
|
-
import { safeStringify } from "./shared/stringify.js";
|
|
5
5
|
import { f32, i32, u32 } from "./data/numeric.js";
|
|
6
6
|
import { NotStorageError, isUsableAsStorage } from "./extension.js";
|
|
7
7
|
import { TgpuLaidOutBufferImpl, isUsableAsUniform } from "./core/buffer/bufferUsage.js";
|
package/tgsl/accessIndex.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
|
|
2
2
|
import { MatrixColumnsAccess, isDisarray } from "../data/dataTypes.js";
|
|
3
|
-
import {
|
|
3
|
+
import { snip } from "../data/snippet.js";
|
|
4
4
|
import { isKnownAtComptime } from "../types.js";
|
|
5
5
|
import { stitch } from "../core/resolve/stitch.js";
|
|
6
6
|
import { derefSnippet } from "../data/ref.js";
|
|
@@ -18,24 +18,18 @@ function accessIndex(target, indexArg) {
|
|
|
18
18
|
const index = typeof indexArg === "number" ? coerceToSnippet(indexArg) : indexArg;
|
|
19
19
|
if (isWgslArray(target.dataType) || isDisarray(target.dataType)) {
|
|
20
20
|
const elementType = target.dataType.elementType;
|
|
21
|
-
const isElementNatEph = isNaturallyEphemeral(elementType);
|
|
22
|
-
const isTargetEphemeral = isEphemeralSnippet(target);
|
|
23
|
-
const isIndexConstant = index.origin === "constant";
|
|
24
21
|
let origin;
|
|
25
|
-
if (target.origin === "constant-
|
|
26
|
-
else origin =
|
|
27
|
-
else
|
|
28
|
-
else if (!isTargetEphemeral && !isElementNatEph) origin = target.origin;
|
|
29
|
-
else if (isIndexConstant && target.origin === "constant") origin = "constant";
|
|
30
|
-
else origin = "runtime";
|
|
22
|
+
if (target.origin === "constant-immutable-def") origin = index.origin === "constant" || index.origin === "constant-immutable-def" ? "constant-immutable-def" : "runtime-immutable-def";
|
|
23
|
+
else if (target.origin === "constant") origin = index.origin === "constant" || index.origin === "constant-immutable-def" ? "constant" : "runtime";
|
|
24
|
+
else origin = target.origin;
|
|
31
25
|
if (target.value instanceof ArrayExpression && isKnownAtComptime(index)) return target.value.elements[index.value];
|
|
32
|
-
return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin);
|
|
26
|
+
return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, elementType, origin, target.possibleSideEffects || index.possibleSideEffects);
|
|
33
27
|
}
|
|
34
|
-
if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin
|
|
28
|
+
if (isVec(target.dataType)) return snip(isKnownAtComptime(target) && isKnownAtComptime(index) ? target.value[index.value] : stitch`${target}[${index}]`, target.dataType.primitive, target.origin, target.possibleSideEffects || index.possibleSideEffects);
|
|
35
29
|
if (isPtr(target.dataType)) return accessIndex(derefSnippet(target), index);
|
|
36
30
|
if (target.value instanceof MatrixColumnsAccess) {
|
|
37
31
|
const propType = indexableTypeToResult[target.value.matrix.dataType.type];
|
|
38
|
-
return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin);
|
|
32
|
+
return snip(stitch`${target.value.matrix}[${index}]`, propType, target.origin, target.possibleSideEffects || index.possibleSideEffects);
|
|
39
33
|
}
|
|
40
34
|
if (target.dataType.type in indexableTypeToResult) throw new Error("The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.");
|
|
41
35
|
if (isKnownAtComptime(target) && isKnownAtComptime(index)) return coerceToSnippet(target.value[index.value]);
|
package/tgsl/accessProp.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { isEphemeralSnippet, isSnippet, snip } from "../data/snippet.js";
|
|
1
|
+
import { isMat, isPtr, isVec, isWgslArray, isWgslStruct } from "../data/wgslTypes.js";
|
|
2
|
+
import { MatrixColumnsAccess, UnknownData, isUnstruct, undecorate } from "../data/dataTypes.js";
|
|
3
|
+
import { isSnippet, snip } from "../data/snippet.js";
|
|
5
4
|
import { isKnownAtComptime } from "../types.js";
|
|
6
5
|
import { stitch } from "../core/resolve/stitch.js";
|
|
7
6
|
import { derefSnippet } from "../data/ref.js";
|
|
8
|
-
import {
|
|
9
|
-
import { coerceToSnippet } from "./generationHelpers.js";
|
|
7
|
+
import { bool, f16, f32, i32, u32 } from "../data/numeric.js";
|
|
8
|
+
import { coerceToSnippet, numericLiteralToSnippet } from "./generationHelpers.js";
|
|
10
9
|
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../data/vector.js";
|
|
11
10
|
import { AutoStruct } from "../data/autoStruct.js";
|
|
12
11
|
import { EntryInputRouter } from "../core/function/entryInputRouter.js";
|
|
13
|
-
import {
|
|
12
|
+
import { InfixDispatch, infixOperators } from "./infixDispatch.js";
|
|
14
13
|
|
|
15
14
|
//#region src/tgsl/accessProp.ts
|
|
16
15
|
const infixKinds = [
|
|
@@ -30,15 +29,6 @@ const infixKinds = [
|
|
|
30
29
|
"mat3x3f",
|
|
31
30
|
"mat4x4f"
|
|
32
31
|
];
|
|
33
|
-
const infixOperators = {
|
|
34
|
-
add,
|
|
35
|
-
sub,
|
|
36
|
-
mul,
|
|
37
|
-
div,
|
|
38
|
-
mod,
|
|
39
|
-
bitShiftLeft,
|
|
40
|
-
bitShiftRight
|
|
41
|
-
};
|
|
42
32
|
const swizzleLenToType = {
|
|
43
33
|
f: {
|
|
44
34
|
1: f32,
|
|
@@ -74,23 +64,23 @@ const swizzleLenToType = {
|
|
|
74
64
|
function accessProp(target, propName) {
|
|
75
65
|
if (infixKinds.includes(target.dataType.type) && propName in infixOperators) {
|
|
76
66
|
const operator = infixOperators[propName];
|
|
77
|
-
return snip(new InfixDispatch(
|
|
67
|
+
return snip(new InfixDispatch(target, operator), UnknownData, target.origin, target.possibleSideEffects);
|
|
78
68
|
}
|
|
79
69
|
if (isWgslArray(target.dataType) && propName === "length") {
|
|
80
|
-
if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime");
|
|
81
|
-
return
|
|
70
|
+
if (target.dataType.elementCount === 0) return snip(stitch`arrayLength(&${target})`, u32, "runtime", target.possibleSideEffects);
|
|
71
|
+
return numericLiteralToSnippet(target.dataType.elementCount);
|
|
82
72
|
}
|
|
83
|
-
if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin);
|
|
73
|
+
if (isMat(target.dataType) && propName === "columns") return snip(new MatrixColumnsAccess(target), UnknownData, target.origin, target.possibleSideEffects);
|
|
84
74
|
if (isWgslStruct(target.dataType) || isUnstruct(target.dataType)) {
|
|
85
75
|
let propType = target.dataType.propTypes[propName];
|
|
86
76
|
if (!propType) return;
|
|
87
77
|
propType = undecorate(propType);
|
|
88
|
-
return snip(stitch`${target}.${propName}`, propType, target.origin
|
|
78
|
+
return snip(stitch`${target}.${propName}`, propType, target.origin, target.possibleSideEffects);
|
|
89
79
|
}
|
|
90
80
|
if (target.dataType instanceof AutoStruct) {
|
|
91
81
|
const result = target.dataType.accessProp(propName);
|
|
92
82
|
if (!result) return;
|
|
93
|
-
return snip(stitch`${target}.${result.prop}`, result.type, "argument");
|
|
83
|
+
return snip(stitch`${target}.${result.prop}`, result.type, "argument", target.possibleSideEffects);
|
|
94
84
|
}
|
|
95
85
|
if (target.dataType instanceof EntryInputRouter) {
|
|
96
86
|
const result = target.dataType.accessProp(propName);
|
|
@@ -104,19 +94,16 @@ function accessProp(target, propName) {
|
|
|
104
94
|
return accessProp(derefed, propName);
|
|
105
95
|
}
|
|
106
96
|
if (isVec(target.dataType)) {
|
|
107
|
-
if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant");
|
|
97
|
+
if (propName === "kind") return snip(target.dataType.type, UnknownData, "constant", false);
|
|
108
98
|
}
|
|
109
99
|
const propLength = propName.length;
|
|
110
|
-
if (isVec(target.dataType) && propLength >= 1 && propLength <= 4) {
|
|
111
|
-
const isXYZW = /^[xyzw]+$/.test(propName);
|
|
112
|
-
const isRGBA = /^[rgba]+$/.test(propName);
|
|
113
|
-
if (!isXYZW && !isRGBA) return;
|
|
100
|
+
if (isVec(target.dataType) && propLength >= 1 && propLength <= 4 && /^[xyzw]+$|^[rgba]+$/.test(propName)) {
|
|
114
101
|
const swizzleType = swizzleLenToType[target.dataType.type.includes("bool") ? "b" : target.dataType.type[4]][propLength];
|
|
115
102
|
if (!swizzleType) return;
|
|
116
|
-
return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType,
|
|
103
|
+
return snip(isKnownAtComptime(target) ? target.value[propName] : stitch`${target}.${propName}`, swizzleType, propLength === 1 ? target.origin : target.origin === "constant" || target.origin === "constant-immutable-def" ? "constant" : "runtime", target.possibleSideEffects);
|
|
117
104
|
}
|
|
118
105
|
if (isKnownAtComptime(target) || target.dataType === UnknownData) return coerceToSnippet(target.value[propName]);
|
|
119
106
|
}
|
|
120
107
|
|
|
121
108
|
//#endregion
|
|
122
|
-
export { accessProp
|
|
109
|
+
export { accessProp };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getName } from "../../shared/meta.js";
|
|
2
1
|
import { isWgslArray, isWgslStruct } from "../../data/wgslTypes.js";
|
|
2
|
+
import { getName } from "../../shared/meta.js";
|
|
3
3
|
import { bool, f16, f32, i32, u32 } from "../../data/numeric.js";
|
|
4
4
|
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u } from "../../data/vector.js";
|
|
5
5
|
import { sizeOf } from "../../data/sizeOf.js";
|
package/tgsl/conversion.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DEV, TEST } from "../shared/env.js";
|
|
2
2
|
import { isMat, isPtr, isVec } from "../data/wgslTypes.js";
|
|
3
|
+
import { safeStringify } from "../shared/stringify.js";
|
|
3
4
|
import { UnknownData, undecorate } from "../data/dataTypes.js";
|
|
4
|
-
import { snip } from "../data/snippet.js";
|
|
5
|
+
import { snip, withDataType } from "../data/snippet.js";
|
|
5
6
|
import { WgslTypeError, invariant } from "../errors.js";
|
|
6
7
|
import { stitch } from "../core/resolve/stitch.js";
|
|
7
8
|
import { RefOperator, derefSnippet } from "../data/ref.js";
|
|
8
9
|
import { schemaCallWrapperGPU } from "../data/schemaCallWrapper.js";
|
|
9
|
-
import { safeStringify } from "../shared/stringify.js";
|
|
10
10
|
import { assertExhaustive } from "../shared/utilityTypes.js";
|
|
11
11
|
|
|
12
12
|
//#region src/tgsl/conversion.ts
|
|
@@ -160,7 +160,7 @@ function getBestConversion(types, targetTypes) {
|
|
|
160
160
|
function applyActionToSnippet(ctx, snippet, action, targetType) {
|
|
161
161
|
if (action.action === "none") {
|
|
162
162
|
if (targetType === snippet.dataType) return snippet;
|
|
163
|
-
return
|
|
163
|
+
return withDataType(targetType, snippet);
|
|
164
164
|
}
|
|
165
165
|
switch (action.action) {
|
|
166
166
|
case "ref": return snip(new RefOperator(snippet, targetType), targetType, snippet.origin);
|
package/tgsl/forOfUtils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { $gpuCallable } from "../shared/symbols.js";
|
|
2
|
-
import { isPtr, isVec, isWgslArray } from "../data/wgslTypes.js";
|
|
2
|
+
import { isNaturallyEphemeral, isPtr, isVec, isWgslArray } from "../data/wgslTypes.js";
|
|
3
3
|
import { UnknownData } from "../data/dataTypes.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isAlias, snip } from "../data/snippet.js";
|
|
5
5
|
import { WgslTypeError, invariant } from "../errors.js";
|
|
6
6
|
import { stitch } from "../core/resolve/stitch.js";
|
|
7
7
|
import { createPtrFromOrigin, implicitFrom } from "../data/ptr.js";
|
|
@@ -13,17 +13,20 @@ import { isTgpuRange } from "../std/range.js";
|
|
|
13
13
|
|
|
14
14
|
//#region src/tgsl/forOfUtils.ts
|
|
15
15
|
function getLoopVarKind(elementSnippet) {
|
|
16
|
-
return elementSnippet.origin === "constant-
|
|
16
|
+
return elementSnippet.origin === "constant-immutable-def" ? "const" : "let";
|
|
17
17
|
}
|
|
18
18
|
function getElementSnippet(iterableSnippet, index) {
|
|
19
19
|
const elementSnippet = accessIndex(iterableSnippet, index);
|
|
20
20
|
if (!elementSnippet) throw new WgslTypeError("`for ... of ...` loops only support array or vector iterables");
|
|
21
21
|
return elementSnippet;
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Determines the type of the element as accessible inside of the `for .. of` loop body
|
|
25
|
+
*/
|
|
23
26
|
function getElementType(elementSnippet, iterableSnippet) {
|
|
24
27
|
let elementType = elementSnippet.dataType;
|
|
25
28
|
if (elementType === UnknownData) throw new WgslTypeError(stitch`The elements in iterable ${iterableSnippet} are of unknown type`);
|
|
26
|
-
if (
|
|
29
|
+
if (isNaturallyEphemeral(elementSnippet.dataType) || elementSnippet.origin === "runtime" || elementSnippet.origin === "constant" || elementSnippet.origin === "constant-immutable-def" || elementSnippet.origin === "runtime-immutable-def") return elementType;
|
|
27
30
|
if (!isPtr(elementType)) {
|
|
28
31
|
const ptrType = createPtrFromOrigin(elementSnippet.origin, concretize(elementType));
|
|
29
32
|
invariant(ptrType !== void 0, `Creating pointer type from origin ${elementSnippet.origin}`);
|
|
@@ -47,7 +50,7 @@ function getRangeSnippets(ctx, iterableSnippet, unroll = false) {
|
|
|
47
50
|
comparison: step < 0 ? ">" : "<"
|
|
48
51
|
};
|
|
49
52
|
}
|
|
50
|
-
if (!unroll &&
|
|
53
|
+
if (!unroll && !isAlias(iterableSnippet)) throw new Error(`\`for ... of ...\` loops only support std.range or iterables stored in variables.
|
|
51
54
|
-----
|
|
52
55
|
You can wrap iterable with \`tgpu.unroll(...)\`. If iterable is known at comptime, the loop will be unrolled.
|
|
53
56
|
-----`);
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { $internal, $resolve } from "../shared/symbols.js";
|
|
2
2
|
import { WORKAROUND_getSchema, isMatInstance, isNaturallyEphemeral, isVecInstance } from "../data/wgslTypes.js";
|
|
3
3
|
import { UnknownData } from "../data/dataTypes.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isAlias, isSnippet, snip } from "../data/snippet.js";
|
|
5
5
|
import { WgslTypeError } from "../errors.js";
|
|
6
6
|
import { getOwnSnippet } from "../types.js";
|
|
7
|
-
import { stitch } from "../core/resolve/stitch.js";
|
|
8
7
|
import { isRef } from "../data/ref.js";
|
|
9
8
|
import { abstractFloat, abstractInt, bool, f32, i32 } from "../data/numeric.js";
|
|
10
9
|
|
|
11
10
|
//#region src/tgsl/generationHelpers.ts
|
|
12
11
|
function numericLiteralToSnippet(value) {
|
|
13
|
-
if (value >= 2 ** 63 || value < -(2 ** 63)) return snip(value, abstractFloat, "constant");
|
|
12
|
+
if (value >= 2 ** 63 || value < -(2 ** 63)) return snip(value, abstractFloat, "constant", false);
|
|
14
13
|
if (Number.isInteger(value)) {
|
|
15
14
|
if (!Number.isSafeInteger(value)) console.warn(`The integer ${value} exceeds the safe integer range and may have lost precision.`);
|
|
16
|
-
return snip(value, abstractInt, "constant");
|
|
15
|
+
return snip(value, abstractInt, "constant", false);
|
|
17
16
|
}
|
|
18
|
-
return snip(value, abstractFloat, "constant");
|
|
17
|
+
return snip(value, abstractFloat, "constant", false);
|
|
19
18
|
}
|
|
20
19
|
function concretize(type) {
|
|
21
20
|
if (type.type === "abstractFloat") return f32;
|
|
@@ -30,11 +29,11 @@ function coerceToSnippet(value) {
|
|
|
30
29
|
if (isRef(value)) throw new Error("Cannot use refs (d.ref(...)) from the outer scope.");
|
|
31
30
|
const ownSnippet = getOwnSnippet(value);
|
|
32
31
|
if (ownSnippet) return ownSnippet;
|
|
33
|
-
if (isVecInstance(value) || isMatInstance(value)) return snip(value, WORKAROUND_getSchema(value), "constant");
|
|
34
|
-
if (typeof value === "string" || typeof value === "function" || typeof value === "object" || typeof value === "symbol" || typeof value === "undefined" || value === null) return snip(value, UnknownData, "constant");
|
|
32
|
+
if (isVecInstance(value) || isMatInstance(value)) return snip(value, WORKAROUND_getSchema(value), "constant", false);
|
|
33
|
+
if (typeof value === "string" || typeof value === "function" || typeof value === "object" || typeof value === "symbol" || typeof value === "undefined" || value === null) return snip(value, UnknownData, "constant", false);
|
|
35
34
|
if (typeof value === "number") return numericLiteralToSnippet(value);
|
|
36
|
-
if (typeof value === "boolean") return snip(value, bool, "constant");
|
|
37
|
-
return snip(value, UnknownData, "constant");
|
|
35
|
+
if (typeof value === "boolean") return snip(value, bool, "constant", false);
|
|
36
|
+
return snip(value, UnknownData, "constant", false);
|
|
38
37
|
}
|
|
39
38
|
/**
|
|
40
39
|
* Intermediate representation for WGSL array expressions.
|
|
@@ -53,12 +52,12 @@ var ArrayExpression = class {
|
|
|
53
52
|
return "ArrayExpression";
|
|
54
53
|
}
|
|
55
54
|
[$resolve](ctx) {
|
|
56
|
-
for (const elem of this.elements) if (elem
|
|
55
|
+
for (const elem of this.elements) if (isAlias(elem) && !isNaturallyEphemeral(elem.dataType)) {
|
|
57
56
|
const snippetStr = ctx.resolve(elem.value, elem.dataType).value;
|
|
58
57
|
const snippetType = ctx.resolve(concretize(elem.dataType)).value;
|
|
59
58
|
throw new WgslTypeError(`'${snippetStr}' reference cannot be used in an array constructor.\n-----\nTry '${snippetType}(${snippetStr})' or 'arrayOf(${snippetType}, count)([...])' to copy the value instead.\n-----`);
|
|
60
59
|
}
|
|
61
|
-
return
|
|
60
|
+
return ctx.gen.typeInstantiation(this.type, this.elements);
|
|
62
61
|
}
|
|
63
62
|
};
|
|
64
63
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { inCodegenMode } from "../execMode.js";
|
|
2
|
+
import { add, bitShiftLeft, bitShiftRight, div, mod, mul, sub } from "../std/operators.js";
|
|
3
|
+
|
|
4
|
+
//#region src/tgsl/infixDispatch.ts
|
|
5
|
+
const infixOperators = {
|
|
6
|
+
add,
|
|
7
|
+
sub,
|
|
8
|
+
mul,
|
|
9
|
+
div,
|
|
10
|
+
mod,
|
|
11
|
+
bitShiftLeft,
|
|
12
|
+
bitShiftRight
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* InfixDispatch is only used in codegen mode.
|
|
16
|
+
* `lhs` may either be Numeric or Snippet.
|
|
17
|
+
* @example
|
|
18
|
+
* const external = d.vec2u(1);
|
|
19
|
+
* const fn = () => {
|
|
20
|
+
* 'use gpu';
|
|
21
|
+
* external.mul(2); // lhs is Numeric
|
|
22
|
+
* d.vec2u(1).mul(2) // lhs is a snippet
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
var InfixDispatch = class {
|
|
26
|
+
lhs;
|
|
27
|
+
operator;
|
|
28
|
+
constructor(lhs, operator) {
|
|
29
|
+
this.lhs = lhs;
|
|
30
|
+
this.operator = operator;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
function isInfixDispatch(o) {
|
|
34
|
+
return o instanceof InfixDispatch;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* This function is used on vec/mat prototypes.
|
|
38
|
+
* This is done in runtime in order to avoid a circular dependency.
|
|
39
|
+
*/
|
|
40
|
+
function assignInfixOperator(base, operator, operatorSymbol) {
|
|
41
|
+
const opImpl = infixOperators[operator];
|
|
42
|
+
Object.defineProperty(base.prototype, operatorSymbol, { value: opImpl });
|
|
43
|
+
function jsInfixDispatchFor(arg) {
|
|
44
|
+
return opImpl(this, arg);
|
|
45
|
+
}
|
|
46
|
+
Object.defineProperty(base.prototype, operator, { get() {
|
|
47
|
+
if (inCodegenMode()) return new InfixDispatch(this, opImpl);
|
|
48
|
+
return jsInfixDispatchFor;
|
|
49
|
+
} });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
export { InfixDispatch, assignInfixOperator, infixOperators, isInfixDispatch };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedSnippet, Snippet } from "../data/snippet.js";
|
|
2
2
|
import { GenerationCtx } from "./generationHelpers.js";
|
|
3
|
-
import { FunctionDefinitionOptions } from "./shaderGenerator_members.js";
|
|
3
|
+
import { ConstantDefinitionOptions, FunctionDefinitionOptions, VariableDefinitionOptions } from "./shaderGenerator_members.js";
|
|
4
4
|
import { BaseData } from "../data/wgslTypes.js";
|
|
5
5
|
|
|
6
6
|
//#region src/tgsl/shaderGenerator.d.ts
|
|
@@ -13,9 +13,12 @@ import { BaseData } from "../data/wgslTypes.js";
|
|
|
13
13
|
*/
|
|
14
14
|
interface ShaderGenerator {
|
|
15
15
|
initGenerator(ctx: GenerationCtx): void;
|
|
16
|
+
declareGlobalConst(options: ConstantDefinitionOptions): ResolvedSnippet;
|
|
17
|
+
declareGlobalVar(options: VariableDefinitionOptions): ResolvedSnippet;
|
|
16
18
|
functionDefinition(options: FunctionDefinitionOptions): string;
|
|
17
19
|
typeInstantiation(schema: BaseData, args: readonly Snippet[]): ResolvedSnippet;
|
|
18
20
|
typeAnnotation(schema: BaseData): string;
|
|
21
|
+
numericLiteral(value: number, schema: BaseData): ResolvedSnippet;
|
|
19
22
|
}
|
|
20
23
|
//#endregion
|
|
21
24
|
export { ShaderGenerator };
|