@aardworx/wombat.rendering 0.9.14 → 0.9.16

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 (65) hide show
  1. package/dist/runtime/derivedModes/modeKeyCpu.d.ts +62 -0
  2. package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -0
  3. package/dist/runtime/derivedModes/modeKeyCpu.js +225 -0
  4. package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -0
  5. package/dist/runtime/derivedModes/partition.d.ts +36 -0
  6. package/dist/runtime/derivedModes/partition.d.ts.map +1 -0
  7. package/dist/runtime/derivedModes/partition.js +170 -0
  8. package/dist/runtime/derivedModes/partition.js.map +1 -0
  9. package/dist/runtime/derivedModes/slotTable.d.ts +70 -0
  10. package/dist/runtime/derivedModes/slotTable.d.ts.map +1 -0
  11. package/dist/runtime/derivedModes/slotTable.js +130 -0
  12. package/dist/runtime/derivedModes/slotTable.js.map +1 -0
  13. package/dist/runtime/heapScene/growBuffer.d.ts +33 -0
  14. package/dist/runtime/heapScene/growBuffer.d.ts.map +1 -0
  15. package/dist/runtime/heapScene/growBuffer.js +76 -0
  16. package/dist/runtime/heapScene/growBuffer.js.map +1 -0
  17. package/dist/runtime/heapScene/packers.d.ts +25 -0
  18. package/dist/runtime/heapScene/packers.d.ts.map +1 -0
  19. package/dist/runtime/heapScene/packers.js +111 -0
  20. package/dist/runtime/heapScene/packers.js.map +1 -0
  21. package/dist/runtime/heapScene/pools.d.ts +181 -0
  22. package/dist/runtime/heapScene/pools.d.ts.map +1 -0
  23. package/dist/runtime/heapScene/pools.js +417 -0
  24. package/dist/runtime/heapScene/pools.js.map +1 -0
  25. package/dist/runtime/heapScene/scanKernel.d.ts +11 -0
  26. package/dist/runtime/heapScene/scanKernel.d.ts.map +1 -0
  27. package/dist/runtime/heapScene/scanKernel.js +181 -0
  28. package/dist/runtime/heapScene/scanKernel.js.map +1 -0
  29. package/dist/runtime/heapScene.d.ts.map +1 -1
  30. package/dist/runtime/heapScene.js +346 -937
  31. package/dist/runtime/heapScene.js.map +1 -1
  32. package/dist/runtime/index.d.ts +4 -0
  33. package/dist/runtime/index.d.ts.map +1 -1
  34. package/dist/runtime/index.js +5 -0
  35. package/dist/runtime/index.js.map +1 -1
  36. package/dist/runtime/pipelineCache/bitfield.d.ts +5 -0
  37. package/dist/runtime/pipelineCache/bitfield.d.ts.map +1 -0
  38. package/dist/runtime/pipelineCache/bitfield.js +201 -0
  39. package/dist/runtime/pipelineCache/bitfield.js.map +1 -0
  40. package/dist/runtime/pipelineCache/cache.d.ts +36 -0
  41. package/dist/runtime/pipelineCache/cache.d.ts.map +1 -0
  42. package/dist/runtime/pipelineCache/cache.js +108 -0
  43. package/dist/runtime/pipelineCache/cache.js.map +1 -0
  44. package/dist/runtime/pipelineCache/descriptor.d.ts +58 -0
  45. package/dist/runtime/pipelineCache/descriptor.d.ts.map +1 -0
  46. package/dist/runtime/pipelineCache/descriptor.js +100 -0
  47. package/dist/runtime/pipelineCache/descriptor.js.map +1 -0
  48. package/dist/runtime/pipelineCache/index.d.ts +5 -0
  49. package/dist/runtime/pipelineCache/index.d.ts.map +1 -0
  50. package/dist/runtime/pipelineCache/index.js +12 -0
  51. package/dist/runtime/pipelineCache/index.js.map +1 -0
  52. package/package.json +1 -1
  53. package/src/runtime/derivedModes/modeKeyCpu.ts +251 -0
  54. package/src/runtime/derivedModes/partition.ts +206 -0
  55. package/src/runtime/derivedModes/slotTable.ts +153 -0
  56. package/src/runtime/heapScene/growBuffer.ts +75 -0
  57. package/src/runtime/heapScene/packers.ts +127 -0
  58. package/src/runtime/heapScene/pools.ts +492 -0
  59. package/src/runtime/heapScene/scanKernel.ts +184 -0
  60. package/src/runtime/heapScene.ts +397 -1064
  61. package/src/runtime/index.ts +40 -0
  62. package/src/runtime/pipelineCache/bitfield.ts +225 -0
  63. package/src/runtime/pipelineCache/cache.ts +129 -0
  64. package/src/runtime/pipelineCache/descriptor.ts +150 -0
  65. package/src/runtime/pipelineCache/index.ts +37 -0
