@aardworx/wombat.rendering 0.8.1 → 0.9.1

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 (141) hide show
  1. package/dist/core/command.d.ts +7 -9
  2. package/dist/core/command.d.ts.map +1 -1
  3. package/dist/core/renderTask.d.ts +64 -1
  4. package/dist/core/renderTask.d.ts.map +1 -1
  5. package/dist/core/renderTask.js +3 -1
  6. package/dist/core/renderTask.js.map +1 -1
  7. package/dist/resources/preparedRenderObject.js +3 -3
  8. package/dist/resources/preparedRenderObject.js.map +1 -1
  9. package/dist/resources/uniformBuffer.d.ts.map +1 -1
  10. package/dist/resources/uniformBuffer.js +17 -0
  11. package/dist/resources/uniformBuffer.js.map +1 -1
  12. package/dist/runtime/derivedUniforms/dispatch.d.ts +105 -0
  13. package/dist/runtime/derivedUniforms/dispatch.d.ts.map +1 -0
  14. package/dist/runtime/derivedUniforms/dispatch.js +355 -0
  15. package/dist/runtime/derivedUniforms/dispatch.js.map +1 -0
  16. package/dist/runtime/derivedUniforms/index.d.ts +6 -0
  17. package/dist/runtime/derivedUniforms/index.d.ts.map +1 -0
  18. package/dist/runtime/derivedUniforms/index.js +26 -0
  19. package/dist/runtime/derivedUniforms/index.js.map +1 -0
  20. package/dist/runtime/derivedUniforms/recipes.d.ts +42 -0
  21. package/dist/runtime/derivedUniforms/recipes.d.ts.map +1 -0
  22. package/dist/runtime/derivedUniforms/recipes.js +134 -0
  23. package/dist/runtime/derivedUniforms/recipes.js.map +1 -0
  24. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts +56 -0
  25. package/dist/runtime/derivedUniforms/sceneIntegration.d.ts.map +1 -0
  26. package/dist/runtime/derivedUniforms/sceneIntegration.js +171 -0
  27. package/dist/runtime/derivedUniforms/sceneIntegration.js.map +1 -0
  28. package/dist/runtime/derivedUniforms/slotId.d.ts +15 -0
  29. package/dist/runtime/derivedUniforms/slotId.d.ts.map +1 -0
  30. package/dist/runtime/derivedUniforms/slotId.js +30 -0
  31. package/dist/runtime/derivedUniforms/slotId.js.map +1 -0
  32. package/dist/runtime/derivedUniforms/slots.d.ts +49 -0
  33. package/dist/runtime/derivedUniforms/slots.d.ts.map +1 -0
  34. package/dist/runtime/derivedUniforms/slots.js +123 -0
  35. package/dist/runtime/derivedUniforms/slots.js.map +1 -0
  36. package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts +13 -0
  37. package/dist/runtime/derivedUniforms/uberKernel.wgsl.d.ts.map +1 -0
  38. package/dist/runtime/derivedUniforms/uberKernel.wgsl.js +218 -0
  39. package/dist/runtime/derivedUniforms/uberKernel.wgsl.js.map +1 -0
  40. package/dist/runtime/flattenTree.d.ts +5 -0
  41. package/dist/runtime/flattenTree.d.ts.map +1 -0
  42. package/dist/runtime/flattenTree.js +45 -0
  43. package/dist/runtime/flattenTree.js.map +1 -0
  44. package/dist/runtime/heapAdapter.d.ts +16 -0
  45. package/dist/runtime/heapAdapter.d.ts.map +1 -0
  46. package/dist/runtime/heapAdapter.js +263 -0
  47. package/dist/runtime/heapAdapter.js.map +1 -0
  48. package/dist/runtime/heapEffect.d.ts +235 -0
  49. package/dist/runtime/heapEffect.d.ts.map +1 -0
  50. package/dist/runtime/heapEffect.js +529 -0
  51. package/dist/runtime/heapEffect.js.map +1 -0
  52. package/dist/runtime/heapEffectIR.d.ts +34 -0
  53. package/dist/runtime/heapEffectIR.d.ts.map +1 -0
  54. package/dist/runtime/heapEffectIR.js +1161 -0
  55. package/dist/runtime/heapEffectIR.js.map +1 -0
  56. package/dist/runtime/heapEligibility.d.ts +9 -0
  57. package/dist/runtime/heapEligibility.d.ts.map +1 -0
  58. package/dist/runtime/heapEligibility.js +195 -0
  59. package/dist/runtime/heapEligibility.js.map +1 -0
  60. package/dist/runtime/heapScene.d.ts +240 -31
  61. package/dist/runtime/heapScene.d.ts.map +1 -1
  62. package/dist/runtime/heapScene.js +3334 -265
  63. package/dist/runtime/heapScene.js.map +1 -1
  64. package/dist/runtime/heapShaderFamily.d.ts +132 -0
  65. package/dist/runtime/heapShaderFamily.d.ts.map +1 -0
  66. package/dist/runtime/heapShaderFamily.js +866 -0
  67. package/dist/runtime/heapShaderFamily.js.map +1 -0
  68. package/dist/runtime/hybridScene.d.ts +133 -0
  69. package/dist/runtime/hybridScene.d.ts.map +1 -0
  70. package/dist/runtime/hybridScene.js +159 -0
  71. package/dist/runtime/hybridScene.js.map +1 -0
  72. package/dist/runtime/index.d.ts +8 -1
  73. package/dist/runtime/index.d.ts.map +1 -1
  74. package/dist/runtime/index.js +9 -1
  75. package/dist/runtime/index.js.map +1 -1
  76. package/dist/runtime/renderTask.d.ts +21 -4
  77. package/dist/runtime/renderTask.d.ts.map +1 -1
  78. package/dist/runtime/renderTask.js +127 -32
  79. package/dist/runtime/renderTask.js.map +1 -1
  80. package/dist/runtime/runtime.d.ts +33 -3
  81. package/dist/runtime/runtime.d.ts.map +1 -1
  82. package/dist/runtime/runtime.js +12 -3
  83. package/dist/runtime/runtime.js.map +1 -1
  84. package/dist/runtime/scenePass.d.ts +28 -3
  85. package/dist/runtime/scenePass.d.ts.map +1 -1
  86. package/dist/runtime/scenePass.js +37 -4
  87. package/dist/runtime/scenePass.js.map +1 -1
  88. package/dist/runtime/textureAtlas/atlasMipGutterKernel.d.ts +35 -0
  89. package/dist/runtime/textureAtlas/atlasMipGutterKernel.d.ts.map +1 -0
  90. package/dist/runtime/textureAtlas/atlasMipGutterKernel.js +247 -0
  91. package/dist/runtime/textureAtlas/atlasMipGutterKernel.js.map +1 -0
  92. package/dist/runtime/textureAtlas/atlasPool.d.ts +240 -0
  93. package/dist/runtime/textureAtlas/atlasPool.d.ts.map +1 -0
  94. package/dist/runtime/textureAtlas/atlasPool.js +798 -0
  95. package/dist/runtime/textureAtlas/atlasPool.js.map +1 -0
  96. package/dist/runtime/textureAtlas/bvhTree2d.d.ts +33 -0
  97. package/dist/runtime/textureAtlas/bvhTree2d.d.ts.map +1 -0
  98. package/dist/runtime/textureAtlas/bvhTree2d.js +501 -0
  99. package/dist/runtime/textureAtlas/bvhTree2d.js.map +1 -0
  100. package/dist/runtime/textureAtlas/packer.d.ts +50 -0
  101. package/dist/runtime/textureAtlas/packer.d.ts.map +1 -0
  102. package/dist/runtime/textureAtlas/packer.js +390 -0
  103. package/dist/runtime/textureAtlas/packer.js.map +1 -0
  104. package/dist/window/loop.d.ts +14 -0
  105. package/dist/window/loop.d.ts.map +1 -1
  106. package/dist/window/loop.js +18 -5
  107. package/dist/window/loop.js.map +1 -1
  108. package/package.json +6 -5
  109. package/src/core/command.ts +9 -9
  110. package/src/core/renderTask.ts +55 -2
  111. package/src/resources/preparedRenderObject.ts +3 -3
  112. package/src/resources/uniformBuffer.ts +15 -0
  113. package/src/runtime/derivedUniforms/dispatch.ts +407 -0
  114. package/src/runtime/derivedUniforms/index.ts +52 -0
  115. package/src/runtime/derivedUniforms/recipes.ts +159 -0
  116. package/src/runtime/derivedUniforms/sceneIntegration.ts +239 -0
  117. package/src/runtime/derivedUniforms/slotId.ts +35 -0
  118. package/src/runtime/derivedUniforms/slots.ts +155 -0
  119. package/src/runtime/derivedUniforms/uberKernel.wgsl.ts +220 -0
  120. package/src/runtime/flattenTree.ts +46 -0
  121. package/src/runtime/heapAdapter.ts +314 -0
  122. package/src/runtime/heapEffect.ts +728 -0
  123. package/src/runtime/heapEffectIR.ts +1211 -0
  124. package/src/runtime/heapEligibility.ts +189 -0
  125. package/src/runtime/heapScene.ts +3981 -349
  126. package/src/runtime/heapShaderFamily.ts +1102 -0
  127. package/src/runtime/hybridScene.ts +310 -0
  128. package/src/runtime/index.ts +45 -1
  129. package/src/runtime/renderTask.ts +167 -32
  130. package/src/runtime/runtime.ts +37 -4
  131. package/src/runtime/scenePass.ts +39 -4
  132. package/src/runtime/textureAtlas/atlasMipGutterKernel.ts +291 -0
  133. package/src/runtime/textureAtlas/atlasPool.ts +991 -0
  134. package/src/runtime/textureAtlas/bvhTree2d.ts +530 -0
  135. package/src/runtime/textureAtlas/packer.ts +429 -0
  136. package/src/window/loop.ts +32 -6
  137. package/dist/runtime/heapShader.d.ts +0 -12
  138. package/dist/runtime/heapShader.d.ts.map +0 -1
  139. package/dist/runtime/heapShader.js +0 -157
  140. package/dist/runtime/heapShader.js.map +0 -1
  141. package/src/runtime/heapShader.ts +0 -185
