@aardworx/wombat.rendering 0.9.11 → 0.9.13

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.
Files changed (79) hide show
  1. package/dist/runtime/derivedUniforms/codegen.d.ts +8 -0
  2. package/dist/runtime/derivedUniforms/codegen.d.ts.map +1 -0
  3. package/dist/runtime/derivedUniforms/codegen.js +449 -0
  4. package/dist/runtime/derivedUniforms/codegen.js.map +1 -0
  5. package/dist/runtime/derivedUniforms/dispatch.d.ts +14 -93
  6. package/dist/runtime/derivedUniforms/dispatch.d.ts.map +1 -1
  7. package/dist/runtime/derivedUniforms/dispatch.js +123 -299
  8. package/dist/runtime/derivedUniforms/dispatch.js.map +1 -1
  9. package/dist/runtime/derivedUniforms/flatten.d.ts +25 -0
  10. package/dist/runtime/derivedUniforms/flatten.d.ts.map +1 -0
  11. package/dist/runtime/derivedUniforms/flatten.js +71 -0
  12. package/dist/runtime/derivedUniforms/flatten.js.map +1 -0
  13. package/dist/runtime/derivedUniforms/index.d.ts +10 -5
  14. package/dist/runtime/derivedUniforms/index.d.ts.map +1 -1
  15. package/dist/runtime/derivedUniforms/index.js +24 -19
  16. package/dist/runtime/derivedUniforms/index.js.map +1 -1
  17. package/dist/runtime/derivedUniforms/marker.d.ts +76 -0
  18. package/dist/runtime/derivedUniforms/marker.d.ts.map +1 -0
  19. package/dist/runtime/derivedUniforms/marker.js +156 -0
  20. package/dist/runtime/derivedUniforms/marker.js.map +1 -0
  21. package/dist/runtime/derivedUniforms/recipes.d.ts +6 -41
  22. package/dist/runtime/derivedUniforms/recipes.d.ts.map +1 -1
  23. package/dist/runtime/derivedUniforms/recipes.js +53 -129
  24. package/dist/runtime/derivedUniforms/recipes.js.map +1 -1
  25. package/dist/runtime/derivedUniforms/records.d.ts +40 -0
  26. package/dist/runtime/derivedUniforms/records.d.ts.map +1 -0
  27. package/dist/runtime/derivedUniforms/records.js +151 -0
  28. package/dist/runtime/derivedUniforms/records.js.map +1 -0
  29. package/dist/runtime/derivedUniforms/registry.d.ts +33 -0
  30. package/dist/runtime/derivedUniforms/registry.d.ts.map +1 -0
  31. package/dist/runtime/derivedUniforms/registry.js +58 -0
  32. package/dist/runtime/derivedUniforms/registry.js.map +1 -0
  33. package/dist/runtime/derivedUniforms/rule.d.ts +26 -0
  34. package/dist/runtime/derivedUniforms/rule.d.ts.map +1 -0
  35. package/dist/runtime/derivedUniforms/rule.js +35 -0
  36. package/dist/runtime/derivedUniforms/rule.js.map +1 -0
  37. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts +34 -33
  38. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts.map +1 -1
  39. package/dist/runtime/derivedUniforms/sceneIntegration.js +80 -90
  40. package/dist/runtime/derivedUniforms/sceneIntegration.js.map +1 -1
  41. package/dist/runtime/heapScene.d.ts.map +1 -1
  42. package/dist/runtime/heapScene.js +78 -26
  43. package/dist/runtime/heapScene.js.map +1 -1
  44. package/dist/runtime/hybridScene.js +1 -1
  45. package/dist/runtime/hybridScene.js.map +1 -1
  46. package/dist/runtime/index.d.ts +1 -0
  47. package/dist/runtime/index.d.ts.map +1 -1
  48. package/dist/runtime/index.js +2 -0
  49. package/dist/runtime/index.js.map +1 -1
  50. package/dist/runtime/renderTask.js +1 -1
  51. package/dist/runtime/renderTask.js.map +1 -1
  52. package/dist/runtime/runtime.js +1 -1
  53. package/dist/runtime/runtime.js.map +1 -1
  54. package/package.json +1 -1
  55. package/src/runtime/derivedUniforms/codegen.ts +477 -0
  56. package/src/runtime/derivedUniforms/dispatch.ts +135 -341
  57. package/src/runtime/derivedUniforms/flatten.ts +89 -0
  58. package/src/runtime/derivedUniforms/index.ts +50 -34
  59. package/src/runtime/derivedUniforms/marker.ts +169 -0
  60. package/src/runtime/derivedUniforms/recipes.ts +63 -155
  61. package/src/runtime/derivedUniforms/records.ts +158 -0
  62. package/src/runtime/derivedUniforms/registry.ts +77 -0
  63. package/src/runtime/derivedUniforms/rule.ts +59 -0
  64. package/src/runtime/derivedUniforms/sceneIntegration.ts +115 -149
  65. package/src/runtime/heapScene.ts +77 -28
  66. package/src/runtime/hybridScene.ts +1 -1
  67. package/src/runtime/index.ts +8 -0
  68. package/src/runtime/renderTask.ts +1 -1
  69. package/src/runtime/runtime.ts +1 -1
  70. package/dist/runtime/derivedUniforms/slotId.d.ts +0 -15
  71. package/dist/runtime/derivedUniforms/slotId.d.ts.map +0 -1
  72. package/dist/runtime/derivedUniforms/slotId.js +0 -30
  73. package/dist/runtime/derivedUniforms/slotId.js.map +0 -1
  74. package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts +0 -13
  75. package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts.map +0 -1
  76. package/dist/runtime/derivedUniforms/uberKernel.wgsl.js +0 -218
  77. package/dist/runtime/derivedUniforms/uberKernel.wgsl.js.map +0 -1
  78. package/src/runtime/derivedUniforms/slotId.ts +0 -35
  79. package/src/runtime/derivedUniforms/uberKernel.wgsl.ts +0 -220
