@aardworx/wombat.rendering 0.9.13 → 0.9.15
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 +45 -0
- package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -0
- package/dist/runtime/derivedModes/modeKeyCpu.js +179 -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/derivedUniforms/marker.d.ts +11 -3
- package/dist/runtime/derivedUniforms/marker.d.ts.map +1 -1
- package/dist/runtime/derivedUniforms/marker.js +10 -5
- package/dist/runtime/derivedUniforms/marker.js.map +1 -1
- 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 +228 -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 +213 -0
- package/src/runtime/derivedModes/partition.ts +206 -0
- package/src/runtime/derivedModes/slotTable.ts +153 -0
- package/src/runtime/derivedUniforms/marker.ts +19 -6
- 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 +283 -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,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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"}
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
// Arena + pool allocators that back the heap renderer's per-RO
|
|
2
|
+
// storage. Pulled out of heapScene.ts as a unit because the five
|
|
3
|
+
// classes here are tightly interleaved:
|
|
4
|
+
//
|
|
5
|
+
// AttributeArena — byte-bump over a STORAGE GrowBuffer
|
|
6
|
+
// IndexAllocator — element-bump over an INDEX GrowBuffer
|
|
7
|
+
// DrawHeap — slot-indexed allocator over a STORAGE GrowBuffer
|
|
8
|
+
// (one slot per RO drawHeader)
|
|
9
|
+
// UniformPool — aval-keyed refcounted alloc on top of AttributeArena
|
|
10
|
+
// IndexPool — aval-keyed refcounted alloc on top of IndexAllocator,
|
|
11
|
+
// with value-tuple dedup for constant avals (§5b).
|
|
12
|
+
//
|
|
13
|
+
// Plus the per-allocation header constants used by all of them and
|
|
14
|
+
// the `buildArenaState` / `arenaBytes` / `writeAttribute` / `asAval`
|
|
15
|
+
// / `isBufferView` / `asFloat32` helpers that the heap-scene factory
|
|
16
|
+
// uses to assemble the arena.
|
|
17
|
+
import { AVal } from "@aardworx/wombat.adaptive";
|
|
18
|
+
import { GrowBuffer, ALIGN16 } from "./growBuffer.js";
|
|
19
|
+
// ─── Per-allocation header layout ──────────────────────────────────────
|
|
20
|
+
/** Per-allocation header: (u32 typeId, u32 length). Data follows
|
|
21
|
+
* the header aligned up to 16 bytes (so positions/normals/etc. line
|
|
22
|
+
* up for future vec4 reads). */
|
|
23
|
+
export const ALLOC_HEADER_BYTES = 8;
|
|
24
|
+
export const ALLOC_HEADER_PAD_TO = 16;
|
|
25
|
+
/** Encoding-tag enum (low 16 bits of typeId). */
|
|
26
|
+
export const ENC_V3F_TIGHT = 1; // tightly-packed array of vec3<f32> (12 B/elt)
|
|
27
|
+
/** Semantic-tag enum (high 16 bits of typeId). Optional metadata —
|
|
28
|
+
* the shader doesn't branch on this. */
|
|
29
|
+
export const SEM_POSITIONS = 1;
|
|
30
|
+
export const SEM_NORMALS = 2;
|
|
31
|
+
/**
|
|
32
|
+
* Aval-keyed pool of arena allocations. One allocation per unique
|
|
33
|
+
* aval (object identity). Two draws referencing the same aval share
|
|
34
|
+
* the allocation; their DrawHeaders carry the same u32 ref. Holds
|
|
35
|
+
* uniforms (fixed-size scalars/vectors/matrices) AND attribute arrays
|
|
36
|
+
* (variable-size). The caller decides `dataBytes` + `length` per
|
|
37
|
+
* acquisition — the pool just keys on aval identity and refcounts.
|
|
38
|
+
*
|
|
39
|
+
* Sharing emerges from aval identity — no separate "frequency"
|
|
40
|
+
* declaration needed. A `cval` shared by all draws → 1 alloc.
|
|
41
|
+
* A static positions array shared across instanced draws → 1 alloc.
|
|
42
|
+
* Same code path either way.
|
|
43
|
+
*/
|
|
44
|
+
export class UniformPool {
|
|
45
|
+
// Keyed by `aval<unknown>` *by reference* (a plain JS `Map`). These
|
|
46
|
+
// keys are overwhelmingly reactive `cval`s (per-object trafos,
|
|
47
|
+
// colours, …) and the hot path is `acquire`/`release` ~once per
|
|
48
|
+
// drawHeader field per RO.
|
|
49
|
+
byAval = new Map();
|
|
50
|
+
has(av) { return this.byAval.has(av); }
|
|
51
|
+
entry(av) { return this.byAval.get(av); }
|
|
52
|
+
/**
|
|
53
|
+
* Acquire (or share) an allocation for `aval`. Caller passes the
|
|
54
|
+
* pre-read `value` (so the pool doesn't need a token) plus the
|
|
55
|
+
* (`dataBytes`, `typeId`, `length`, `pack`) describing how to lay
|
|
56
|
+
* it out. If a new allocation is made, the value is packed and
|
|
57
|
+
* uploaded immediately.
|
|
58
|
+
*/
|
|
59
|
+
acquire(device, arena, av, value, dataBytes, typeId, length, pack) {
|
|
60
|
+
const existing = this.byAval.get(av);
|
|
61
|
+
if (existing !== undefined) {
|
|
62
|
+
existing.refcount++;
|
|
63
|
+
return existing.ref;
|
|
64
|
+
}
|
|
65
|
+
const ref = arena.alloc(dataBytes);
|
|
66
|
+
const allocBytes = ALIGN16(ALLOC_HEADER_PAD_TO + dataBytes);
|
|
67
|
+
const buf = new ArrayBuffer(allocBytes);
|
|
68
|
+
const u32 = new Uint32Array(buf);
|
|
69
|
+
const f32 = new Float32Array(buf);
|
|
70
|
+
u32[0] = typeId;
|
|
71
|
+
u32[1] = length;
|
|
72
|
+
// stride_bytes (offset 8): bytes per element. Lets the VS decode
|
|
73
|
+
// pick V3- vs V4-tight load expressions for vec4 attributes.
|
|
74
|
+
u32[2] = length > 0 ? Math.floor(dataBytes / length) : 0;
|
|
75
|
+
pack(value, f32, ALLOC_HEADER_PAD_TO / 4);
|
|
76
|
+
arena.write(ref, new Uint8Array(buf));
|
|
77
|
+
void device;
|
|
78
|
+
this.byAval.set(av, { ref, dataBytes, typeId, pack, refcount: 1 });
|
|
79
|
+
return ref;
|
|
80
|
+
}
|
|
81
|
+
/** Decrement refcount; if zero, free the arena allocation. */
|
|
82
|
+
release(arena, av) {
|
|
83
|
+
const e = this.byAval.get(av);
|
|
84
|
+
if (e === undefined)
|
|
85
|
+
return;
|
|
86
|
+
e.refcount--;
|
|
87
|
+
if (e.refcount > 0)
|
|
88
|
+
return;
|
|
89
|
+
arena.release(e.ref, ALIGN16(ALLOC_HEADER_PAD_TO + e.dataBytes));
|
|
90
|
+
this.byAval.delete(av);
|
|
91
|
+
}
|
|
92
|
+
/** Re-pack one entry's data region into the arena's CPU shadow. */
|
|
93
|
+
repack(device, arena, av, val) {
|
|
94
|
+
const e = this.byAval.get(av);
|
|
95
|
+
if (e === undefined)
|
|
96
|
+
return;
|
|
97
|
+
const dst = new Float32Array(e.dataBytes / 4);
|
|
98
|
+
e.pack(val, dst, 0);
|
|
99
|
+
arena.write(e.ref + ALLOC_HEADER_PAD_TO, new Uint8Array(dst.buffer, dst.byteOffset, e.dataBytes));
|
|
100
|
+
void device;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ─── IndexPool ─────────────────────────────────────────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* Aval-keyed pool over the `IndexAllocator`. Two draws referencing
|
|
106
|
+
* the same `Uint32Array` (or aval thereof) share an index range —
|
|
107
|
+
* 19K instanced clones of the same mesh share one allocation, one
|
|
108
|
+
* upload.
|
|
109
|
+
*
|
|
110
|
+
* **Value-equality dedup for constant avals (§5b):** when an
|
|
111
|
+
* incoming aval has `isConstant === true`, the pool also keys by
|
|
112
|
+
* the underlying `ArrayBuffer` tuple `(buffer, byteOffset,
|
|
113
|
+
* byteLength)`. Two distinct constant avals wrapping the same
|
|
114
|
+
* `Uint32Array` view collapse to one allocation.
|
|
115
|
+
*/
|
|
116
|
+
export class IndexPool {
|
|
117
|
+
byAval = new Map();
|
|
118
|
+
byValueKey = new Map();
|
|
119
|
+
bufferIds = new WeakMap();
|
|
120
|
+
nextBufferId = 1;
|
|
121
|
+
bufferIdOf(buf) {
|
|
122
|
+
let id = this.bufferIds.get(buf);
|
|
123
|
+
if (id === undefined) {
|
|
124
|
+
id = this.nextBufferId++;
|
|
125
|
+
this.bufferIds.set(buf, id);
|
|
126
|
+
}
|
|
127
|
+
return id;
|
|
128
|
+
}
|
|
129
|
+
acquire(device, indices, av, arr) {
|
|
130
|
+
const bound = this.byAval.get(av);
|
|
131
|
+
if (bound !== undefined) {
|
|
132
|
+
bound.perAvalCount++;
|
|
133
|
+
bound.entry.totalRefcount++;
|
|
134
|
+
return { firstIndex: bound.entry.firstIndex, count: bound.entry.count };
|
|
135
|
+
}
|
|
136
|
+
let valueKey;
|
|
137
|
+
if (av.isConstant) {
|
|
138
|
+
valueKey = `${this.bufferIdOf(arr.buffer)}:${arr.byteOffset}:${arr.byteLength}`;
|
|
139
|
+
const shared = this.byValueKey.get(valueKey);
|
|
140
|
+
if (shared !== undefined) {
|
|
141
|
+
shared.totalRefcount++;
|
|
142
|
+
this.byAval.set(av, { entry: shared, perAvalCount: 1 });
|
|
143
|
+
return { firstIndex: shared.firstIndex, count: shared.count };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const firstIndex = indices.alloc(arr.length);
|
|
147
|
+
indices.write(firstIndex * 4, new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength));
|
|
148
|
+
void device;
|
|
149
|
+
const entry = { firstIndex, count: arr.length, totalRefcount: 1, valueKey };
|
|
150
|
+
this.byAval.set(av, { entry, perAvalCount: 1 });
|
|
151
|
+
if (valueKey !== undefined)
|
|
152
|
+
this.byValueKey.set(valueKey, entry);
|
|
153
|
+
return { firstIndex, count: arr.length };
|
|
154
|
+
}
|
|
155
|
+
release(indices, av) {
|
|
156
|
+
const bound = this.byAval.get(av);
|
|
157
|
+
if (bound === undefined)
|
|
158
|
+
return;
|
|
159
|
+
bound.perAvalCount--;
|
|
160
|
+
bound.entry.totalRefcount--;
|
|
161
|
+
if (bound.perAvalCount === 0)
|
|
162
|
+
this.byAval.delete(av);
|
|
163
|
+
if (bound.entry.totalRefcount > 0)
|
|
164
|
+
return;
|
|
165
|
+
indices.release(bound.entry.firstIndex, bound.entry.count);
|
|
166
|
+
if (bound.entry.valueKey !== undefined) {
|
|
167
|
+
this.byValueKey.delete(bound.entry.valueKey);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ─── DrawHeap (slot-indexed) ───────────────────────────────────────────
|
|
172
|
+
/**
|
|
173
|
+
* Slot-indexed allocator over a GrowBuffer. `slotBytes` is set per-
|
|
174
|
+
* instance — each bucket sizes its DrawHeader from its effect's
|
|
175
|
+
* schema, so a bucket whose layout is e.g. 96 B / slot uses a
|
|
176
|
+
* DrawHeap with `slotBytes=96`.
|
|
177
|
+
*/
|
|
178
|
+
export class DrawHeap {
|
|
179
|
+
buf;
|
|
180
|
+
slotBytes;
|
|
181
|
+
free = [];
|
|
182
|
+
nextSlot = 0;
|
|
183
|
+
constructor(buf, slotBytes) {
|
|
184
|
+
this.buf = buf;
|
|
185
|
+
this.slotBytes = slotBytes;
|
|
186
|
+
}
|
|
187
|
+
get buffer() { return this.buf.buffer; }
|
|
188
|
+
/** Bytes per slot — caller multiplies by slot index for byte offsets. */
|
|
189
|
+
get bytesPerSlot() { return this.slotBytes; }
|
|
190
|
+
/** High-water mark in bytes (used to size bind-group entry on rebuild). */
|
|
191
|
+
get usedBytes() { return this.nextSlot * this.slotBytes; }
|
|
192
|
+
alloc() {
|
|
193
|
+
const slot = this.free.length > 0 ? this.free.pop() : this.nextSlot++;
|
|
194
|
+
this.buf.ensureCapacity((slot + 1) * this.slotBytes);
|
|
195
|
+
this.buf.setUsed(Math.max(this.buf.usedBytes, (slot + 1) * this.slotBytes));
|
|
196
|
+
return slot;
|
|
197
|
+
}
|
|
198
|
+
release(slot) { this.free.push(slot); }
|
|
199
|
+
onResize(cb) { return this.buf.onResize(cb); }
|
|
200
|
+
destroy() { this.buf.destroy(); }
|
|
201
|
+
}
|
|
202
|
+
// ─── AttributeArena (byte-bump) ────────────────────────────────────────
|
|
203
|
+
/**
|
|
204
|
+
* Byte-bump allocator over a GrowBuffer for variable-size attribute
|
|
205
|
+
* allocations. Each allocation gets a 16-byte aligned start (8-byte
|
|
206
|
+
* (typeId, length) header at the start, data 16 bytes in). Frees go
|
|
207
|
+
* onto a sorted free list with coalesce on insert.
|
|
208
|
+
*/
|
|
209
|
+
export class AttributeArena {
|
|
210
|
+
buf;
|
|
211
|
+
cursor = 0;
|
|
212
|
+
freeList = [];
|
|
213
|
+
/** CPU shadow of the entire GPU buffer; writes go here first then
|
|
214
|
+
* flush() emits one writeBuffer per dirty contiguous range. */
|
|
215
|
+
shadow;
|
|
216
|
+
dirtyMin = Infinity;
|
|
217
|
+
dirtyMax = 0;
|
|
218
|
+
constructor(buf) {
|
|
219
|
+
this.buf = buf;
|
|
220
|
+
this.shadow = new Uint8Array(buf.capacity);
|
|
221
|
+
buf.onResize(() => {
|
|
222
|
+
const grown = new Uint8Array(buf.capacity);
|
|
223
|
+
grown.set(this.shadow);
|
|
224
|
+
this.shadow = grown;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
get buffer() { return this.buf.buffer; }
|
|
228
|
+
get capacity() { return this.buf.capacity; }
|
|
229
|
+
get usedBytes() { return this.cursor; }
|
|
230
|
+
write(dst, data) {
|
|
231
|
+
this.shadow.set(data, dst);
|
|
232
|
+
if (dst < this.dirtyMin)
|
|
233
|
+
this.dirtyMin = dst;
|
|
234
|
+
const end = dst + data.byteLength;
|
|
235
|
+
if (end > this.dirtyMax)
|
|
236
|
+
this.dirtyMax = end;
|
|
237
|
+
}
|
|
238
|
+
flush(device) {
|
|
239
|
+
if (this.dirtyMax <= this.dirtyMin)
|
|
240
|
+
return;
|
|
241
|
+
device.queue.writeBuffer(this.buf.buffer, this.dirtyMin, this.shadow.buffer, this.shadow.byteOffset + this.dirtyMin, this.dirtyMax - this.dirtyMin);
|
|
242
|
+
this.dirtyMin = Infinity;
|
|
243
|
+
this.dirtyMax = 0;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Allocate space for one attribute. Returns the byte ref (offset
|
|
247
|
+
* to the header — data lives at ref + 16).
|
|
248
|
+
*/
|
|
249
|
+
alloc(dataBytes) {
|
|
250
|
+
const allocBytes = ALIGN16(ALLOC_HEADER_PAD_TO + dataBytes);
|
|
251
|
+
// First-fit reuse from free list.
|
|
252
|
+
for (let i = 0; i < this.freeList.length; i++) {
|
|
253
|
+
const f = this.freeList[i];
|
|
254
|
+
if (f.size >= allocBytes) {
|
|
255
|
+
const ref = f.off;
|
|
256
|
+
if (f.size === allocBytes)
|
|
257
|
+
this.freeList.splice(i, 1);
|
|
258
|
+
else {
|
|
259
|
+
f.off += allocBytes;
|
|
260
|
+
f.size -= allocBytes;
|
|
261
|
+
}
|
|
262
|
+
return ref;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const ref = this.cursor;
|
|
266
|
+
this.cursor += allocBytes;
|
|
267
|
+
this.buf.ensureCapacity(this.cursor);
|
|
268
|
+
this.buf.setUsed(this.cursor);
|
|
269
|
+
return ref;
|
|
270
|
+
}
|
|
271
|
+
release(ref, dataBytes) {
|
|
272
|
+
const allocBytes = ALIGN16(ALLOC_HEADER_PAD_TO + dataBytes);
|
|
273
|
+
insertSortedFreeBlock(this.freeList, ref, allocBytes);
|
|
274
|
+
}
|
|
275
|
+
onResize(cb) { return this.buf.onResize(cb); }
|
|
276
|
+
destroy() { this.buf.destroy(); }
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Insert `{off, size}` into a free-list kept sorted by `off`, then
|
|
280
|
+
* coalesce with the two immediate neighbours.
|
|
281
|
+
*/
|
|
282
|
+
export function insertSortedFreeBlock(freeList, off, size) {
|
|
283
|
+
let lo = 0, hi = freeList.length;
|
|
284
|
+
while (lo < hi) {
|
|
285
|
+
const mid = (lo + hi) >>> 1;
|
|
286
|
+
if (freeList[mid].off <= off)
|
|
287
|
+
lo = mid + 1;
|
|
288
|
+
else
|
|
289
|
+
hi = mid;
|
|
290
|
+
}
|
|
291
|
+
const prev = lo > 0 ? freeList[lo - 1] : undefined;
|
|
292
|
+
if (prev !== undefined && prev.off + prev.size === off) {
|
|
293
|
+
prev.size += size;
|
|
294
|
+
const next = freeList[lo];
|
|
295
|
+
if (next !== undefined && prev.off + prev.size === next.off) {
|
|
296
|
+
prev.size += next.size;
|
|
297
|
+
freeList.splice(lo, 1);
|
|
298
|
+
}
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const next = freeList[lo];
|
|
302
|
+
if (next !== undefined && off + size === next.off) {
|
|
303
|
+
next.off = off;
|
|
304
|
+
next.size += size;
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
freeList.splice(lo, 0, { off, size });
|
|
308
|
+
}
|
|
309
|
+
// ─── IndexAllocator (element-bump) ─────────────────────────────────────
|
|
310
|
+
/**
|
|
311
|
+
* Element-bump allocator over an index GrowBuffer (units = u32). Each
|
|
312
|
+
* draw's index range is allocated as one block; on release the block
|
|
313
|
+
* is returned to a free list and can be reused first-fit.
|
|
314
|
+
*/
|
|
315
|
+
export class IndexAllocator {
|
|
316
|
+
buf;
|
|
317
|
+
cursor = 0; // in u32s, not bytes
|
|
318
|
+
freeList = [];
|
|
319
|
+
shadow;
|
|
320
|
+
dirtyMin = Infinity;
|
|
321
|
+
dirtyMax = 0;
|
|
322
|
+
constructor(buf) {
|
|
323
|
+
this.buf = buf;
|
|
324
|
+
this.shadow = new Uint8Array(buf.capacity);
|
|
325
|
+
buf.onResize(() => {
|
|
326
|
+
const grown = new Uint8Array(buf.capacity);
|
|
327
|
+
grown.set(this.shadow);
|
|
328
|
+
this.shadow = grown;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
get buffer() { return this.buf.buffer; }
|
|
332
|
+
get usedElements() { return this.cursor; }
|
|
333
|
+
write(dstByteOffset, data) {
|
|
334
|
+
this.shadow.set(data, dstByteOffset);
|
|
335
|
+
if (dstByteOffset < this.dirtyMin)
|
|
336
|
+
this.dirtyMin = dstByteOffset;
|
|
337
|
+
const end = dstByteOffset + data.byteLength;
|
|
338
|
+
if (end > this.dirtyMax)
|
|
339
|
+
this.dirtyMax = end;
|
|
340
|
+
}
|
|
341
|
+
flush(device) {
|
|
342
|
+
if (this.dirtyMax <= this.dirtyMin)
|
|
343
|
+
return;
|
|
344
|
+
device.queue.writeBuffer(this.buf.buffer, this.dirtyMin, this.shadow.buffer, this.shadow.byteOffset + this.dirtyMin, this.dirtyMax - this.dirtyMin);
|
|
345
|
+
this.dirtyMin = Infinity;
|
|
346
|
+
this.dirtyMax = 0;
|
|
347
|
+
}
|
|
348
|
+
alloc(elements) {
|
|
349
|
+
for (let i = 0; i < this.freeList.length; i++) {
|
|
350
|
+
const f = this.freeList[i];
|
|
351
|
+
if (f.size >= elements) {
|
|
352
|
+
const off = f.off;
|
|
353
|
+
if (f.size === elements)
|
|
354
|
+
this.freeList.splice(i, 1);
|
|
355
|
+
else {
|
|
356
|
+
f.off += elements;
|
|
357
|
+
f.size -= elements;
|
|
358
|
+
}
|
|
359
|
+
return off;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
const off = this.cursor;
|
|
363
|
+
this.cursor += elements;
|
|
364
|
+
this.buf.ensureCapacity(this.cursor * 4);
|
|
365
|
+
this.buf.setUsed(this.cursor * 4);
|
|
366
|
+
return off;
|
|
367
|
+
}
|
|
368
|
+
release(off, elements) {
|
|
369
|
+
insertSortedFreeBlock(this.freeList, off, elements);
|
|
370
|
+
}
|
|
371
|
+
onResize(cb) { return this.buf.onResize(cb); }
|
|
372
|
+
destroy() { this.buf.destroy(); }
|
|
373
|
+
}
|
|
374
|
+
export function buildArenaState(device, attrBytesHint, idxBytesHint, label, idxExtraUsage = 0) {
|
|
375
|
+
const attrs = new AttributeArena(new GrowBuffer(device, `${label}/attrs`, GPUBufferUsage.STORAGE, attrBytesHint));
|
|
376
|
+
const indices = new IndexAllocator(new GrowBuffer(device, `${label}/idx`, GPUBufferUsage.INDEX | idxExtraUsage, idxBytesHint));
|
|
377
|
+
return { attrs, indices };
|
|
378
|
+
}
|
|
379
|
+
export function arenaBytes(arena) {
|
|
380
|
+
return arena.attrs.usedBytes + arena.indices.usedElements * 4;
|
|
381
|
+
}
|
|
382
|
+
/** Upload a single attribute — header (typeId, length) + data — into the arena at byte offset `ref`. */
|
|
383
|
+
export function writeAttribute(device, buf, ref, typeId, length, data) {
|
|
384
|
+
const allocBytes = ALIGN16(ALLOC_HEADER_PAD_TO + data.byteLength);
|
|
385
|
+
const staging = new ArrayBuffer(allocBytes);
|
|
386
|
+
const u32 = new Uint32Array(staging);
|
|
387
|
+
const f32 = new Float32Array(staging);
|
|
388
|
+
u32[0] = typeId;
|
|
389
|
+
u32[1] = length;
|
|
390
|
+
f32.set(data, ALLOC_HEADER_PAD_TO / 4);
|
|
391
|
+
device.queue.writeBuffer(buf, ref, staging, 0, allocBytes);
|
|
392
|
+
}
|
|
393
|
+
export function asAval(v) {
|
|
394
|
+
return (typeof v === "object" && v !== null && typeof v.getValue === "function")
|
|
395
|
+
? v
|
|
396
|
+
: AVal.constant(v);
|
|
397
|
+
}
|
|
398
|
+
/** Heuristic predicate — BufferView has `buffer: aval<IBuffer>` + elementType. */
|
|
399
|
+
export function isBufferView(v) {
|
|
400
|
+
if (typeof v !== "object" || v === null)
|
|
401
|
+
return false;
|
|
402
|
+
const o = v;
|
|
403
|
+
return typeof o.buffer === "object" && o.buffer !== null
|
|
404
|
+
&& typeof o.buffer.getValue === "function"
|
|
405
|
+
&& typeof o.elementType === "object" && o.elementType !== null;
|
|
406
|
+
}
|
|
407
|
+
/** Float32 view over a host-side buffer source. Used by the BufferView
|
|
408
|
+
* packer to hand the pool a typed array it can `set()` from. */
|
|
409
|
+
export function asFloat32(data) {
|
|
410
|
+
if (data instanceof Float32Array)
|
|
411
|
+
return data;
|
|
412
|
+
if (ArrayBuffer.isView(data)) {
|
|
413
|
+
return new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);
|
|
414
|
+
}
|
|
415
|
+
return new Float32Array(data); // ArrayBuffer
|
|
416
|
+
}
|
|
417
|
+
//# sourceMappingURL=pools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pools.js","sourceRoot":"","sources":["../../../src/runtime/heapScene/pools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const SCAN_TILE_SIZE = 512;
|
|
2
|
+
export declare const SCAN_WG_SIZE = 256;
|
|
3
|
+
/** numBlocks ≤ TILE_SIZE — single-pass blockOffsets fits in shared memory. */
|
|
4
|
+
export declare const SCAN_MAX_RECORDS: number;
|
|
5
|
+
/** Tile size for the firstDrawInTile binary-search-fold index. */
|
|
6
|
+
export declare const TILE_K = 64;
|
|
7
|
+
/** drawTable record width: (firstEmit, drawIdx, indexStart, indexCount, instanceCount). */
|
|
8
|
+
export declare const RECORD_U32 = 5;
|
|
9
|
+
export declare const RECORD_BYTES: number;
|
|
10
|
+
export declare const HEAP_SCAN_WGSL = "\nstruct Params {\n numRecords: u32,\n numBlocks: u32,\n _pad0: u32,\n _pad1: u32,\n};\n\nstruct Record {\n firstEmit: u32,\n drawIdx: u32,\n indexStart: u32,\n indexCount: u32,\n instanceCount: u32,\n};\n\n@group(0) @binding(0) var<storage, read_write> drawTable: array<Record>;\n@group(0) @binding(1) var<storage, read_write> blockSums: array<u32>;\n@group(0) @binding(2) var<storage, read_write> blockOffsets: array<u32>;\n@group(0) @binding(3) var<storage, read_write> indirect: array<u32>;\n@group(0) @binding(4) var<uniform> params: Params;\n@group(0) @binding(5) var<storage, read_write> firstDrawInTile: array<u32>;\n\nconst TILE_SIZE: u32 = 512u;\nconst WG_SIZE: u32 = 256u;\nconst TILE_K: u32 = 64u;\n\nvar<workgroup> sdata: array<u32, 512>;\n\nfn blellochScan(tid: u32) {\n var offset: u32 = 1u;\n for (var d: u32 = TILE_SIZE >> 1u; d > 0u; d = d >> 1u) {\n workgroupBarrier();\n if (tid < d) {\n let ai = offset * (2u * tid + 1u) - 1u;\n let bi = offset * (2u * tid + 2u) - 1u;\n sdata[bi] = sdata[bi] + sdata[ai];\n }\n offset = offset * 2u;\n }\n if (tid == 0u) { sdata[TILE_SIZE - 1u] = 0u; }\n for (var d: u32 = 1u; d < TILE_SIZE; d = d * 2u) {\n offset = offset >> 1u;\n workgroupBarrier();\n if (tid < d) {\n let ai = offset * (2u * tid + 1u) - 1u;\n let bi = offset * (2u * tid + 2u) - 1u;\n let t = sdata[ai];\n sdata[ai] = sdata[bi];\n sdata[bi] = sdata[bi] + t;\n }\n }\n workgroupBarrier();\n}\n\n@compute @workgroup_size(WG_SIZE)\nfn scanTile(@builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wgid: vec3<u32>) {\n let tid = lid.x;\n let blockOff = wgid.x * TILE_SIZE;\n let n = params.numRecords;\n let i0 = blockOff + tid;\n let i1 = blockOff + tid + WG_SIZE;\n var v0: u32 = 0u;\n var v1: u32 = 0u;\n if (i0 < n) { v0 = drawTable[i0].indexCount * drawTable[i0].instanceCount; }\n if (i1 < n) { v1 = drawTable[i1].indexCount * drawTable[i1].instanceCount; }\n sdata[tid] = v0;\n sdata[tid + WG_SIZE] = v1;\n workgroupBarrier();\n blellochScan(tid);\n if (i0 < n) { drawTable[i0].firstEmit = sdata[tid]; }\n if (i1 < n) { drawTable[i1].firstEmit = sdata[tid + WG_SIZE]; }\n if (tid == WG_SIZE - 1u) {\n blockSums[wgid.x] = sdata[tid + WG_SIZE] + v1;\n }\n}\n\n@compute @workgroup_size(WG_SIZE)\nfn scanBlocks(@builtin(local_invocation_id) lid: vec3<u32>) {\n let tid = lid.x;\n let n = params.numBlocks;\n let i0 = tid;\n let i1 = tid + WG_SIZE;\n var v0: u32 = 0u;\n var v1: u32 = 0u;\n if (i0 < n) { v0 = blockSums[i0]; }\n if (i1 < n) { v1 = blockSums[i1]; }\n sdata[tid] = v0;\n sdata[tid + WG_SIZE] = v1;\n workgroupBarrier();\n blellochScan(tid);\n if (i0 < n) { blockOffsets[i0] = sdata[tid]; }\n if (i1 < n) { blockOffsets[i1] = sdata[tid + WG_SIZE]; }\n workgroupBarrier();\n if (tid == 0u) {\n if (n > 0u) {\n let lastIdx = n - 1u;\n let total = blockOffsets[lastIdx] + blockSums[lastIdx];\n indirect[0] = total;\n } else {\n indirect[0] = 0u;\n }\n indirect[1] = 1u;\n indirect[2] = 0u;\n indirect[3] = 0u;\n }\n}\n\n@compute @workgroup_size(WG_SIZE)\nfn addOffsets(@builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wgid: vec3<u32>) {\n let tid = lid.x;\n let blockOff = wgid.x * TILE_SIZE;\n let n = params.numRecords;\n let off = blockOffsets[wgid.x];\n let i0 = blockOff + tid;\n let i1 = blockOff + tid + WG_SIZE;\n if (i0 < n) { drawTable[i0].firstEmit = drawTable[i0].firstEmit + off; }\n if (i1 < n) { drawTable[i1].firstEmit = drawTable[i1].firstEmit + off; }\n}\n\n@compute @workgroup_size(WG_SIZE)\nfn buildTileIndex(@builtin(global_invocation_id) gid: vec3<u32>) {\n let tileIdx = gid.x;\n // totalEmit is computed by scanBlocks into indirect[0]; reading it\n // from indirect avoids a separate uniform/storage round-trip.\n let totalEmit = indirect[0];\n let numTiles = (totalEmit + TILE_K - 1u) / TILE_K;\n if (tileIdx > numTiles) { return; }\n if (params.numRecords == 0u) {\n if (tileIdx == 0u) { firstDrawInTile[0] = 0u; }\n return;\n }\n if (tileIdx == numTiles) {\n // Sentinel for the open upper bound \u2014 the LAST VALID SLOT, not\n // numRecords. The render VS uses\n // hi = firstDrawInTile[_tileIdx + 1u]\n // and the binary search treats hi as INCLUSIVE. If the sentinel\n // were numRecords (one past last), the search would drag lo into\n // the OOB slot for emits in the last tile, since drawTable reads\n // past recordCount return 0 (binding size clamping) and 0 \u2264 emit\n // is always true. Visible symptom: the LAST few emits in the\n // bucket land on slot=numRecords (drawIdx=0, indexCount=0 \u2192 /-by-\n // zero) \u2192 degenerate / cross-RO triangle stitched to slot 0.\n firstDrawInTile[tileIdx] = params.numRecords - 1u;\n return;\n }\n let tileStart = tileIdx * TILE_K;\n var lo: u32 = 0u;\n var hi: u32 = params.numRecords - 1u;\n loop {\n if (lo >= hi) { break; }\n let mid = (lo + hi + 1u) >> 1u;\n if (drawTable[mid].firstEmit <= tileStart) { lo = mid; } else { hi = mid - 1u; }\n }\n firstDrawInTile[tileIdx] = lo;\n}\n";
|
|
11
|
+
//# sourceMappingURL=scanKernel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanKernel.d.ts","sourceRoot":"","sources":["../../../src/runtime/heapScene/scanKernel.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,YAAY,MAAQ,CAAC;AAClC,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,QAAkC,CAAC;AAEhE,kEAAkE;AAClE,eAAO,MAAM,MAAM,KAAK,CAAC;AAEzB,2FAA2F;AAC3F,eAAO,MAAM,UAAU,IAAM,CAAC;AAC9B,eAAO,MAAM,YAAY,QAAiB,CAAC;AAE3C,eAAO,MAAM,cAAc,mqKA4J1B,CAAC"}
|