@aardworx/wombat.rendering 0.9.14 → 0.9.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/runtime/derivedModes/modeKeyCpu.d.ts +62 -0
  2. package/dist/runtime/derivedModes/modeKeyCpu.d.ts.map +1 -0
  3. package/dist/runtime/derivedModes/modeKeyCpu.js +225 -0
  4. package/dist/runtime/derivedModes/modeKeyCpu.js.map +1 -0
  5. package/dist/runtime/derivedModes/partition.d.ts +36 -0
  6. package/dist/runtime/derivedModes/partition.d.ts.map +1 -0
  7. package/dist/runtime/derivedModes/partition.js +170 -0
  8. package/dist/runtime/derivedModes/partition.js.map +1 -0
  9. package/dist/runtime/derivedModes/slotTable.d.ts +70 -0
  10. package/dist/runtime/derivedModes/slotTable.d.ts.map +1 -0
  11. package/dist/runtime/derivedModes/slotTable.js +130 -0
  12. package/dist/runtime/derivedModes/slotTable.js.map +1 -0
  13. package/dist/runtime/heapScene/growBuffer.d.ts +33 -0
  14. package/dist/runtime/heapScene/growBuffer.d.ts.map +1 -0
  15. package/dist/runtime/heapScene/growBuffer.js +76 -0
  16. package/dist/runtime/heapScene/growBuffer.js.map +1 -0
  17. package/dist/runtime/heapScene/packers.d.ts +25 -0
  18. package/dist/runtime/heapScene/packers.d.ts.map +1 -0
  19. package/dist/runtime/heapScene/packers.js +111 -0
  20. package/dist/runtime/heapScene/packers.js.map +1 -0
  21. package/dist/runtime/heapScene/pools.d.ts +181 -0
  22. package/dist/runtime/heapScene/pools.d.ts.map +1 -0
  23. package/dist/runtime/heapScene/pools.js +417 -0
  24. package/dist/runtime/heapScene/pools.js.map +1 -0
  25. package/dist/runtime/heapScene/scanKernel.d.ts +11 -0
  26. package/dist/runtime/heapScene/scanKernel.d.ts.map +1 -0
  27. package/dist/runtime/heapScene/scanKernel.js +181 -0
  28. package/dist/runtime/heapScene/scanKernel.js.map +1 -0
  29. package/dist/runtime/heapScene.d.ts.map +1 -1
  30. package/dist/runtime/heapScene.js +346 -937
  31. package/dist/runtime/heapScene.js.map +1 -1
  32. package/dist/runtime/index.d.ts +4 -0
  33. package/dist/runtime/index.d.ts.map +1 -1
  34. package/dist/runtime/index.js +5 -0
  35. package/dist/runtime/index.js.map +1 -1
  36. package/dist/runtime/pipelineCache/bitfield.d.ts +5 -0
  37. package/dist/runtime/pipelineCache/bitfield.d.ts.map +1 -0
  38. package/dist/runtime/pipelineCache/bitfield.js +201 -0
  39. package/dist/runtime/pipelineCache/bitfield.js.map +1 -0
  40. package/dist/runtime/pipelineCache/cache.d.ts +36 -0
  41. package/dist/runtime/pipelineCache/cache.d.ts.map +1 -0
  42. package/dist/runtime/pipelineCache/cache.js +108 -0
  43. package/dist/runtime/pipelineCache/cache.js.map +1 -0
  44. package/dist/runtime/pipelineCache/descriptor.d.ts +58 -0
  45. package/dist/runtime/pipelineCache/descriptor.d.ts.map +1 -0
  46. package/dist/runtime/pipelineCache/descriptor.js +100 -0
  47. package/dist/runtime/pipelineCache/descriptor.js.map +1 -0
  48. package/dist/runtime/pipelineCache/index.d.ts +5 -0
  49. package/dist/runtime/pipelineCache/index.d.ts.map +1 -0
  50. package/dist/runtime/pipelineCache/index.js +12 -0
  51. package/dist/runtime/pipelineCache/index.js.map +1 -0
  52. package/package.json +1 -1
  53. package/src/runtime/derivedModes/modeKeyCpu.ts +251 -0
  54. package/src/runtime/derivedModes/partition.ts +206 -0
  55. package/src/runtime/derivedModes/slotTable.ts +153 -0
  56. package/src/runtime/heapScene/growBuffer.ts +75 -0
  57. package/src/runtime/heapScene/packers.ts +127 -0
  58. package/src/runtime/heapScene/pools.ts +492 -0
  59. package/src/runtime/heapScene/scanKernel.ts +184 -0
  60. package/src/runtime/heapScene.ts +397 -1064
  61. package/src/runtime/index.ts +40 -0
  62. package/src/runtime/pipelineCache/bitfield.ts +225 -0
  63. package/src/runtime/pipelineCache/cache.ts +129 -0
  64. package/src/runtime/pipelineCache/descriptor.ts +150 -0
  65. package/src/runtime/pipelineCache/index.ts +37 -0