@@ -1,58 +1,49 @@
1
- // §7 heap scene integration helper.
1
+ // §7 v2 heap-scene integration.
2
2
  //
3
- // Subscription model. Standard adaptive idiom: calling `av.getValue(t)`
4
- // inside an `evaluateAlways(t, ...)` scope (re-)adds the evaluating
5
- // object to `av.outputs`. We don't manage subscription manually.
3
+ // One DerivedUniformsScene per heap scene: owns the rule registry, the (single,
4
+ // scene-wide) records buffer, the constituent-slots heap (df32 trafo halves), the
5
+ // constituents GPU buffer, and the dispatcher. Per RO: flatten each rule against the
6
+ // RO's rule set, register it, resolve every input leaf to a tagged slot handle
7
+ // (constituent fwd/bwd / host drawHeader byte), and push one record.
6
8
  //
7
- // Per frame, the heap scene's `update()` runs `evaluateAlways` once on
8
- // the parent scene-object (as it already does). Inside that scope:
9
- // 1. `scene.constituents.pullDirty(token)` drains the dirty queue.
10
- // For each dirty aval, it calls `getValue(token)` which both
11
- // gives us the new value AND re-establishes our subscription on
12
- // that specific aval. O(changed). Avals that didn't change keep
13
- // us in their outputs from earlier evaluations.
14
- // 2. `scene.uploadDirty(dirtySlots)` — O(changed) value uploads +
15
- // O(changed) bitmask flips.
16
- // 3. Per bucket: `bucket.dispatcher.encode(enc)`. The kernel
17
- // early-returns on records whose inputs are all clean.
18
- //
19
- // On clean frames pullDirty/uploadDirty are no-ops. The records
20
- // buffer is static. CPU steady-state cost: zero.
9
+ // Per frame, inside the heap scene's `evaluateAlways(token, …)` scope:
10
+ // const dirty = scene.pullDirty(token); // drains changed trafo avals (re-subscribes)
11
+ // scene.uploadDirty(dirty); // O(changed) value uploads
12
+ // scene.encode(enc); // one compute dispatch
13
+ // Clean frames: zero CPU work, records buffer static.
14
+ // See docs/derived-uniforms-extensible.md.
21
15
  import { ConstituentSlots, DF32_MAT4_BYTES, } from "./slots.js";
