@aardworx/wombat.rendering 0.19.9 → 0.19.11
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/dist/resources/preparedRenderObject.d.ts +11 -1
- package/dist/resources/preparedRenderObject.d.ts.map +1 -1
- package/dist/resources/preparedRenderObject.js +100 -8
- package/dist/resources/preparedRenderObject.js.map +1 -1
- package/dist/runtime/derivedModes/axisEnum.d.ts +21 -0
- package/dist/runtime/derivedModes/axisEnum.d.ts.map +1 -0
- package/dist/runtime/derivedModes/axisEnum.js +64 -0
- package/dist/runtime/derivedModes/axisEnum.js.map +1 -0
- package/dist/runtime/derivedModes/cpuEval.d.ts +11 -0
- package/dist/runtime/derivedModes/cpuEval.d.ts.map +1 -0
- package/dist/runtime/derivedModes/cpuEval.js +98 -0
- package/dist/runtime/derivedModes/cpuEval.js.map +1 -0
- package/dist/runtime/derivedUniforms/cpuEval.d.ts +25 -0
- package/dist/runtime/derivedUniforms/cpuEval.d.ts.map +1 -0
- package/dist/runtime/derivedUniforms/cpuEval.js +293 -0
- package/dist/runtime/derivedUniforms/cpuEval.js.map +1 -0
- package/package.json +1 -1
- package/src/resources/preparedRenderObject.ts +93 -5
- package/src/runtime/derivedModes/axisEnum.ts +65 -0
- package/src/runtime/derivedModes/cpuEval.ts +104 -0
- package/src/runtime/derivedUniforms/cpuEval.ts +271 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// CPU interpreter for derived-uniform rule IR (a wombat.shader `Expr`).
|
|
2
|
+
//
|
|
3
|
+
// Evaluates a `derivedUniform(u => …)` rule in DOUBLE precision (M44d / V3d /
|
|
4
|
+
// …) — no df32 dual-float trick, no GPU constituent slots. The heap path
|
|
5
|
+
// compiles rules into a §7 GPU compute pass (f32, df32 for the inverse trick);
|
|
6
|
+
// here we just interpret the IR with f64 host math (`M44d.inverse()` is exact
|
|
7
|
+
// enough that the backward-storage trick is unnecessary), and `writeField`
|
|
8
|
+
// narrows the result to f32 at pack time.
|
|
9
|
+
//
|
|
10
|
+
// Used by the legacy per-RO uniform path so derived uniforms work on ROs that
|
|
11
|
+
// aren't heap-eligible (a storage buffer, 2+ textures, …). The evaluator is a
|
|
12
|
+
// standalone `Expr → value` function so other CPU rule paths can reuse it.
|
|
13
|
+
import { V2d, V3d, V4d, M22d, M33d, M44d } from "@aardworx/wombat.base";
|
|
14
|
+
// ── runtime classification ───────────────────────────────────────────────
|
|
15
|
+
function isVec(v) {
|
|
16
|
+
return v instanceof V2d || v instanceof V3d || v instanceof V4d;
|
|
17
|
+
}
|
|
18
|
+
function isMat(v) {
|
|
19
|
+
return v instanceof M22d || v instanceof M33d || v instanceof M44d;
|
|
20
|
+
}
|
|
21
|
+
function data(v) { return v._data; }
|
|
22
|
+
function num(v) {
|
|
23
|
+
if (typeof v === "number")
|
|
24
|
+
return v;
|
|
25
|
+
if (typeof v === "boolean")
|
|
26
|
+
return v ? 1 : 0;
|
|
27
|
+
throw new Error("derived eval: expected scalar, got " + describe(v));
|
|
28
|
+
}
|
|
29
|
+
function describe(v) {
|
|
30
|
+
if (isVec(v))
|
|
31
|
+
return "vec" + data(v).length;
|
|
32
|
+
if (isMat(v))
|
|
33
|
+
return "mat";
|
|
34
|
+
return typeof v;
|
|
35
|
+
}
|
|
36
|
+
function vecOf(d) {
|
|
37
|
+
switch (d.length) {
|
|
38
|
+
case 2: return new V2d(d[0], d[1]);
|
|
39
|
+
case 3: return new V3d(d[0], d[1], d[2]);
|
|
40
|
+
case 4: return new V4d(d[0], d[1], d[2], d[3]);
|
|
41
|
+
default: throw new Error("derived eval: bad vector arity " + d.length);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ── leaf coercion (by the IR leaf type) ──────────────────────────────────
|
|
45
|
+
function toM44(raw) {
|
|
46
|
+
if (raw instanceof M44d)
|
|
47
|
+
return raw;
|
|
48
|
+
const o = raw;
|
|
49
|
+
if (o && o.forward !== undefined)
|
|
50
|
+
return toM44(o.forward); // Trafo3d → forward
|
|
51
|
+
if (o && o._data !== undefined && o._data.length >= 16)
|
|
52
|
+
return M44d.fromArray(o._data); // M44f
|
|
53
|
+
throw new Error("derived eval: leaf is not a mat4: " + describe(raw));
|
|
54
|
+
}
|
|
55
|
+
function upperLeft3(m) {
|
|
56
|
+
const d = data(m); // row-major r*4+c
|
|
57
|
+
return M33d.fromArray([d[0], d[1], d[2], d[4], d[5], d[6], d[8], d[9], d[10]]);
|
|
58
|
+
}
|
|
59
|
+
function toM33(raw) {
|
|
60
|
+
if (raw instanceof M33d)
|
|
61
|
+
return raw;
|
|
62
|
+
const o = raw;
|
|
63
|
+
if (raw instanceof M44d)
|
|
64
|
+
return upperLeft3(raw);
|
|
65
|
+
if (o && o.forward !== undefined)
|
|
66
|
+
return upperLeft3(toM44(o.forward));
|
|
67
|
+
if (o && o._data !== undefined && o._data.length === 9)
|
|
68
|
+
return M33d.fromArray(o._data);
|
|
69
|
+
if (o && o._data !== undefined && o._data.length >= 16)
|
|
70
|
+
return upperLeft3(toM44(raw));
|
|
71
|
+
throw new Error("derived eval: leaf is not a mat3: " + describe(raw));
|
|
72
|
+
}
|
|
73
|
+
function toM22(raw) {
|
|
74
|
+
if (raw instanceof M22d)
|
|
75
|
+
return raw;
|
|
76
|
+
const o = raw;
|
|
77
|
+
if (o && o._data !== undefined && o._data.length === 4)
|
|
78
|
+
return M22d.fromArray(o._data);
|
|
79
|
+
throw new Error("derived eval: leaf is not a mat2: " + describe(raw));
|
|
80
|
+
}
|
|
81
|
+
function toVec(raw, n) {
|
|
82
|
+
if (isVec(raw))
|
|
83
|
+
return raw;
|
|
84
|
+
const o = raw;
|
|
85
|
+
if (o && o._data !== undefined) {
|
|
86
|
+
const d = o._data;
|
|
87
|
+
return vecOf(n === 2 ? [d[0], d[1]] : n === 3 ? [d[0], d[1], d[2]] : [d[0], d[1], d[2], d[3]]);
|
|
88
|
+
}
|
|
89
|
+
throw new Error("derived eval: leaf is not a vec" + n + ": " + describe(raw));
|
|
90
|
+
}
|
|
91
|
+
function coerce(raw, t) {
|
|
92
|
+
switch (t.kind) {
|
|
93
|
+
case "Matrix": return t.rows === 4 ? toM44(raw) : t.rows === 3 ? toM33(raw) : toM22(raw);
|
|
94
|
+
case "Vector": return toVec(raw, t.dim);
|
|
95
|
+
case "Float": return Number(raw);
|
|
96
|
+
case "Int": return Math.trunc(Number(raw));
|
|
97
|
+
case "Bool": return Boolean(raw);
|
|
98
|
+
default: throw new Error("derived eval: unsupported leaf type " + t.kind);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// ── arithmetic over scalar / vector / matrix ─────────────────────────────
|
|
102
|
+
function negate(x) {
|
|
103
|
+
if (typeof x === "number")
|
|
104
|
+
return -x;
|
|
105
|
+
if (isVec(x) || isMat(x))
|
|
106
|
+
return remap(x, (a) => -a);
|
|
107
|
+
throw new Error("derived eval: cannot negate " + describe(x));
|
|
108
|
+
}
|
|
109
|
+
/** Map a vector/matrix's components through `f`, returning the same shape. */
|
|
110
|
+
function remap(v, f) {
|
|
111
|
+
const d = data(v);
|
|
112
|
+
const out = new Array(d.length);
|
|
113
|
+
for (let i = 0; i < d.length; i++)
|
|
114
|
+
out[i] = f(d[i]);
|
|
115
|
+
return isMat(v) ? matOf(out) : vecOf(out);
|
|
116
|
+
}
|
|
117
|
+
function matOf(d) {
|
|
118
|
+
switch (d.length) {
|
|
119
|
+
case 4: return M22d.fromArray(d);
|
|
120
|
+
case 9: return M33d.fromArray(d);
|
|
121
|
+
case 16: return M44d.fromArray(d);
|
|
122
|
+
default: throw new Error("derived eval: bad matrix arity " + d.length);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Element-wise binary op, broadcasting a scalar against a vector/matrix. */
|
|
126
|
+
function elementwise(a, b, f) {
|
|
127
|
+
if (typeof a === "number" && typeof b === "number")
|
|
128
|
+
return f(a, b);
|
|
129
|
+
if (isVec(a) || isMat(a)) {
|
|
130
|
+
const da = data(a);
|
|
131
|
+
const out = new Array(da.length);
|
|
132
|
+
if (typeof b === "number") {
|
|
133
|
+
for (let i = 0; i < da.length; i++)
|
|
134
|
+
out[i] = f(da[i], b);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const db = data(b);
|
|
138
|
+
for (let i = 0; i < da.length; i++)
|
|
139
|
+
out[i] = f(da[i], db[i]);
|
|
140
|
+
}
|
|
141
|
+
return isMat(a) ? matOf(out) : vecOf(out);
|
|
142
|
+
}
|
|
143
|
+
if (typeof a === "number" && (isVec(b) || isMat(b))) {
|
|
144
|
+
const db = data(b);
|
|
145
|
+
const out = new Array(db.length);
|
|
146
|
+
for (let i = 0; i < db.length; i++)
|
|
147
|
+
out[i] = f(a, db[i]);
|
|
148
|
+
return isMat(b) ? matOf(out) : vecOf(out);
|
|
149
|
+
}
|
|
150
|
+
throw new Error(`derived eval: cannot combine ${describe(a)} and ${describe(b)}`);
|
|
151
|
+
}
|
|
152
|
+
/** `Mul` node — scalar·scalar, scalar·(vec|mat) broadcast, or component-wise
|
|
153
|
+
* vec·vec (mat·mat / mat·vec / vec·mat have their own node kinds). */
|
|
154
|
+
function mulNode(a, b) {
|
|
155
|
+
if (typeof a === "number" && isMat(b))
|
|
156
|
+
return b.mul(a);
|
|
157
|
+
if (typeof b === "number" && isMat(a))
|
|
158
|
+
return a.mul(b);
|
|
159
|
+
return elementwise(a, b, (x, y) => x * y);
|
|
160
|
+
}
|
|
161
|
+
function vlen(v) {
|
|
162
|
+
if (typeof v === "number")
|
|
163
|
+
return Math.abs(v);
|
|
164
|
+
const d = data(v);
|
|
165
|
+
let s = 0;
|
|
166
|
+
for (let i = 0; i < d.length; i++)
|
|
167
|
+
s += d[i] * d[i];
|
|
168
|
+
return Math.sqrt(s);
|
|
169
|
+
}
|
|
170
|
+
function dot(a, b) {
|
|
171
|
+
const da = data(a), db = data(b);
|
|
172
|
+
let s = 0;
|
|
173
|
+
for (let i = 0; i < da.length; i++)
|
|
174
|
+
s += da[i] * db[i];
|
|
175
|
+
return s;
|
|
176
|
+
}
|
|
177
|
+
function normalize(v) {
|
|
178
|
+
const len = vlen(v);
|
|
179
|
+
return len === 0 ? v : remap(v, (x) => x / len);
|
|
180
|
+
}
|
|
181
|
+
function swizzle(v, comps) {
|
|
182
|
+
const d = data(v);
|
|
183
|
+
const idx = (c) => ({ x: 0, y: 1, z: 2, w: 3 }[c] ?? 0);
|
|
184
|
+
if (comps.length === 1)
|
|
185
|
+
return d[idx(comps[0])];
|
|
186
|
+
return vecOf(comps.map((c) => d[idx(c)]));
|
|
187
|
+
}
|
|
188
|
+
function convertMatrix(v, t) {
|
|
189
|
+
if (t.kind === "Matrix" && t.rows === 3 && v instanceof M44d)
|
|
190
|
+
return upperLeft3(v);
|
|
191
|
+
if (isMat(v))
|
|
192
|
+
return v; // identity-ish convert
|
|
193
|
+
throw new Error("derived eval: ConvertMatrix on " + describe(v));
|
|
194
|
+
}
|
|
195
|
+
// ── intrinsics (vec-componentwise where natural) ─────────────────────────
|
|
196
|
+
const UNARY = {
|
|
197
|
+
sin: Math.sin, cos: Math.cos, tan: Math.tan, abs: Math.abs, floor: Math.floor,
|
|
198
|
+
ceil: Math.ceil, sqrt: Math.sqrt, exp: Math.exp, log: Math.log,
|
|
199
|
+
exp2: (x) => 2 ** x, log2: Math.log2, sign: Math.sign, fract: (x) => x - Math.floor(x),
|
|
200
|
+
};
|
|
201
|
+
const BINARY = {
|
|
202
|
+
min: Math.min, max: Math.max, pow: (x, y) => x ** y, atan2: Math.atan2,
|
|
203
|
+
};
|
|
204
|
+
function intrinsic(name, a) {
|
|
205
|
+
if (UNARY[name])
|
|
206
|
+
return typeof a[0] === "number" ? UNARY[name](a[0]) : remap(a[0], UNARY[name]);
|
|
207
|
+
if (BINARY[name])
|
|
208
|
+
return elementwise(a[0], a[1], BINARY[name]);
|
|
209
|
+
switch (name) {
|
|
210
|
+
case "normalize": return normalize(a[0]);
|
|
211
|
+
case "length": return vlen(a[0]);
|
|
212
|
+
case "dot": return dot(a[0], a[1]);
|
|
213
|
+
case "cross": return a[0].cross(a[1]);
|
|
214
|
+
case "distance": return vlen(elementwise(a[0], a[1], (x, y) => x - y));
|
|
215
|
+
case "step": return elementwise(a[1], a[0], (x, edge) => (x < edge ? 0 : 1));
|
|
216
|
+
case "clamp": return elementwise(elementwise(a[0], a[1], Math.max), a[2], Math.min);
|
|
217
|
+
case "mix": { // a + (b - a) * t
|
|
218
|
+
const diff = elementwise(a[1], a[0], (y, x) => y - x);
|
|
219
|
+
const scaled = elementwise(diff, a[2], (d, t) => d * t);
|
|
220
|
+
return elementwise(a[0], scaled, (x, s) => x + s);
|
|
221
|
+
}
|
|
222
|
+
case "reflect": {
|
|
223
|
+
const d = dot(a[0], a[1]);
|
|
224
|
+
return elementwise(a[0], elementwise(a[1], 2 * d, (n, k) => n * k), (i, s) => i - s);
|
|
225
|
+
}
|
|
226
|
+
default: throw new Error("derived eval: unsupported intrinsic '" + name + "'");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
export function interpretExpr(ir, readLeaf, opts = {}) {
|
|
230
|
+
const ev = (e) => {
|
|
231
|
+
switch (e.kind) {
|
|
232
|
+
case "Const": {
|
|
233
|
+
const v = e.value;
|
|
234
|
+
if (v.kind === "Bool")
|
|
235
|
+
return v.value;
|
|
236
|
+
if (v.kind === "Int" || v.kind === "Float")
|
|
237
|
+
return v.value;
|
|
238
|
+
throw new Error("derived eval: null const");
|
|
239
|
+
}
|
|
240
|
+
case "ReadInput": {
|
|
241
|
+
// Scope-agnostic: the readLeaf decides what a name resolves to
|
|
242
|
+
// (uniforms for derived uniforms; uniforms + `declared` for modes).
|
|
243
|
+
const raw = readLeaf(e.name);
|
|
244
|
+
if (raw === undefined)
|
|
245
|
+
throw new Error("derived eval: missing leaf '" + e.name + "'");
|
|
246
|
+
return coerce(raw, e.type);
|
|
247
|
+
}
|
|
248
|
+
case "Var": {
|
|
249
|
+
const v = opts.locals?.get(e.var.name);
|
|
250
|
+
if (v === undefined)
|
|
251
|
+
throw new Error("derived eval: unbound local '" + e.var.name + "'");
|
|
252
|
+
return v;
|
|
253
|
+
}
|
|
254
|
+
case "Call": {
|
|
255
|
+
if (opts.callFn === undefined)
|
|
256
|
+
throw new Error("derived eval: Call '" + e.fn.signature.name + "' but no callFn provided");
|
|
257
|
+
return opts.callFn(e.fn.signature.name, e.args.map(ev));
|
|
258
|
+
}
|
|
259
|
+
case "Neg": return negate(ev(e.value));
|
|
260
|
+
case "Not": return !ev(e.value);
|
|
261
|
+
case "Add": return elementwise(ev(e.lhs), ev(e.rhs), (x, y) => x + y);
|
|
262
|
+
case "Sub": return elementwise(ev(e.lhs), ev(e.rhs), (x, y) => x - y);
|
|
263
|
+
case "Div": return elementwise(ev(e.lhs), ev(e.rhs), (x, y) => x / y);
|
|
264
|
+
case "Mod": return elementwise(ev(e.lhs), ev(e.rhs), (x, y) => x % y);
|
|
265
|
+
case "Mul": return mulNode(ev(e.lhs), ev(e.rhs));
|
|
266
|
+
case "MulMatMat": return ev(e.lhs).mul(ev(e.rhs));
|
|
267
|
+
case "MulMatVec": return ev(e.lhs).mul(ev(e.rhs));
|
|
268
|
+
case "MulVecMat": return ev(e.rhs).transpose().mul(ev(e.lhs));
|
|
269
|
+
case "Transpose": return ev(e.value).transpose();
|
|
270
|
+
case "Inverse": return ev(e.value).inverse();
|
|
271
|
+
case "Determinant": return ev(e.value).determinant();
|
|
272
|
+
case "Dot": return dot(ev(e.lhs), ev(e.rhs));
|
|
273
|
+
case "Cross": return ev(e.lhs).cross(ev(e.rhs));
|
|
274
|
+
case "Length": return vlen(ev(e.value));
|
|
275
|
+
case "ConvertMatrix": return convertMatrix(ev(e.value), e.type);
|
|
276
|
+
case "VecSwizzle": return swizzle(ev(e.value), e.comps);
|
|
277
|
+
case "NewVector": return vecOf(e.components.map((c) => num(ev(c))));
|
|
278
|
+
case "And": return ev(e.lhs) && ev(e.rhs);
|
|
279
|
+
case "Or": return ev(e.lhs) || ev(e.rhs);
|
|
280
|
+
case "Eq": return num(ev(e.lhs)) === num(ev(e.rhs));
|
|
281
|
+
case "Neq": return num(ev(e.lhs)) !== num(ev(e.rhs));
|
|
282
|
+
case "Lt": return num(ev(e.lhs)) < num(ev(e.rhs));
|
|
283
|
+
case "Le": return num(ev(e.lhs)) <= num(ev(e.rhs));
|
|
284
|
+
case "Gt": return num(ev(e.lhs)) > num(ev(e.rhs));
|
|
285
|
+
case "Ge": return num(ev(e.lhs)) >= num(ev(e.rhs));
|
|
286
|
+
case "Conditional": return ev(e.cond) ? ev(e.ifTrue) : ev(e.ifFalse);
|
|
287
|
+
case "CallIntrinsic": return intrinsic(e.op.name, e.args.map(ev));
|
|
288
|
+
default: throw new Error("derived eval: unsupported IR node '" + e.kind + "'");
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
return ev(ir);
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=cpuEval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cpuEval.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/cpuEval.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aardworx/wombat.rendering",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.11",
|
|
4
4
|
"description": "WebGPU rendering layer for the Wombat TypeScript stack — RenderObject/RenderTask/runtime + window glue, port of Aardvark.Rendering's lower layers on top of WebGPU and wombat.shader.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "krauthaufen",
|
|
@@ -29,8 +29,13 @@ import {
|
|
|
29
29
|
type aval,
|
|
30
30
|
HashMap,
|
|
31
31
|
cval,
|
|
32
|
+
AVal,
|
|
32
33
|
} from "@aardworx/wombat.adaptive";
|
|
33
34
|
import type { Type } from "@aardworx/wombat.shader/ir";
|
|
35
|
+
import { isDerivedRule } from "../runtime/derivedUniforms/rule.js";
|
|
36
|
+
import { STANDARD_DERIVED_RULES, STANDARD_TRAFO_LEAVES } from "../runtime/derivedUniforms/recipes.js";
|
|
37
|
+
import { interpretExpr } from "../runtime/derivedUniforms/cpuEval.js";
|
|
38
|
+
import { evaluateModeRule } from "../runtime/derivedModes/cpuEval.js";
|
|
34
39
|
import { prepareAdaptiveBuffer } from "./adaptiveBuffer.js";
|
|
35
40
|
import { prepareAdaptiveTexture } from "./adaptiveTexture.js";
|
|
36
41
|
import { prepareAdaptiveSampler } from "./adaptiveSampler.js";
|
|
@@ -365,6 +370,8 @@ export class PreparedRenderObject {
|
|
|
365
370
|
pipelineCtx: PipelineBuildContext,
|
|
366
371
|
pipelineState: import("../core/index.js").PipelineState,
|
|
367
372
|
private readonly active: aval<boolean> | undefined = undefined,
|
|
373
|
+
private readonly modeRules: import("../core/renderObject.js").RenderObject["modeRules"] = undefined,
|
|
374
|
+
private readonly modeUniformReader: ((name: string, token: AdaptiveToken) => unknown) | undefined = undefined,
|
|
368
375
|
) {
|
|
369
376
|
this.groups = groups;
|
|
370
377
|
this._pipelineCtx = pipelineCtx;
|
|
@@ -377,6 +384,28 @@ export class PreparedRenderObject {
|
|
|
377
384
|
/** Internal — exposed for tests. The PipelineState the RO is reading. */
|
|
378
385
|
get pipelineState(): import("../core/index.js").PipelineState { return this._pipelineState; }
|
|
379
386
|
|
|
387
|
+
/**
|
|
388
|
+
* Override pipeline-axis values with CPU-evaluated derived-mode rules.
|
|
389
|
+
* Each rule reads per-RO uniforms + the SG-declared default; evaluating
|
|
390
|
+
* under `token` registers the dependency so a uniform/declared change
|
|
391
|
+
* re-keys the pipeline (recompile via the snapshot cache). The heap path
|
|
392
|
+
* does this on a GPU partition kernel — this is the legacy per-RO answer.
|
|
393
|
+
*/
|
|
394
|
+
private applyModeRules(snap: PipelineSnap, token: AdaptiveToken): PipelineSnap {
|
|
395
|
+
const mr = this.modeRules;
|
|
396
|
+
const ru = this.modeUniformReader;
|
|
397
|
+
if (mr === undefined || ru === undefined) return snap;
|
|
398
|
+
const read = (name: string): unknown => ru(name, token);
|
|
399
|
+
const ov: Record<string, unknown> = {};
|
|
400
|
+
if (mr.cull !== undefined) ov.cullMode = evaluateModeRule(mr.cull, read, token);
|
|
401
|
+
if (mr.frontFace !== undefined) ov.frontFace = evaluateModeRule(mr.frontFace, read, token);
|
|
402
|
+
if (mr.topology !== undefined) ov.topology = evaluateModeRule(mr.topology, read, token);
|
|
403
|
+
if (mr.depthWrite !== undefined) ov.depthWrite = evaluateModeRule(mr.depthWrite, read, token);
|
|
404
|
+
if (mr.depthCompare !== undefined) ov.depthCompare = evaluateModeRule(mr.depthCompare, read, token);
|
|
405
|
+
if (mr.alphaToCoverage !== undefined) ov.alphaToCoverage = evaluateModeRule(mr.alphaToCoverage, read, token);
|
|
406
|
+
return { ...snap, ...ov };
|
|
407
|
+
}
|
|
408
|
+
|
|
380
409
|
acquire(): void {
|
|
381
410
|
for (const r of this.vertexBuffers.values()) r.acquire();
|
|
382
411
|
if (this.indexBuffer !== undefined) this.indexBuffer.acquire();
|
|
@@ -395,7 +424,7 @@ export class PreparedRenderObject {
|
|
|
395
424
|
* surrounding sort / record path can read it without forcing.
|
|
396
425
|
*/
|
|
397
426
|
update(token: AdaptiveToken): void {
|
|
398
|
-
const snap = snapshotPipeline(this._pipelineState, token);
|
|
427
|
+
const snap = this.applyModeRules(snapshotPipeline(this._pipelineState, token), token);
|
|
399
428
|
const key = pipelineKeyOf(snap);
|
|
400
429
|
let pipeline = this._pipelineCache.get(key);
|
|
401
430
|
if (pipeline === undefined) {
|
|
@@ -747,6 +776,20 @@ export function prepareRenderObject(
|
|
|
747
776
|
...(opts.effectId !== undefined ? { effectId: opts.effectId } : {}),
|
|
748
777
|
};
|
|
749
778
|
|
|
779
|
+
// Derived-mode rules (cull/frontFace/… as a function of per-RO uniforms)
|
|
780
|
+
// are evaluated CPU-side in the legacy path. Build a uniform reader over
|
|
781
|
+
// the RO's provider (resolving nested derived-uniform rules too).
|
|
782
|
+
let modeUniformReader: ((name: string, token: AdaptiveToken) => unknown) | undefined;
|
|
783
|
+
if (obj.modeRules !== undefined) {
|
|
784
|
+
const uniProv = asUniformProvider(obj.uniforms);
|
|
785
|
+
modeUniformReader = (name: string, token: AdaptiveToken): unknown => {
|
|
786
|
+
const v = uniProv.tryGet(name);
|
|
787
|
+
if (v === undefined) return undefined;
|
|
788
|
+
if (isDerivedRule(v)) return interpretExpr(v.ir, (n) => readLeaf(n, uniProv, effect.avalBindings, token));
|
|
789
|
+
return (v as aval<unknown>).getValue(token);
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
|
|
750
793
|
return new PreparedRenderObject(
|
|
751
794
|
device,
|
|
752
795
|
vertexBindings, vertexBuffers, vertexViews,
|
|
@@ -756,6 +799,8 @@ export function prepareRenderObject(
|
|
|
756
799
|
pipelineCtx,
|
|
757
800
|
obj.pipelineState,
|
|
758
801
|
obj.active,
|
|
802
|
+
obj.modeRules,
|
|
803
|
+
modeUniformReader,
|
|
759
804
|
);
|
|
760
805
|
}
|
|
761
806
|
|
|
@@ -785,11 +830,14 @@ function mergeUniformInputs(
|
|
|
785
830
|
let merged = HashMap.empty<string, aval<unknown>>();
|
|
786
831
|
for (const f of block.fields) {
|
|
787
832
|
const u = user.tryGet(f.name);
|
|
788
|
-
if (u !== undefined) { merged = merged.add(f.name, u); continue; }
|
|
833
|
+
if (u !== undefined) { merged = merged.add(f.name, resolveUniform(u, user, bindings)); continue; }
|
|
789
834
|
const getter = bindings?.[f.name];
|
|
790
|
-
if (getter
|
|
791
|
-
|
|
792
|
-
|
|
835
|
+
if (getter !== undefined) { merged = merged.add(f.name, resolveUniform(getter(), user, bindings)); continue; }
|
|
836
|
+
// Standard derived recipe by name (ModelViewTrafo, …) — derive it CPU-side
|
|
837
|
+
// here just as the heap path derives it on the GPU, so the legacy path
|
|
838
|
+
// serves the same declared uniforms.
|
|
839
|
+
const recipe = STANDARD_DERIVED_RULES.get(f.name);
|
|
840
|
+
if (recipe !== undefined) merged = merged.add(f.name, ruleToAval(recipe, user, bindings));
|
|
793
841
|
}
|
|
794
842
|
return merged;
|
|
795
843
|
}
|
|
@@ -798,6 +846,46 @@ function isAval(v: unknown): boolean {
|
|
|
798
846
|
return typeof v === "object" && v !== null && typeof (v as { getValue?: unknown }).getValue === "function";
|
|
799
847
|
}
|
|
800
848
|
|
|
849
|
+
// A uniform binding value is either an aval/constant or a derivedUniform RULE.
|
|
850
|
+
// Rules are evaluated on CPU (cpuEval) in double precision and exposed as a
|
|
851
|
+
// derived aval — the legacy per-RO path's answer to the heap's §7 compute pass.
|
|
852
|
+
type UProvider = import("../core/index.js").IUniformProvider;
|
|
853
|
+
type Bindings = Readonly<Record<string, () => unknown>> | undefined;
|
|
854
|
+
|
|
855
|
+
function resolveUniform(v: unknown, user: UProvider, bindings: Bindings): aval<unknown> {
|
|
856
|
+
if (isDerivedRule(v)) return ruleToAval(v, user, bindings);
|
|
857
|
+
return isAval(v) ? (v as aval<unknown>) : cval(v);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function ruleToAval(rule: import("../runtime/derivedUniforms/rule.js").DerivedRule, user: UProvider, bindings: Bindings): aval<unknown> {
|
|
861
|
+
return AVal.custom((token: AdaptiveToken) =>
|
|
862
|
+
interpretExpr(rule.ir, (leaf) => readLeaf(leaf, user, bindings, token)),
|
|
863
|
+
) as aval<unknown>;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Resolve a `u.<name>` leaf to its current value, recursing through nested
|
|
867
|
+
// rules / standard recipes. Reading the leaf aval's value under `token`
|
|
868
|
+
// registers the dependency, so the derived aval re-evaluates reactively.
|
|
869
|
+
function readLeaf(name: string, user: UProvider, bindings: Bindings, token: AdaptiveToken): unknown {
|
|
870
|
+
const evalRule = (r: unknown): unknown =>
|
|
871
|
+
interpretExpr((r as import("../runtime/derivedUniforms/rule.js").DerivedRule).ir, (n) => readLeaf(n, user, bindings, token));
|
|
872
|
+
const lookup = (n: string): unknown => {
|
|
873
|
+
const u = user.tryGet(n);
|
|
874
|
+
if (u !== undefined) return isDerivedRule(u) ? evalRule(u) : isAval(u) ? (u as aval<unknown>).getValue(token) : u;
|
|
875
|
+
const getter = bindings?.[n];
|
|
876
|
+
if (getter !== undefined) { const v = getter(); return isDerivedRule(v) ? evalRule(v) : isAval(v) ? (v as aval<unknown>).getValue(token) : v; }
|
|
877
|
+
const recipe = STANDARD_DERIVED_RULES.get(n);
|
|
878
|
+
if (recipe !== undefined) return evalRule(recipe);
|
|
879
|
+
return undefined;
|
|
880
|
+
};
|
|
881
|
+
const direct = lookup(name);
|
|
882
|
+
if (direct !== undefined) return direct;
|
|
883
|
+
// Standard recipes read short trafo leaves (Model / View / Proj) that the RO
|
|
884
|
+
// binds under ModelTrafo / ViewTrafo / ProjTrafo — alias them like the heap.
|
|
885
|
+
const alias = STANDARD_TRAFO_LEAVES.get(name);
|
|
886
|
+
return alias !== undefined ? lookup(alias) : undefined;
|
|
887
|
+
}
|
|
888
|
+
|
|
801
889
|
function ubAsBlock(ub: import("../core/index.js").UniformBlockInfo): import("../core/index.js").UniformBlockInfo {
|
|
802
890
|
return ub;
|
|
803
891
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Canonical per-axis enum tables + value mapping for derived modes.
|
|
2
|
+
//
|
|
3
|
+
// Used by the legacy CPU-eval path (derivedModes/cpuEval). heapScene's
|
|
4
|
+
// GPU-routing path keeps a parallel inline copy of this table + helpers
|
|
5
|
+
// (heapScene.ts ~AXIS_ENUM_TABLE / resolveAxisValue / resolveDeclaredU32);
|
|
6
|
+
// they must stay in sync — fold both onto this module when convenient.
|
|
7
|
+
// The index↔value mapping is the WebGPU enum order; a rule body returns a
|
|
8
|
+
// u32 index and the renderer maps it to the concrete mode value here.
|
|
9
|
+
|
|
10
|
+
import type { aval, AdaptiveToken } from "@aardworx/wombat.adaptive";
|
|
11
|
+
import type { DerivedModeRule, ModeAxis } from "./rule.js";
|
|
12
|
+
|
|
13
|
+
/** u32 index → mode value, per axis. `blend` has no canonical table —
|
|
14
|
+
* blend rules return object literals directly (see resolveAxisValue). */
|
|
15
|
+
export const AXIS_ENUM_TABLE: { readonly [A in ModeAxis]: ReadonlyArray<unknown> } = {
|
|
16
|
+
cull: ["none", "front", "back"],
|
|
17
|
+
frontFace: ["ccw", "cw"],
|
|
18
|
+
topology: ["point-list", "line-list", "line-strip", "triangle-list", "triangle-strip"],
|
|
19
|
+
depthCompare: ["never", "less", "equal", "less-equal", "greater", "not-equal", "greater-equal", "always"],
|
|
20
|
+
depthWrite: [false, true],
|
|
21
|
+
alphaToCoverage: [false, true],
|
|
22
|
+
blend: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Map a rule's resolved output to its axis-shape value:
|
|
27
|
+
* - object → already the full axis value (e.g. a blend AttachmentBlend).
|
|
28
|
+
* - number → enum-table lookup for enum axes; pass-through otherwise.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveAxisValue<A extends ModeAxis>(rule: DerivedModeRule<A>, value: unknown): unknown {
|
|
31
|
+
if (typeof value === "object" && value !== null) return value;
|
|
32
|
+
if (typeof value === "number") {
|
|
33
|
+
const table = AXIS_ENUM_TABLE[rule.axis];
|
|
34
|
+
if (table.length > 0) {
|
|
35
|
+
const v = table[value];
|
|
36
|
+
if (v !== undefined) return v;
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a rule's `declared` SG-context value to its u32 index:
|
|
45
|
+
* - omitted → 0 (axis canonical zero).
|
|
46
|
+
* - number → passed through.
|
|
47
|
+
* - aval / string / boolean → looked up in the canonical enum table.
|
|
48
|
+
*/
|
|
49
|
+
export function declaredToU32<A extends ModeAxis>(rule: DerivedModeRule<A>, tok: AdaptiveToken): number {
|
|
50
|
+
const d = rule.declared;
|
|
51
|
+
if (d === undefined) return 0;
|
|
52
|
+
const v = (typeof d === "object" && d !== null && "getValue" in (d as object))
|
|
53
|
+
? (d as aval<unknown>).getValue(tok)
|
|
54
|
+
: d;
|
|
55
|
+
if (typeof v === "number") return v >>> 0;
|
|
56
|
+
const table = AXIS_ENUM_TABLE[rule.axis];
|
|
57
|
+
if (table.length === 0) {
|
|
58
|
+
throw new Error(`derivedModes: axis '${rule.axis}' has no canonical enum table; pass \`declared\` as a u32 index or omit it`);
|
|
59
|
+
}
|
|
60
|
+
const i = table.indexOf(v);
|
|
61
|
+
if (i < 0) {
|
|
62
|
+
throw new Error(`derivedModes: declared value '${String(v)}' for axis '${rule.axis}' not in canonical enum table ${JSON.stringify(table)}`);
|
|
63
|
+
}
|
|
64
|
+
return i;
|
|
65
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// CPU evaluation of a derived-MODE rule for the legacy per-RO path.
|
|
2
|
+
//
|
|
3
|
+
// A `derivedMode(...)` rule is a RuleExpr whose body computes a pipeline-axis
|
|
4
|
+
// value (cull / frontFace / …) from per-RO uniforms (e.g. determinant of the
|
|
5
|
+
// model matrix) and the SG-declared default. The heap path lowers this to a
|
|
6
|
+
// GPU partition kernel; the legacy per-RO path has no kernel, so we evaluate
|
|
7
|
+
// the rule body on the CPU here — the "v1 evaluates rules CPU-side" design in
|
|
8
|
+
// core/renderObject.ts.
|
|
9
|
+
//
|
|
10
|
+
// Reuses the matrix-aware expression interpreter (derivedUniforms/cpuEval) and
|
|
11
|
+
// adds a small Stmt walker (locals + control flow) plus user-function `Call`
|
|
12
|
+
// resolution against the rule's own Module (helpers like `flipCull` are NOT
|
|
13
|
+
// inlined — they're separate Function items in template.values).
|
|
14
|
+
|
|
15
|
+
import type { Expr, Stmt, ValueDef } from "@aardworx/wombat.shader/ir";
|
|
16
|
+
import type { AdaptiveToken } from "@aardworx/wombat.adaptive";
|
|
17
|
+
import { interpretExpr, type EvalValue } from "../derivedUniforms/cpuEval.js";
|
|
18
|
+
import type { DerivedModeRule, ModeAxis, ModeValue } from "./rule.js";
|
|
19
|
+
import { declaredToU32, resolveAxisValue } from "./axisEnum.js";
|
|
20
|
+
|
|
21
|
+
const NO_RETURN = Symbol("no-return");
|
|
22
|
+
type RunResult = EvalValue | typeof NO_RETURN;
|
|
23
|
+
|
|
24
|
+
interface FnDef { readonly params: readonly string[]; readonly body: Stmt; }
|
|
25
|
+
|
|
26
|
+
function truthy(v: EvalValue): boolean {
|
|
27
|
+
return typeof v === "boolean" ? v : typeof v === "number" ? v !== 0 : true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Evaluate a derived-mode rule to its concrete axis value for one RO.
|
|
32
|
+
* `readUniform(name)` returns the RO's current value for a `u.<name>` leaf
|
|
33
|
+
* (Trafo3d / M44f / number / …); reading it under `token` registers the
|
|
34
|
+
* dependency so the pipeline re-keys when it changes. Returns the mapped
|
|
35
|
+
* mode value (e.g. "back", or `true` for depthWrite).
|
|
36
|
+
*/
|
|
37
|
+
export function evaluateModeRule<A extends ModeAxis>(
|
|
38
|
+
rule: DerivedModeRule<A>,
|
|
39
|
+
readUniform: (name: string) => unknown,
|
|
40
|
+
token: AdaptiveToken,
|
|
41
|
+
): ModeValue<A> {
|
|
42
|
+
// Collect helper functions + the entry body from the rule's Module.
|
|
43
|
+
const fns = new Map<string, FnDef>();
|
|
44
|
+
let body: Stmt | undefined;
|
|
45
|
+
for (const v of rule.expr.template.values as readonly ValueDef[]) {
|
|
46
|
+
if (v.kind === "Function") fns.set(v.signature.name, { params: v.signature.parameters.map((p) => p.name), body: v.body });
|
|
47
|
+
else if (v.kind === "Entry") body = v.entry.body;
|
|
48
|
+
}
|
|
49
|
+
if (body === undefined) {
|
|
50
|
+
throw new Error(`derivedModes: rule for axis '${rule.axis}' has no Entry in its template`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const declaredU32 = declaredToU32(rule, token);
|
|
54
|
+
const readLeaf = (name: string): unknown => (name === "declared" ? declaredU32 : readUniform(name));
|
|
55
|
+
|
|
56
|
+
// Mutually-recursive: an expr `Call` runs a function body; a function body
|
|
57
|
+
// evaluates exprs via interpretExpr with `callFn` wired back here.
|
|
58
|
+
const callFn = (name: string, args: EvalValue[]): EvalValue => {
|
|
59
|
+
const fn = fns.get(name);
|
|
60
|
+
if (fn === undefined) throw new Error(`derivedModes: rule calls unknown function '${name}'`);
|
|
61
|
+
const locals = new Map<string, EvalValue>();
|
|
62
|
+
fn.params.forEach((p, i) => { if (args[i] !== undefined) locals.set(p, args[i]!); });
|
|
63
|
+
return evalBody(fn.body, locals);
|
|
64
|
+
};
|
|
65
|
+
const evalExpr = (e: Expr, locals: Map<string, EvalValue>): EvalValue =>
|
|
66
|
+
interpretExpr(e, readLeaf, { locals, callFn });
|
|
67
|
+
|
|
68
|
+
const run = (s: Stmt, locals: Map<string, EvalValue>): RunResult => {
|
|
69
|
+
switch (s.kind) {
|
|
70
|
+
case "Sequential":
|
|
71
|
+
case "Isolated": {
|
|
72
|
+
for (const c of s.body) { const r = run(c, locals); if (r !== NO_RETURN) return r; }
|
|
73
|
+
return NO_RETURN;
|
|
74
|
+
}
|
|
75
|
+
case "Declare": {
|
|
76
|
+
if (s.init !== undefined && s.init.kind === "Expr") locals.set(s.var.name, evalExpr(s.init.value, locals));
|
|
77
|
+
return NO_RETURN;
|
|
78
|
+
}
|
|
79
|
+
case "Write": {
|
|
80
|
+
if (s.target.kind === "LVar") locals.set(s.target.var.name, evalExpr(s.value, locals));
|
|
81
|
+
return NO_RETURN;
|
|
82
|
+
}
|
|
83
|
+
case "If": {
|
|
84
|
+
if (truthy(evalExpr(s.cond, locals))) return run(s.then, locals);
|
|
85
|
+
return s.else !== undefined ? run(s.else, locals) : NO_RETURN;
|
|
86
|
+
}
|
|
87
|
+
case "ReturnValue": return evalExpr(s.value, locals);
|
|
88
|
+
case "Expression":
|
|
89
|
+
case "Nop":
|
|
90
|
+
case "Return":
|
|
91
|
+
return NO_RETURN;
|
|
92
|
+
default:
|
|
93
|
+
throw new Error(`derivedModes: unsupported statement '${s.kind}' in rule body`);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const evalBody = (b: Stmt, locals: Map<string, EvalValue>): EvalValue => {
|
|
97
|
+
const r = run(b, locals);
|
|
98
|
+
if (r === NO_RETURN) throw new Error(`derivedModes: rule body for axis '${rule.axis}' produced no return value`);
|
|
99
|
+
return r;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const raw = evalBody(body, new Map());
|
|
103
|
+
return resolveAxisValue(rule, raw) as ModeValue<A>;
|
|
104
|
+
}
|