typegpu 0.12.0 → 0.12.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/bin.mjs +28 -6
- package/core/buffer/buffer.js +4 -0
- package/core/pipeline/computePipeline.js +1 -1
- package/core/pipeline/renderPipeline.js +1 -1
- package/core/pipeline/webgpuLimitations.d.ts +10 -0
- package/core/pipeline/webgpuLimitations.js +81 -0
- package/data/array.d.ts +12 -1
- package/data/array.js +9 -0
- package/data/assignInfixOperators.d.ts +1 -0
- package/data/assignInfixOperators.js +14 -0
- package/data/generalizeFn.d.ts +25 -0
- package/data/generalizeFn.js +89 -0
- package/data/index.d.ts +1 -0
- package/data/index.js +2 -14
- package/data/numberOps.d.ts +1 -2
- package/data/numberOps.js +2 -8
- package/data/vectorOps.d.ts +5 -43
- package/data/vectorOps.js +7 -570
- package/indexNamedExports.d.ts +1 -1
- package/package.json +4 -2
- package/shared/meta.js +1 -1
- package/shared/symbols.js +1 -1
- package/std/boolean.d.ts +8 -8
- package/std/boolean.js +9 -13
- package/std/index.d.ts +1 -1
- package/std/index.js +1 -1
- package/std/numeric.d.ts +7 -0
- package/std/numeric.js +59 -124
- package/std/operators.js +12 -45
- package/std/texture.js +8 -5
- package/tgpuLogger.d.ts +1 -1
- package/tgpuLogger.js +1 -0
- package/tgsl/wgslGenerator.js +2 -1
- package/core/pipeline/limitsOverflow.d.ts +0 -2
- package/core/pipeline/limitsOverflow.js +0 -16
package/std/boolean.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const allEq: import("../types.ts").DualFn<(<T extends AnyVecInsta
|
|
|
16
16
|
* all(eq(vec4i(4, 3, 2, 1), vec4i(4, 3, 2, 1))) // returns true
|
|
17
17
|
* allEq(vec4i(4, 3, 2, 1), vec4i(4, 3, 2, 1)) // returns true
|
|
18
18
|
*/
|
|
19
|
-
export declare const eq: import("../types.ts").DualFn<(<T extends AnyVecInstance>(lhs: T, rhs: T) => T
|
|
19
|
+
export declare const eq: import("../types.ts").DualFn<(<T extends AnyVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
20
20
|
/**
|
|
21
21
|
* Checks **component-wise** whether `lhs != rhs`.
|
|
22
22
|
* This function does **not** return `bool`, for that use-case, wrap the result in `any`.
|
|
@@ -25,7 +25,7 @@ export declare const eq: import("../types.ts").DualFn<(<T extends AnyVecInstance
|
|
|
25
25
|
* ne(vec3u(0, 1, 2), vec3u(2, 1, 0)) // returns vec3b(true, false, true)
|
|
26
26
|
* any(ne(vec4i(4, 3, 2, 1), vec4i(4, 2, 2, 1))) // returns true
|
|
27
27
|
*/
|
|
28
|
-
export declare const ne: import("../types.ts").DualFn<(<T extends AnyVecInstance>(lhs: T, rhs: T) => T
|
|
28
|
+
export declare const ne: import("../types.ts").DualFn<(<T extends AnyVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
29
29
|
/**
|
|
30
30
|
* Checks **component-wise** whether `lhs < rhs`.
|
|
31
31
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`.
|
|
@@ -34,7 +34,7 @@ export declare const ne: import("../types.ts").DualFn<(<T extends AnyVecInstance
|
|
|
34
34
|
* lt(vec3u(0, 1, 2), vec3u(2, 1, 0)) // returns vec3b(true, false, false)
|
|
35
35
|
* all(lt(vec4i(1, 2, 3, 4), vec4i(2, 3, 4, 5))) // returns true
|
|
36
36
|
*/
|
|
37
|
-
export declare const lt: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => T
|
|
37
|
+
export declare const lt: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
38
38
|
/**
|
|
39
39
|
* Checks **component-wise** whether `lhs <= rhs`.
|
|
40
40
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`.
|
|
@@ -43,7 +43,7 @@ export declare const lt: import("../types.ts").DualFn<(<T extends AnyNumericVecI
|
|
|
43
43
|
* le(vec3u(0, 1, 2), vec3u(2, 1, 0)) // returns vec3b(true, true, false)
|
|
44
44
|
* all(le(vec4i(1, 2, 3, 4), vec4i(2, 3, 3, 5))) // returns true
|
|
45
45
|
*/
|
|
46
|
-
export declare const le: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => T
|
|
46
|
+
export declare const le: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<import("../data/generalizeFn.ts").ToBool<T>>)>;
|
|
47
47
|
/**
|
|
48
48
|
* Checks **component-wise** whether `lhs > rhs`.
|
|
49
49
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`.
|
|
@@ -52,7 +52,7 @@ export declare const le: import("../types.ts").DualFn<(<T extends AnyNumericVecI
|
|
|
52
52
|
* gt(vec3u(0, 1, 2), vec3u(2, 1, 0)) // returns vec3b(false, false, true)
|
|
53
53
|
* all(gt(vec4i(2, 3, 4, 5), vec4i(1, 2, 3, 4))) // returns true
|
|
54
54
|
*/
|
|
55
|
-
export declare const gt: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => T
|
|
55
|
+
export declare const gt: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<import("../data/generalizeFn.ts").ToBool<T>>)>;
|
|
56
56
|
/**
|
|
57
57
|
* Checks **component-wise** whether `lhs >= rhs`.
|
|
58
58
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`.
|
|
@@ -61,7 +61,7 @@ export declare const gt: import("../types.ts").DualFn<(<T extends AnyNumericVecI
|
|
|
61
61
|
* ge(vec3u(0, 1, 2), vec3u(2, 1, 0)) // returns vec3b(false, true, true)
|
|
62
62
|
* all(ge(vec4i(2, 2, 4, 5), vec4i(1, 2, 3, 4))) // returns true
|
|
63
63
|
*/
|
|
64
|
-
export declare const ge: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => T
|
|
64
|
+
export declare const ge: import("../types.ts").DualFn<(<T extends AnyNumericVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
65
65
|
declare function cpuNot(value: boolean): boolean;
|
|
66
66
|
declare function cpuNot<T extends AnyBooleanVecInstance>(value: T): T;
|
|
67
67
|
/**
|
|
@@ -79,14 +79,14 @@ export declare const not: import("../types.ts").DualFn<typeof cpuNot>;
|
|
|
79
79
|
* or(vec2b(false, true), vec2b(false, false)) // returns vec2b(false, true)
|
|
80
80
|
* or(vec3b(true, true, false), vec3b(false, true, false)) // returns vec3b(true, true, false)
|
|
81
81
|
*/
|
|
82
|
-
export declare const or: import("../types.ts").DualFn<(<T extends AnyBooleanVecInstance>(lhs: T, rhs: T) => T)>;
|
|
82
|
+
export declare const or: import("../types.ts").DualFn<(<T extends AnyBooleanVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
83
83
|
/**
|
|
84
84
|
* Returns **component-wise** logical `and` result.
|
|
85
85
|
* @example
|
|
86
86
|
* and(vec2b(false, true), vec2b(true, true)) // returns vec2b(false, true)
|
|
87
87
|
* and(vec3b(true, true, false), vec3b(false, true, false)) // returns vec3b(false, true, false)
|
|
88
88
|
*/
|
|
89
|
-
export declare const and: import("../types.ts").DualFn<(<T extends AnyBooleanVecInstance>(lhs: T, rhs: T) => T)>;
|
|
89
|
+
export declare const and: import("../types.ts").DualFn<(<T extends AnyBooleanVecInstance>(lhs: T, rhs: T) => import("../data/generalizeFn.ts").ToBool<T>)>;
|
|
90
90
|
/**
|
|
91
91
|
* Returns `true` if each component of `value` is true.
|
|
92
92
|
* @example
|
package/std/boolean.js
CHANGED
|
@@ -4,11 +4,11 @@ import { bool, f16, f32, i32, u32 } from "../data/numeric.js";
|
|
|
4
4
|
import { isSnippetNumeric, snip } from "../data/snippet.js";
|
|
5
5
|
import { vec2b, vec2f, vec2h, vec2i, vec2u, vec3b, vec3f, vec3h, vec3i, vec3u, vec4b, vec4f, vec4h, vec4i, vec4u, } from "../data/vector.js";
|
|
6
6
|
import { VectorOps } from "../data/vectorOps.js";
|
|
7
|
-
import {
|
|
7
|
+
import { generalizeBoolFn, generalizeFn } from "../data/generalizeFn.js";
|
|
8
|
+
import { isBool, isVecBool, isVecBoolInstance, } from "../data/wgslTypes.js";
|
|
8
9
|
import { SignatureNotSupportedError } from "../errors.js";
|
|
9
10
|
import { unify } from "../tgsl/conversion.js";
|
|
10
11
|
import { cpuCopy } from "./copy.js";
|
|
11
|
-
import { sub } from "./operators.js";
|
|
12
12
|
function correspondingBooleanVectorSchema(dataType) {
|
|
13
13
|
if (dataType.type.includes('2')) {
|
|
14
14
|
return vec2b;
|
|
@@ -33,7 +33,7 @@ export const allEq = dualImpl({
|
|
|
33
33
|
codegenImpl: (_ctx, [lhs, rhs]) => stitch `all(${lhs} == ${rhs})`,
|
|
34
34
|
sideEffects: false,
|
|
35
35
|
});
|
|
36
|
-
const cpuEq = (lhs, rhs) =>
|
|
36
|
+
const cpuEq = (lhs, rhs) => generalizeBoolFn((a, b) => a === b, [lhs, rhs]);
|
|
37
37
|
/**
|
|
38
38
|
* Checks **component-wise** whether `lhs == rhs`.
|
|
39
39
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`, or use `allEq`.
|
|
@@ -71,7 +71,7 @@ export const ne = dualImpl({
|
|
|
71
71
|
codegenImpl: (_ctx, [lhs, rhs]) => stitch `(${lhs} != ${rhs})`,
|
|
72
72
|
sideEffects: false,
|
|
73
73
|
});
|
|
74
|
-
const cpuLt = (lhs, rhs) =>
|
|
74
|
+
const cpuLt = (lhs, rhs) => generalizeBoolFn((a, b) => a < b, [lhs, rhs]);
|
|
75
75
|
/**
|
|
76
76
|
* Checks **component-wise** whether `lhs < rhs`.
|
|
77
77
|
* This function does **not** return `bool`, for that use-case, wrap the result in `all`.
|
|
@@ -183,7 +183,7 @@ export const not = dualImpl({
|
|
|
183
183
|
codegenImpl: (_ctx, [arg]) => stitch `!(${arg})`,
|
|
184
184
|
sideEffects: false,
|
|
185
185
|
});
|
|
186
|
-
const cpuOr = (lhs, rhs) =>
|
|
186
|
+
const cpuOr = (lhs, rhs) => generalizeBoolFn((a, b) => a || b, [lhs, rhs]);
|
|
187
187
|
/**
|
|
188
188
|
* Returns **component-wise** logical `or` result.
|
|
189
189
|
* @example
|
|
@@ -257,13 +257,8 @@ export const isCloseTo = dualImpl({
|
|
|
257
257
|
}),
|
|
258
258
|
// CPU implementation
|
|
259
259
|
normalImpl: (lhs, rhs, precision = 0.01) => {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
if (isVecInstance(lhs) && isVecInstance(rhs)) {
|
|
264
|
-
return VectorOps.isCloseToZero[lhs.kind](sub(lhs, rhs), precision);
|
|
265
|
-
}
|
|
266
|
-
return false;
|
|
260
|
+
const componentResult = generalizeBoolFn((lhs, rhs) => Math.abs(lhs - rhs) < precision, [lhs, rhs]);
|
|
261
|
+
return typeof componentResult === 'boolean' ? componentResult : all(componentResult);
|
|
267
262
|
},
|
|
268
263
|
// GPU implementation
|
|
269
264
|
codegenImpl: (_ctx, [lhs, rhs, precision = snip(0.01, f32, /* origin */ 'constant', false)]) => {
|
|
@@ -283,7 +278,8 @@ function cpuSelect(f, t, cond) {
|
|
|
283
278
|
if (typeof cond === 'boolean') {
|
|
284
279
|
return cpuCopy(cond ? t : f);
|
|
285
280
|
}
|
|
286
|
-
|
|
281
|
+
// generalizeFn will handle this fine, it just has no mixed type overload.
|
|
282
|
+
return generalizeFn((f, t, c) => (c ? t : f), [f, t, cond]);
|
|
287
283
|
}
|
|
288
284
|
export const validSelectBranchTypes = [
|
|
289
285
|
f32,
|
package/std/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { copy } from './copy.ts';
|
|
5
5
|
export { discard } from './discard.ts';
|
|
6
|
-
export { 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.ts';
|
|
6
|
+
export { 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, intdiv, } from './numeric.ts';
|
|
7
7
|
export { add, bitShiftLeft, bitShiftRight, div, mod, mul, neg, sub } from './operators.ts';
|
|
8
8
|
export { rotateX4, rotateY4, rotateZ4, scale4, translate4 } from './matrix.ts';
|
|
9
9
|
export { identity2, identity3, identity4, rotationX4, rotationY4, rotationZ4, scaling4, translation4, } from '../data/matrix.ts';
|
package/std/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// NOTE: This is a barrel file, internal files should not import things from this file
|
|
5
5
|
export { copy } from "./copy.js";
|
|
6
6
|
export { discard } from "./discard.js";
|
|
7
|
-
export { 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";
|
|
7
|
+
export { 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, intdiv, } from "./numeric.js";
|
|
8
8
|
export { add, bitShiftLeft, bitShiftRight, div, mod, mul, neg, sub } from "./operators.js";
|
|
9
9
|
export { rotateX4, rotateY4, rotateZ4, scale4, translate4 } from "./matrix.js";
|
|
10
10
|
export { identity2, identity3, identity4, rotationX4, rotationY4, rotationZ4, scaling4, translation4, } from "../data/matrix.js";
|
package/std/numeric.d.ts
CHANGED
|
@@ -248,4 +248,11 @@ export declare const transpose: import("../types.ts").DualFn<typeof cpuTranspose
|
|
|
248
248
|
declare function cpuTrunc(value: number): number;
|
|
249
249
|
declare function cpuTrunc<T extends AnyFloatVecInstance>(value: T): T;
|
|
250
250
|
export declare const trunc: import("../types.ts").DualFn<typeof cpuTrunc>;
|
|
251
|
+
declare function cpuIntdiv(lhs: number, rhs: number): number;
|
|
252
|
+
/**
|
|
253
|
+
* Performs integer division on the passed in scalars.
|
|
254
|
+
* Equivalent to `trunc(trunc(lhs) / trunc(rhs))`. Coerces both
|
|
255
|
+
* arguments to integers if they're floating point.
|
|
256
|
+
*/
|
|
257
|
+
export declare const intdiv: import("../types.ts").DualFn<typeof cpuIntdiv>;
|
|
251
258
|
export {};
|
package/std/numeric.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { dualImpl, MissingCpuImplError } from "../core/function/dualImpl.js";
|
|
2
2
|
import { stitch } from "../core/resolve/stitch.js";
|
|
3
3
|
import { mat2x2f, mat3x3f, mat4x4f } from "../data/matrix.js";
|
|
4
|
-
import { smoothstepScalar } from "../data/numberOps.js";
|
|
4
|
+
import { clampScalar, smoothstepScalar } from "../data/numberOps.js";
|
|
5
5
|
import { abstractFloat, abstractInt, f16, f32, i32, u32 } from "../data/numeric.js";
|
|
6
6
|
import { abstruct } from "../data/struct.js";
|
|
7
7
|
import { vec2f, vec2h, vec2i, vec2u, vec3f, vec3h, vec3i, vec3u, vec4f, vec4h, vec4i, vec4u, } from "../data/vector.js";
|
|
8
8
|
import { VectorOps } from "../data/vectorOps.js";
|
|
9
|
-
import {
|
|
9
|
+
import { generalizeFn, upCast } from "../data/generalizeFn.js";
|
|
10
|
+
import { isHalfPrecisionSchema, WORKAROUND_getSchema, } from "../data/wgslTypes.js";
|
|
10
11
|
import { SignatureNotSupportedError } from "../errors.js";
|
|
11
12
|
import { assertExhaustive } from "../shared/utilityTypes.js";
|
|
12
13
|
import { unify } from "../tgsl/conversion.js";
|
|
@@ -60,10 +61,7 @@ const anyConcreteIntegerPrimitive = [i32, u32];
|
|
|
60
61
|
const anyConcreteIntegerVec = [vec2i, vec3i, vec4i, vec2u, vec3u, vec4u];
|
|
61
62
|
const anyConcreteInteger = [...anyConcreteIntegerPrimitive, ...anyConcreteIntegerVec];
|
|
62
63
|
function cpuAbs(value) {
|
|
63
|
-
|
|
64
|
-
return Math.abs(value);
|
|
65
|
-
}
|
|
66
|
-
return VectorOps.abs[value.kind](value);
|
|
64
|
+
return generalizeFn(Math.abs, [value]);
|
|
67
65
|
}
|
|
68
66
|
export const abs = dualImpl({
|
|
69
67
|
name: 'abs',
|
|
@@ -73,10 +71,7 @@ export const abs = dualImpl({
|
|
|
73
71
|
sideEffects: false,
|
|
74
72
|
});
|
|
75
73
|
function cpuAcos(value) {
|
|
76
|
-
|
|
77
|
-
return Math.acos(value);
|
|
78
|
-
}
|
|
79
|
-
return VectorOps.acos[value.kind](value);
|
|
74
|
+
return generalizeFn(Math.acos, [value]);
|
|
80
75
|
}
|
|
81
76
|
export const acos = dualImpl({
|
|
82
77
|
name: 'acos',
|
|
@@ -86,10 +81,7 @@ export const acos = dualImpl({
|
|
|
86
81
|
sideEffects: false,
|
|
87
82
|
});
|
|
88
83
|
function cpuAcosh(value) {
|
|
89
|
-
|
|
90
|
-
return Math.acosh(value);
|
|
91
|
-
}
|
|
92
|
-
return VectorOps.acosh[value.kind](value);
|
|
84
|
+
return generalizeFn(Math.acosh, [value]);
|
|
93
85
|
}
|
|
94
86
|
export const acosh = dualImpl({
|
|
95
87
|
name: 'acosh',
|
|
@@ -99,10 +91,7 @@ export const acosh = dualImpl({
|
|
|
99
91
|
sideEffects: false,
|
|
100
92
|
});
|
|
101
93
|
function cpuAsin(value) {
|
|
102
|
-
|
|
103
|
-
return Math.asin(value);
|
|
104
|
-
}
|
|
105
|
-
return VectorOps.asin[value.kind](value);
|
|
94
|
+
return generalizeFn(Math.asin, [value]);
|
|
106
95
|
}
|
|
107
96
|
export const asin = dualImpl({
|
|
108
97
|
name: 'asin',
|
|
@@ -112,10 +101,7 @@ export const asin = dualImpl({
|
|
|
112
101
|
sideEffects: false,
|
|
113
102
|
});
|
|
114
103
|
function cpuAsinh(value) {
|
|
115
|
-
|
|
116
|
-
return Math.asinh(value);
|
|
117
|
-
}
|
|
118
|
-
return VectorOps.asinh[value.kind](value);
|
|
104
|
+
return generalizeFn(Math.asinh, [value]);
|
|
119
105
|
}
|
|
120
106
|
export const asinh = dualImpl({
|
|
121
107
|
name: 'asinh',
|
|
@@ -125,10 +111,7 @@ export const asinh = dualImpl({
|
|
|
125
111
|
sideEffects: false,
|
|
126
112
|
});
|
|
127
113
|
function cpuAtan(value) {
|
|
128
|
-
|
|
129
|
-
return Math.atan(value);
|
|
130
|
-
}
|
|
131
|
-
return VectorOps.atan[value.kind](value);
|
|
114
|
+
return generalizeFn(Math.atan, [value]);
|
|
132
115
|
}
|
|
133
116
|
export const atan = dualImpl({
|
|
134
117
|
name: 'atan',
|
|
@@ -138,10 +121,7 @@ export const atan = dualImpl({
|
|
|
138
121
|
sideEffects: false,
|
|
139
122
|
});
|
|
140
123
|
function cpuAtanh(value) {
|
|
141
|
-
|
|
142
|
-
return Math.atanh(value);
|
|
143
|
-
}
|
|
144
|
-
return VectorOps.atanh[value.kind](value);
|
|
124
|
+
return generalizeFn(Math.atanh, [value]);
|
|
145
125
|
}
|
|
146
126
|
export const atanh = dualImpl({
|
|
147
127
|
name: 'atanh',
|
|
@@ -151,10 +131,7 @@ export const atanh = dualImpl({
|
|
|
151
131
|
sideEffects: false,
|
|
152
132
|
});
|
|
153
133
|
function cpuAtan2(y, x) {
|
|
154
|
-
|
|
155
|
-
return Math.atan2(y, x);
|
|
156
|
-
}
|
|
157
|
-
return VectorOps.atan2[y.kind](y, x);
|
|
134
|
+
return generalizeFn(Math.atan2, [y, x]);
|
|
158
135
|
}
|
|
159
136
|
export const atan2 = dualImpl({
|
|
160
137
|
name: 'atan2',
|
|
@@ -164,10 +141,7 @@ export const atan2 = dualImpl({
|
|
|
164
141
|
sideEffects: false,
|
|
165
142
|
});
|
|
166
143
|
function cpuCeil(value) {
|
|
167
|
-
|
|
168
|
-
return Math.ceil(value);
|
|
169
|
-
}
|
|
170
|
-
return VectorOps.ceil[value.kind](value);
|
|
144
|
+
return generalizeFn(Math.ceil, [value]);
|
|
171
145
|
}
|
|
172
146
|
export const ceil = dualImpl({
|
|
173
147
|
name: 'ceil',
|
|
@@ -177,10 +151,7 @@ export const ceil = dualImpl({
|
|
|
177
151
|
sideEffects: false,
|
|
178
152
|
});
|
|
179
153
|
function cpuClamp(value, low, high) {
|
|
180
|
-
|
|
181
|
-
return Math.min(Math.max(low, value), high);
|
|
182
|
-
}
|
|
183
|
-
return VectorOps.clamp[value.kind](value, low, high);
|
|
154
|
+
return generalizeFn(clampScalar, [value, low, high]);
|
|
184
155
|
}
|
|
185
156
|
export const clamp = dualImpl({
|
|
186
157
|
name: 'clamp',
|
|
@@ -190,10 +161,7 @@ export const clamp = dualImpl({
|
|
|
190
161
|
sideEffects: false,
|
|
191
162
|
});
|
|
192
163
|
function cpuCos(value) {
|
|
193
|
-
|
|
194
|
-
return Math.cos(value);
|
|
195
|
-
}
|
|
196
|
-
return VectorOps.cos[value.kind](value);
|
|
164
|
+
return generalizeFn(Math.cos, [value]);
|
|
197
165
|
}
|
|
198
166
|
export const cos = dualImpl({
|
|
199
167
|
name: 'cos',
|
|
@@ -203,10 +171,7 @@ export const cos = dualImpl({
|
|
|
203
171
|
sideEffects: false,
|
|
204
172
|
});
|
|
205
173
|
function cpuCosh(value) {
|
|
206
|
-
|
|
207
|
-
return Math.cosh(value);
|
|
208
|
-
}
|
|
209
|
-
return VectorOps.cosh[value.kind](value);
|
|
174
|
+
return generalizeFn(Math.cosh, [value]);
|
|
210
175
|
}
|
|
211
176
|
export const cosh = dualImpl({
|
|
212
177
|
name: 'cosh',
|
|
@@ -324,10 +289,7 @@ export const dot4I8Packed = dualImpl({
|
|
|
324
289
|
sideEffects: false,
|
|
325
290
|
});
|
|
326
291
|
function cpuExp(value) {
|
|
327
|
-
|
|
328
|
-
return Math.exp(value);
|
|
329
|
-
}
|
|
330
|
-
return VectorOps.exp[value.kind](value);
|
|
292
|
+
return generalizeFn(Math.exp, [value]);
|
|
331
293
|
}
|
|
332
294
|
export const exp = dualImpl({
|
|
333
295
|
name: 'exp',
|
|
@@ -337,10 +299,7 @@ export const exp = dualImpl({
|
|
|
337
299
|
sideEffects: false,
|
|
338
300
|
});
|
|
339
301
|
function cpuExp2(value) {
|
|
340
|
-
|
|
341
|
-
return (2 ** value);
|
|
342
|
-
}
|
|
343
|
-
return VectorOps.exp2[value.kind](value);
|
|
302
|
+
return generalizeFn((val) => 2 ** val, [value]);
|
|
344
303
|
}
|
|
345
304
|
export const exp2 = dualImpl({
|
|
346
305
|
name: 'exp2',
|
|
@@ -396,10 +355,7 @@ export const firstTrailingBit = dualImpl({
|
|
|
396
355
|
sideEffects: false,
|
|
397
356
|
});
|
|
398
357
|
function cpuFloor(value) {
|
|
399
|
-
|
|
400
|
-
return Math.floor(value);
|
|
401
|
-
}
|
|
402
|
-
return VectorOps.floor[value.kind](value);
|
|
358
|
+
return generalizeFn(Math.floor, [value]);
|
|
403
359
|
}
|
|
404
360
|
export const floor = dualImpl({
|
|
405
361
|
name: 'floor',
|
|
@@ -422,10 +378,7 @@ export const fma = dualImpl({
|
|
|
422
378
|
sideEffects: false,
|
|
423
379
|
});
|
|
424
380
|
function cpuFract(value) {
|
|
425
|
-
|
|
426
|
-
return (value - Math.floor(value));
|
|
427
|
-
}
|
|
428
|
-
return VectorOps.fract[value.kind](value);
|
|
381
|
+
return generalizeFn((value) => value - Math.floor(value), [value]);
|
|
429
382
|
}
|
|
430
383
|
export const fract = dualImpl({
|
|
431
384
|
name: 'fract',
|
|
@@ -542,10 +495,7 @@ export const length = dualImpl({
|
|
|
542
495
|
sideEffects: false,
|
|
543
496
|
});
|
|
544
497
|
function cpuLog(value) {
|
|
545
|
-
|
|
546
|
-
return Math.log(value);
|
|
547
|
-
}
|
|
548
|
-
return VectorOps.log[value.kind](value);
|
|
498
|
+
return generalizeFn(Math.log, [value]);
|
|
549
499
|
}
|
|
550
500
|
export const log = dualImpl({
|
|
551
501
|
name: 'log',
|
|
@@ -555,10 +505,7 @@ export const log = dualImpl({
|
|
|
555
505
|
sideEffects: false,
|
|
556
506
|
});
|
|
557
507
|
function cpuLog2(value) {
|
|
558
|
-
|
|
559
|
-
return Math.log2(value);
|
|
560
|
-
}
|
|
561
|
-
return VectorOps.log2[value.kind](value);
|
|
508
|
+
return generalizeFn(Math.log2, [value]);
|
|
562
509
|
}
|
|
563
510
|
export const log2 = dualImpl({
|
|
564
511
|
name: 'log2',
|
|
@@ -568,10 +515,7 @@ export const log2 = dualImpl({
|
|
|
568
515
|
sideEffects: false,
|
|
569
516
|
});
|
|
570
517
|
function cpuMax(a, b) {
|
|
571
|
-
|
|
572
|
-
return Math.max(a, b);
|
|
573
|
-
}
|
|
574
|
-
return VectorOps.max[a.kind](a, b);
|
|
518
|
+
return generalizeFn(Math.max, [a, b]);
|
|
575
519
|
}
|
|
576
520
|
export const max = dualImpl({
|
|
577
521
|
name: 'max',
|
|
@@ -581,10 +525,7 @@ export const max = dualImpl({
|
|
|
581
525
|
sideEffects: false,
|
|
582
526
|
});
|
|
583
527
|
function cpuMin(a, b) {
|
|
584
|
-
|
|
585
|
-
return Math.min(a, b);
|
|
586
|
-
}
|
|
587
|
-
return VectorOps.min[a.kind](a, b);
|
|
528
|
+
return generalizeFn(Math.min, [a, b]);
|
|
588
529
|
}
|
|
589
530
|
export const min = dualImpl({
|
|
590
531
|
name: 'min',
|
|
@@ -594,16 +535,7 @@ export const min = dualImpl({
|
|
|
594
535
|
sideEffects: false,
|
|
595
536
|
});
|
|
596
537
|
function cpuMix(e1, e2, e3) {
|
|
597
|
-
|
|
598
|
-
if (typeof e3 !== 'number' || typeof e2 !== 'number') {
|
|
599
|
-
throw new Error('When e1 and e2 are numbers, the blend factor must be a number.');
|
|
600
|
-
}
|
|
601
|
-
return (e1 * (1 - e3) + e2 * e3);
|
|
602
|
-
}
|
|
603
|
-
if (typeof e1 === 'number' || typeof e2 === 'number') {
|
|
604
|
-
throw new Error('e1 and e2 need to both be vectors of the same kind.');
|
|
605
|
-
}
|
|
606
|
-
return VectorOps.mix[e1.kind](e1, e2, e3);
|
|
538
|
+
return generalizeFn((e1, e2, e3) => e1 * (1 - e3) + e2 * e3, [e1, ...upCast([e2, e3])]);
|
|
607
539
|
}
|
|
608
540
|
export const mix = dualImpl({
|
|
609
541
|
name: 'mix',
|
|
@@ -655,18 +587,15 @@ export const modf = dualImpl({
|
|
|
655
587
|
export const normalize = dualImpl({
|
|
656
588
|
name: 'normalize',
|
|
657
589
|
signature: unifyRestrictedSignature(anyFloatVec),
|
|
658
|
-
normalImpl: (v) =>
|
|
590
|
+
normalImpl: (v) => {
|
|
591
|
+
const len = length(v);
|
|
592
|
+
return generalizeFn((e) => e / len, [v]);
|
|
593
|
+
},
|
|
659
594
|
codegenImpl: (_ctx, [value]) => stitch `normalize(${value})`,
|
|
660
595
|
sideEffects: false,
|
|
661
596
|
});
|
|
662
597
|
function powCpu(base, exponent) {
|
|
663
|
-
|
|
664
|
-
return (base ** exponent);
|
|
665
|
-
}
|
|
666
|
-
if (isVecInstance(base) && isVecInstance(exponent)) {
|
|
667
|
-
return VectorOps.pow[base.kind](base, exponent);
|
|
668
|
-
}
|
|
669
|
-
throw new Error(`Invalid arguments to pow(): '${base}' '${exponent}'`);
|
|
598
|
+
return generalizeFn((a, b) => a ** b, [base, exponent]);
|
|
670
599
|
}
|
|
671
600
|
export const pow = dualImpl({
|
|
672
601
|
name: 'pow',
|
|
@@ -775,10 +704,7 @@ export const saturate = dualImpl({
|
|
|
775
704
|
sideEffects: false,
|
|
776
705
|
});
|
|
777
706
|
function cpuSign(e) {
|
|
778
|
-
|
|
779
|
-
return Math.sign(e);
|
|
780
|
-
}
|
|
781
|
-
return VectorOps.sign[e.kind](e);
|
|
707
|
+
return generalizeFn(Math.sign, [e]);
|
|
782
708
|
}
|
|
783
709
|
export const sign = dualImpl({
|
|
784
710
|
name: 'sign',
|
|
@@ -795,10 +721,7 @@ export const sign = dualImpl({
|
|
|
795
721
|
sideEffects: false,
|
|
796
722
|
});
|
|
797
723
|
function cpuSin(value) {
|
|
798
|
-
|
|
799
|
-
return Math.sin(value);
|
|
800
|
-
}
|
|
801
|
-
return VectorOps.sin[value.kind](value);
|
|
724
|
+
return generalizeFn(Math.sin, [value]);
|
|
802
725
|
}
|
|
803
726
|
export const sin = dualImpl({
|
|
804
727
|
name: 'sin',
|
|
@@ -808,10 +731,7 @@ export const sin = dualImpl({
|
|
|
808
731
|
sideEffects: false,
|
|
809
732
|
});
|
|
810
733
|
function cpuSinh(value) {
|
|
811
|
-
|
|
812
|
-
return Math.sinh(value);
|
|
813
|
-
}
|
|
814
|
-
throw new MissingCpuImplError('CPU implementation for sinh on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues');
|
|
734
|
+
return generalizeFn(Math.sinh, [value]);
|
|
815
735
|
}
|
|
816
736
|
export const sinh = dualImpl({
|
|
817
737
|
name: 'sinh',
|
|
@@ -821,10 +741,7 @@ export const sinh = dualImpl({
|
|
|
821
741
|
sideEffects: false,
|
|
822
742
|
});
|
|
823
743
|
function cpuSmoothstep(edge0, edge1, x) {
|
|
824
|
-
|
|
825
|
-
return smoothstepScalar(edge0, edge1, x);
|
|
826
|
-
}
|
|
827
|
-
return VectorOps.smoothstep[x.kind](edge0, edge1, x);
|
|
744
|
+
return generalizeFn(smoothstepScalar, [edge0, edge1, x]);
|
|
828
745
|
}
|
|
829
746
|
export const smoothstep = dualImpl({
|
|
830
747
|
name: 'smoothstep',
|
|
@@ -834,10 +751,7 @@ export const smoothstep = dualImpl({
|
|
|
834
751
|
sideEffects: false,
|
|
835
752
|
});
|
|
836
753
|
function cpuSqrt(value) {
|
|
837
|
-
|
|
838
|
-
return Math.sqrt(value);
|
|
839
|
-
}
|
|
840
|
-
return VectorOps.sqrt[value.kind](value);
|
|
754
|
+
return generalizeFn(Math.sqrt, [value]);
|
|
841
755
|
}
|
|
842
756
|
export const sqrt = dualImpl({
|
|
843
757
|
name: 'sqrt',
|
|
@@ -873,10 +787,7 @@ export const tan = dualImpl({
|
|
|
873
787
|
sideEffects: false,
|
|
874
788
|
});
|
|
875
789
|
function cpuTanh(value) {
|
|
876
|
-
|
|
877
|
-
return Math.tanh(value);
|
|
878
|
-
}
|
|
879
|
-
return VectorOps.tanh[value.kind](value);
|
|
790
|
+
return generalizeFn(Math.tanh, [value]);
|
|
880
791
|
}
|
|
881
792
|
export const tanh = dualImpl({
|
|
882
793
|
name: 'tanh',
|
|
@@ -954,3 +865,27 @@ export const trunc = dualImpl({
|
|
|
954
865
|
codegenImpl: (_ctx, [value]) => stitch `trunc(${value})`,
|
|
955
866
|
sideEffects: false,
|
|
956
867
|
});
|
|
868
|
+
function cpuIntdiv(lhs, rhs) {
|
|
869
|
+
if (typeof lhs !== 'number' || typeof rhs !== 'number') {
|
|
870
|
+
throw new Error('std.intdiv called with invalid arguments.');
|
|
871
|
+
}
|
|
872
|
+
return Math.trunc(Math.trunc(lhs) / Math.trunc(rhs));
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Performs integer division on the passed in scalars.
|
|
876
|
+
* Equivalent to `trunc(trunc(lhs) / trunc(rhs))`. Coerces both
|
|
877
|
+
* arguments to integers if they're floating point.
|
|
878
|
+
*/
|
|
879
|
+
export const intdiv = dualImpl({
|
|
880
|
+
name: 'intdiv',
|
|
881
|
+
signature: (lhs, rhs) => {
|
|
882
|
+
const unified = unify([lhs, rhs], [u32, i32]);
|
|
883
|
+
if (!unified) {
|
|
884
|
+
throw new SignatureNotSupportedError([lhs, rhs], [u32, i32, abstractInt]);
|
|
885
|
+
}
|
|
886
|
+
return { argTypes: unified, returnType: unified[0] };
|
|
887
|
+
},
|
|
888
|
+
normalImpl: cpuIntdiv,
|
|
889
|
+
codegenImpl: (ctx, [lhs, rhs]) => ctx.gen.emitBinaryOp(lhs, '/', rhs),
|
|
890
|
+
sideEffects: false,
|
|
891
|
+
});
|