22
- import { RecipeId, recipeIdByName, recipeInputs, recipeInputCount, DERIVED_UNIFORM_NAMES, } from "./recipes.js";
23
- import { DerivedUniformsDispatcher, DerivedUniformsPipeline, uploadConstituentsRange, } from "./dispatch.js";
24
- /** Scene-wide §7 state. One per heap scene. Owns the single records
25
- * buffer + dispatcher all buckets share constituents, dirty mask,
26
- * AND main heap (arena.attrs.buffer), so per-bucket records would
27
- * just multiply dispatch overhead for no reason. */
16
+ import { DerivedUniformRegistry } from "./registry.js";
17
+ import { RecordsBuffer, SlotTag, makeHandle } from "./records.js";
18
+ import { DerivedUniformsDispatcher, uploadConstituentsRange } from "./dispatch.js";
19
+ import { flatten } from "./flatten.js";
20
+ import { ruleFromIR } from "./rule.js";
28
21
  export class DerivedUniformsScene {
29
22
  device;
30
23
  constituents;
31
- pipeline;
24
+ registry = new DerivedUniformRegistry();
25
+ /** Single scene-wide records buffer — all buckets share constituents AND the main heap, so per-bucket records would just multiply dispatch overhead. */
26
+ records = new RecordsBuffer();
32
27
  dispatcher;
33
- /** Constituents storage GPU buffer (df32 mat4 array). */
28
+ /** Constituents storage GPU buffer (`array<vec2<f32>>` — df32 mat4 halves). */
34
29
  constituentsBuf;
35
- /** Caller-owned main heap (arena.attrs.buffer). Updated via
36
- * `rebindMainHeap` on arena resize. */
37
30
  mainHeapRef;
38
31
  /** Bumped each time a shared GPU buffer is replaced. */
39
32
  bufferEpoch = 0;
40
33
  constructor(device, mainHeapBuf, opts) {
41
34
  this.device = device;
42
35
  const initial = opts?.initialConstituentSlots ?? 64;
43
- const subscribe = () => { };
44
- this.constituents = new ConstituentSlots(subscribe, initial);
45
- this.pipeline = new DerivedUniformsPipeline(device);
36
+ this.constituents = new ConstituentSlots(() => { }, initial);
46
37
  this.constituentsBuf = device.createBuffer({
47
38
  label: "derivedUniforms.constituents",
48
39
  size: initial * DF32_MAT4_BYTES,
49
40
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
50
41
  });
51
42
  this.mainHeapRef = { current: mainHeapBuf };
52
- this.dispatcher = new DerivedUniformsDispatcher(device, this.pipeline, {
43
+ this.dispatcher = new DerivedUniformsDispatcher(device, {
53
44
  constituentsBuf: () => this.constituentsBuf,
54
45
  mainHeapBuf: () => this.mainHeapRef.current,
55
- }, opts?.initialRecordCapacity ?? 64);
46
+ });
56
47
  }
57
48
  rebindMainHeap(mainHeapBuf) {
58
49
  this.mainHeapRef.current = mainHeapBuf;
@@ -70,102 +61,101 @@ export class DerivedUniformsScene {
70
61
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,
71
62
  });
72
63
  this.bufferEpoch++;
73
- // The fresh buffer is zero-initialized; the previous contents are
74
- // gone. Re-upload everything we've ever packed (slot 0..slotCount).
75
- // Without this, slots that were last written before the grow read
76
- // zero on the GPU — every df_mul on them produces NaN.
64
+ // Fresh buffer is zero-initialised; re-upload everything packed so far.
77
65
  const slotCount = this.constituents.slotCount;
78
66
  if (slotCount > 0) {
79
67
  const mirror = this.constituents.cpuMirror;
80
68
  this.device.queue.writeBuffer(this.constituentsBuf, 0, mirror.buffer, mirror.byteOffset, slotCount * DF32_MAT4_BYTES);
81
69
  }
82
70
  }
