@aardworx/wombat.rendering 0.9.33 → 0.19.0

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 (107) hide show
  1. package/dist/core/renderObject.d.ts +16 -0
  2. package/dist/core/renderObject.d.ts.map +1 -1
  3. package/dist/runtime/derivedModes/kernelCodegen.d.ts +90 -0
  4. package/dist/runtime/derivedModes/kernelCodegen.d.ts.map +1 -0
  5. package/dist/runtime/derivedModes/kernelCodegen.js +623 -0
  6. package/dist/runtime/derivedModes/kernelCodegen.js.map +1 -0
  7. package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -1
  8. package/dist/runtime/derivedModes/modeKeyCpu.js +23 -67
  9. package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -1
  10. package/dist/runtime/derivedModes/partitionDispatcher.d.ts +79 -0
  11. package/dist/runtime/derivedModes/partitionDispatcher.d.ts.map +1 -0
  12. package/dist/runtime/derivedModes/partitionDispatcher.js +303 -0
  13. package/dist/runtime/derivedModes/partitionDispatcher.js.map +1 -0
  14. package/dist/runtime/derivedModes/partitionKernel.d.ts +12 -0
  15. package/dist/runtime/derivedModes/partitionKernel.d.ts.map +1 -0
  16. package/dist/runtime/derivedModes/partitionKernel.js +127 -0
  17. package/dist/runtime/derivedModes/partitionKernel.js.map +1 -0
  18. package/dist/runtime/derivedModes/partitionKernelLayout.d.ts +4 -0
  19. package/dist/runtime/derivedModes/partitionKernelLayout.d.ts.map +1 -0
  20. package/dist/runtime/derivedModes/partitionKernelLayout.js +24 -0
  21. package/dist/runtime/derivedModes/partitionKernelLayout.js.map +1 -0
  22. package/dist/runtime/derivedModes/rule.d.ts +38 -86
  23. package/dist/runtime/derivedModes/rule.d.ts.map +1 -1
  24. package/dist/runtime/derivedModes/rule.js +34 -74
  25. package/dist/runtime/derivedModes/rule.js.map +1 -1
  26. package/dist/runtime/derivedUniforms/dispatch.d.ts +10 -8
  27. package/dist/runtime/derivedUniforms/dispatch.d.ts.map +1 -1
  28. package/dist/runtime/derivedUniforms/dispatch.js +31 -18
  29. package/dist/runtime/derivedUniforms/dispatch.js.map +1 -1
  30. package/dist/runtime/derivedUniforms/marker.d.ts +90 -11
  31. package/dist/runtime/derivedUniforms/marker.d.ts.map +1 -1
  32. package/dist/runtime/derivedUniforms/marker.js +161 -15
  33. package/dist/runtime/derivedUniforms/marker.js.map +1 -1
  34. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts +25 -6
  35. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts.map +1 -1
  36. package/dist/runtime/derivedUniforms/sceneIntegration.js +61 -20
  37. package/dist/runtime/derivedUniforms/sceneIntegration.js.map +1 -1
  38. package/dist/runtime/heapAdapter.d.ts.map +1 -1
  39. package/dist/runtime/heapAdapter.js +17 -0
  40. package/dist/runtime/heapAdapter.js.map +1 -1
  41. package/dist/runtime/heapEligibility.d.ts.map +1 -1
  42. package/dist/runtime/heapEligibility.js +22 -2
  43. package/dist/runtime/heapEligibility.js.map +1 -1
  44. package/dist/runtime/heapScene/chunkedArena.d.ts +76 -0
  45. package/dist/runtime/heapScene/chunkedArena.d.ts.map +1 -0
  46. package/dist/runtime/heapScene/chunkedArena.js +223 -0
  47. package/dist/runtime/heapScene/chunkedArena.js.map +1 -0
  48. package/dist/runtime/heapScene/freelist.d.ts +55 -0
  49. package/dist/runtime/heapScene/freelist.d.ts.map +1 -0
  50. package/dist/runtime/heapScene/freelist.js +188 -0
  51. package/dist/runtime/heapScene/freelist.js.map +1 -0
  52. package/dist/runtime/heapScene/growBuffer.d.ts +23 -2
  53. package/dist/runtime/heapScene/growBuffer.d.ts.map +1 -1
  54. package/dist/runtime/heapScene/growBuffer.js +35 -3
  55. package/dist/runtime/heapScene/growBuffer.js.map +1 -1
  56. package/dist/runtime/heapScene/pools.d.ts +84 -42
  57. package/dist/runtime/heapScene/pools.d.ts.map +1 -1
  58. package/dist/runtime/heapScene/pools.js +309 -134
  59. package/dist/runtime/heapScene/pools.js.map +1 -1
  60. package/dist/runtime/heapScene.d.ts +24 -0
  61. package/dist/runtime/heapScene.d.ts.map +1 -1
  62. package/dist/runtime/heapScene.js +1158 -92
  63. package/dist/runtime/heapScene.js.map +1 -1
  64. package/dist/runtime/hybridScene.d.ts +15 -0
  65. package/dist/runtime/hybridScene.d.ts.map +1 -1
  66. package/dist/runtime/hybridScene.js +16 -0
  67. package/dist/runtime/hybridScene.js.map +1 -1
  68. package/dist/runtime/index.d.ts +4 -3
  69. package/dist/runtime/index.d.ts.map +1 -1
  70. package/dist/runtime/index.js +4 -3
  71. package/dist/runtime/index.js.map +1 -1
  72. package/dist/runtime/renderTask.d.ts +5 -0
  73. package/dist/runtime/renderTask.d.ts.map +1 -1
  74. package/dist/runtime/renderTask.js +1 -0
  75. package/dist/runtime/renderTask.js.map +1 -1
  76. package/dist/runtime/runtime.d.ts +6 -0
  77. package/dist/runtime/runtime.d.ts.map +1 -1
  78. package/dist/runtime/runtime.js +1 -0
  79. package/dist/runtime/runtime.js.map +1 -1
  80. package/dist/runtime/textureAtlas/atlasPool.d.ts +12 -0
  81. package/dist/runtime/textureAtlas/atlasPool.d.ts.map +1 -1
  82. package/dist/runtime/textureAtlas/atlasPool.js +20 -0
  83. package/dist/runtime/textureAtlas/atlasPool.js.map +1 -1
  84. package/package.json +1 -1
  85. package/src/core/renderObject.ts +16 -0
  86. package/src/runtime/derivedModes/kernelCodegen.ts +673 -0
  87. package/src/runtime/derivedModes/modeKeyCpu.ts +22 -60
  88. package/src/runtime/derivedModes/partitionDispatcher.ts +349 -0
  89. package/src/runtime/derivedModes/partitionKernelLayout.ts +25 -0
  90. package/src/runtime/derivedModes/rule.ts +66 -145
  91. package/src/runtime/derivedUniforms/dispatch.ts +48 -21
  92. package/src/runtime/derivedUniforms/marker.ts +210 -16
  93. package/src/runtime/derivedUniforms/sceneIntegration.ts +67 -20
  94. package/src/runtime/heapAdapter.ts +17 -0
  95. package/src/runtime/heapEligibility.ts +22 -1
  96. package/src/runtime/heapScene/chunkedArena.ts +238 -0
  97. package/src/runtime/heapScene/freelist.ts +196 -0
  98. package/src/runtime/heapScene/growBuffer.ts +39 -2
  99. package/src/runtime/heapScene/pools.ts +350 -143
  100. package/src/runtime/heapScene.ts +1350 -88
  101. package/src/runtime/hybridScene.ts +31 -0
  102. package/src/runtime/index.ts +12 -9
  103. package/src/runtime/renderTask.ts +6 -0
  104. package/src/runtime/runtime.ts +7 -0
  105. package/src/runtime/textureAtlas/atlasPool.ts +19 -0
  106. package/src/runtime/derivedModes/gpuDispatcher.ts +0 -226
  107. package/src/runtime/derivedModes/gpuKernel.ts +0 -98
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkedArena.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/chunkedArena.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * A best-fit free-block manager. All offsets and sizes are in the
3
+ * caller's units (bytes for the attribute arena, u32 elements for
4
+ * the index allocator); the freelist doesn't interpret them.
5
+ */
6
+ export declare class Freelist {
7
+ /** size → set of starting offsets currently free at that size. */
8
+ private readonly bySize;
9
+ /** Sorted ascending list of every size present in `bySize`. */
10
+ private readonly sizes;
11
+ /** off → size, for the right-coalesce probe in `release`. */
12
+ private readonly byStart;
13
+ /** off+size (= end offset) → off, for the left-coalesce probe. */
14
+ private readonly byEnd;
15
+ /** Number of distinct free blocks currently tracked. */
16
+ get blockCount(): number;
17
+ /**
18
+ * Return any offset of a free block whose size is ≥ `size`, splitting
19
+ * off any leftover bytes back into the freelist. Returns `undefined`
20
+ * when no block fits.
21
+ */
22
+ alloc(size: number): number | undefined;
23
+ /**
24
+ * Reintroduce a `(off, size)` block, coalescing with any immediate
25
+ * neighbour on the left (some other block ending at `off`) or right
26
+ * (some other block starting at `off + size`).
27
+ */
28
+ release(off: number, size: number): void;
29
+ /**
30
+ * Take and remove the free block whose end offset is exactly
31
+ * `endOff`, if any exists. Used by `AttributeArena` /
32
+ * `IndexAllocator` to shrink the bump cursor back when releases
33
+ * expose a free tail (§5 — cursor-shrink hygiene for long-lived
34
+ * high-churn scenes).
35
+ */
36
+ takeBlockEndingAt(endOff: number): {
37
+ off: number;
38
+ size: number;
39
+ } | undefined;
40
+ /** Drop every block. */
41
+ clear(): void;
42
+ /** Snapshot for tests / debugging — sorted by offset. */
43
+ toArray(): Array<{
44
+ off: number;
45
+ size: number;
46
+ }>;
47
+ /** Internal consistency check (paranoia mode). Walks the freelist
48
+ * and asserts no two blocks overlap. O(N log N). Cheap enough to
49
+ * run after every alloc/release while debugging an allocator
50
+ * invariant violation. Throws with the offending pair on failure. */
51
+ assertInvariants(where: string): void;
52
+ private addBlock;
53
+ private removeBlock;
54
+ }
55
+ //# sourceMappingURL=freelist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freelist.d.ts","sourceRoot":"","sources":["../../../src/runtime/heapScene/freelist.ts"],"names":[],"mappings":"AA+BA;;;;GAIG;AACH,qBAAa,QAAQ;IACnB,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,wDAAwD;IACxD,IAAI,UAAU,IAAI,MAAM,CAA8B;IAEtD;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAavC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAqBxC;;;;;;OAMG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAQ5E,wBAAwB;IACxB,KAAK,IAAI,IAAI;IAOb,yDAAyD;IACzD,OAAO,IAAI,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAO/C;;;0EAGsE;IACtE,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA+BrC,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,WAAW;CAYpB"}
@@ -0,0 +1,188 @@
1
+ // Freelist — best-fit free-block manager used by AttributeArena and
2
+ // IndexAllocator. Replaces the earlier `{off,size}[]` sorted-by-off
3
+ // freelist (whose alloc was O(N) first-fit and release was O(log N)
4
+ // binary-search-then-coalesce).
5
+ //
6
+ // Design:
7
+ //
8
+ // bySize: size → Set<off> — exact-size buckets
9
+ // sizes: sorted ascending array of distinct sizes — for lower_bound
10
+ // byStart: off → size — for right-coalesce
11
+ // byEnd: off+size → off — for left-coalesce
12
+ //
13
+ // `alloc(size)` → lower_bound(sizes, size) picks the smallest bucket
14
+ // with size ≥ requested. O(log K) lookup over distinct
15
+ // sizes K (typically dozens), then constant-time pop
16
+ // from the size's offset set. If the bucket size
17
+ // exceeds the request, the remainder reinserts at
18
+ // (off+size, leftover).
19
+ // `release(o,s)` → check `byEnd[o]` (left neighbour ends here) and
20
+ // `byStart[o+s]` (right neighbour starts here) for
21
+ // O(1) adjacency lookups. Coalesce both sides then
22
+ // reinsert one merged block.
23
+ //
24
+ // On realistic heap-renderer workloads the number of *distinct*
25
+ // free-block sizes is typically much smaller than the number of
26
+ // blocks (allocations cluster around the schema's drawHeader
27
+ // fields: mat4=64B, vec4=16B, …), so the K-sized sorted array's
28
+ // splice cost stays cheap even at thousands of live free blocks.
29
+ // For truly heterogeneous workloads, swap `sizes` for a balanced
30
+ // tree — none of the API changes.
31
+ /**
32
+ * A best-fit free-block manager. All offsets and sizes are in the
33
+ * caller's units (bytes for the attribute arena, u32 elements for
34
+ * the index allocator); the freelist doesn't interpret them.
35
+ */
36
+ export class Freelist {
37
+ /** size → set of starting offsets currently free at that size. */
38
+ bySize = new Map();
39
+ /** Sorted ascending list of every size present in `bySize`. */
40
+ sizes = [];
41
+ /** off → size, for the right-coalesce probe in `release`. */
42
+ byStart = new Map();
43
+ /** off+size (= end offset) → off, for the left-coalesce probe. */
44
+ byEnd = new Map();
45
+ /** Number of distinct free blocks currently tracked. */
46
+ get blockCount() { return this.byStart.size; }
47
+ /**
48
+ * Return any offset of a free block whose size is ≥ `size`, splitting
49
+ * off any leftover bytes back into the freelist. Returns `undefined`
50
+ * when no block fits.
51
+ */
52
+ alloc(size) {
53
+ const idx = lowerBound(this.sizes, size);
54
+ if (idx >= this.sizes.length)
55
+ return undefined;
56
+ const foundSize = this.sizes[idx];
57
+ const set = this.bySize.get(foundSize);
58
+ // Set iteration order is insertion order — using the first inserted
59
+ // gives deterministic alloc patterns under matched test workloads.
60
+ const off = set.values().next().value;
61
+ this.removeBlock(off, foundSize);
62
+ if (foundSize > size)
63
+ this.addBlock(off + size, foundSize - size);
64
+ return off;
65
+ }
66
+ /**
67
+ * Reintroduce a `(off, size)` block, coalescing with any immediate
68
+ * neighbour on the left (some other block ending at `off`) or right
69
+ * (some other block starting at `off + size`).
70
+ */
71
+ release(off, size) {
72
+ let mergeOff = off;
73
+ let mergeSize = size;
74
+ // Left neighbour: a block whose end offset is exactly `off`.
75
+ const leftStart = this.byEnd.get(mergeOff);
76
+ if (leftStart !== undefined) {
77
+ const leftSize = this.byStart.get(leftStart);
78
+ this.removeBlock(leftStart, leftSize);
79
+ mergeOff = leftStart;
80
+ mergeSize += leftSize;
81
+ }
82
+ // Right neighbour: a block whose start offset is exactly `off + size`.
83
+ const rightStart = mergeOff + mergeSize;
84
+ const rightSize = this.byStart.get(rightStart);
85
+ if (rightSize !== undefined) {
86
+ this.removeBlock(rightStart, rightSize);
87
+ mergeSize += rightSize;
88
+ }
89
+ this.addBlock(mergeOff, mergeSize);
90
+ }
91
+ /**
92
+ * Take and remove the free block whose end offset is exactly
93
+ * `endOff`, if any exists. Used by `AttributeArena` /
94
+ * `IndexAllocator` to shrink the bump cursor back when releases
95
+ * expose a free tail (§5 — cursor-shrink hygiene for long-lived
96
+ * high-churn scenes).
97
+ */
98
+ takeBlockEndingAt(endOff) {
99
+ const off = this.byEnd.get(endOff);
100
+ if (off === undefined)
101
+ return undefined;
102
+ const size = this.byStart.get(off);
103
+ this.removeBlock(off, size);
104
+ return { off, size };
105
+ }
106
+ /** Drop every block. */
107
+ clear() {
108
+ this.bySize.clear();
109
+ this.sizes.length = 0;
110
+ this.byStart.clear();
111
+ this.byEnd.clear();
112
+ }
113
+ /** Snapshot for tests / debugging — sorted by offset. */
114
+ toArray() {
115
+ const out = [];
116
+ for (const [off, size] of this.byStart)
117
+ out.push({ off, size });
118
+ out.sort((a, b) => a.off - b.off);
119
+ return out;
120
+ }
121
+ /** Internal consistency check (paranoia mode). Walks the freelist
122
+ * and asserts no two blocks overlap. O(N log N). Cheap enough to
123
+ * run after every alloc/release while debugging an allocator
124
+ * invariant violation. Throws with the offending pair on failure. */
125
+ assertInvariants(where) {
126
+ const blocks = this.toArray();
127
+ for (let i = 1; i < blocks.length; i++) {
128
+ const a = blocks[i - 1];
129
+ const b = blocks[i];
130
+ if (a.off + a.size > b.off) {
131
+ throw new Error(`Freelist@${where}: overlapping free blocks ` +
132
+ `(${a.off},${a.size}) and (${b.off},${b.size}) — ` +
133
+ `${a.off}+${a.size}=${a.off + a.size} > ${b.off}`);
134
+ }
135
+ }
136
+ for (const [off, size] of this.byStart) {
137
+ const endLookup = this.byEnd.get(off + size);
138
+ if (endLookup !== off) {
139
+ throw new Error(`Freelist@${where}: byStart/byEnd desync — byStart[${off}]=${size} ` +
140
+ `but byEnd[${off + size}]=${endLookup} (expected ${off})`);
141
+ }
142
+ const sizeSet = this.bySize.get(size);
143
+ if (sizeSet === undefined || !sizeSet.has(off)) {
144
+ throw new Error(`Freelist@${where}: byStart/bySize desync — byStart[${off}]=${size} ` +
145
+ `but bySize[${size}] does not contain ${off}`);
146
+ }
147
+ }
148
+ }
149
+ addBlock(off, size) {
150
+ let set = this.bySize.get(size);
151
+ if (set === undefined) {
152
+ set = new Set();
153
+ this.bySize.set(size, set);
154
+ const idx = lowerBound(this.sizes, size);
155
+ this.sizes.splice(idx, 0, size);
156
+ }
157
+ set.add(off);
158
+ this.byStart.set(off, size);
159
+ this.byEnd.set(off + size, off);
160
+ }
161
+ removeBlock(off, size) {
162
+ const set = this.bySize.get(size);
163
+ if (set === undefined)
164
+ return;
165
+ set.delete(off);
166
+ if (set.size === 0) {
167
+ this.bySize.delete(size);
168
+ const idx = lowerBound(this.sizes, size);
169
+ if (this.sizes[idx] === size)
170
+ this.sizes.splice(idx, 1);
171
+ }
172
+ this.byStart.delete(off);
173
+ this.byEnd.delete(off + size);
174
+ }
175
+ }
176
+ /** Index of the first element of `arr` that is `>= target`. */
177
+ function lowerBound(arr, target) {
178
+ let lo = 0, hi = arr.length;
179
+ while (lo < hi) {
180
+ const mid = (lo + hi) >>> 1;
181
+ if (arr[mid] < target)
182
+ lo = mid + 1;
183
+ else
184
+ hi = mid;
185
+ }
186
+ return lo;
187
+ }
188
+ //# sourceMappingURL=freelist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"freelist.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/freelist.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,17 @@ export declare const ALIGN16: (n: number) => number;
12
12
  * it allocates, and `ensureCapacity` grows when required. This
