@aardworx/wombat.rendering 0.19.23 → 0.19.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/elementType.d.ts +2 -0
- package/dist/core/elementType.d.ts.map +1 -1
- package/dist/core/elementType.js +10 -0
- package/dist/core/elementType.js.map +1 -1
- package/dist/core/provider.d.ts.map +1 -1
- package/dist/core/provider.js +65 -32
- package/dist/core/provider.js.map +1 -1
- package/dist/core/renderObject.d.ts +9 -0
- package/dist/core/renderObject.d.ts.map +1 -1
- package/dist/resources/preparedRenderObject.d.ts.map +1 -1
- package/dist/resources/preparedRenderObject.js +19 -2
- package/dist/resources/preparedRenderObject.js.map +1 -1
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts +2 -12
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -1
- package/dist/runtime/derivedModes/modeKeyCpu.js +30 -13
- package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -1
- package/dist/runtime/derivedModes/partitionDispatcher.d.ts +11 -0
- package/dist/runtime/derivedModes/partitionDispatcher.d.ts.map +1 -1
- package/dist/runtime/derivedModes/partitionDispatcher.js +31 -0
- package/dist/runtime/derivedModes/partitionDispatcher.js.map +1 -1
- package/dist/runtime/derivedUniforms/dispatch.d.ts +5 -1
- package/dist/runtime/derivedUniforms/dispatch.d.ts.map +1 -1
- package/dist/runtime/derivedUniforms/dispatch.js +28 -13
- package/dist/runtime/derivedUniforms/dispatch.js.map +1 -1
- package/dist/runtime/derivedUniforms/records.d.ts +15 -0
- package/dist/runtime/derivedUniforms/records.d.ts.map +1 -1
- package/dist/runtime/derivedUniforms/records.js +81 -14
- package/dist/runtime/derivedUniforms/records.js.map +1 -1
- package/dist/runtime/derivedUniforms/sceneIntegration.d.ts +6 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.d.ts.map +1 -1
- package/dist/runtime/derivedUniforms/sceneIntegration.js +9 -0
- package/dist/runtime/derivedUniforms/sceneIntegration.js.map +1 -1
- package/dist/runtime/flattenTree.d.ts.map +1 -1
- package/dist/runtime/flattenTree.js +46 -2
- package/dist/runtime/flattenTree.js.map +1 -1
- package/dist/runtime/heapAdapter.d.ts +3 -1
- package/dist/runtime/heapAdapter.d.ts.map +1 -1
- package/dist/runtime/heapAdapter.js +42 -4
- package/dist/runtime/heapAdapter.js.map +1 -1
- package/dist/runtime/heapDecoder.d.ts.map +1 -1
- package/dist/runtime/heapDecoder.js +8 -3
- package/dist/runtime/heapDecoder.js.map +1 -1
- package/dist/runtime/heapEffect.d.ts +14 -1
- package/dist/runtime/heapEffect.d.ts.map +1 -1
- package/dist/runtime/heapEffect.js +13 -1
- package/dist/runtime/heapEffect.js.map +1 -1
- package/dist/runtime/heapEffectIR.d.ts.map +1 -1
- package/dist/runtime/heapEffectIR.js +18 -9
- package/dist/runtime/heapEffectIR.js.map +1 -1
- package/dist/runtime/heapEligibility.d.ts.map +1 -1
- package/dist/runtime/heapEligibility.js +64 -12
- package/dist/runtime/heapEligibility.js.map +1 -1
- package/dist/runtime/heapIrBuilders.d.ts +8 -0
- package/dist/runtime/heapIrBuilders.d.ts.map +1 -1
- package/dist/runtime/heapIrBuilders.js +47 -2
- package/dist/runtime/heapIrBuilders.js.map +1 -1
- package/dist/runtime/heapScene/chunkedArena.d.ts +20 -28
- package/dist/runtime/heapScene/chunkedArena.d.ts.map +1 -1
- package/dist/runtime/heapScene/chunkedArena.js +28 -91
- package/dist/runtime/heapScene/chunkedArena.js.map +1 -1
- package/dist/runtime/heapScene/freelist.d.ts +1 -1
- package/dist/runtime/heapScene/freelist.js +3 -3
- package/dist/runtime/heapScene/freelist.js.map +1 -1
- package/dist/runtime/heapScene/pools.d.ts +103 -59
- package/dist/runtime/heapScene/pools.d.ts.map +1 -1
- package/dist/runtime/heapScene/pools.js +335 -194
- package/dist/runtime/heapScene/pools.js.map +1 -1
- package/dist/runtime/heapScene.d.ts +116 -1
- package/dist/runtime/heapScene.d.ts.map +1 -1
- package/dist/runtime/heapScene.js +581 -125
- package/dist/runtime/heapScene.js.map +1 -1
- package/dist/runtime/hybridScene.d.ts.map +1 -1
- package/dist/runtime/hybridScene.js +19 -3
- package/dist/runtime/hybridScene.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/elementType.ts +10 -0
- package/src/core/provider.ts +56 -28
- package/src/core/renderObject.ts +9 -0
- package/src/resources/preparedRenderObject.ts +22 -3
- package/src/runtime/derivedModes/modeKeyCpu.ts +26 -11
- package/src/runtime/derivedModes/partitionDispatcher.ts +30 -0
- package/src/runtime/derivedUniforms/dispatch.ts +26 -10
- package/src/runtime/derivedUniforms/records.ts +70 -15
- package/src/runtime/derivedUniforms/sceneIntegration.ts +10 -0
- package/src/runtime/flattenTree.ts +47 -2
- package/src/runtime/heapAdapter.ts +40 -5
- package/src/runtime/heapDecoder.ts +8 -3
- package/src/runtime/heapEffect.ts +15 -1
- package/src/runtime/heapEffectIR.ts +18 -9
- package/src/runtime/heapEligibility.ts +39 -12
- package/src/runtime/heapIrBuilders.ts +50 -2
- package/src/runtime/heapScene/chunkedArena.ts +29 -94
- package/src/runtime/heapScene/freelist.ts +3 -3
- package/src/runtime/heapScene/pools.ts +340 -218
- package/src/runtime/heapScene.ts +717 -141
- package/src/runtime/hybridScene.ts +20 -3
- package/src/runtime/index.ts +5 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import type { IDisposable } from "@aardworx/wombat.adaptive";
|
|
16
16
|
import { GrowBuffer, DEFAULT_MAX_BUFFER_BYTES } from "./growBuffer.js";
|
|
17
|
-
import { AttributeArena
|
|
17
|
+
import { AttributeArena } from "./pools.js";
|
|
18
18
|
|
|
19
19
|
/** Address inside a chunked arena. */
|
|
20
20
|
export interface ChunkedRef {
|
|
@@ -46,6 +46,15 @@ export class ChunkedAttributeArena {
|
|
|
46
46
|
get chunks(): ReadonlyArray<AttributeArena> { return this._chunks; }
|
|
47
47
|
chunk(i: number): AttributeArena { return this._chunks[i]!; }
|
|
48
48
|
|
|
49
|
+
/** Bump headroom (bytes) of chunk `i` — free space before its cap, used by
|
|
50
|
+
* group placement. Out-of-range → 0. */
|
|
51
|
+
bumpHeadroom(i: number): number {
|
|
52
|
+
return i >= 0 && i < this._chunks.length ? this._chunks[i]!.bumpHeadroom : 0;
|
|
53
|
+
}
|
|
54
|
+
/** Open a fresh empty chunk (page) and return its index. Used by group
|
|
55
|
+
* placement when no existing chunk can hold a draw's whole group. */
|
|
56
|
+
openPage(): number { return this.openChunk(); }
|
|
57
|
+
|
|
49
58
|
/**
|
|
50
59
|
* Allocate `dataBytes` of attribute storage. Tries the `hint`
|
|
51
60
|
* chunk first when given (caller passes the RO's chunk to keep all
|
|
@@ -81,12 +90,12 @@ export class ChunkedAttributeArena {
|
|
|
81
90
|
c.release(off, dataBytes);
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
/**
|
|
93
|
+
/** No-op (mirror-less arena — writes upload immediately). Kept for API compat. */
|
|
85
94
|
flush(device: GPUDevice): void {
|
|
86
95
|
for (const c of this._chunks) c.flush(device);
|
|
87
96
|
}
|
|
88
97
|
|
|
89
|
-
/** Write into a specific chunk
|
|
98
|
+
/** Write into a specific chunk (immediate GPU upload). */
|
|
90
99
|
write(chunkIdx: number, dst: number, data: Uint8Array): void {
|
|
91
100
|
this._chunks[chunkIdx]!.write(dst, data);
|
|
92
101
|
}
|
|
@@ -124,100 +133,25 @@ export class ChunkedAttributeArena {
|
|
|
124
133
|
return s;
|
|
125
134
|
}
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
private openChunk(): number {
|
|
133
|
-
const idx = this._chunks.length;
|
|
134
|
-
const buf = new GrowBuffer(
|
|
135
|
-
this.device, `${this.label}/c${idx}`, this.usage,
|
|
136
|
-
this.initialChunkBytes, this.maxChunkBytes,
|
|
137
|
-
);
|
|
138
|
-
this._chunks.push(new AttributeArena(buf));
|
|
139
|
-
for (const cb of this.onChunkAddedCbs) cb(idx);
|
|
140
|
-
return idx;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/** Multi-chunk wrapper around `IndexAllocator`. Element-bump units
|
|
145
|
-
* are u32. Same chunk-open / hint / fallback semantics as
|
|
146
|
-
* `ChunkedAttributeArena`. */
|
|
147
|
-
export class ChunkedIndexAllocator {
|
|
148
|
-
private readonly _chunks: IndexAllocator[] = [];
|
|
149
|
-
private readonly onChunkAddedCbs = new Set<(chunkIdx: number) => void>();
|
|
150
|
-
|
|
151
|
-
constructor(
|
|
152
|
-
private readonly device: GPUDevice,
|
|
153
|
-
private readonly label: string,
|
|
154
|
-
private readonly usage: GPUBufferUsageFlags,
|
|
155
|
-
private readonly initialChunkBytes: number,
|
|
156
|
-
private readonly maxChunkBytes: number = DEFAULT_MAX_BUFFER_BYTES,
|
|
157
|
-
) {
|
|
158
|
-
this.openChunk();
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
get chunkCount(): number { return this._chunks.length; }
|
|
162
|
-
get chunks(): ReadonlyArray<IndexAllocator> { return this._chunks; }
|
|
163
|
-
chunk(i: number): IndexAllocator { return this._chunks[i]!; }
|
|
164
|
-
|
|
165
|
-
alloc(elements: number, hint?: number): ChunkedRef {
|
|
166
|
-
if (hint !== undefined && hint >= 0 && hint < this._chunks.length) {
|
|
167
|
-
const off = this._chunks[hint]!.tryAlloc(elements);
|
|
168
|
-
if (off !== undefined) return { chunkIdx: hint, off };
|
|
169
|
-
}
|
|
170
|
-
for (let i = this._chunks.length - 1; i >= 0; i--) {
|
|
171
|
-
if (i === hint) continue;
|
|
172
|
-
const off = this._chunks[i]!.tryAlloc(elements);
|
|
173
|
-
if (off !== undefined) return { chunkIdx: i, off };
|
|
174
|
-
}
|
|
175
|
-
const newIdx = this.openChunk();
|
|
176
|
-
const off = this._chunks[newIdx]!.tryAlloc(elements);
|
|
177
|
-
if (off === undefined) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`ChunkedIndexAllocator '${this.label}': allocation of ${elements} elements exceeds maxChunkBytes/4 ${this.maxChunkBytes / 4}`,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
return { chunkIdx: newIdx, off };
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
release(chunkIdx: number, off: number, elements: number): void {
|
|
186
|
-
const c = this._chunks[chunkIdx];
|
|
187
|
-
if (c === undefined) return;
|
|
188
|
-
c.release(off, elements);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
flush(device: GPUDevice): void {
|
|
192
|
-
for (const c of this._chunks) c.flush(device);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
write(chunkIdx: number, dst: number, data: Uint8Array): void {
|
|
196
|
-
this._chunks[chunkIdx]!.write(dst, data);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
onChunkAdded(cb: (chunkIdx: number) => void): IDisposable {
|
|
200
|
-
this.onChunkAddedCbs.add(cb);
|
|
201
|
-
return { dispose: () => { this.onChunkAddedCbs.delete(cb); } };
|
|
136
|
+
/** Total fragmentation waste across all chunks (diagnostic / trigger). */
|
|
137
|
+
totalWasteBytes(): number {
|
|
138
|
+
let s = 0;
|
|
139
|
+
for (const c of this._chunks) s += c.wasteBytes;
|
|
140
|
+
return s;
|
|
202
141
|
}
|
|
203
142
|
|
|
204
|
-
|
|
205
|
-
|
|
143
|
+
/** Waste-triggered compaction across every chunk. Returns one entry per
|
|
144
|
+
* chunk that actually relocated data — `remap` maps OLD→NEW byte offset
|
|
145
|
+
* within that chunk. Empty array when nothing was worth compacting. The
|
|
146
|
+
* caller must have flushed pending arena writes first (the GPU copy reads
|
|
147
|
+
* the live buffers). */
|
|
148
|
+
compact(device: GPUDevice, wasteFloorBytes: number, force = false): Array<{ chunkIdx: number; remap: Map<number, number> }> {
|
|
149
|
+
const out: Array<{ chunkIdx: number; remap: Map<number, number> }> = [];
|
|
206
150
|
for (let i = 0; i < this._chunks.length; i++) {
|
|
207
|
-
const
|
|
208
|
-
|
|
151
|
+
const remap = this._chunks[i]!.compact(device, wasteFloorBytes, force);
|
|
152
|
+
if (remap.size > 0) out.push({ chunkIdx: i, remap });
|
|
209
153
|
}
|
|
210
|
-
|
|
211
|
-
disposables.push(this._chunks[idx]!.onResize(() => cb(idx)));
|
|
212
|
-
cb(idx);
|
|
213
|
-
}));
|
|
214
|
-
return { dispose: () => { for (const d of disposables) d.dispose(); } };
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
totalUsedElements(): number {
|
|
218
|
-
let s = 0;
|
|
219
|
-
for (const c of this._chunks) s += c.usedElements;
|
|
220
|
-
return s;
|
|
154
|
+
return out;
|
|
221
155
|
}
|
|
222
156
|
|
|
223
157
|
destroy(): void {
|
|
@@ -231,8 +165,9 @@ export class ChunkedIndexAllocator {
|
|
|
231
165
|
this.device, `${this.label}/c${idx}`, this.usage,
|
|
232
166
|
this.initialChunkBytes, this.maxChunkBytes,
|
|
233
167
|
);
|
|
234
|
-
this._chunks.push(new
|
|
168
|
+
this._chunks.push(new AttributeArena(this.device, buf));
|
|
235
169
|
for (const cb of this.onChunkAddedCbs) cb(idx);
|
|
236
170
|
return idx;
|
|
237
171
|
}
|
|
238
172
|
}
|
|
173
|
+
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Freelist — best-fit free-block manager used by AttributeArena
|
|
2
|
-
//
|
|
1
|
+
// Freelist — best-fit free-block manager used by AttributeArena.
|
|
2
|
+
// Replaces the earlier `{off,size}[]` sorted-by-off
|
|
3
3
|
// freelist (whose alloc was O(N) first-fit and release was O(log N)
|
|
4
4
|
// binary-search-then-coalesce).
|
|
5
5
|
//
|
|
@@ -94,7 +94,7 @@ export class Freelist {
|
|
|
94
94
|
/**
|
|
95
95
|
* Take and remove the free block whose end offset is exactly
|
|
96
96
|
* `endOff`, if any exists. Used by `AttributeArena` /
|
|
97
|
-
* `
|
|
97
|
+
* `AttributeArena` to shrink the bump cursor back when releases
|
|
98
98
|
* expose a free tail (§5 — cursor-shrink hygiene for long-lived
|
|
99
99
|
* high-churn scenes).
|
|
100
100
|
*/
|