83
- /** Routed from heap scene's `inputChanged(t, o)`. Returns true iff
84
- * `o` matched a known constituent aval. */
71
+ /** Routed from the heap scene's `inputChanged(t, o)`. True iff `o` is a tracked trafo aval. */
85
72
  routeInputChanged(o) {
86
73
  if (!this.constituents.has(o))
87
74
  return false;
88
75
  this.constituents.markDirty(o);
89
76
  return true;
90
77
  }
91
- /** Apply the dirty set: upload changed constituent values. O(changed). */
78
+ /** Drain changed trafo avals (re-subscribes via `getValue`). Call inside the scene's evaluate scope. */
79
+ pullDirty(token) {
80
+ return this.constituents.pullDirty(token);
81
+ }
82
+ /** Upload the changed constituent value range. O(changed). */
92
83
  uploadDirty(dirty) {
93
84
  if (dirty.size === 0)
94
85
  return;
95
86
  this.ensureConstituentsCapacity(this.constituents.slotCount * DF32_MAT4_BYTES);
96
87
  uploadConstituentsRange(this.device, this.constituentsBuf, this.constituents.cpuMirror, dirty);
97
88
  }
89
+ /** Run the uber-kernel. No-op if there are no records. */
90
+ encode(enc) {
91
+ return this.dispatcher.encode(enc, this.registry, this.records);
92
+ }
98
93
  dispose() {
99
94
  this.dispatcher.dispose();
100
95
  this.constituentsBuf.destroy();
101
96
  }
102
97
  }