13
13
  * separates allocation policy from grow policy.
14
14
  */
15
+ /**
16
+ * Default chunk capacity cap when none is provided. We pick 256 MB as
17
+ * a safety ceiling that's well within typical adapter
18
+ * `maxStorageBufferBindingSize` (WebGPU spec minimum is 128 MB; most
19
+ * desktop GPUs expose 2 GiB+, mobile/integrated ≥ 256 MB). Callers
20
+ * that know the adapter limit should pass it explicitly so chunks
21
+ * can grow to whatever the hardware supports — see §3 in
22
+ * `docs/heap-future-work.md` and `runtime/heapScene.ts`'s scene
23
+ * factory where the device limit is threaded in.
24
+ */
25
+ export declare const DEFAULT_MAX_BUFFER_BYTES: number;
15
26
  export declare class GrowBuffer {
16
27
  private readonly device;
17
28
  private readonly label;
@@ -20,13 +31,23 @@ export declare class GrowBuffer {
20
31
  private cap;
21
32
  private used;
22
33
  private readonly listeners;
23
- constructor(device: GPUDevice, label: string, usage: GPUBufferUsageFlags, initialBytes: number);
34
+ private readonly maxBytes;
35
+ constructor(device: GPUDevice, label: string, usage: GPUBufferUsageFlags, initialBytes: number, maxBytes?: number);
24
36
  get buffer(): GPUBuffer;
25
37
  get capacity(): number;
38
+ get maxCapacity(): number;
26
39
  get usedBytes(): number;
27
40
  setUsed(n: number): void;
28
41
  onResize(cb: () => void): IDisposable;
29
- /** Ensure the buffer is at least `bytes` capacity. Grows by pow2 + copies live tail. */
42
+ /**
43
+ * Ensure the buffer is at least `bytes` capacity. Grows by pow2 +
44
+ * copies live tail. Throws if `bytes` exceeds the configured
45
+ * `maxBytes` cap — caller is expected to either open a new chunk
46
+ * (full §3 multi-draw-call path, deferred) or reject the
47
+ * allocation upstream (see `isHeapEligible`'s §2 large-object
48
+ * eject, which keeps multi-MB single ROs out of the heap arena
49
+ * entirely).
50
+ */
30
51
  ensureCapacity(bytes: number): void;
31
52
  destroy(): void;
32
53
  }
@@ -1 +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"}
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;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,QAAoB,CAAC;AAE1D,qBAAa,UAAU;IAOnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IARxB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEf,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,mBAAmB,EAC3C,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAAiC;IAe7C,IAAI,MAAM,IAAI,SAAS,CAAqB;IAC5C,IAAI,QAAQ,IAAI,MAAM,CAAqB;IAC3C,IAAI,WAAW,IAAI,MAAM,CAA0B;IACnD,IAAI,SAAS,IAAI,MAAM,CAAsB;IAC7C,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,WAAW;IAIrC;;;;;;;;OAQG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA0BnC,OAAO,IAAI,IAAI;CAChB"}
@@ -23,6 +23,17 @@ export const ALIGN16 = (n) => (n + 15) & ~15;
23
23
  * it allocates, and `ensureCapacity` grows when required. This
24
24
  * separates allocation policy from grow policy.
25
25
  */
26
+ /**
27
+ * Default chunk capacity cap when none is provided. We pick 256 MB as
28
+ * a safety ceiling that's well within typical adapter
29
+ * `maxStorageBufferBindingSize` (WebGPU spec minimum is 128 MB; most
30
+ * desktop GPUs expose 2 GiB+, mobile/integrated ≥ 256 MB). Callers
31
+ * that know the adapter limit should pass it explicitly so chunks
32
+ * can grow to whatever the hardware supports — see §3 in
33
+ * `docs/heap-future-work.md` and `runtime/heapScene.ts`'s scene
34
+ * factory where the device limit is threaded in.
35
+ */
36
+ export const DEFAULT_MAX_BUFFER_BYTES = 256 * 1024 * 1024;
26
37
  export class GrowBuffer {
27
38
  device;
28
39
  label;
@@ -31,11 +42,16 @@ export class GrowBuffer {
31
42
  cap;
32
43
  used = 0;
33
44
  listeners = new Set();
34
- constructor(device, label, usage, initialBytes) {
45
+ maxBytes;
46
+ constructor(device, label, usage, initialBytes, maxBytes = DEFAULT_MAX_BUFFER_BYTES) {
35
47
  this.device = device;
36
48
  this.label = label;
37
49
  this.usage = usage;
38
50
  this.cap = Math.max(MIN_BUFFER_BYTES, POW2(initialBytes));
51
+ this.maxBytes = Math.max(this.cap, maxBytes);
52
+ if (this.cap > this.maxBytes) {
53
+ throw new Error(`GrowBuffer '${label}': initial capacity ${this.cap} exceeds maxBytes ${this.maxBytes}`);
54
+ }
39
55
  this.buf = device.createBuffer({
40
56
  size: this.cap,
41
57
  usage: usage | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
@@ -44,17 +60,33 @@ export class GrowBuffer {
44
60
  }
45
61
  get buffer() { return this.buf; }
46
62
  get capacity() { return this.cap; }
63
+ get maxCapacity() { return this.maxBytes; }
47
64
  get usedBytes() { return this.used; }
48
65
  setUsed(n) { this.used = n; }
49
66
  onResize(cb) {
50
67
  this.listeners.add(cb);
51
68
  return { dispose: () => { this.listeners.delete(cb); } };
52
69
  }
53
- /** Ensure the buffer is at least `bytes` capacity. Grows by pow2 + copies live tail. */
70
+ /**
71
+ * Ensure the buffer is at least `bytes` capacity. Grows by pow2 +
72
+ * copies live tail. Throws if `bytes` exceeds the configured
73
+ * `maxBytes` cap — caller is expected to either open a new chunk
74
+ * (full §3 multi-draw-call path, deferred) or reject the
75
+ * allocation upstream (see `isHeapEligible`'s §2 large-object
76
+ * eject, which keeps multi-MB single ROs out of the heap arena
77
+ * entirely).
78
+ */
54
79
  ensureCapacity(bytes) {
55
80
  if (bytes <= this.cap)
56
81
  return;
57
- const newCap = POW2(bytes);
82
+ if (bytes > this.maxBytes) {
83
+ throw new Error(`GrowBuffer '${this.label}': requested ${bytes} bytes exceeds maxBytes ${this.maxBytes}. ` +
84
+ `This is the adapter's per-binding storage limit — landing larger workloads needs the ` +
85
+ `multi-chunk path (§3 in docs/heap-future-work.md) or upstream eviction via §2.`);
86
+ }
87
+ let newCap = POW2(bytes);
88
+ if (newCap > this.maxBytes)
89
+ newCap = this.maxBytes;
58
90
  const newBuf = this.device.createBuffer({
59
91
  size: newCap,
60
92
  usage: this.usage | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC,
@@ -1 +1 @@
1
- {"version":3,"file":"growBuffer.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/growBuffer.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,kEAAkE;AAClE,EAAE;AACF,oEAAoE;AACpE,qEAAqE;AACrE,6DAA6D;AAC7D,aAAa;AAIb,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE;IACxC,IAAI,CAAC,GAAG,CAAC,CAAC;IAAC,OAAO,CAAC,GAAG,CAAC;QAAE,CAAC,KAAK,CAAC,CAAC;IAAC,OAAO,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAErD;;;;;;;;;GASG;AACH,MAAM,OAAO,UAAU;IAMF;IACA;IACA;IAPX,GAAG,CAAY;IACf,GAAG,CAAS;IACZ,IAAI,GAAG,CAAC,CAAC;IACA,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IACnD,YACmB,MAAiB,EACjB,KAAa,EACb,KAA0B,EAC3C,YAAoB;QAHH,WAAM,GAAN,MAAM,CAAW;QACjB,UAAK,GAAL,KAAK,CAAQ;QACb,UAAK,GAAL,KAAK,CAAqB;QAG3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,GAAG;YACd,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC,QAAQ,GAAG,cAAc,CAAC,QAAQ;YAChE,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,KAAgB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAa,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,IAAI,SAAS,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,CAAS,IAAU,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAc;QACrB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IACD,wFAAwF;IACxF,cAAc,CAAC,KAAa;QAC1B,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG;YAAE,OAAO;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YACtC,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,cAAc,CAAC,QAAQ,GAAG,cAAc,CAAC,QAAQ;YACrE,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,aAAa,EAAE,CAAC,CAAC;YACpF,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC;QAClB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC;QAClB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS;YAAE,EAAE,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,KAAW,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;CACxC"}
1
+ {"version":3,"file":"growBuffer.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/growBuffer.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { aval, IDisposable } from "@aardworx/wombat.adaptive";
2
2
  import type { BufferView } from "../../core/bufferView.js";
3
3
  import type { HostBufferSource } from "../../core/buffer.js";
4
4
  import { GrowBuffer } from "./growBuffer.js";
5
+ import { ChunkedAttributeArena, ChunkedIndexAllocator } from "./chunkedArena.js";
5
6
  /** Per-allocation header: (u32 typeId, u32 length). Data follows
6
7
  * the header aligned up to 16 bytes (so positions/normals/etc. line
7
8
  * up for future vec4 reads). */
@@ -13,44 +14,56 @@ export declare const ENC_V3F_TIGHT = 1;
13
14
  * the shader doesn't branch on this. */
14
15
  export declare const SEM_POSITIONS = 1;
15
16
  export declare const SEM_NORMALS = 2;
17
+ /**
18
+ * One pool entry tracks a single (aval, chunkIdx) pair. Refs are
19
+ * byte offsets within the chunk's GPUBuffer; chunkIdx is implicit
20
+ * in which chunk's bind group is active at draw time (shaders
21
+ * never decode it).
22
+ */
16
23
  interface PoolEntry {
17
- /** Byte offset into the arena. Data starts at ref + ALLOC_HEADER_PAD_TO. */
24
+ readonly chunkIdx: number;
18
25
  readonly ref: number;
19
26
  readonly dataBytes: number;
20
27
  readonly typeId: number;
21
- /** Packer used to refresh the data region on aval marks. */
22
28
  readonly pack: (val: unknown, dst: Float32Array, off: number) => void;
23
29
  refcount: number;
24
30
  }
25
31
  /**
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.
32
+ * `(aval, chunkIdx)`-keyed pool of chunked-arena allocations. An
33
+ * aval that's referenced from multiple chunks (e.g. two ROs sharing
34
+ * a uniform but landing in different chunks) gets one entry per
35
+ * chunk accepted duplication cost of the multi-draw-call
36
+ * per-chunk render path (§3). Within a single chunk, ROs sharing
37
+ * an aval still share the underlying allocation.
37
38
  */
38
39
  export declare class UniformPool {
39
40
  private readonly byAval;
40
- has(av: aval<unknown>): boolean;
41
- entry(av: aval<unknown>): PoolEntry | undefined;
41
+ has(av: aval<unknown>, chunkIdx: number): boolean;
42
+ /** True when the pool holds at least one entry for `av` in any
43
+ * chunk. Used by the scene's `inputChanged` dispatch to decide
44
+ * whether a marking aval is one of our tracked allocations. */
45
+ hasAny(av: aval<unknown>): boolean;
46
+ entry(av: aval<unknown>, chunkIdx: number): PoolEntry | undefined;
47
+ /** First chunk this aval is allocated in, if any. Used by `addRO`
48
+ * to prefer co-locating a new RO with its already-allocated
49
+ * shared inputs (avoids unnecessary duplication). */
50
+ firstChunkContaining(av: aval<unknown>): number | undefined;
42
51
  /**
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.
52
+ * Acquire (or share) an allocation for `aval` in `chunkIdx`.
53
+ * Returns the byte offset within that chunk's GPUBuffer. If a
54
+ * fresh allocation is made, the value is packed + uploaded
55
+ * immediately into the chunk's CPU shadow.
48
56
  */
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;
57
+ acquire(device: GPUDevice, arena: ChunkedAttributeArena, av: aval<unknown>, chunkIdx: number, value: unknown, dataBytes: number, typeId: number, length: number, pack: (val: unknown, dst: Float32Array, off: number) => void): number;
58
+ release(arena: ChunkedAttributeArena, av: aval<unknown>, chunkIdx: number): void;
59
+ /** Re-pack one entry's data region into every chunk that holds
60
+ * this aval. When an aval is shared across N chunks (each chunk
61
+ * has its own duplicate alloc), every duplicate needs the
62
+ * refresh so all the chunks' ROs see the new value. */
63
+ repack(device: GPUDevice, arena: ChunkedAttributeArena, av: aval<unknown>, val: unknown): void;
64
+ /** Total bytes touched by `repack` for this aval — sum across
65
+ * chunks. Used by the dirty-bytes diagnostics. */
66
+ totalDataBytes(av: aval<unknown>): number;
54
67
  }
55
68
  /**
56
69
  * Aval-keyed pool over the `IndexAllocator`. Two draws referencing
@@ -65,16 +78,21 @@ export declare class UniformPool {
65
78
  * `Uint32Array` view collapse to one allocation.
66
79
  */
67
80
  export declare class IndexPool {
81
+ /** Per-aval, per-chunk bookkeeping. Same aval acquired in two
82
+ * chunks gets two entries (accepted §3 duplication). */
68
83
  private readonly byAval;
84
+ /** Per-chunk constant-aval value-dedup (§5b in-chunk). */
69
85
  private readonly byValueKey;
70
86
  private readonly bufferIds;
71
87
  private nextBufferId;
72
88
  private bufferIdOf;
73
- acquire(device: GPUDevice, indices: IndexAllocator, av: aval<Uint32Array>, arr: Uint32Array): {
89
+ firstChunkContaining(av: aval<Uint32Array>): number | undefined;
90
+ acquire(device: GPUDevice, indices: ChunkedIndexAllocator, av: aval<Uint32Array>, chunkIdx: number, arr: Uint32Array): {
91
+ chunkIdx: number;
74
92
  firstIndex: number;
75
93
  count: number;
76
94
  };
77
- release(indices: IndexAllocator, av: aval<Uint32Array>): void;
95
+ release(indices: ChunkedIndexAllocator, av: aval<Uint32Array>, chunkIdx: number): void;
78
96
  }
79
97
  /**
80
98
  * Slot-indexed allocator over a GrowBuffer. `slotBytes` is set per-
@@ -87,6 +105,8 @@ export declare class DrawHeap {
87
105
  private readonly slotBytes;
88
106
  private free;
89
107
  private nextSlot;
108
+ /** DEBUG: tracks slot live/free state. true = live (in use). */
109
+ private readonly live;
90
110
  constructor(buf: GrowBuffer, slotBytes: number);
91
111
  get buffer(): GPUBuffer;
92
112
  /** Bytes per slot — caller multiplies by slot index for byte offsets. */
@@ -107,7 +127,12 @@ export declare class DrawHeap {
107
127
  export declare class AttributeArena {
108
128
  private readonly buf;
109
129
  private cursor;
110
- private freeList;
130
+ private readonly freelist;
131
+ /** DEBUG: tracks every live allocation by start byte → size. Set
132
+ * on alloc, cleared on release. Used by `assertNoOverlap()` to
133
+ * detect allocator returning overlapping ranges. Enabled in
134
+ * development; cheap (one Map insert/delete per alloc). */
135
+ private readonly liveAllocs;
111
136
  /** CPU shadow of the entire GPU buffer; writes go here first then
112
137
  * flush() emits one writeBuffer per dirty contiguous range. */
113
138
  private shadow;
@@ -117,34 +142,42 @@ export declare class AttributeArena {
117
142
  get buffer(): GPUBuffer;
118
143
  get capacity(): number;
119
144
  get usedBytes(): number;
145
+ /** Read 4 u32s from the CPU shadow starting at byte `off`. Used by
146
+ * the validator to compare against the GPU's read-back values:
147
+ * if CPU shadow is correct but GPU shows garbage → the corruption
148
+ * came from a GPU-side write (a compute kernel writing to a wrong
149
+ * byte). If both differ from what pool.acquire wrote → CPU-side
150
+ * write path is the culprit. */
151
+ peekShadowU32(off: number, count: number): Uint32Array;
120
152
  write(dst: number, data: Uint8Array): void;
121
153
  flush(device: GPUDevice): void;
122
154
  /**
123
155
  * Allocate space for one attribute. Returns the byte ref (offset
124
156
  * to the header — data lives at ref + 16).
125
157
  */
158
+ /** Non-throwing alloc — returns `undefined` when the request
159
+ * would exceed the underlying GrowBuffer's `maxCapacity` cap.
160
+ * Used by `ChunkedAttributeArena` to probe before spilling to
161
+ * the next chunk. */
162
+ tryAlloc(dataBytes: number): number | undefined;
126
163
  alloc(dataBytes: number): number;
127
164
  release(ref: number, dataBytes: number): void;
165
+ /** Throws if the just-returned alloc overlaps any live allocation. */
166
+ private recordAlloc;
128
167
  onResize(cb: () => void): IDisposable;
129
168
  destroy(): void;
130
169
  }
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
170
  /**
140
171
  * Element-bump allocator over an index GrowBuffer (units = u32). Each
141
172
  * 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.
173
+ * is returned to a Freelist and can be reused best-fit.
143
174
  */
144
175
  export declare class IndexAllocator {
145
176
  private readonly buf;
146
177
  private cursor;
147
- private freeList;
178
+ private readonly freelist;
179
+ /** DEBUG: live index allocations tracked by start element. */
180
+ private readonly liveAllocs;
148
181
  private shadow;
149
182
  private dirtyMin;
150
183
  private dirtyMax;
@@ -153,6 +186,11 @@ export declare class IndexAllocator {
153
186
  get usedElements(): number;
154
187
  write(dstByteOffset: number, data: Uint8Array): void;
155
188
  flush(device: GPUDevice): void;
189
+ /** Non-throwing alloc — returns `undefined` when the request
190
+ * would exceed the underlying GrowBuffer's `maxCapacity` cap.
191
+ * Used by `ChunkedIndexAllocator` to probe before spilling. */
192
+ tryAlloc(elements: number): number | undefined;
193
+ private recordAlloc;
156
194
  alloc(elements: number): number;
157
195
  release(off: number, elements: number): void;
158
196
  onResize(cb: () => void): IDisposable;
@@ -161,13 +199,17 @@ export declare class IndexAllocator {
161
199
  /**
162
200
  * Global arena state: attribute / uniform data lives in `attrs`
163
201
  * (multi-typed-view storage); indices live in `indices` (separate
164
- * INDEX-usage buffer).
202
+ * INDEX-usage buffer). Both are chunked: each chunk owns a separate
203
+ * GPUBuffer + Freelist. Refs that downstream code stores are byte
204
+ * offsets within a chunk; the chunk identity is carried alongside
205
+ * (via bucket.chunkIdx in heapScene) and made implicit at draw
206
+ * time by which chunk's bind group is active.
165
207
  */
166
208
  export interface ArenaState {
167
- readonly attrs: AttributeArena;
168
- readonly indices: IndexAllocator;
209
+ readonly attrs: ChunkedAttributeArena;
210
+ readonly indices: ChunkedIndexAllocator;
169
211
  }
170
- export declare function buildArenaState(device: GPUDevice, attrBytesHint: number, idxBytesHint: number, label: string, idxExtraUsage?: GPUBufferUsageFlags): ArenaState;
212
+ export declare function buildArenaState(device: GPUDevice, attrBytesHint: number, idxBytesHint: number, label: string, idxExtraUsage?: GPUBufferUsageFlags, maxChunkBytes?: number | undefined): ArenaState;
171
213
  export declare function arenaBytes(arena: ArenaState): number;
172
214
  /** Upload a single attribute — header (typeId, length) + data — into the arena at byte offset `ref`. */
173
215
  export declare function writeAttribute(device: GPUDevice, buf: GPUBuffer, ref: number, typeId: number, length: number, data: Float32Array): void;