@@ -0,0 +1,184 @@
1
+ // Megacall GPU prefix-sum compute shader + record-layout constants.
2
+ //
3
+ // Four-pass scan over the bucket's drawTable:
4
+ // 1. scanTile — per-tile Blelloch scan, writes per-tile sums
5
+ // 2. scanBlocks — exclusive scan over the per-tile sums →
6
+ // tile offsets + total emit count
7
+ // 3. addOffsets — add tile offsets back into per-record
8
+ // firstEmit values
9
+ // 4. buildTileIndex — per-tile binary-search-fold for the VS
10
+ // prelude (mapping vertex_index → drawIdx)
11
+ //
12
+ // All four entry points share one WGSL module + one binding layout
13
+ // (defined below). The host runs them in sequence with the same bind
14
+ // group; only the dispatch shape and entry point change per pass.
15
+
16
+ export const SCAN_TILE_SIZE = 512;
17
+ export const SCAN_WG_SIZE = 256;
18
+ /** numBlocks ≤ TILE_SIZE — single-pass blockOffsets fits in shared memory. */
19
+ export const SCAN_MAX_RECORDS = SCAN_TILE_SIZE * SCAN_TILE_SIZE;
20
+
21
+ /** Tile size for the firstDrawInTile binary-search-fold index. */
22
+ export const TILE_K = 64;
23
+
24
+ /** drawTable record width: (firstEmit, drawIdx, indexStart, indexCount, instanceCount). */
25
+ export const RECORD_U32 = 5;
26
+ export const RECORD_BYTES = RECORD_U32 * 4;
27
+
28
+ export const HEAP_SCAN_WGSL = `
29
+ struct Params {
30
+ numRecords: u32,
31
+ numBlocks: u32,
32
+ _pad0: u32,
33
+ _pad1: u32,
34
+ };
35
+
36
+ struct Record {
37
+ firstEmit: u32,
38
+ drawIdx: u32,
39
+ indexStart: u32,
40
+ indexCount: u32,
41
+ instanceCount: u32,
42
+ };
43
+
44
+ @group(0) @binding(0) var<storage, read_write> drawTable: array<Record>;
45
+ @group(0) @binding(1) var<storage, read_write> blockSums: array<u32>;
46
+ @group(0) @binding(2) var<storage, read_write> blockOffsets: array<u32>;
47
+ @group(0) @binding(3) var<storage, read_write> indirect: array<u32>;
48
+ @group(0) @binding(4) var<uniform> params: Params;
49
+ @group(0) @binding(5) var<storage, read_write> firstDrawInTile: array<u32>;
50
+
51
+ const TILE_SIZE: u32 = 512u;
52
+ const WG_SIZE: u32 = 256u;
53
+ const TILE_K: u32 = 64u;
54
+
55
+ var<workgroup> sdata: array<u32, 512>;
56
+
57
+ fn blellochScan(tid: u32) {
58
+ var offset: u32 = 1u;
59
+ for (var d: u32 = TILE_SIZE >> 1u; d > 0u; d = d >> 1u) {
60
+ workgroupBarrier();
61
+ if (tid < d) {
62
+ let ai = offset * (2u * tid + 1u) - 1u;
63
+ let bi = offset * (2u * tid + 2u) - 1u;
64
+ sdata[bi] = sdata[bi] + sdata[ai];
65
+ }
66
+ offset = offset * 2u;
67
+ }
68
+ if (tid == 0u) { sdata[TILE_SIZE - 1u] = 0u; }
69
+ for (var d: u32 = 1u; d < TILE_SIZE; d = d * 2u) {
70
+ offset = offset >> 1u;
71
+ workgroupBarrier();
72
+ if (tid < d) {
73
+ let ai = offset * (2u * tid + 1u) - 1u;
74
+ let bi = offset * (2u * tid + 2u) - 1u;
75
+ let t = sdata[ai];
76
+ sdata[ai] = sdata[bi];
77
+ sdata[bi] = sdata[bi] + t;
78
+ }
79
+ }
80
+ workgroupBarrier();
81
+ }
82
+
83
+ @compute @workgroup_size(WG_SIZE)
84
+ fn scanTile(@builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wgid: vec3<u32>) {
85
+ let tid = lid.x;
86
+ let blockOff = wgid.x * TILE_SIZE;
87
+ let n = params.numRecords;
88
+ let i0 = blockOff + tid;
89
+ let i1 = blockOff + tid + WG_SIZE;
90
+ var v0: u32 = 0u;
91
+ var v1: u32 = 0u;
92
+ if (i0 < n) { v0 = drawTable[i0].indexCount * drawTable[i0].instanceCount; }
93
+ if (i1 < n) { v1 = drawTable[i1].indexCount * drawTable[i1].instanceCount; }
94
+ sdata[tid] = v0;
95
+ sdata[tid + WG_SIZE] = v1;
96
+ workgroupBarrier();
97
+ blellochScan(tid);
98
+ if (i0 < n) { drawTable[i0].firstEmit = sdata[tid]; }
99
+ if (i1 < n) { drawTable[i1].firstEmit = sdata[tid + WG_SIZE]; }
100
+ if (tid == WG_SIZE - 1u) {
101
+ blockSums[wgid.x] = sdata[tid + WG_SIZE] + v1;
102
+ }
103
+ }
104
+
105
+ @compute @workgroup_size(WG_SIZE)
106
+ fn scanBlocks(@builtin(local_invocation_id) lid: vec3<u32>) {
107
+ let tid = lid.x;
108
+ let n = params.numBlocks;
109
+ let i0 = tid;
110
+ let i1 = tid + WG_SIZE;
111
+ var v0: u32 = 0u;
112
+ var v1: u32 = 0u;
113
+ if (i0 < n) { v0 = blockSums[i0]; }
114
+ if (i1 < n) { v1 = blockSums[i1]; }
115
+ sdata[tid] = v0;
116
+ sdata[tid + WG_SIZE] = v1;
117
+ workgroupBarrier();
118
+ blellochScan(tid);
119
+ if (i0 < n) { blockOffsets[i0] = sdata[tid]; }
120
+ if (i1 < n) { blockOffsets[i1] = sdata[tid + WG_SIZE]; }
121
+ workgroupBarrier();
122
+ if (tid == 0u) {
123
+ if (n > 0u) {
124
+ let lastIdx = n - 1u;
125
+ let total = blockOffsets[lastIdx] + blockSums[lastIdx];
126
+ indirect[0] = total;
127
+ } else {
128
+ indirect[0] = 0u;
129
+ }
130
+ indirect[1] = 1u;
131
+ indirect[2] = 0u;
132
+ indirect[3] = 0u;
133
+ }
134
+ }
135
+
136
+ @compute @workgroup_size(WG_SIZE)
137
+ fn addOffsets(@builtin(local_invocation_id) lid: vec3<u32>, @builtin(workgroup_id) wgid: vec3<u32>) {
138
+ let tid = lid.x;
139
+ let blockOff = wgid.x * TILE_SIZE;
140
+ let n = params.numRecords;
141
+ let off = blockOffsets[wgid.x];
142
+ let i0 = blockOff + tid;
143
+ let i1 = blockOff + tid + WG_SIZE;
144
+ if (i0 < n) { drawTable[i0].firstEmit = drawTable[i0].firstEmit + off; }
145
+ if (i1 < n) { drawTable[i1].firstEmit = drawTable[i1].firstEmit + off; }
146
+ }
147
+
148
+ @compute @workgroup_size(WG_SIZE)
149
+ fn buildTileIndex(@builtin(global_invocation_id) gid: vec3<u32>) {
150
+ let tileIdx = gid.x;
151
+ // totalEmit is computed by scanBlocks into indirect[0]; reading it
152
+ // from indirect avoids a separate uniform/storage round-trip.
153
+ let totalEmit = indirect[0];
154
+ let numTiles = (totalEmit + TILE_K - 1u) / TILE_K;
155
+ if (tileIdx > numTiles) { return; }
156
+ if (params.numRecords == 0u) {
157
+ if (tileIdx == 0u) { firstDrawInTile[0] = 0u; }
158
+ return;
159
+ }
160
+ if (tileIdx == numTiles) {
161
+ // Sentinel for the open upper bound — the LAST VALID SLOT, not
162
+ // numRecords. The render VS uses
163
+ // hi = firstDrawInTile[_tileIdx + 1u]
164
+ // and the binary search treats hi as INCLUSIVE. If the sentinel
165
+ // were numRecords (one past last), the search would drag lo into
166
+ // the OOB slot for emits in the last tile, since drawTable reads
167
+ // past recordCount return 0 (binding size clamping) and 0 ≤ emit
168
+ // is always true. Visible symptom: the LAST few emits in the
169
+ // bucket land on slot=numRecords (drawIdx=0, indexCount=0 → /-by-
170
+ // zero) → degenerate / cross-RO triangle stitched to slot 0.
171
+ firstDrawInTile[tileIdx] = params.numRecords - 1u;
172
+ return;
173
+ }
174
+ let tileStart = tileIdx * TILE_K;
175
+ var lo: u32 = 0u;
176
+ var hi: u32 = params.numRecords - 1u;
177
+ loop {
178
+ if (lo >= hi) { break; }
179
+ let mid = (lo + hi + 1u) >> 1u;
180
+ if (drawTable[mid].firstEmit <= tileStart) { lo = mid; } else { hi = mid - 1u; }
181
+ }
182
+ firstDrawInTile[tileIdx] = lo;
183
+ }
184
+ `;