103
- /** Register all derived-uniform records for one RO. */
104
- export function registerRoDerivations(scene, req) {
105
- if (req.requiredNames.length === 0) {
106
- return { recordIds: [], constituentAvals: [] };
107
- }
98
+ export function registerRoDerivations(scene, owner, req) {
99
+ if (req.rules.size === 0)
100
+ return { owner, constituentAvals: [], ruleHashes: [] };
108
101
  const acquiredAvals = [];
109
- const pairFor = new Map();
110
- const TRAFO_FIELD = {
111
- Model: "modelTrafo", View: "viewTrafo", Proj: "projTrafo",
112
- };
113
- const acquirePair = (key) => {
114
- let p = pairFor.get(key);
102
+ const ruleHashes = [];
103
+ const pairByName = new Map();
104
+ const acquireTrafo = (name) => {
105
+ let p = pairByName.get(name);
115
106
  if (p !== undefined)
116
107
  return p;
117
- const av = req.trafos[TRAFO_FIELD[key]];
108
+ const av = req.trafoAvals.get(name);
118
109
  if (av === undefined) {
119
- throw new Error(`derivedUniforms: RO requires '${key}' trafo but trafos.${TRAFO_FIELD[key]} is undefined`);
110
+ throw new Error(`derivedUniforms: rule references trafo '${name}' not available on this RO`);
120
111
  }
121
112
  p = scene.constituents.acquire(av);
122
- pairFor.set(key, p);
113
+ pairByName.set(name, p);
123
114
  acquiredAvals.push(av);
124
115
  return p;
125
116
  };
126
- const resolveConstituent = (ref) => {
127
- switch (ref) {
128
- case "Model.fwd": return acquirePair("Model").fwd;
129
- case "Model.bwd": return acquirePair("Model").inv;
130
- case "View.fwd": return acquirePair("View").fwd;
131
- case "View.bwd": return acquirePair("View").inv;
132
- case "Proj.fwd": return acquirePair("Proj").fwd;
133
- case "Proj.bwd": return acquirePair("Proj").inv;
117
+ const resolve = (inp) => {
118
+ // A matrix-typed leaf bound as an aval is a `Trafo3d` ⇒ a df32 constituent slot
119
+ // (its `Inverse` reads the stored backward half — free).
120
+ if (inp.type.kind === "Matrix" && req.trafoAvals.has(inp.name)) {
121
+ const p = acquireTrafo(inp.name);
122
+ return makeHandle(SlotTag.Constituent, inp.inverse ? p.inv : p.fwd);
134
123
  }
135
- };
136
- const recordIds = [];
137
- for (const name of req.requiredNames) {
138
- const id = recipeIdByName(name);
139
- if (id === undefined) {
140
- throw new Error(`derivedUniforms: unknown derived name '${name}'`);
124
+ // Anything else is a plain host uniform — whatever value reached this RO (the sg
125
+ // already collapsed any subtree overrides).
126
+ if (inp.inverse) {
127
+ throw new Error(`derivedUniforms: Inverse of a non-constituent input '${inp.name}' is not supported`);
141
128
  }
142
- const off = req.byteOffsetByName.get(name);
143
- if (off === undefined) {
144
- throw new Error(`derivedUniforms: '${name}' has no byte offset in drawHeader for this RO`);
129
+ const off = req.hostUniformOffset(inp.name);
130
+ if (off !== undefined)
131
+ return makeHandle(SlotTag.HostHeap, req.drawHeaderBaseByte + off);
132
+ throw new Error(`derivedUniforms: rule input '${inp.name}' cannot be resolved on this RO ` +
133
+ `(not a Trafo3d binding, and non-trafo host-uniform leaves aren't supported yet)`);
134
+ };
135
+ for (const [outName, rule] of req.rules) {
136
+ // `flatten` returns the same Expr object when nothing was substituted (the common case —
137
+ // the standard recipes reference no derived names), so we can reuse `rule` (it already
138
+ // carries a precomputed `.hash`) and skip a redundant IR hash walk per RO.
139
+ const flatIr = flatten(outName, rule.ir, req.rules);
140
+ const flat = flatIr === rule.ir ? rule : ruleFromIR(flatIr, rule.outputType);
141
+ const id = scene.registry.register(flat);
142
+ ruleHashes.push(flat.hash);
143
+ const entry = scene.registry.get(id);
144
+ const inSlots = entry.inputs.map(resolve);
145
+ const outOff = req.outputOffset(outName);
146
+ if (outOff === undefined) {
147
+ throw new Error(`derivedUniforms: no drawHeader slot for derived uniform '${outName}' on this RO`);
145
148
  }
146
- const refs = recipeInputs(id);
147
- const slots = refs.map(resolveConstituent);
148
- const inCount = recipeInputCount(id);
149
- const rec = {
150
- recipe: id,
151
- in0: slots[0],
152
- in1: inCount >= 2 ? slots[1] : 0,
153
- in2: inCount >= 3 ? slots[2] : 0,
154
- outByte: req.drawHeaderBaseByte + off,
155
- };
156
- recordIds.push(scene.dispatcher.records.add(rec));
149
+ scene.records.add(owner, id, makeHandle(SlotTag.HostHeap, req.drawHeaderBaseByte + outOff), inSlots);
157
150
  }
158
- return { recordIds, constituentAvals: acquiredAvals };
151
+ scene.ensureConstituentsCapacity(scene.constituents.slotCount * DF32_MAT4_BYTES);
152
+ return { owner, constituentAvals: acquiredAvals, ruleHashes };
159
153
  }
160
154
  export function deregisterRoDerivations(scene, reg) {
161
- for (const id of reg.recordIds)
162
- scene.dispatcher.records.remove(id);
155
+ scene.records.removeAllForOwner(reg.owner);
156
+ for (const h of reg.ruleHashes)
157
+ scene.registry.release(h);
163
158
  for (const av of reg.constituentAvals)
164
159
  scene.constituents.release(av);
165
160
  }
166
- export function isDerivedUniformName(name) {
167
- return DERIVED_UNIFORM_NAMES.has(name);
168
- }
169
- // Re-export RecipeId for callers (e.g. heapScene's drawHeader walk).
170
- export { RecipeId };
171
161
  //# sourceMappingURL=sceneIntegration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sceneIntegration.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/sceneIntegration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sceneIntegration.js","sourceRoot":"","sources":["../../../src/runtime/derivedUniforms/sceneIntegration.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"heapScene.d.ts","sourceRoot":"","sources":["../../src/runtime/heapScene.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heapScene.d.ts","sourceRoot":"","sources":["../../src/runtime/heapScene.ts"],"names":[],"mappings":"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"}
@@ -48,7 +48,7 @@ import { compileHeapEffectIR } from "./heapEffectIR.js";
48
48
  import { buildShaderFamily, compileShaderFamily, } from "./heapShaderFamily.js";
49
49
  import { ATLAS_PAGE_FORMATS, atlasFormatIndex, } from "./textureAtlas/atlasPool.js";
50
50
  import { ATLAS_ARRAY_SIZE, ATLAS_LINEAR_BINDING_BASE, ATLAS_SRGB_BINDING_BASE, ATLAS_SAMPLER_BINDING, } from "./heapEffect.js";
51
- import { DerivedUniformsScene, registerRoDerivations, deregisterRoDerivations, isDerivedUniformName, } from "./derivedUniforms/index.js";
51
+ import { DerivedUniformsScene, registerRoDerivations, deregisterRoDerivations, isDerivedRule, STANDARD_DERIVED_RULES, STANDARD_TRAFO_LEAVES, inputsOf, } from "./derivedUniforms/index.js";
52
52
  // ---------------------------------------------------------------------------
53
53
  // Per-allocation arena layout
54
54
  // ---------------------------------------------------------------------------
@@ -1058,18 +1058,49 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
1058
1058
  // ─── §7 derived-uniforms (opt-in) ─────────────────────────────────
1059
1059
  // Constructed lazily after sceneObj so the SubscribeFn can reference
1060
1060
  // both. `derivedScene` is undefined when the option is off; nothing
1061
- // else in this file should run when it is.
1062
- const enableDerivedUniforms = opts.enableDerivedUniforms === true;
1061
+ // else in this file should run when it is. On by default — pass
1062
+ // `enableDerivedUniforms: false` to opt out.
1063
+ const enableDerivedUniforms = opts.enableDerivedUniforms !== false;
1063
1064
  const derivedScene = enableDerivedUniforms
1064
1065
  ? new DerivedUniformsScene(device, arena.attrs.buffer, {
1065
1066
  // Larger initial capacity reduces grow-during-first-frame churn.
1066
1067
  initialConstituentSlots: 4096,
1067
- initialRecordCapacity: 8192,
1068
1068
  })
1069
1069
  : undefined;
1070
1070
  /** Per-RO §7 registration handles, keyed by global drawId.
1071
1071
  * Drained on removeDraw to release slots + records. */
1072
1072
  const derivedByDrawId = new Map();
1073
+ /** The derived-uniform rule for a uniform binding on this RO, if any: an explicit
1074
+ * `derivedUniform(...)` value in `spec.inputs`, or a standard trafo recipe by name
1075
+ * (recipes apply only when their base-trafo leaves are actually bound on this RO —
1076
+ * otherwise the field falls back to its `spec.inputs` value, if any).
1077
+ * (A uniform binding is either a value — an aval/constant — or a rule.) */
1078
+ const ruleForUniform = (spec, name) => {
1079
+ if (derivedScene === undefined)
1080
+ return undefined;
1081
+ const v = spec.inputs[name];
1082
+ const explicit = isDerivedRule(v);
1083
+ const rule = explicit ? v : STANDARD_DERIVED_RULES.get(name);
1084
+ if (rule === undefined)
1085
+ return undefined;
1086
+ // Each input leaf must be a uniform bound on this RO (a value, not another rule): a
1087
+ // matrix-typed leaf resolves to a df32 constituent slot (it's expected to be an
1088
+ // aval<Trafo3d>); anything else reads the packed value from the drawHeader. If a leaf
1089
+ // isn't bound: for an explicit user rule that's a hard error; for a standard recipe it
1090
+ // just means "this RO doesn't supply the base trafos", so the field falls back to its
1091
+ // packed `spec.inputs` value (or errors later if there is none — same as without §7).
1092
+ for (const inp of inputsOf(rule.ir)) {
1093
+ const specName = STANDARD_TRAFO_LEAVES.get(inp.name) ?? inp.name;
1094
+ const lv = spec.inputs[specName];
1095
+ if (lv === undefined || isDerivedRule(lv)) {
1096
+ if (explicit) {
1097
+ throw new Error(`derivedUniform '${name}': leaf '${inp.name}' is not a uniform bound on this RO`);
1098
+ }
1099
+ return undefined; // standard recipe, base trafos not bound here — use the packed value
1100
+ }
1101
+ }
1102
+ return rule;
1103
+ };
1073
1104
  // ─── Atlas bindings ───────────────────────────────────────────────
1074
1105
  //
1075
1106
  // A bucket whose textures live in the atlas binds N consecutive
@@ -1940,7 +1971,7 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
1940
1971
  // pre-pass. We still allocate an arena slot here so the
1941
1972
  // drawHeader gets a valid ref written by packBucketHeader; §7
1942
1973
  // overwrites the arena data each frame the inputs are dirty.
1943
- if (derivedScene !== undefined && isDerivedUniformName(f.name)) {
1974
+ if (ruleForUniform(spec, f.name) !== undefined) {
1944
1975
  const dummyAval = AVal.constant(M44d.zero);
1945
1976
  const ref = pool.acquire(device, arena.attrs, dummyAval, M44d.zero, PACKER_MAT4.dataBytes, PACKER_MAT4.typeId, 1, PACKER_MAT4.pack);
1946
1977
  perDrawRefs.set(f.name, ref);
@@ -2064,36 +2095,57 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
2064
2095
  drawIdToLocalSlot[drawId] = localSlot;
2065
2096
  drawIdToIndexAval[drawId] = indicesAval;
2066
2097
  // ─── §7 derived-uniforms registration ────────────────────────────
2067
- // Collect the derived names this effect actually uses (i.e. fields
2068
- // declared in the drawHeader for this effect AND in the §7 set).
2069
- // For each, the kernel writes into byte offset
2070
- // localSlot * drawHeaderBytes + field.byteOffset
2071
- // i.e. this RO's drawHeader region in the bucket's drawHeap.
2098
+ // A uniform binding on this RO is either a value (aval/constant) or a rule —
2099
+ // collect the rules (explicit `derivedUniform(...)` values + standard trafo
2100
+ // recipes) for fields the effect declares. The kernel writes each result into
2101
+ // this RO's drawHeader region in the bucket's drawHeap (its arena slot).
2072
2102
  if (derivedScene !== undefined) {
2073
- const requiredNames = [];
2074
- const arenaByteOffsetByName = new Map();
2103
+ const ruleSubset = new Map();
2104
+ const outOffsetByName = new Map();
2075
2105
  for (const f of bucket.layout.drawHeaderFields) {
2076
2106
  if (f.name === "__layoutId")
2077
2107
  continue;
2078
2108
  if (!effectFields.has(f.name))
2079
2109
  continue;
2080
- if (!isDerivedUniformName(f.name))
2110
+ const rule = ruleForUniform(spec, f.name);
2111
+ if (rule === undefined)
2081
2112
  continue;
2082
2113
  const ref = perDrawRefs.get(f.name);
2083
2114
  if (ref === undefined)
2084
2115
  continue;
2085
- requiredNames.push(f.name);
2086
- arenaByteOffsetByName.set(f.name, ref + ALLOC_HEADER_PAD_TO);
2116
+ ruleSubset.set(f.name, rule);
2117
+ outOffsetByName.set(f.name, ref + ALLOC_HEADER_PAD_TO);
2087
2118
  }
2088
- if (requiredNames.length > 0) {
2089
- const reg = registerRoDerivations(derivedScene, {
2090
- trafos: {
2091
- modelTrafo: spec.inputs["ModelTrafo"],
2092
- viewTrafo: spec.inputs["ViewTrafo"],
2093
- projTrafo: spec.inputs["ProjTrafo"],
2119
+ if (ruleSubset.size > 0) {
2120
+ // Trafo avals a rule leaf may reference: the standard `Model`/`View`/`Proj`
2121
+ // leaf names (mapped to their `*Trafo` bindings), plus every aval-valued input
2122
+ // by its own name (so a `derivedUniform(u => u.ViewTrafo.mul(u.ModelTrafo))`
2123
+ // resolves `u.ViewTrafo` to that binding). resolveSource only uses these for
2124
+ // matrix-typed leaves; a non-matrix leaf falls through to the (unsupported-in-v0)
2125
+ // host path.
2126
+ const trafoAvals = new Map();
2127
+ for (const [leaf, specName] of STANDARD_TRAFO_LEAVES) {
2128
+ const av = spec.inputs[specName];
2129
+ if (av !== undefined && !isDerivedRule(av))
2130
+ trafoAvals.set(leaf, av);
2131
+ }
2132
+ for (const n of Object.keys(spec.inputs)) {
2133
+ const v = spec.inputs[n];
2134
+ if (v !== undefined && !isDerivedRule(v) && !trafoAvals.has(n))
2135
+ trafoAvals.set(n, v);
2136
+ }
2137
+ const reg = registerRoDerivations(derivedScene, {}, {
2138
+ rules: ruleSubset,
2139
+ trafoAvals,
2140
+ // A non-trafo rule leaf reads the uniform's data straight from this RO's
2141
+ // drawHeader region in the arena (= its pool ref + the alloc-header pad).
2142
+ // Only resolvable if the uniform was actually packed (i.e. it's a drawHeader
2143
+ // field of the effect too) — undefined otherwise, which `resolveSource` rejects.
2144
+ hostUniformOffset: (n) => {
2145
+ const r = perDrawRefs.get(n);
2146
+ return r === undefined ? undefined : r + ALLOC_HEADER_PAD_TO;
2094
2147
  },
2095
- requiredNames,
2096
- byteOffsetByName: arenaByteOffsetByName,
2148
+ outputOffset: (n) => outOffsetByName.get(n),
2097
2149
  drawHeaderBaseByte: 0,
2098
2150
  });
2099
2151
  derivedByDrawId.set(drawId, reg);
@@ -2438,18 +2490,18 @@ export function buildHeapScene(device, sig, initialDraws, opts = {}) {
2438
2490
  // freezes after one frame.
2439
2491
  let dirty;
2440
2492
  sceneObj.evaluateAlways(token, (t) => {
2441
- dirty = derivedScene.constituents.pullDirty(t);
2493
+ dirty = derivedScene.pullDirty(t);
2442
2494
  });
2443
2495
  const _t1 = performance.now();
2444
2496
  derivedScene.uploadDirty(dirty);
2445
2497
  const _t2 = performance.now();
2446
2498
  if (dirty.size > 0)
2447
- derivedScene.dispatcher.encode(enc);
2499
+ derivedScene.encode(enc);
2448
2500
  const _t3 = performance.now();
2449
2501
  stats.derivedPullMs = _t1 - _t0;
2450
2502
  stats.derivedUploadMs = _t2 - _t1;
2451
2503
  stats.derivedEncodeMs = _t3 - _t2;
2452
- stats.derivedRecords = derivedScene.dispatcher.records.recordCount;
2504
+ stats.derivedRecords = derivedScene.records.recordCount;
2453
2505
  }
2454
2506
  let anyDirty = false;
2455
2507
  for (const b of buckets) {