@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.
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts +62 -0
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -0
- package/dist/runtime/derivedModes/modeKeyCpu.js +225 -0
- package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -0
- package/dist/runtime/derivedModes/partition.d.ts +36 -0
- package/dist/runtime/derivedModes/partition.d.ts.map +1 -0
- package/dist/runtime/derivedModes/partition.js +170 -0
- package/dist/runtime/derivedModes/partition.js.map +1 -0
- package/dist/runtime/derivedModes/slotTable.d.ts +70 -0
- package/dist/runtime/derivedModes/slotTable.d.ts.map +1 -0
- package/dist/runtime/derivedModes/slotTable.js +130 -0
- package/dist/runtime/derivedModes/slotTable.js.map +1 -0
- package/dist/runtime/heapScene/growBuffer.d.ts +33 -0
- package/dist/runtime/heapScene/growBuffer.d.ts.map +1 -0
- package/dist/runtime/heapScene/growBuffer.js +76 -0
- package/dist/runtime/heapScene/growBuffer.js.map +1 -0
- package/dist/runtime/heapScene/packers.d.ts +25 -0
- package/dist/runtime/heapScene/packers.d.ts.map +1 -0
- package/dist/runtime/heapScene/packers.js +111 -0
- package/dist/runtime/heapScene/packers.js.map +1 -0
- package/dist/runtime/heapScene/pools.d.ts +181 -0
- package/dist/runtime/heapScene/pools.d.ts.map +1 -0
- package/dist/runtime/heapScene/pools.js +417 -0
- package/dist/runtime/heapScene/pools.js.map +1 -0
- package/dist/runtime/heapScene/scanKernel.d.ts +11 -0
- package/dist/runtime/heapScene/scanKernel.d.ts.map +1 -0
- package/dist/runtime/heapScene/scanKernel.js +181 -0
- package/dist/runtime/heapScene/scanKernel.js.map +1 -0
- package/dist/runtime/heapScene.d.ts.map +1 -1
- package/dist/runtime/heapScene.js +346 -937
- package/dist/runtime/heapScene.js.map +1 -1
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pipelineCache/bitfield.d.ts +5 -0
- package/dist/runtime/pipelineCache/bitfield.d.ts.map +1 -0
- package/dist/runtime/pipelineCache/bitfield.js +201 -0
- package/dist/runtime/pipelineCache/bitfield.js.map +1 -0
- package/dist/runtime/pipelineCache/cache.d.ts +36 -0
- package/dist/runtime/pipelineCache/cache.d.ts.map +1 -0
- package/dist/runtime/pipelineCache/cache.js +108 -0
- package/dist/runtime/pipelineCache/cache.js.map +1 -0
- package/dist/runtime/pipelineCache/descriptor.d.ts +58 -0
- package/dist/runtime/pipelineCache/descriptor.d.ts.map +1 -0
- package/dist/runtime/pipelineCache/descriptor.js +100 -0
- package/dist/runtime/pipelineCache/descriptor.js.map +1 -0
- package/dist/runtime/pipelineCache/index.d.ts +5 -0
- package/dist/runtime/pipelineCache/index.d.ts.map +1 -0
- package/dist/runtime/pipelineCache/index.js +12 -0
- package/dist/runtime/pipelineCache/index.js.map +1 -0
- package/package.json +1 -1
- package/src/runtime/derivedModes/modeKeyCpu.ts +251 -0
- package/src/runtime/derivedModes/partition.ts +206 -0
- package/src/runtime/derivedModes/slotTable.ts +153 -0
- package/src/runtime/heapScene/growBuffer.ts +75 -0
- package/src/runtime/heapScene/packers.ts +127 -0
- package/src/runtime/heapScene/pools.ts +492 -0
- package/src/runtime/heapScene/scanKernel.ts +184 -0
- package/src/runtime/heapScene.ts +397 -1064
- package/src/runtime/index.ts +40 -0
- package/src/runtime/pipelineCache/bitfield.ts +225 -0
- package/src/runtime/pipelineCache/cache.ts +129 -0
- package/src/runtime/pipelineCache/descriptor.ts +150 -0
- 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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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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"}
|