@aardworx/wombat.rendering 0.9.16 → 0.9.18
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/core/renderObject.d.ts +19 -0
- package/dist/core/renderObject.d.ts.map +1 -1
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts +33 -1
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -1
- package/dist/runtime/derivedModes/modeKeyCpu.js +124 -31
- package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -1
- package/dist/runtime/derivedModes/rule.d.ts +59 -0
- package/dist/runtime/derivedModes/rule.d.ts.map +1 -0
- package/dist/runtime/derivedModes/rule.js +55 -0
- package/dist/runtime/derivedModes/rule.js.map +1 -0
- package/dist/runtime/heapAdapter.d.ts.map +1 -1
- package/dist/runtime/heapAdapter.js +1 -0
- package/dist/runtime/heapAdapter.js.map +1 -1
- package/dist/runtime/heapScene.d.ts +32 -0
- package/dist/runtime/heapScene.d.ts.map +1 -1
- package/dist/runtime/heapScene.js +55 -5
- package/dist/runtime/heapScene.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/renderObject.ts +19 -0
- package/src/runtime/derivedModes/modeKeyCpu.ts +142 -23
- package/src/runtime/derivedModes/rule.ts +110 -0
- package/src/runtime/heapAdapter.ts +1 -0
- package/src/runtime/heapScene.ts +88 -5
- package/src/runtime/index.ts +10 -0
|
@@ -891,7 +891,14 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
|
|
|
891
891
|
// right per-effect helper at draw time. Atlas-binding shape follows
|
|
892
892
|
// from `family.drawHeaderUnion.atlasTextureBindings.size > 0`.
|
|
893
893
|
void texIdOf; // retained for future per-bucket diagnostics
|
|
894
|
-
function findOrCreateBucket(effect, _textures, pipelineState
|
|
894
|
+
function findOrCreateBucket(effect, _textures, pipelineState,
|
|
895
|
+
/**
|
|
896
|
+
* Optional precomputed descriptor. addDrawImpl passes this when
|
|
897
|
+
* the spec carries `modeRules` so the bucket key reflects the
|
|
898
|
+
* rule-evaluated value (not the raw PS aval values). When omitted
|
|
899
|
+
* the descriptor is snapshotted from PS as before.
|
|
900
|
+
*/
|
|
901
|
+
precomputedDescriptor) {
|
|
895
902
|
if (!familyBuilt) {
|
|
896
903
|
throw new Error("heapScene: findOrCreateBucket called before family build");
|
|
897
904
|
}
|
|
@@ -904,13 +911,25 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
|
|
|
904
911
|
// (the actual value-set in the descriptor), so identical-value
|
|
905
912
|
// cvals collapse to ONE bucket. See docs/derived-modes.md and
|
|
906
913
|
// tests/heap-multi-pipeline-bucket.test.ts.
|
|
907
|
-
const psDescriptor = snapshotDescriptor(pipelineState, sig);
|
|
914
|
+
const psDescriptor = precomputedDescriptor ?? snapshotDescriptor(pipelineState, sig);
|
|
908
915
|
const psModeKey = encodeModeKey(psDescriptor);
|
|
909
916
|
const bk = `family#${fam.schema.id}|mk#${psModeKey.toString(16)}`;
|
|
910
917
|
const existing = bucketByKey.get(bk);
|
|
911
918
|
if (existing !== undefined)
|
|
912
919
|
return existing;
|
|
913
|
-
|
|
920
|
+
// If a precomputed descriptor is supplied (rule-evaluated path),
|
|
921
|
+
// use its post-rule axis values so the pipeline reflects what the
|
|
922
|
+
// RO actually wants. Otherwise fall through to PS-aval forcing.
|
|
923
|
+
const ps = precomputedDescriptor !== undefined
|
|
924
|
+
? {
|
|
925
|
+
topology: precomputedDescriptor.topology,
|
|
926
|
+
cullMode: precomputedDescriptor.cullMode,
|
|
927
|
+
frontFace: precomputedDescriptor.frontFace,
|
|
928
|
+
...(precomputedDescriptor.depth !== undefined
|
|
929
|
+
? { depth: { write: precomputedDescriptor.depth.write, compare: precomputedDescriptor.depth.compare } }
|
|
930
|
+
: {}),
|
|
931
|
+
}
|
|
932
|
+
: resolvePipelineState(pipelineState);
|
|
914
933
|
const layout = fam.schema.drawHeaderUnion;
|
|
915
934
|
const isAtlasBucket = layout.atlasTextureBindings.size > 0;
|
|
916
935
|
const vsModule = fam.vsModule;
|
|
@@ -1185,7 +1204,23 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
|
|
|
1185
1204
|
const perInstanceAttributes = spec.instanceAttributes !== undefined
|
|
1186
1205
|
? new Set(Object.keys(spec.instanceAttributes))
|
|
1187
1206
|
: new Set();
|
|
1188
|
-
|
|
1207
|
+
// If the spec has modeRules, pre-snapshot the rule-evaluated
|
|
1208
|
+
// descriptor so the bucket key + pipeline reflect post-rule
|
|
1209
|
+
// values. Without this, two ROs with identical PS but different
|
|
1210
|
+
// rule outputs would collide on the same bucket.
|
|
1211
|
+
let precomputedDescriptor;
|
|
1212
|
+
if (spec.modeRules !== undefined) {
|
|
1213
|
+
const uAvals = new Map();
|
|
1214
|
+
for (const [name, val] of Object.entries(spec.inputs)) {
|
|
1215
|
+
uAvals.set(name, asAval(val));
|
|
1216
|
+
}
|
|
1217
|
+
precomputedDescriptor = snapshotDescriptor(spec.pipelineState, sig, {
|
|
1218
|
+
modeRules: spec.modeRules,
|
|
1219
|
+
uniformAvals: uAvals,
|
|
1220
|
+
token: outerTok,
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
const bucket = findOrCreateBucket(spec.effect, spec.textures, spec.pipelineState, precomputedDescriptor);
|
|
1189
1224
|
const fam = familyFor(spec.effect);
|
|
1190
1225
|
const effectFields = fam.fieldsForEffect.get(spec.effect.id);
|
|
1191
1226
|
// Indices live in their own INDEX-usage buffer (WebGPU constraint).
|
|
@@ -1357,7 +1392,22 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
|
|
|
1357
1392
|
// skipSubscribe: this tracker doesn't install its own callbacks.
|
|
1358
1393
|
// The scene-level `modeAvalToDrawIds` does it once per unique aval
|
|
1359
1394
|
// (the 20k-ROs-share-one-cullCval optimization).
|
|
1360
|
-
|
|
1395
|
+
// If the spec has modeRules, pre-build a uniforms-aval map the
|
|
1396
|
+
// rule closures will read against; the tracker auto-discovers
|
|
1397
|
+
// which avals each rule reads and surfaces them via forEachLeaf.
|
|
1398
|
+
let uniformAvals;
|
|
1399
|
+
if (spec.modeRules !== undefined) {
|
|
1400
|
+
const m = new Map();
|
|
1401
|
+
for (const [name, val] of Object.entries(spec.inputs)) {
|
|
1402
|
+
m.set(name, asAval(val));
|
|
1403
|
+
}
|
|
1404
|
+
uniformAvals = m;
|
|
1405
|
+
}
|
|
1406
|
+
const tracker = new ModeKeyTracker(spec.pipelineState, sig, () => { dirtyModeKeyDrawIds.add(drawId); }, {
|
|
1407
|
+
skipSubscribe: true,
|
|
1408
|
+
...(spec.modeRules !== undefined ? { modeRules: spec.modeRules } : {}),
|
|
1409
|
+
...(uniformAvals !== undefined ? { uniformAvals } : {}),
|
|
1410
|
+
});
|
|
1361
1411
|
drawIdToModeTracker[drawId] = tracker;
|
|
1362
1412
|
tracker.forEachLeaf((av) => subscribeModeLeaf(av, drawId));
|
|
1363
1413
|
// ─── §7 derived-uniforms registration ────────────────────────────
|