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/operators.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { dualImpl } from "../core/function/dualImpl.js";
|
|
2
2
|
import { stitch } from "../core/resolve/stitch.js";
|
|
3
3
|
import { abstractFloat, f16, f32, u32 } from "../data/numeric.js";
|
|
4
|
-
import { vec2i, vec2u, vec3i, vec3u, vec4i, vec4u
|
|
4
|
+
import { vec2i, vec2u, vec3i, vec3u, vec4i, vec4u } from "../data/vector.js";
|
|
5
5
|
import { VectorOps } from "../data/vectorOps.js";
|
|
6
|
+
import { generalizeFn, upCast } from "../data/generalizeFn.js";
|
|
6
7
|
import { isFloat32VecInstance, isInteger32VecInstance, isMat, isMatInstance, isUint32VecInstance, isVec, isVecInstance, } from "../data/wgslTypes.js";
|
|
7
8
|
import { SignatureNotSupportedError } from "../errors.js";
|
|
8
9
|
import { unify } from "../tgsl/conversion.js";
|
|
@@ -59,13 +60,13 @@ function cpuAdd(lhs, rhs) {
|
|
|
59
60
|
return lhs + rhs; // default addition
|
|
60
61
|
}
|
|
61
62
|
if (typeof lhs === 'number' && isVecInstance(rhs)) {
|
|
62
|
-
return
|
|
63
|
+
return generalizeFn((e) => lhs + e, [rhs]); // mixed addition
|
|
63
64
|
}
|
|
64
65
|
if (isVecInstance(lhs) && typeof rhs === 'number') {
|
|
65
|
-
return
|
|
66
|
+
return generalizeFn((e) => e + rhs, [lhs]); // mixed addition
|
|
66
67
|
}
|
|
67
68
|
if ((isVecInstance(lhs) && isVecInstance(rhs)) || (isMatInstance(lhs) && isMatInstance(rhs))) {
|
|
68
|
-
return
|
|
69
|
+
return generalizeFn((a, b) => a + b, [lhs, rhs]); // component-wise addition
|
|
69
70
|
}
|
|
70
71
|
throw new Error('Add/Sub called with invalid arguments.');
|
|
71
72
|
}
|
|
@@ -92,13 +93,13 @@ function cpuMul(lhs, rhs) {
|
|
|
92
93
|
return lhs * rhs; // default multiplication
|
|
93
94
|
}
|
|
94
95
|
if (typeof lhs === 'number' && (isVecInstance(rhs) || isMatInstance(rhs))) {
|
|
95
|
-
return
|
|
96
|
+
return generalizeFn((e) => lhs * e, [rhs]); // scale
|
|
96
97
|
}
|
|
97
98
|
if ((isVecInstance(lhs) || isMatInstance(lhs)) && typeof rhs === 'number') {
|
|
98
|
-
return
|
|
99
|
+
return generalizeFn((e) => e * rhs, [lhs]); // scale
|
|
99
100
|
}
|
|
100
101
|
if (isVecInstance(lhs) && isVecInstance(rhs)) {
|
|
101
|
-
return
|
|
102
|
+
return generalizeFn((a, b) => a * b, [lhs, rhs]); // component-wise
|
|
102
103
|
}
|
|
103
104
|
if (isFloat32VecInstance(lhs) && isMatInstance(rhs)) {
|
|
104
105
|
return VectorOps.mulVxM[rhs.kind](lhs, rhs); // row-vector-matrix
|
|
@@ -107,7 +108,7 @@ function cpuMul(lhs, rhs) {
|
|
|
107
108
|
return VectorOps.mulMxV[lhs.kind](lhs, rhs); // matrix-column-vector
|
|
108
109
|
}
|
|
109
110
|
if (isMatInstance(lhs) && isMatInstance(rhs)) {
|
|
110
|
-
return VectorOps.
|
|
111
|
+
return VectorOps.mulMxM[lhs.kind](lhs, rhs); // matrix multiplication
|
|
111
112
|
}
|
|
112
113
|
throw new Error('Mul called with invalid arguments.');
|
|
113
114
|
}
|
|
@@ -119,21 +120,7 @@ export const mul = dualImpl({
|
|
|
119
120
|
sideEffects: false,
|
|
120
121
|
});
|
|
121
122
|
function cpuDiv(lhs, rhs) {
|
|
122
|
-
|
|
123
|
-
return lhs / rhs;
|
|
124
|
-
}
|
|
125
|
-
if (typeof lhs === 'number' && isVecInstance(rhs)) {
|
|
126
|
-
const schema = vecTypeToConstructor[rhs.kind];
|
|
127
|
-
return VectorOps.div[rhs.kind](schema(lhs), rhs);
|
|
128
|
-
}
|
|
129
|
-
if (isVecInstance(lhs) && typeof rhs === 'number') {
|
|
130
|
-
const schema = vecTypeToConstructor[lhs.kind];
|
|
131
|
-
return VectorOps.div[lhs.kind](lhs, schema(rhs));
|
|
132
|
-
}
|
|
133
|
-
if (isVecInstance(lhs) && isVecInstance(rhs)) {
|
|
134
|
-
return VectorOps.div[lhs.kind](lhs, rhs);
|
|
135
|
-
}
|
|
136
|
-
throw new Error('Div called with invalid arguments.');
|
|
123
|
+
return generalizeFn((a, b) => a / b, upCast([lhs, rhs]));
|
|
137
124
|
}
|
|
138
125
|
export const div = dualImpl({
|
|
139
126
|
name: 'div',
|
|
@@ -151,33 +138,13 @@ export const mod = dualImpl({
|
|
|
151
138
|
name: 'mod',
|
|
152
139
|
signature: binaryDivSignature,
|
|
153
140
|
normalImpl: ((a, b) => {
|
|
154
|
-
|
|
155
|
-
return (a % b); // scalar % scalar
|
|
156
|
-
}
|
|
157
|
-
if (typeof a === 'number' && isVecInstance(b)) {
|
|
158
|
-
// scalar % vector
|
|
159
|
-
const schema = vecTypeToConstructor[b.kind];
|
|
160
|
-
return VectorOps.mod[b.kind](schema(a), b);
|
|
161
|
-
}
|
|
162
|
-
if (isVecInstance(a) && typeof b === 'number') {
|
|
163
|
-
const schema = vecTypeToConstructor[a.kind];
|
|
164
|
-
// vector % scalar
|
|
165
|
-
return VectorOps.mod[a.kind](a, schema(b));
|
|
166
|
-
}
|
|
167
|
-
if (isVecInstance(a) && isVecInstance(b)) {
|
|
168
|
-
// vector % vector
|
|
169
|
-
return VectorOps.mod[a.kind](a, b);
|
|
170
|
-
}
|
|
171
|
-
throw new Error('Mod called with invalid arguments, expected types: number or vector.');
|
|
141
|
+
return generalizeFn((a, b) => a % b, upCast([a, b]));
|
|
172
142
|
}),
|
|
173
143
|
codegenImpl: (ctx, [lhs, rhs]) => ctx.gen.emitBinaryOp(lhs, '%', rhs),
|
|
174
144
|
sideEffects: false,
|
|
175
145
|
});
|
|
176
146
|
function cpuNeg(value) {
|
|
177
|
-
|
|
178
|
-
return -value;
|
|
179
|
-
}
|
|
180
|
-
return VectorOps.neg[value.kind](value);
|
|
147
|
+
return generalizeFn((value) => -value, [value]);
|
|
181
148
|
}
|
|
182
149
|
export const neg = dualImpl({
|
|
183
150
|
name: 'neg',
|
package/std/texture.js
CHANGED
|
@@ -5,13 +5,16 @@ import { f32, i32, u32 } from "../data/numeric.js";
|
|
|
5
5
|
import { vec2u, vec3u, vec4f, vec4i, vec4u } from "../data/vector.js";
|
|
6
6
|
import { Void, } from "../data/wgslTypes.js";
|
|
7
7
|
import { getTextureFormatInfo, } from "../core/texture/textureFormats.js";
|
|
8
|
+
function compactSnippetArgs(args) {
|
|
9
|
+
return args.filter((arg) => arg !== undefined);
|
|
10
|
+
}
|
|
8
11
|
function sampleCpu(_texture, _sampler, _coords, _offsetOrArrayIndex, _maybeOffset) {
|
|
9
12
|
throw new MissingCpuImplError('Texture sampling relies on GPU resources and cannot be executed outside of a draw call');
|
|
10
13
|
}
|
|
11
14
|
export const textureSample = dualImpl({
|
|
12
15
|
name: 'textureSample',
|
|
13
16
|
normalImpl: sampleCpu,
|
|
14
|
-
codegenImpl: (
|
|
17
|
+
codegenImpl: (ctx, args) => ctx.gen.emitCall('textureSample', [], compactSnippetArgs(args)),
|
|
15
18
|
signature: (...args) => {
|
|
16
19
|
const isDepth = args[0].type.startsWith('texture_depth');
|
|
17
20
|
return {
|
|
@@ -27,7 +30,7 @@ function sampleBiasCpu(_texture, _sampler, _coords, _biasOrArrayIndex, _biasOrOf
|
|
|
27
30
|
export const textureSampleBias = dualImpl({
|
|
28
31
|
name: 'textureSampleBias',
|
|
29
32
|
normalImpl: sampleBiasCpu,
|
|
30
|
-
codegenImpl: (
|
|
33
|
+
codegenImpl: (ctx, args) => ctx.gen.emitCall('textureSampleBias', [], compactSnippetArgs(args)),
|
|
31
34
|
signature: (...args) => ({
|
|
32
35
|
argTypes: args,
|
|
33
36
|
returnType: vec4f,
|
|
@@ -40,7 +43,7 @@ function sampleLevelCpu(_texture, _sampler, _coords, _level, _offsetOrArrayIndex
|
|
|
40
43
|
export const textureSampleLevel = dualImpl({
|
|
41
44
|
name: 'textureSampleLevel',
|
|
42
45
|
normalImpl: sampleLevelCpu,
|
|
43
|
-
codegenImpl: (
|
|
46
|
+
codegenImpl: (ctx, args) => ctx.gen.emitCall('textureSampleLevel', [], compactSnippetArgs(args)),
|
|
44
47
|
signature: (...args) => {
|
|
45
48
|
const isDepth = args[0].type.startsWith('texture_depth');
|
|
46
49
|
return {
|
|
@@ -56,7 +59,7 @@ function textureLoadCpu(_texture, _coords, _levelOrArrayIndex) {
|
|
|
56
59
|
export const textureLoad = dualImpl({
|
|
57
60
|
name: 'textureLoad',
|
|
58
61
|
normalImpl: textureLoadCpu,
|
|
59
|
-
codegenImpl: (
|
|
62
|
+
codegenImpl: (ctx, args) => ctx.gen.emitCall('textureLoad', [], compactSnippetArgs(args)),
|
|
60
63
|
signature: (...args) => {
|
|
61
64
|
const texture = args[0];
|
|
62
65
|
if (isWgslTexture(texture)) {
|
|
@@ -104,7 +107,7 @@ function textureDimensionsCpu(_texture, _level) {
|
|
|
104
107
|
export const textureDimensions = dualImpl({
|
|
105
108
|
name: 'textureDimensions',
|
|
106
109
|
normalImpl: textureDimensionsCpu,
|
|
107
|
-
codegenImpl: (
|
|
110
|
+
codegenImpl: (ctx, args) => ctx.gen.emitCall('textureDimensions', [], compactSnippetArgs(args)),
|
|
108
111
|
signature: (...args) => {
|
|
109
112
|
const dim = args[0].dimension;
|
|
110
113
|
if (dim === '1d') {
|
package/tgpuLogger.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const warningTypes: readonly ["deprecated", "suspicious", "fallback", "precision-loss", "implicit-conversion", "webgpu-feature-missing", "webgpu-limits-exceeded", "locations-mismatched", "log-limit-exceeded", "external-omitted"];
|
|
1
|
+
declare const warningTypes: readonly ["deprecated", "suspicious", "fallback", "precision-loss", "implicit-conversion", "webgpu-feature-missing", "webgpu-limits-exceeded", "locations-mismatched", "log-limit-exceeded", "external-omitted", "uniform-schema-misaligned"];
|
|
2
2
|
type WarningType = (typeof warningTypes)[number];
|
|
3
3
|
interface Logger {
|
|
4
4
|
warn(type: WarningType, ...args: unknown[]): void;
|
package/tgpuLogger.js
CHANGED
package/tgsl/wgslGenerator.js
CHANGED
|
@@ -699,8 +699,9 @@ export class WgslGenerator {
|
|
|
699
699
|
elemType = concretize(values[0]?.dataType);
|
|
700
700
|
}
|
|
701
701
|
const arrayType = arrayOf(elemType, values.length);
|
|
702
|
+
const allConstant = values.every((value) => value.origin === 'constant');
|
|
702
703
|
return snip(new ArrayExpression(arrayType, values), arrayType,
|
|
703
|
-
/* origin */ 'runtime', values.some((v) => v.possibleSideEffects));
|
|
704
|
+
/* origin */ allConstant ? 'constant' : 'runtime', values.some((v) => v.possibleSideEffects));
|
|
704
705
|
}
|
|
705
706
|
if (expression[0] === NODE.conditionalExpr) {
|
|
706
707
|
// ternary operator
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { logger } from "../../tgpuLogger.js";
|
|
2
|
-
export function warnIfOverflow(layouts, limits) {
|
|
3
|
-
const entries = Object.values(layouts)
|
|
4
|
-
.flatMap((layout) => Object.values(layout.entries))
|
|
5
|
-
.filter((entry) => entry !== null);
|
|
6
|
-
const uniform = entries.filter((entry) => 'uniform' in entry).length;
|
|
7
|
-
const storage = entries.filter((entry) => 'storage' in entry).length;
|
|
8
|
-
if (uniform > limits.maxUniformBuffersPerShaderStage) {
|
|
9
|
-
logger.warn('webgpu-limits-exceeded', `Total number of uniform buffers (${uniform}) exceeds maxUniformBuffersPerShaderStage (${limits.maxUniformBuffersPerShaderStage}). Consider:
|
|
10
|
-
1. Grouping some of the uniforms into one using 'd.struct',
|
|
11
|
-
2. Increasing the limit when requesting a device or creating a root.`);
|
|
12
|
-
}
|
|
13
|
-
if (storage > limits.maxStorageBuffersPerShaderStage) {
|
|
14
|
-
logger.warn('webgpu-limits-exceeded', `Total number of storage buffers (${storage}) exceeds maxStorageBuffersPerShaderStage (${limits.maxStorageBuffersPerShaderStage}).`);
|
|
15
|
-
}
|
|
16
|
-
}
|