@@ -0,0 +1,130 @@
1
+ // SlotTable — per-bucket (or per-scene-scope) registry that maps a
2
+ // per-RO modeKey to a fixed slot index. Each slot owns one
3
+ // `GPURenderPipeline` and one offset into a shared indirect-args
4
+ // buffer. The partition kernel reads `modeKeyToSlot` to atomic-add a
5
+ // record's counts into the right slot; encode iterates the slots and
6
+ // emits one `drawIndirect` per slot (zero-record slots draw zero).
7
+ //
8
+ // Lifecycle:
9
+ //
10
+ // - addRO(modeKey, descriptor) → ensures the slot exists.
11
+ // - On miss, allocates a new slot, fires `precompile` for the
12
+ // missing descriptor (or `getOrCreateSync` if `sync=true`).
13
+ // - removeRO(modeKey) → drops a refcount on the slot. v1 keeps the
14
+ // slot around even at refcount=0 (pipelines are cheap to retain
15
+ // and the future case is "RO reappears next frame").
16
+ // - ready(): Promise<void> → resolves when every registered slot
17
+ // has a linked pipeline.
18
+ // - syncLookup(modeKey) → slot index or -1 (used by partition kernel
19
+ // setup; missing slot is a logical error post-ready()).
20
+ //
21
+ // This module does NOT touch heapScene. It's a generic data structure
22
+ // that the heap integration drives. Tests use a mock builder.
23
+ import { PipelineCache, encodeModeKey as encodeMK, } from "../pipelineCache/index.js";
24
+ /**
25
+ * One SlotTable per `(effect, textureSet)` bucket. The cache may be
26
+ * shared across buckets — pipelines that happen to share a descriptor
27
+ * (rare across distinct effects, since pipeline objects bake the
28
+ * shader / layout) still dedupe at the cache level if a builder
29
+ * legitimately produces the same GPURenderPipeline for the same
30
+ * descriptor key.
31
+ */
32
+ export class SlotTable {
33
+ cache;
34
+ builder;
35
+ entries = [];
36
+ byKey = new Map();
37
+ /** Tracks pending precompile promises so ready() waits for the union. */
38
+ pending = new Set();
39
+ version = 0;
40
+ constructor(cache, builder) {
41
+ this.cache = cache;
42
+ this.builder = builder;
43
+ }
44
+ /** Total slot count (linked or pending). */
45
+ get slotCount() { return this.entries.length; }
46
+ /**
47
+ * Bumps whenever a new slot is appended. Consumers (partition setup,
48
+ * indirect-args resize, GPU lookup-table upload) compare against
49
+ * their last-seen value to know when to re-upload.
50
+ */
51
+ get layoutVersion() { return this.version; }
52
+ /** Iterate all slots in slot-index order. */
53
+ *all() { yield* this.entries; }
54
+ /**
55
+ * Add (or reference-bump) the slot for `descriptor`. Returns the
56
+ * existing slot if it already exists, otherwise creates one and
57
+ * kicks off compilation via `builder` (async by default).
58
+ *
59
+ * Pass `sync: true` on the runtime-mutation path to use
60
+ * `builder.createSync` instead — the returned slot's `pipeline` will
61
+ * be populated immediately.
62
+ */
63
+ addRO(descriptor, options = {}) {
64
+ const modeKey = encodeMK(descriptor);
65
+ const existing = this.byKey.get(modeKey);
66
+ if (existing !== undefined) {
67
+ existing.refCount += 1;
68
+ return existing;
69
+ }
70
+ const slotIndex = this.entries.length;
71
+ const entry = {
72
+ slotIndex, modeKey, descriptor, refCount: 1, pipeline: null,
73
+ };
74
+ this.entries.push(entry);
75
+ this.byKey.set(modeKey, entry);
76
+ this.version += 1;
77
+ if (options.sync === true) {
78
+ entry.pipeline = this.cache.getOrCreateSync(this.builder, descriptor);
79
+ }
80
+ else {
81
+ // Use the cache's precompile path so concurrent requests
82
+ // deduplicate. Tracks promise so `ready()` blocks until done.
83
+ const p = this.cache.precompile(this.builder, [descriptor]).then(() => {
84
+ const got = this.cache.lookup(modeKey);
85
+ if (got !== null)
86
+ entry.pipeline = got;
87
+ });
88
+ this.pending.add(p);
89
+ // Auto-clean once settled.
90
+ p.finally(() => this.pending.delete(p));
91
+ }
92
+ return entry;
93
+ }
94
+ /** Drop one reference from the slot. Pipelines stay resident. */
95
+ removeRO(modeKey) {
96
+ const e = this.byKey.get(modeKey);
97
+ if (e === undefined)
98
+ return;
99
+ if (e.refCount > 0)
100
+ e.refCount -= 1;
101
+ }
102
+ /**
103
+ * Move an RO from one slot to another (reactive aval mutation
104
+ * caused its modeKey to change). Returns the new (possibly newly
105
+ * allocated) slot.
106
+ */
107
+ rebindRO(fromModeKey, toDescriptor, options = {}) {
108
+ this.removeRO(fromModeKey);
109
+ return this.addRO(toDescriptor, options);
110
+ }
111
+ /** Sync slot lookup by modeKey. Returns the entry or null. */
112
+ lookup(modeKey) {
113
+ return this.byKey.get(modeKey) ?? null;
114
+ }
115
+ /**
116
+ * Resolves when every currently-registered slot has a linked
117
+ * pipeline. Subsequent `addRO` calls after this resolves with
118
+ * `sync: false` will produce fresh pending work; call `ready()`
119
+ * again to wait.
120
+ */
121
+ async ready() {
122
+ if (this.pending.size === 0)
123
+ return;
124
+ // Snapshot current pending set; new ones added during await
125
+ // resolve on their own callers' awaits if needed.
126
+ const snap = [...this.pending];
127
+ await Promise.all(snap);
128
+ }
129
+ }
130
+ //# sourceMappingURL=slotTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slotTable.js","sourceRoot":"","sources":["../../../src/runtime/derivedModes/slotTable.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,2DAA2D;AAC3D,iEAAiE;AACjE,qEAAqE;AACrE,qEAAqE;AACrE,mEAAmE;AACnE,EAAE;AACF,aAAa;AACb,EAAE;AACF,4DAA4D;AAC5D,kEAAkE;AAClE,kEAAkE;AAClE,qEAAqE;AACrE,oEAAoE;AACpE,yDAAyD;AACzD,mEAAmE;AACnE,6BAA6B;AAC7B,uEAAuE;AACvE,4DAA4D;AAC5D,EAAE;AACF,sEAAsE;AACtE,8DAA8D;AAE9D,OAAO,EACL,aAAa,EACb,aAAa,IAAI,QAAQ,GAG1B,MAAM,2BAA2B,CAAC;AAYnC;;;;;;;GAOG;AACH,MAAM,OAAO,SAAS;IAQT;IACA;IARM,OAAO,GAAqB,EAAE,CAAC;IAC/B,KAAK,GAAK,IAAI,GAAG,EAA0B,CAAC;IAC7D,yEAAyE;IACjE,OAAO,GAA0B,IAAI,GAAG,EAAE,CAAC;IAC3C,OAAO,GAAG,CAAC,CAAC;IAEpB,YACW,KAAoB,EACpB,OAAwB;QADxB,UAAK,GAAL,KAAK,CAAe;QACpB,YAAO,GAAP,OAAO,CAAiB;IAChC,CAAC;IAEJ,4CAA4C;IAC5C,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACvD;;;;OAIG;IACH,IAAI,aAAa,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACpD,6CAA6C;IAC7C,CAAC,GAAG,KAAuC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjE;;;;;;;;OAQG;IACH,KAAK,CACH,UAAmC,EACnC,UAA8B,EAAE;QAEhC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC;YACvB,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACtC,MAAM,KAAK,GAAmB;YAC5B,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI;SAC5D,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAClB,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC1B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,8DAA8D;YAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBACpE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACvC,IAAI,GAAG,KAAK,IAAI;oBAAE,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC;YACzC,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACpB,2BAA2B;YAC3B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iEAAiE;IACjE,QAAQ,CAAC,OAAe;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO;QAC5B,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC;YAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,QAAQ,CACN,WAAmB,EACnB,YAAqC,EACrC,UAA8B,EAAE;QAEhC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,8DAA8D;IAC9D,MAAM,CAAC,OAAe;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACpC,4DAA4D;QAC5D,kDAAkD;QAClD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { IDisposable } from "@aardworx/wombat.adaptive";
2
+ export declare const MIN_BUFFER_BYTES: number;
3
+ export declare const POW2: (n: number) => number;
4
+ export declare const ALIGN16: (n: number) => number;
5
+ /**
6
+ * A GPUBuffer that can grow to next power-of-two on demand. On grow,
7
+ * a fresh buffer is created at the new size, the live tail copied
8
+ * over via copyBufferToBuffer, and dependents (bind groups, mostly)
9
+ * are notified to rebuild via the `onResize` callback.
10
+ *
11
+ * `usedBytes` is the high-water mark — the runtime advances this as
12
+ * it allocates, and `ensureCapacity` grows when required. This
13
+ * separates allocation policy from grow policy.
14
+ */
15
+ export declare class GrowBuffer {
16
+ private readonly device;
17
+ private readonly label;
18
+ private readonly usage;
19
+ private buf;
20
+ private cap;
21
+ private used;
22
+ private readonly listeners;
23
+ constructor(device: GPUDevice, label: string, usage: GPUBufferUsageFlags, initialBytes: number);
24
+ get buffer(): GPUBuffer;
25
+ get capacity(): number;
26
+ get usedBytes(): number;
27
+ setUsed(n: number): void;
28
+ onResize(cb: () => void): IDisposable;
29
+ /** Ensure the buffer is at least `bytes` capacity. Grows by pow2 + copies live tail. */
30
+ ensureCapacity(bytes: number): void;
31
+ destroy(): void;
32
+ }
33
+ //# sourceMappingURL=growBuffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"growBuffer.d.ts","sourceRoot":"","sources":["../../../src/runtime/heapScene/growBuffer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAE1C,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,KAAG,MAEhC,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,GAAG,MAAM,WAAmB,CAAC;AAErD;;;;;;;;;GASG;AACH,qBAAa,UAAU;IAMnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAPxB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;gBAEhC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,mBAAmB,EAC3C,YAAY,EAAE,MAAM;IAStB,IAAI,MAAM,IAAI,SAAS,CAAqB;IAC5C,IAAI,QAAQ,IAAI,MAAM,CAAqB;IAC3C,IAAI,SAAS,IAAI,MAAM,CAAsB;IAC7C,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,WAAW;IAIrC,wFAAwF;IACxF,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAkBnC,OAAO,IAAI,IAAI;CAChB"}
@@ -0,0 +1,76 @@
1
+ // GrowBuffer — pow2-grown GPUBuffer with a high-water mark and
2
+ // resize-listener machinery for dependents (bind groups, mostly).
3
+ //
4
+ // On grow, a fresh buffer is created at the next pow2 capacity, the
5
+ // live tail is copied over via copyBufferToBuffer, and the listeners
6
+ // (registered via `onResize`) are invoked. The old buffer is
7
+ // destroyed.
8
+ export const MIN_BUFFER_BYTES = 64 * 1024;
9
+ export const POW2 = (n) => {
10
+ let p = 1;
11
+ while (p < n)
12
+ p <<= 1;
13
+ return p;
14
+ };
15
+ export const ALIGN16 = (n) => (n + 15) & ~15;
16
+ /**
17
+ * A GPUBuffer that can grow to next power-of-two on demand. On grow,
18
+ * a fresh buffer is created at the new size, the live tail copied
19
+ * over via copyBufferToBuffer, and dependents (bind groups, mostly)
20
+ * are notified to rebuild via the `onResize` callback.
21
+ *
22
+ * `usedBytes` is the high-water mark — the runtime advances this as
23
+ * it allocates, and `ensureCapacity` grows when required. This
24
+ * separates allocation policy from grow policy.
25
+ */
26
+ export class GrowBuffer {
27
+ device;
28
+ label;
29
+ usage;
30
+ buf;
31
+ cap;
32
+ used = 0;
33
+ listeners = new Set();
34
+ constructor(device, label, usage, initialBytes) {
35
+ this.device = device;
36
+ this.label = label;
37
+ this.usage = usage;
38
+ this.cap = Math.max(MIN_BUFFER_BYTES, POW2(initialBytes));
39
+ this.buf = device.createBuffer({
40
+ size: this.cap,
41
+ usage: usage | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
42
+ label,
43
+ });
44
+ }
45
+ get buffer() { return this.buf; }
46
+ get capacity() { return this.cap; }
47
+ get usedBytes() { return this.used; }
48
+ setUsed(n) { this.used = n; }
49
+ onResize(cb) {
50
+ this.listeners.add(cb);
51
+ return { dispose: () => { this.listeners.delete(cb); } };
52
+ }
53
+ /** Ensure the buffer is at least `bytes` capacity. Grows by pow2 + copies live tail. */
54
+ ensureCapacity(bytes) {
55
+ if (bytes <= this.cap)
56
+ return;
57
+ const newCap = POW2(bytes);
58
+ const newBuf = this.device.createBuffer({
59
+ size: newCap,
60
+ usage: this.usage | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
61
+ label: this.label,
62
+ });
63
+ if (this.used > 0) {
64
+ const enc = this.device.createCommandEncoder({ label: `${this.label}: grow-copy` });
65
+ enc.copyBufferToBuffer(this.buf, 0, newBuf, 0, ALIGN16(this.used));
66
+ this.device.queue.submit([enc.finish()]);
67
+ }
68
+ this.buf.destroy();
69
+ this.buf = newBuf;
70
+ this.cap = newCap;
71
+ for (const cb of this.listeners)
72
+ cb();
73
+ }
74
+ destroy() { this.buf.destroy(); }
75
+ }
76
+ //# sourceMappingURL=growBuffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"growBuffer.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/growBuffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface WgslPacker {
2
+ /** Tightly-packed size in bytes of one value (mat4 = 64, vec3 = 12, …). */
3
+ readonly dataBytes: number;
4
+ readonly typeId: number;
5
+ /**
6
+ * Pack `val` (the aval's `.getValue(tok)` result) into `dst` at
7
+ * float offset `off`.
8
+ */
9
+ readonly pack: (val: unknown, dst: Float32Array, off: number) => void;
10
+ }
11
+ export declare const PACKER_MAT4: WgslPacker;
12
+ export declare const PACKER_VEC4: WgslPacker;
13
+ export declare const PACKER_VEC3: WgslPacker;
14
+ export declare const PACKER_VEC2: WgslPacker;
15
+ export declare const PACKER_F32: WgslPacker;
16
+ export declare const PACKER_U32: WgslPacker;
17
+ export declare const PACKER_UVEC2: WgslPacker;
18
+ export declare const PACKER_UVEC3: WgslPacker;
19
+ export declare const PACKER_UVEC4: WgslPacker;
20
+ export declare const PACKER_I32: WgslPacker;
21
+ export declare const PACKER_IVEC2: WgslPacker;
22
+ export declare const PACKER_IVEC3: WgslPacker;
23
+ export declare const PACKER_IVEC4: WgslPacker;
24
+ export declare function packerForWgslType(wgslType: string): WgslPacker;
25
+ //# sourceMappingURL=packers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packers.d.ts","sourceRoot":"","sources":["../../../src/runtime/heapScene/packers.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACvE;AASD,eAAO,MAAM,WAAW,EAAE,UASzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAOzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAOzB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAMzB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAGxB,CAAC;AA2BF,eAAO,MAAM,UAAU,YAAoC,CAAC;AAC5D,eAAO,MAAM,YAAY,YAAkC,CAAC;AAC5D,eAAO,MAAM,YAAY,YAAkC,CAAC;AAC5D,eAAO,MAAM,YAAY,YAAkC,CAAC;AAC5D,eAAO,MAAM,UAAU,YAAmC,CAAC;AAC3D,eAAO,MAAM,YAAY,YAAiC,CAAC;AAC3D,eAAO,MAAM,YAAY,YAAiC,CAAC;AAC3D,eAAO,MAAM,YAAY,YAAiC,CAAC;AAE3D,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAkB9D"}
@@ -0,0 +1,111 @@
1
+ // WGSL-type → JS-value packers used by heapScene to write per-draw
2
+ // uniforms into the arena's Float32Array staging mirror.
3
+ //
4
+ // One packer per supported WGSL type. The `pack` callback takes the
5
+ // aval's `.getValue(tok)` result and writes its bytes to `dst` at
6
+ // float offset `off`. Coerces between Trafo3d / M44d / V4f / V3d /
7
+ // V3f / number as needed.
8
+ //
9
+ // Integer scalar / vector packers go through a same-buffer Uint32/
10
+ // Int32 view to avoid the lossy i32 → f32 coercion you'd get from a
11
+ // direct `dst[off] = ...` assignment.
12
+ function packMat44(m, dst, off) {
13
+ // Zero-alloc flat copy (row-major) straight into the f32 staging
14
+ // buffer — `copyTo` does `dst.set(m._data, off)` which narrows f64→f32
15
+ // on store, no throwaway `number[]` per call.
16
+ m.copyTo(dst, off);
17
+ }
18
+ export const PACKER_MAT4 = {
19
+ dataBytes: 64, typeId: 0,
20
+ pack: (val, dst, off) => {
21
+ // Accept Trafo3d (uses .forward) or M44d directly.
22
+ const m = val.forward !== undefined
23
+ ? val.forward
24
+ : val;
25
+ packMat44(m, dst, off);
26
+ },
27
+ };
28
+ export const PACKER_VEC4 = {
29
+ dataBytes: 16, typeId: 0,
30
+ pack: (val, dst, off) => {
31
+ const v = val;
32
+ dst[off + 0] = v.x;
33
+ dst[off + 1] = v.y;
34
+ dst[off + 2] = v.z;
35
+ dst[off + 3] = v.w;
36
+ },
37
+ };
38
+ export const PACKER_VEC3 = {
39
+ dataBytes: 12, typeId: 0,
40
+ pack: (val, dst, off) => {
41
+ // V3f or V3d both expose .x/.y/.z; cast through a common shape.
42
+ const v = val;
43
+ dst[off + 0] = v.x;
44
+ dst[off + 1] = v.y;
45
+ dst[off + 2] = v.z;
46
+ },
47
+ };
48
+ export const PACKER_VEC2 = {
49
+ dataBytes: 8, typeId: 0,
50
+ pack: (val, dst, off) => {
51
+ const v = val;
52
+ dst[off + 0] = v.x;
53
+ dst[off + 1] = v.y;
54
+ },
55
+ };
56
+ export const PACKER_F32 = {
57
+ dataBytes: 4, typeId: 0,
58
+ pack: (val, dst, off) => { dst[off] = val; },
59
+ };
60
+ function makeIntPacker(ctor, dim) {
61
+ const bytes = dim * 4;
62
+ if (dim === 1) {
63
+ return {
64
+ dataBytes: bytes, typeId: 0,
65
+ pack: (val, dst, off) => {
66
+ new ctor(dst.buffer, dst.byteOffset + off * 4, 1)[0] = val;
67
+ },
68
+ };
69
+ }
70
+ return {
71
+ dataBytes: bytes, typeId: 0,
72
+ pack: (val, dst, off) => {
73
+ const view = new ctor(dst.buffer, dst.byteOffset + off * 4, dim);
74
+ const v = val;
75
+ view[0] = v.x;
76
+ view[1] = v.y;
77
+ if (dim >= 3)
78
+ view[2] = v.z;
79
+ if (dim >= 4)
80
+ view[3] = v.w;
81
+ },
82
+ };
83
+ }
84
+ export const PACKER_U32 = makeIntPacker(Uint32Array, 1);
85
+ export const PACKER_UVEC2 = makeIntPacker(Uint32Array, 2);
86
+ export const PACKER_UVEC3 = makeIntPacker(Uint32Array, 3);
87
+ export const PACKER_UVEC4 = makeIntPacker(Uint32Array, 4);
88
+ export const PACKER_I32 = makeIntPacker(Int32Array, 1);
89
+ export const PACKER_IVEC2 = makeIntPacker(Int32Array, 2);
90
+ export const PACKER_IVEC3 = makeIntPacker(Int32Array, 3);
91
+ export const PACKER_IVEC4 = makeIntPacker(Int32Array, 4);
92
+ export function packerForWgslType(wgslType) {
93
+ switch (wgslType) {
94
+ case "mat4x4<f32>": return PACKER_MAT4;
95
+ case "vec4<f32>": return PACKER_VEC4;
96
+ case "vec3<f32>": return PACKER_VEC3;
97
+ case "vec2<f32>": return PACKER_VEC2;
98
+ case "f32": return PACKER_F32;
99
+ case "u32": return PACKER_U32;
100
+ case "vec2<u32>": return PACKER_UVEC2;
101
+ case "vec3<u32>": return PACKER_UVEC3;
102
+ case "vec4<u32>": return PACKER_UVEC4;
103
+ case "i32": return PACKER_I32;
104
+ case "vec2<i32>": return PACKER_IVEC2;
105
+ case "vec3<i32>": return PACKER_IVEC3;
106
+ case "vec4<i32>": return PACKER_IVEC4;
107
+ default:
108
+ throw new Error(`heapScene: no JS-side packer for WGSL type '${wgslType}'`);
109
+ }
110
+ }
111
+ //# sourceMappingURL=packers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packers.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/packers.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,yDAAyD;AACzD,EAAE;AACF,oEAAoE;AACpE,kEAAkE;AAClE,mEAAmE;AACnE,0BAA0B;AAC1B,EAAE;AACF,mEAAmE;AACnE,oEAAoE;AACpE,sCAAsC;AAetC,SAAS,SAAS,CAAC,CAAO,EAAE,GAAiB,EAAE,GAAW;IACxD,iEAAiE;IACjE,uEAAuE;IACvE,8CAA8C;IAC9C,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACtB,mDAAmD;QACnD,MAAM,CAAC,GAAI,GAA0B,CAAC,OAAO,KAAK,SAAS;YACzD,CAAC,CAAE,GAAyB,CAAC,OAAO;YACpC,CAAC,CAAE,GAAY,CAAC;QAClB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,GAAU,CAAC;QACrB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACtB,gEAAgE;QAChE,MAAM,CAAC,GAAG,GAA0C,CAAC;QACrD,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAe;IACrC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,GAA+B,CAAC;QAC1C,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,GAAa,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,SAAS,aAAa,CACpB,IAA4C,EAC5C,GAAkB;IAElB,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;IACtB,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACd,OAAO;YACL,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAC3B,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;gBACtB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAqB,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAa,CAAC;YACtF,CAAC;SACF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAqB,EAAE,GAAG,CAAC,UAAU,GAAG,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YAChF,MAAM,CAAC,GAAG,GAAuD,CAAC;YAClE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,GAAG,IAAI,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;YAC7B,IAAI,GAAG,IAAI,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC;QAC/B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAO,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAO,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAK,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAE3D,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,aAAa,CAAC,CAAC,OAAO,WAAW,CAAC;QACvC,KAAK,WAAW,CAAC,CAAG,OAAO,WAAW,CAAC;QACvC,KAAK,WAAW,CAAC,CAAG,OAAO,WAAW,CAAC;QACvC,KAAK,WAAW,CAAC,CAAG,OAAO,WAAW,CAAC;QACvC,KAAK,KAAK,CAAC,CAAS,OAAO,UAAU,CAAC;QACtC,KAAK,KAAK,CAAC,CAAS,OAAO,UAAU,CAAC;QACtC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC,KAAK,KAAK,CAAC,CAAS,OAAO,UAAU,CAAC;QACtC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC,KAAK,WAAW,CAAC,CAAG,OAAO,YAAY,CAAC;QACxC;YACE,MAAM,IAAI,KAAK,CAAC,+CAA+C,QAAQ,GAAG,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
@@ -0,0 +1,181 @@
1
+ import type { aval, IDisposable } from "@aardworx/wombat.adaptive";
2
+ import type { BufferView } from "../../core/bufferView.js";
3
+ import type { HostBufferSource } from "../../core/buffer.js";
4
+ import { GrowBuffer } from "./growBuffer.js";
5
+ /** Per-allocation header: (u32 typeId, u32 length). Data follows
6
+ * the header aligned up to 16 bytes (so positions/normals/etc. line
7
+ * up for future vec4 reads). */
8
+ export declare const ALLOC_HEADER_BYTES = 8;
9
+ export declare const ALLOC_HEADER_PAD_TO = 16;
10
+ /** Encoding-tag enum (low 16 bits of typeId). */
11
+ export declare const ENC_V3F_TIGHT = 1;
12
+ /** Semantic-tag enum (high 16 bits of typeId). Optional metadata —
13
+ * the shader doesn't branch on this. */
14
+ export declare const SEM_POSITIONS = 1;
15
+ export declare const SEM_NORMALS = 2;
16
+ interface PoolEntry {
17
+ /** Byte offset into the arena. Data starts at ref + ALLOC_HEADER_PAD_TO. */
18
+ readonly ref: number;
19
+ readonly dataBytes: number;
20
+ readonly typeId: number;
21
+ /** Packer used to refresh the data region on aval marks. */
22
+ readonly pack: (val: unknown, dst: Float32Array, off: number) => void;
23
+ refcount: number;
24
+ }
25
+ /**
26
+ * Aval-keyed pool of arena allocations. One allocation per unique
27
+ * aval (object identity). Two draws referencing the same aval share
28
+ * the allocation; their DrawHeaders carry the same u32 ref. Holds
29
+ * uniforms (fixed-size scalars/vectors/matrices) AND attribute arrays
30
+ * (variable-size). The caller decides `dataBytes` + `length` per
31
+ * acquisition — the pool just keys on aval identity and refcounts.
32
+ *
33
+ * Sharing emerges from aval identity — no separate "frequency"
34
+ * declaration needed. A `cval` shared by all draws → 1 alloc.
35
+ * A static positions array shared across instanced draws → 1 alloc.
36
+ * Same code path either way.
37
+ */
38
+ export declare class UniformPool {
39
+ private readonly byAval;
40
+ has(av: aval<unknown>): boolean;
41
+ entry(av: aval<unknown>): PoolEntry | undefined;
42
+ /**
43
+ * Acquire (or share) an allocation for `aval`. Caller passes the
44
+ * pre-read `value` (so the pool doesn't need a token) plus the
45
+ * (`dataBytes`, `typeId`, `length`, `pack`) describing how to lay
46
+ * it out. If a new allocation is made, the value is packed and
47
+ * uploaded immediately.
48
+ */
49
+ acquire(device: GPUDevice, arena: AttributeArena, av: aval<unknown>, value: unknown, dataBytes: number, typeId: number, length: number, pack: (val: unknown, dst: Float32Array, off: number) => void): number;
50
+ /** Decrement refcount; if zero, free the arena allocation. */
51
+ release(arena: AttributeArena, av: aval<unknown>): void;
52
+ /** Re-pack one entry's data region into the arena's CPU shadow. */
53
+ repack(device: GPUDevice, arena: AttributeArena, av: aval<unknown>, val: unknown): void;
54
+ }
55
+ /**
56
+ * Aval-keyed pool over the `IndexAllocator`. Two draws referencing
57
+ * the same `Uint32Array` (or aval thereof) share an index range —
58
+ * 19K instanced clones of the same mesh share one allocation, one
59
+ * upload.
60
+ *
61
+ * **Value-equality dedup for constant avals (§5b):** when an
62
+ * incoming aval has `isConstant === true`, the pool also keys by
63
+ * the underlying `ArrayBuffer` tuple `(buffer, byteOffset,
64
+ * byteLength)`. Two distinct constant avals wrapping the same
65
+ * `Uint32Array` view collapse to one allocation.
66
+ */
67
+ export declare class IndexPool {
68
+ private readonly byAval;
69
+ private readonly byValueKey;
70
+ private readonly bufferIds;
71
+ private nextBufferId;
72
+ private bufferIdOf;
73
+ acquire(device: GPUDevice, indices: IndexAllocator, av: aval<Uint32Array>, arr: Uint32Array): {
74
+ firstIndex: number;
75
+ count: number;
76
+ };
77
+ release(indices: IndexAllocator, av: aval<Uint32Array>): void;
78
+ }
79
+ /**
80
+ * Slot-indexed allocator over a GrowBuffer. `slotBytes` is set per-
81
+ * instance — each bucket sizes its DrawHeader from its effect's
82
+ * schema, so a bucket whose layout is e.g. 96 B / slot uses a
83
+ * DrawHeap with `slotBytes=96`.
84
+ */
85
+ export declare class DrawHeap {
86
+ private readonly buf;
87
+ private readonly slotBytes;
88
+ private free;
89
+ private nextSlot;
90
+ constructor(buf: GrowBuffer, slotBytes: number);
91
+ get buffer(): GPUBuffer;
92
+ /** Bytes per slot — caller multiplies by slot index for byte offsets. */
93
+ get bytesPerSlot(): number;
94
+ /** High-water mark in bytes (used to size bind-group entry on rebuild). */
95
+ get usedBytes(): number;
96
+ alloc(): number;
97
+ release(slot: number): void;
98
+ onResize(cb: () => void): IDisposable;
99
+ destroy(): void;
100
+ }
101
+ /**
102
+ * Byte-bump allocator over a GrowBuffer for variable-size attribute
103
+ * allocations. Each allocation gets a 16-byte aligned start (8-byte
104
+ * (typeId, length) header at the start, data 16 bytes in). Frees go
105
+ * onto a sorted free list with coalesce on insert.
106
+ */
107
+ export declare class AttributeArena {
108
+ private readonly buf;
109
+ private cursor;
110
+ private freeList;
111
+ /** CPU shadow of the entire GPU buffer; writes go here first then
112
+ * flush() emits one writeBuffer per dirty contiguous range. */
113
+ private shadow;
114
+ private dirtyMin;
115
+ private dirtyMax;
116
+ constructor(buf: GrowBuffer);
117
+ get buffer(): GPUBuffer;
118
+ get capacity(): number;
119
+ get usedBytes(): number;
120
+ write(dst: number, data: Uint8Array): void;
121
+ flush(device: GPUDevice): void;
122
+ /**
123
+ * Allocate space for one attribute. Returns the byte ref (offset
124
+ * to the header — data lives at ref + 16).
125
+ */
126
+ alloc(dataBytes: number): number;
127
+ release(ref: number, dataBytes: number): void;
128
+ onResize(cb: () => void): IDisposable;
129
+ destroy(): void;
130
+ }
131
+ /**
132
+ * Insert `{off, size}` into a free-list kept sorted by `off`, then
133
+ * coalesce with the two immediate neighbours.
134
+ */
135
+ export declare function insertSortedFreeBlock(freeList: {
136
+ off: number;
137
+ size: number;
138
+ }[], off: number, size: number): void;
139
+ /**
140
+ * Element-bump allocator over an index GrowBuffer (units = u32). Each
141
+ * draw's index range is allocated as one block; on release the block
142
+ * is returned to a free list and can be reused first-fit.
143
+ */
144
+ export declare class IndexAllocator {
145
+ private readonly buf;
146
+ private cursor;
147
+ private freeList;
148
+ private shadow;
149
+ private dirtyMin;
150
+ private dirtyMax;
151
+ constructor(buf: GrowBuffer);
152
+ get buffer(): GPUBuffer;
153
+ get usedElements(): number;
154
+ write(dstByteOffset: number, data: Uint8Array): void;
155
+ flush(device: GPUDevice): void;
156
+ alloc(elements: number): number;
157
+ release(off: number, elements: number): void;
158
+ onResize(cb: () => void): IDisposable;
159
+ destroy(): void;
160
+ }
161
+ /**
162
+ * Global arena state: attribute / uniform data lives in `attrs`
163
+ * (multi-typed-view storage); indices live in `indices` (separate
164
+ * INDEX-usage buffer).
165
+ */
166
+ export interface ArenaState {
167
+ readonly attrs: AttributeArena;
168
+ readonly indices: IndexAllocator;
169
+ }
170
+ export declare function buildArenaState(device: GPUDevice, attrBytesHint: number, idxBytesHint: number, label: string, idxExtraUsage?: GPUBufferUsageFlags): ArenaState;
171
+ export declare function arenaBytes(arena: ArenaState): number;
172
+ /** Upload a single attribute — header (typeId, length) + data — into the arena at byte offset `ref`. */
173
+ export declare function writeAttribute(device: GPUDevice, buf: GPUBuffer, ref: number, typeId: number, length: number, data: Float32Array): void;
174
+ export declare function asAval<T>(v: aval<T> | T): aval<T>;
175
+ /** Heuristic predicate — BufferView has `buffer: aval<IBuffer>` + elementType. */
176
+ export declare function isBufferView(v: unknown): v is BufferView;
177
+ /** Float32 view over a host-side buffer source. Used by the BufferView
178
+ * packer to hand the pool a typed array it can `set()` from. */
179
+ export declare function asFloat32(data: HostBufferSource): Float32Array;
180
+ export {};
181
+ //# sourceMappingURL=pools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pools.d.ts","sourceRoot":"","sources":["../../../src/runtime/heapScene/pools.ts"],"names":[],"mappings":"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"}