@@ -0,0 +1,247 @@
1
+ // Compute kernel that builds an atlas sub-rect's mip pyramid AND fills
2
+ // both gutter rings entirely on GPU, using only core WebGPU 1.0
3
+ // features (no `readonly-and-readwrite-storage-textures`).
4
+ //
5
+ // Architecture
6
+ // ============
7
+ // The whole operation runs inside a per-acquire **scratch buffer**
8
+ // laid out exactly like the destination region of the atlas page
9
+ // (bounding rect of the Iliffe pyramid + gutter, in atlas-pixel
10
+ // coordinates relative to the sub-rect origin). Each pixel is one
11
+ // packed `u32` (rgba8). Rows are padded to 256-byte alignment so the
12
+ // final `copyBufferToTexture` is straight-through.
13
+ //
14
+ // Per acquire:
15
+ // 1. CPU writes the raw source pixels into the scratch buffer at
16
+ // the mip-0 interior offset (via `mappedAtCreation`). One JS
17
+ // loop, no upload validation pitfalls.
18
+ // 2. For each mip k > 0: dispatch the `interior` kernel, which
19
+ // reads 2×2 from mip-(k-1) in the buffer and writes the average
20
+ // to mip-k interior, all in-buffer. Each mip lives in its own
21
+ // compute pass — the pass boundary acts as a barrier so
22
+ // mip-(k-1) is fully written before mip-k reads from it.
23
+ // 3. For each mip k: dispatch the `gutter` kernel, which copies
24
+ // the appropriate clamp / wrap interior cell into each gutter
25
+ // cell. Also one compute pass per mip.
26
+ // 4. `copyBufferToTexture` writes the full scratch buffer to the
27
+ // atlas page at the sub-rect origin.
28
+ //
29
+ // The kernel reads and writes ONE storage buffer through a
30
+ // `read_write` binding. WebGPU validates a single binding (even with
31
+ // read_write access) as one usage entry per resource — no hazard.
32
+ //
33
+ // No device features required. No same-texture binding pitfalls. The
34
+ // scratch buffer is per-acquire and freed after submission completes.
35
+ const WGSL = /* wgsl */ `
36
+ struct Params {
37
+ buf_stride_u32: u32,
38
+ _pad0: u32,
39
+ src_origin_in_buf: vec2<u32>,
40
+ src_size: vec2<u32>,
41
+ dst_origin_in_buf: vec2<u32>,
42
+ dst_size: vec2<u32>,
43
+ }
44
+
45
+ @group(0) @binding(0) var<storage, read_write> buf: array<u32>;
46
+ @group(0) @binding(1) var<uniform> P: Params;
47
+
48
+ fn loadRgba(x: u32, y: u32) -> vec4<f32> {
49
+ let idx = y * P.buf_stride_u32 + x;
50
+ return unpack4x8unorm(buf[idx]);
51
+ }
52
+
53
+ fn storeRgba(x: u32, y: u32, v: vec4<f32>) {
54
+ let idx = y * P.buf_stride_u32 + x;
55
+ buf[idx] = pack4x8unorm(v);
56
+ }
57
+
58
+ @compute @workgroup_size(8, 8, 1)
59
+ fn interior(@builtin(global_invocation_id) gid: vec3<u32>) {
60
+ if (gid.x >= P.dst_size.x || gid.y >= P.dst_size.y) { return; }
61
+ let sx0 = P.src_origin_in_buf.x + gid.x * 2u;
62
+ let sy0 = P.src_origin_in_buf.y + gid.y * 2u;
63
+ let sxMax = P.src_origin_in_buf.x + P.src_size.x - 1u;
64
+ let syMax = P.src_origin_in_buf.y + P.src_size.y - 1u;
65
+ let sx1 = min(sx0 + 1u, sxMax);
66
+ let sy1 = min(sy0 + 1u, syMax);
67
+ let a = loadRgba(sx0, sy0);
68
+ let b = loadRgba(sx1, sy0);
69
+ let c = loadRgba(sx0, sy1);
70
+ let d = loadRgba(sx1, sy1);
71
+ let avg = (a + b + c + d) * 0.25;
72
+ storeRgba(P.dst_origin_in_buf.x + gid.x, P.dst_origin_in_buf.y + gid.y, avg);
73
+ }
74
+
75
+ @compute @workgroup_size(8, 8, 1)
76
+ fn gutter(@builtin(global_invocation_id) gid: vec3<u32>) {
77
+ let totW = P.dst_size.x + 4u;
78
+ let totH = P.dst_size.y + 4u;
79
+ if (gid.x >= totW || gid.y >= totH) { return; }
80
+ let dx = i32(gid.x) - 2;
81
+ let dy = i32(gid.y) - 2;
82
+ let dw = i32(P.dst_size.x);
83
+ let dh = i32(P.dst_size.y);
84
+ if (dx >= 0 && dx < dw && dy >= 0 && dy < dh) { return; }
85
+ var sx: i32;
86
+ var sy: i32;
87
+ if (dx == -2) { sx = dw - 1; }
88
+ else if (dx == -1) { sx = 0; }
89
+ else if (dx == dw) { sx = dw - 1; }
90
+ else if (dx == dw + 1) { sx = 0; }
91
+ else { sx = dx; }
92
+ if (dy == -2) { sy = dh - 1; }
93
+ else if (dy == -1) { sy = 0; }
94
+ else if (dy == dh) { sy = dh - 1; }
95
+ else if (dy == dh + 1) { sy = 0; }
96
+ else { sy = dy; }
97
+ let v = loadRgba(u32(i32(P.dst_origin_in_buf.x) + sx),
98
+ u32(i32(P.dst_origin_in_buf.y) + sy));
99
+ storeRgba(u32(i32(P.dst_origin_in_buf.x) + dx),
100
+ u32(i32(P.dst_origin_in_buf.y) + dy),
101
+ v);
102
+ }
103
+ `;
104
+ const caches = new WeakMap();
105
+ function getKernel(device) {
106
+ const cached = caches.get(device);
107
+ if (cached !== undefined)
108
+ return cached;
109
+ const module = device.createShaderModule({ code: WGSL, label: "atlas/mipGutterKernel" });
110
+ const bindGroupLayout = device.createBindGroupLayout({
111
+ label: "atlas/mipGutterKernel/bgl",
112
+ entries: [
113
+ { binding: 0, visibility: 0x4 /* COMPUTE */, buffer: { type: "storage" } },
114
+ { binding: 1, visibility: 0x4 /* COMPUTE */, buffer: { type: "uniform" } },
115
+ ],
116
+ });
117
+ const layout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
118
+ const interiorPipeline = device.createComputePipeline({
119
+ layout, compute: { module, entryPoint: "interior" },
120
+ label: "atlas/mipGutterKernel/interior",
121
+ });
122
+ const gutterPipeline = device.createComputePipeline({
123
+ layout, compute: { module, entryPoint: "gutter" },
124
+ label: "atlas/mipGutterKernel/gutter",
125
+ });
126
+ const entry = { bindGroupLayout, interiorPipeline, gutterPipeline };
127
+ caches.set(device, entry);
128
+ return entry;
129
+ }
130
+ /**
131
+ * Build the mip pyramid + gutters on GPU and upload the result to a
132
+ * sub-rect of `page`. `srcPixels` is the raw RGBA8 source for mip 0
133
+ * (`srcW × srcH` pixels). The kernel:
134
+ * - Allocates a per-acquire scratch buffer.
135
+ * - Initialises the buffer at creation with mip-0 source pixels at
136
+ * the mip-0 interior offset.
137
+ * - Dispatches per-mip interior + gutter compute passes.
138
+ * - copyBufferToTexture into the page at (subRectX, subRectY).
139
+ *
140
+ * Caller must ensure the page has COPY_DST usage (atlas pages
141
+ * always do).
142
+ *
143
+ * Buffer is destroyed once submitted work completes (fire-and-forget
144
+ * via `onSubmittedWorkDone`).
145
+ */
146
+ export function buildMipsAndGutterOnGpu(device, page, subRectX, subRectY, boundsW, boundsH, srcPixels, srcW, srcH, mips) {
147
+ if (mips.length === 0)
148
+ return;
149
+ const { bindGroupLayout, interiorPipeline, gutterPipeline } = getKernel(device);
150
+ // Buffer layout: rows padded to 256 bytes for the final
151
+ // copyBufferToTexture. Stride in u32: 256 / 4 = 64 minimum, or
152
+ // ceil(boundsW * 4 / 256) * 256 / 4.
153
+ const rowBytes = Math.max(256, Math.ceil(boundsW * 4 / 256) * 256);
154
+ const bufStrideU32 = rowBytes / 4;
155
+ const bufSize = rowBytes * boundsH;
156
+ const scratch = device.createBuffer({
157
+ label: `atlas/mipGutter/scratch(${boundsW}x${boundsH})`,
158
+ size: bufSize,
159
+ usage: 0x80 /* STORAGE */ | 0x04 /* COPY_SRC */ | 0x08 /* COPY_DST */,
160
+ mappedAtCreation: true,
161
+ });
162
+ // CPU init: write mip-0 source pixels at the mip-0 interior offset
163
+ // inside the buffer. mips[0].origin is the interior offset.
164
+ const mip0 = mips[0];
165
+ {
166
+ const mapped = new Uint32Array(scratch.getMappedRange());
167
+ for (let y = 0; y < srcH; y++) {
168
+ for (let x = 0; x < srcW; x++) {
169
+ const si = (y * srcW + x) * 4;
170
+ const r = srcPixels[si];
171
+ const g = srcPixels[si + 1];
172
+ const b = srcPixels[si + 2];
173
+ const a = srcPixels[si + 3];
174
+ // little-endian rgba8: byte0=r, byte1=g, byte2=b, byte3=a.
175
+ const packed = (a << 24) | (b << 16) | (g << 8) | r;
176
+ mapped[(mip0.origin.y + y) * bufStrideU32 + (mip0.origin.x + x)] = packed >>> 0;
177
+ }
178
+ }
179
+ }
180
+ scratch.unmap();
181
+ const enc = device.createCommandEncoder({ label: "atlas/mipGutterKernel" });
182
+ const ubos = [];
183
+ const makeUbo = (srcO, srcS, dstO, dstS) => {
184
+ const buf = device.createBuffer({
185
+ size: 48, // 12 u32, padded
186
+ usage: 0x40 /* UNIFORM */ | 0x08 /* COPY_DST */,
187
+ label: "atlas/mipGutter/params",
188
+ });
189
+ const u = new Uint32Array(12);
190
+ u[0] = bufStrideU32;
191
+ u[1] = 0;
192
+ u[2] = srcO.x;
193
+ u[3] = srcO.y;
194
+ u[4] = srcS.w;
195
+ u[5] = srcS.h;
196
+ u[6] = dstO.x;
197
+ u[7] = dstO.y;
198
+ u[8] = dstS.w;
199
+ u[9] = dstS.h;
200
+ device.queue.writeBuffer(buf, 0, u);
201
+ ubos.push(buf);
202
+ return buf;
203
+ };
204
+ const makeBg = (ubo) => device.createBindGroup({
205
+ layout: bindGroupLayout,
206
+ entries: [
207
+ { binding: 0, resource: { buffer: scratch } },
208
+ { binding: 1, resource: { buffer: ubo } },
209
+ ],
210
+ });
211
+ // Interior passes: one compute pass per mip > 0 (pass boundary
212
+ // gives us the barrier ensuring mip-(k-1) is fully written before
213
+ // mip-k reads it).
214
+ for (let k = 1; k < mips.length; k++) {
215
+ const src = mips[k - 1];
216
+ const dst = mips[k];
217
+ const ubo = makeUbo(src.origin, src.size, dst.origin, dst.size);
218
+ const pass = enc.beginComputePass({ label: `atlas/mipGutter/interior/${k}` });
219
+ pass.setPipeline(interiorPipeline);
220
+ pass.setBindGroup(0, makeBg(ubo));
221
+ pass.dispatchWorkgroups(Math.ceil(dst.size.w / 8), Math.ceil(dst.size.h / 8), 1);
222
+ pass.end();
223
+ }
224
+ // Gutter passes: one per mip (each pass reads mip-k interior,
225
+ // which was either CPU-uploaded for k=0 or written by the interior
226
+ // pass for k>0).
227
+ for (let k = 0; k < mips.length; k++) {
228
+ const dst = mips[k];
229
+ const ubo = makeUbo(dst.origin, dst.size, dst.origin, dst.size);
230
+ const pass = enc.beginComputePass({ label: `atlas/mipGutter/gutter/${k}` });
231
+ pass.setPipeline(gutterPipeline);
232
+ pass.setBindGroup(0, makeBg(ubo));
233
+ pass.dispatchWorkgroups(Math.ceil((dst.size.w + 4) / 8), Math.ceil((dst.size.h + 4) / 8), 1);
234
+ pass.end();
235
+ }
236
+ // Final upload: buffer → page.
237
+ enc.copyBufferToTexture({ buffer: scratch, bytesPerRow: rowBytes, rowsPerImage: boundsH }, { texture: page, origin: { x: subRectX, y: subRectY, z: 0 } }, { width: boundsW, height: boundsH, depthOrArrayLayers: 1 });
238
+ device.queue.submit([enc.finish()]);
239
+ // Lifetime: destroy scratch + per-pass UBOs once submitted work is
240
+ // done. The submit holds a ref until completion.
241
+ void device.queue.onSubmittedWorkDone().then(() => {
242
+ scratch.destroy();
243
+ for (const b of ubos)
244
+ b.destroy();
245
+ });
246
+ }
247
+ //# sourceMappingURL=atlasMipGutterKernel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlasMipGutterKernel.js","sourceRoot":"","sources":["../../../src/runtime/textureAtlas/atlasMipGutterKernel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,240 @@
1
+ import { V2f } from "@aardworx/wombat.base";
2
+ import type { aval } from "@aardworx/wombat.adaptive";
3
+ import type { ITexture, HostTextureSource } from "../../core/texture.js";
4
+ import { TexturePacking } from "./packer.js";
5
+ export declare const ATLAS_PAGE_SIZE = 4096;
6
+ /** Tier S/M source-side dimension cap. */
7
+ export declare const ATLAS_MAX_DIM = 1024;
8
+ /**
9
+ * Maximum number of independent pages allowed per format. The shader's
10
+ * `switch pageRef` runs an N-way ladder; the BGL declares N consecutive
11
+ * texture slots per format. Allocations beyond this throw.
12
+ */
13
+ export declare const ATLAS_MAX_PAGES_PER_FORMAT = 8;
14
+ export type AtlasPageFormat = "rgba8unorm" | "rgba8unorm-srgb";
15
+ export declare const ATLAS_PAGE_FORMATS: readonly AtlasPageFormat[];
16
+ /** Format index used in the drawHeader: 0 = linear, 1 = srgb. */
17
+ export declare const atlasFormatIndex: (f: AtlasPageFormat) => number;
18
+ export interface AtlasPage {
19
+ readonly format: AtlasPageFormat;
20
+ /**
21
+ * The page's own independent `GPUTexture` (dimension: "2d", single
22
+ * 4096² image). Stable for the page's lifetime — never reallocated.
23
+ */
24
+ readonly texture: GPUTexture;
25
+ /** Immutable packer state — `tryAdd`/`remove` produce new instances. */
26
+ packing: TexturePacking<number>;
27
+ /**
28
+ * Page slot index in the format's binding sequence (0..N-1). Same
29
+ * value flows into the drawHeader `pageRef` field; the shader's
30
+ * `switch pageRef` selects the matching `atlasLinear<i>` /
31
+ * `atlasSrgb<i>` declaration.
32
+ */
33
+ readonly pageId: number;
34
+ }
35
+ export interface AtlasAcquisition {
36
+ /** Page slot index within the format's binding sequence (0..N-1). */
37
+ readonly pageId: number;
38
+ /** Top-left of mip 0's interior in the atlas, in atlas pixels. */
39
+ readonly origin: V2f;
40
+ /** Size of mip 0's interior in the atlas, in atlas pixels. */
41
+ readonly size: V2f;
42
+ /** Number of mip levels stored for this acquisition (1 = no pyramid). */
43
+ readonly numMips: number;
44
+ /** Stable refcount handle: pass back to `release`. */
45
+ readonly ref: number;
46
+ /** The page's GPUTexture (so the caller can pin it in the bind group). */
47
+ readonly page: AtlasPage;
48
+ }
49
+ /** Source descriptor accepted by `acquire` (small enough not to need a full ITexture). */
50
+ export interface AtlasSource {
51
+ readonly width: number;
52
+ readonly height: number;
53
+ /**
54
+ * The host source for upload. The pool calls
55
+ * `device.queue.copyExternalImageToTexture` (external) or
56
+ * `writeTexture` (raw) into the page region the first time the
57
+ * sub-rect is allocated. For mipped uploads the pool downscales
58
+ * via canvas-2d and uploads each level into the pyramid sub-region.
59
+ */
60
+ readonly host?: HostTextureSource;
61
+ }
62
+ export interface AtlasAcquireOptions {
63
+ readonly source?: AtlasSource;
64
+ /** When true, reserve a 1.5W×H rect and store an embedded mip pyramid. */
65
+ readonly wantsMips?: boolean;
66
+ /**
67
+ * Number of mip levels to store. Defaults to
68
+ * `floor(log2(max(w,h))) + 1` (full chain to 1×1).
69
+ */
70
+ readonly numMips?: number;
71
+ }
72
+ /**
73
+ * Default mip count for a `w×h` source: full chain down to 1×1.
74
+ */
75
+ export declare const defaultMipCount: (w: number, h: number) => number;
76
+ /**
77
+ * Mip-k pixel size given mip-0 size `(w,h)`. Halves each level and
78
+ * floors at 1×1.
79
+ */
80
+ export declare const mipPixelSize: (w: number, h: number, k: number) => {
81
+ w: number;
82
+ h: number;
83
+ };
84
+ /**
85
+ * Mip-k interior offset from mip-0 interior, both inside the embedded
86
+ * Iliffe pyramid. Mip 0 is at (0,0). Mips 1..N stack vertically in
87
+ * the column at x = W + 4 (mip-0 width + 2 px right gutter of mip-0
88
+ * + 2 px left gutter of the mip column). Each mip k>=1 sits below
89
+ * mip k-1 with 4 px of vertical gutter between them (2 px bottom of
90
+ * mip k-1 + 2 px top of mip k):
91
+ * y_k = sum_{j=1..k-1} (max(1, H >> j) + 4).
92
+ * Caller writes at `(uploadOrigin + mipOffsetInPyramid(w, h, k))`
93
+ * where uploadOrigin is mip-0's interior pixel position.
94
+ */
95
+ export declare const mipOffsetInPyramid: (w: number, h: number, k: number) => {
96
+ x: number;
97
+ y: number;
98
+ };
99
+ /**
100
+ * Aval-identity keyed pool over the per-format page sets. Multiple
101
+ * acquisitions of the same `aval<ITexture>` share one sub-rect; the
102
+ * refcount drives release.
103
+ */
104
+ export declare class AtlasPool {
105
+ private readonly device;
106
+ private readonly pagesByFormat;
107
+ private readonly pageAddedListeners;
108
+ private readonly entriesByAval;
109
+ private readonly entriesByRef;
110
+ /**
111
+ * §5b value-equality dedup map. Constant avals (`isConstant ===
112
+ * true`) wrapping the same inner GPUTexture (kind:"gpu") or
113
+ * HostTextureSource (kind:"host") collapse to one sub-rect.
114
+ * Reactive avals fall through to identity-only since their
115
+ * content can change.
116
+ */
117
+ private readonly entriesByValueKey;
118
+ private nextRef;
119
+ private innerKeyOf;
120
+ constructor(device: GPUDevice);
121
+ /** All currently allocated pages for a given format. */
122
+ pagesFor(format: AtlasPageFormat): readonly AtlasPage[];
123
+ /**
124
+ * Subscribe to page-allocation events. Fires after a fresh
125
+ * `AtlasPage` is appended to the format's page list (its `pageId`
126
+ * is the slot the bind group should now wire up).
127
+ */
128
+ onPageAdded(format: AtlasPageFormat, cb: (pageId: number) => void): {
129
+ dispose(): void;
130
+ };
131
+ /** True for pages we can drive via the compute mip+gutter kernel.
132
+ * The kernel is buffer-based: it allocates a scratch storage
133
+ * buffer matching the sub-rect's bounding box, runs all mip
134
+ * downscale + gutter fill in compute passes over the buffer, then
135
+ * one `copyBufferToTexture` uploads the whole region to the page.
136
+ * No texture storage bindings are needed and no device features
137
+ * are required — works in core WebGPU 1.0. The only constraint is
138
+ * that JS-side pixel extraction succeeds, which falls back to the
139
+ * CPU path on headless platforms without canvas.
140
+ *
141
+ * Disabled in node mock-GPU mode (which lacks queue.onSubmittedWorkDone). */
142
+ private canUseGpuKernel;
143
+ private allocatePage;
144
+ /**
145
+ * Tier-S eligibility: dimension threshold + supported format. If
146
+ * this returns null, the caller should route the texture down the
147
+ * Tier L (standalone) path.
148
+ */
149
+ static eligibleFormat(format: GPUTextureFormat): AtlasPageFormat | null;
150
+ static eligibleSize(width: number, height: number): boolean;
151
+ /**
152
+ * Acquire (or share) a sub-rect. The returned `AtlasAcquisition`
153
+ * gives the page slot index plus the mip-0 `origin`/`size` (in
154
+ * normalized atlas coords) and `numMips`. If the texture is already
155
+ * known (same aval), refcount bumps and we return the existing
156
+ * placement.
157
+ */
158
+ acquire(format: AtlasPageFormat, sourceAval: aval<ITexture>, width: number, height: number, opts?: AtlasAcquireOptions): AtlasAcquisition;
159
+ /**
160
+ * Look up the existing acquisition for a source aval, or `undefined`
161
+ * if the aval is not currently held in the pool. Mirrors
162
+ * `UniformPool.entry` — used by the heap path's reactivity loop to
163
+ * detect "this aval has live refs and just marked".
164
+ */
165
+ entry(sourceAval: aval<ITexture>): AtlasAcquisition | undefined;
166
+ /**
167
+ * Re-pack an aval's atlas placement against a new ITexture value.
168
+ * Mirrors `UniformPool.repack(av, newValue)` — used when an atlas-
169
+ * routed `aval<ITexture>` source swaps. Frees the old sub-rect (and
170
+ * the page slot in the packer) and acquires a fresh one for the new
171
+ * texture; the returned `AtlasAcquisition` carries the (potentially
172
+ * different) `pageId`/`origin`/`size`/`numMips`/`ref`. Refcount is
173
+ * preserved across the swap so multi-RO sharing keeps working.
174
+ *
175
+ * Throws if the new texture isn't Tier-S eligible (different format
176
+ * outside rgba8unorm/srgb, or larger than the cap). Callers should
177
+ * rely on the heap eligibility classifier, but this is a safety net.
178
+ */
179
+ repack(sourceAval: aval<ITexture>, newTexture: ITexture, opts?: AtlasAcquireOptions): AtlasAcquisition;
180
+ /** Decrement the refcount; on zero, free the sub-rect. */
181
+ release(ref: number): void;
182
+ /** Destroy every page texture. The pool becomes unusable. */
183
+ dispose(): void;
184
+ private finalize;
185
+ private upload;
186
+ /**
187
+ * Build a (w+4)×(h+4) extended pixel buffer from `src` (w×h, RGBA8)
188
+ * with the 2-px gutter pre-filled:
189
+ * - Inner ring (1 px) = clamp-replicate (edge texel).
190
+ * - Outer ring (1 px) = wrap (opposite-edge texel).
191
+ * The shader needs both: clamp-replicate absorbs FP-edge bleed for
192
+ * any wrap mode; the outer wrap ring is sampled by the repeat
193
+ * seam-shift ±1 path. By pre-baking these CPU-side we get a single
194
+ * writeTexture call per slot — much faster than per-cell GPU
195
+ * copies, and dodges Dawn's overly-strict same-texture copy
196
+ * validation.
197
+ *
198
+ * Layout matches the shader expectations and `placeWithGutter` in
199
+ * the conformance test. Corner cells are populated by independent
200
+ * per-axis interpretation (e.g. outer-X × outer-Y = diagonal wrap;
201
+ * inner-X × outer-Y = clamp-X × wrap-Y).
202
+ */
203
+ private static buildExtendedWithGutter;
204
+ /**
205
+ * Extract raw RGBA8 pixels from `host` at logical size (w, h).
206
+ * Falls back to a canvas draw + getImageData for external sources;
207
+ * raw sources are copied straight. Returns null when the runtime
208
+ * can't synthesise pixels (headless without canvas, etc.).
209
+ */
210
+ private extractPixels;
211
+ /**
212
+ * Upload a mip level INCLUDING its 2-px gutter ring. Writes a
213
+ * single (w+4)×(h+4) block to (x-2, y-2) — caller passes the
214
+ * interior position (x, y), this routine offsets by -2/-2 to
215
+ * cover the gutter. Returns false if pixel extraction failed (very
216
+ * rare; only on platforms without canvas support).
217
+ */
218
+ private uploadLevelWithGutter;
219
+ /** Unused stub kept for compatibility — see uploadLevelWithGutter. */
220
+ private fillClampGutter;
221
+ private uploadLevel;
222
+ /**
223
+ * Upload `src` (RGBA8, w×h) to `texture` at (x, y) via `writeTexture`.
224
+ * `writeTexture` requires `bytesPerRow` to be a multiple of 256 when
225
+ * the source has more than one row, so non-256-aligned widths need
226
+ * a padded buffer.
227
+ */
228
+ private writeRgba8Padded;
229
+ /**
230
+ * Produce a `CanvasImageSource` we can feed to `drawImage` for
231
+ * downscaling. Returns null when the runtime can't synthesise one
232
+ * (no DOM / OffscreenCanvas / ImageBitmap support).
233
+ */
234
+ private toDrawable;
235
+ private imageDataToCanvas;
236
+ private makeMipCanvas;
237
+ private makeCanvas;
238
+ private makeResult;
239
+ }
240
+ //# sourceMappingURL=atlasPool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlasPool.d.ts","sourceRoot":"","sources":["../../../src/runtime/textureAtlas/atlasPool.ts"],"names":[],"mappings":"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"}