facett-core 0.1.19

facett — visual kernel: render a node/edge Scene into egui (wgpu fast path to come)
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
//! **GFX_V2 item 8 — the colour-encoded ID pass really resolves a click** (needs
//! `--features wgpu`).
//!
//! Every assertion here is on **the id the DEVICE wrote, read back out of the
//! `R32Uint` target at a named pixel**. Not `pass.recorded()`, not a vertex count,
//! not "the target is non-blank". Item 2's lesson on this track was that a pixel
//! assertion stayed green through **0 device frames** because a CPU painter was
//! drawing; the equivalent lie here would be a picking test that passes while the
//! shader writes a constant. So:
//!
//! * **six distinct objects** are on screen at once, never one. A single-object
//!   probe cannot tell a working id encode from `return 0x01000000;`.
//! * their ids are chosen to sit on the **channel-carry boundaries** of the 4-byte
//!   little-endian wire encoding, including `0x0100_0000` (whose low three bytes are
//!   all zero — a pass that dropped a channel would still get this one right, which
//!   is exactly why the others are here) and `0xFFFF_FFFF` (the ceiling).
//! * a probe on **empty space** must return the reserved miss sentinel, and the
//!   sentinel must be distinguishable from a real feature 0.
//! * two **adjacent** quads are probed either side of their shared edge, with ids
//!   whose arithmetic mean is *itself a plausible id* — so any filtering, blending
//!   or MSAA resolve produces a visibly wrong answer rather than a rounding error.
//!
//! Run: `cargo test -p facett-core --features wgpu --test gpu_picking -- --nocapture`
#![cfg(feature = "wgpu")]

use facett_core::engine::pick::{PickId, MAX_FEATURE};
use facett_core::render::gpu::picking::{PickBatch, PickPass, PickTarget, PICK_DEPTH_FORMAT};
use facett_core::render::gpu::request_best_adapter;
use facett_core::render::gpu::preferred_backends;
use egui::{pos2, Rect};

/// The component every row and every SKIP in this file is filed under.
const GATE_COMPONENT: &str = "facett-core";
/// What a skipped arm of this file would have proven, so a SKIPPED matrix row is
/// readable without opening the test.
const GATE_DETAIL: &str = "the GPU id-buffer pick lane on a real device — one id per object, no bleed, and parity with the CPU lane";

/// A real device via the **sanctioned** selector (`request_best_adapter`), not an
/// eleventh hand-rolled `request_adapter(&Default::default())` — that one asks for
/// `LowPower` and picks the wrong GPU on a hybrid box.
///
/// `None` (⇒ the test skips) only when the box has no WebGPU-class adapter at all.
fn device() -> Option<(wgpu::Device, wgpu::Queue)> {
    let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
        backends: preferred_backends(),
        flags: wgpu::InstanceFlags::from_build_config().with_env(),
        backend_options: wgpu::BackendOptions::from_env_or_default(),
        memory_budget_thresholds: wgpu::MemoryBudgetThresholds::default(),
        display: None,
    });
    let adapter = request_best_adapter(&instance, preferred_backends())?;
    // ATTRIBUTION, not decoration. Item 2's key red on this track was a pixel
    // assertion passing through ZERO device frames because a CPU painter drew. Here
    // the equivalent lie is the graceful `None` skip above turning the whole file
    // green on a box that never ran a shader. Print the device that answered, so
    // `-- --nocapture` distinguishes "6 ids proven" from "6 ids skipped".
    let info = adapter.get_info();
    eprintln!("[gpu_picking] device: {} ({:?}, {:?})", info.name, info.backend, info.device_type);
    pollster::block_on(adapter.request_device(&wgpu::DeviceDescriptor {
        label: Some("gpu_picking_test"),
        required_features: wgpu::Features::empty(),
        required_limits: wgpu::Limits::downlevel_defaults(),
        ..Default::default()
    }))
    .ok()
}

const W: u32 = 200;
const H: u32 = 120;

/// The six-object fixture. Each entry is `(name, rect, id, probe)` where `probe` is a
/// pixel **strictly inside** the rect, and every id is a different byte pattern
/// exercising a different carry boundary of the little-endian wire encoding.
fn fixture() -> Vec<(&'static str, Rect, PickId, (u32, u32))> {
    vec![
        // low three bytes ALL ZERO — the floor of the real id space. A pass that
        // wrote only the alpha/high byte would still pass on this one alone.
        ("floor 0x01000000", Rect::from_min_max(pos2(10.0, 10.0), pos2(50.0, 50.0)), PickId::new(1, 0), (30, 30)),
        // byte 0 saturated, one below the R→G carry.
        ("pre-carry 0x010000FF", Rect::from_min_max(pos2(60.0, 10.0), pos2(100.0, 50.0)), PickId::new(1, 0xFF), (80, 30)),
        // the R→G carry itself.
        ("R→G 0x02000100", Rect::from_min_max(pos2(110.0, 10.0), pos2(150.0, 50.0)), PickId::new(2, 0x100), (130, 30)),
        // the G→B carry.
        ("G→B 0x01010000", Rect::from_min_max(pos2(10.0, 60.0), pos2(50.0, 100.0)), PickId::new(1, 0x1_0000), (30, 80)),
        // feature ceiling: all 24 feature bits set, layer still small.
        ("feature ceiling 0x03FFFFFF", Rect::from_min_max(pos2(60.0, 60.0), pos2(100.0, 100.0)), PickId::new(3, MAX_FEATURE), (80, 80)),
        // the absolute ceiling of the id space.
        ("ceiling 0xFFFFFFFF", Rect::from_min_max(pos2(110.0, 60.0), pos2(150.0, 100.0)), PickId::new(255, MAX_FEATURE), (130, 80)),
    ]
}

/// Run one id pass over `batch` into a fresh target and hand back the target.
///
/// A **FRESH** target every time, deliberately (item 2's RESIDUE finding): a reused
/// target holds the previous pass's correct answers, so a pass that wrote nothing at
/// all would read back last frame's right result. wgpu zero-initialises a new
/// texture, so an unwritten texel here reads `0` = the miss sentinel.
fn run_pass(device: &wgpu::Device, queue: &wgpu::Queue, batch: &PickBatch, depth: bool) -> (PickTarget, u32) {
    let mut target = if depth { PickTarget::with_depth() } else { PickTarget::new() };
    target.ensure(device, W, H);
    let mut pass = PickPass::new(device, depth.then_some(PICK_DEPTH_FORMAT));
    pass.set_viewport(queue, W, H);
    pass.upload(device, queue, batch);

    let mut enc = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("pick_test") });
    let drawn = {
        let mut rp = target.begin_pass(&mut enc).expect("target is allocated");
        pass.record(&mut rp)
    };
    queue.submit(Some(enc.finish()));
    device.poll(wgpu::PollType::wait_indefinitely()).ok();
    (target, drawn)
}

/// **The headline.** Six distinct objects, six known pixels, six exact ids — plus
/// empty space resolving to the miss sentinel.
#[test]
fn six_distinct_objects_each_resolve_to_their_own_id_at_a_known_pixel() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "six_distinct_objects_each_resolve_to_their_own_id_at_a_known_pixel", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    let fx = fixture();
    let mut batch = PickBatch::new();
    for (_, rect, id, _) in &fx {
        batch.push_quad(*rect, *id);
    }
    let (target, drawn) = run_pass(&device, &queue, &batch, false);
    assert_eq!(drawn, 36, "six quads is 36 vertices — the pass must actually record them");

    // Every id distinct, so a constant-returning shader cannot satisfy more than one.
    let ids: Vec<u32> = fx.iter().map(|(_, _, id, _)| id.0).collect();
    let mut uniq = ids.clone();
    uniq.sort_unstable();
    uniq.dedup();
    assert_eq!(uniq.len(), fx.len(), "the fixture must have six DISTINCT ids or it proves nothing");

    for (name, _, want, (px, py)) in &fx {
        let got = target.read_id(&device, &queue, *px, *py);
        assert_eq!(
            got, *want,
            "{name}: pixel ({px},{py}) read {:#010x} (layer {} feature {}), expected {:#010x} (layer {} feature {})",
            got.0,
            got.layer(),
            got.feature(),
            want.0,
            want.layer(),
            want.feature()
        );
        assert!(!got.is_nothing(), "{name}: a drawn object must never read as a miss");
    }

    // A MISS: the gutter right of every quad. Must be the sentinel — not id 0 meaning
    // "feature 0", not a neighbour's id, not garbage.
    for (px, py) in [(180, 110), (0, 0), (155, 55), (105, 55)] {
        let got = target.read_id(&device, &queue, px, py);
        assert!(
            got.is_nothing(),
            "empty pixel ({px},{py}) read {:#010x} — a miss must be PickId::NOTHING",
            got.0
        );
    }
    // ...and the sentinel is NOT what a real feature 0 reads as, which is the whole
    // point of reserving layer 0.
    let feature_zero = target.read_id(&device, &queue, 30, 30);
    assert_eq!(feature_zero, PickId::new(1, 0));
    assert_eq!(feature_zero.feature(), 0, "this object really is feature 0");
    assert!(!feature_zero.is_nothing(), "feature 0 must be distinguishable from a miss");
}

/// **No bleed across a shared edge.** Two quads meet at exactly x = 100. The ids are
/// feature 2 and feature 4 of the same layer, so their arithmetic mean is feature 3 —
/// a perfectly plausible object that no pixel is allowed to report. Any filtering,
/// blending or MSAA resolve on the id target produces it.
#[test]
fn adjacent_objects_do_not_bleed_across_their_shared_edge() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "adjacent_objects_do_not_bleed_across_their_shared_edge", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    let left = PickId::new(1, 2); // 0x01000002
    let right = PickId::new(1, 4); // 0x01000004
    let blend = PickId::new(1, 3); // 0x01000003 — the forbidden average
    assert_eq!((left.0 + right.0) / 2, blend.0, "the fixture's mean really is a valid id");

    let mut batch = PickBatch::new();
    batch.push_quad(Rect::from_min_max(pos2(0.0, 0.0), pos2(100.0, 60.0)), left);
    batch.push_quad(Rect::from_min_max(pos2(100.0, 0.0), pos2(200.0, 60.0)), right);
    let (target, _) = run_pass(&device, &queue, &batch, false);

    let a = target.read_id(&device, &queue, 99, 30);
    let b = target.read_id(&device, &queue, 100, 30);
    assert_eq!(a, left, "1 px left of the edge must be the left object, got {:#010x}", a.0);
    assert_eq!(b, right, "1 px right of the edge must be the right object, got {:#010x}", b.0);
    assert_ne!(a, b, "the edge separates two DIFFERENT ids — otherwise this proves nothing");

    // Sweep the whole 20 px band across the seam: not one texel may carry the mean,
    // and every texel must be exactly one of the two real ids.
    let band = target.read_region(&device, &queue, 90, 20, 20, 20);
    assert_eq!(band.len(), 400, "the readback must return the region it was asked for");
    for (i, got) in band.iter().enumerate() {
        let x = 90 + (i % 20) as u32;
        assert_ne!(*got, blend, "texel x={x} carries the BLEND of two ids — the target is filtering");
        assert!(
            *got == left || *got == right,
            "texel x={x} read {:#010x}, which is neither neighbour — the id space is being interpolated",
            got.0
        );
        let want = if x < 100 { left } else { right };
        assert_eq!(*got, want, "texel x={x} is on the wrong side of the seam");
    }
}

/// With a depth attachment the **nearest** id wins, and it wins in **both submission
/// orders**. Without a depth test the answer is "whichever drew last", so the two
/// orders disagree — which is what makes this pair of assertions non-vacuous.
#[test]
fn the_nearest_id_wins_regardless_of_draw_order() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "the_nearest_id_wins_regardless_of_draw_order", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    let near = PickId::new(4, 11);
    let far = PickId::new(4, 22);
    let overlap = Rect::from_min_max(pos2(40.0, 30.0), pos2(120.0, 90.0));

    let mut answers = Vec::new();
    for near_first in [true, false] {
        let mut batch = PickBatch::new();
        let push_near = |b: &mut PickBatch| b.push_quad_at_depth(overlap, near, 0.25);
        let push_far = |b: &mut PickBatch| b.push_quad_at_depth(overlap, far, 0.75);
        if near_first {
            push_near(&mut batch);
            push_far(&mut batch);
        } else {
            push_far(&mut batch);
            push_near(&mut batch);
        }
        let (target, drawn) = run_pass(&device, &queue, &batch, true);
        assert_eq!(drawn, 12, "two quads, 12 vertices");
        assert!(target.has_depth(), "this lane must have a depth attachment");
        let got = target.read_id(&device, &queue, 80, 60);
        assert_eq!(
            got, near,
            "near_first={near_first}: the visible (nearest) object is {:#010x}, read {:#010x}",
            near.0, got.0
        );
        answers.push(got);
    }
    assert_eq!(answers[0], answers[1], "the answer must not depend on submission order");
}

/// The pass **clears** to the miss sentinel — it does not merely start on a
/// zero-initialised texture.
///
/// This is the residue trap from item 2, inverted: draw a full-target id, prove it is
/// there, then run a second pass over the SAME target with nothing to draw. If the
/// clear were `LoadOp::Load` the first pass's ids would still be sitting there and a
/// "clicked empty space" probe would return a stale object.
#[test]
fn a_second_pass_clears_the_previous_frames_ids_to_the_miss_sentinel() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "a_second_pass_clears_the_previous_frames_ids_to_the_miss_sentinel", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    let id = PickId::new(9, 12345);
    let mut batch = PickBatch::new();
    batch.push_quad(Rect::from_min_max(pos2(0.0, 0.0), pos2(W as f32, H as f32)), id);
    let (target, drawn) = run_pass(&device, &queue, &batch, false);
    assert_eq!(drawn, 6);
    assert_eq!(target.read_id(&device, &queue, 100, 60), id, "frame 1 must have painted the whole target");

    // Frame 2 on the SAME target: an empty batch, so only the clear runs.
    let mut empty = PickPass::new(&device, None);
    empty.set_viewport(&queue, W, H);
    empty.upload(&device, &queue, &PickBatch::new());
    let mut enc = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("pick_clear") });
    let drawn2 = {
        let mut rp = target.begin_pass(&mut enc).expect("still allocated");
        empty.record(&mut rp)
    };
    queue.submit(Some(enc.finish()));
    device.poll(wgpu::PollType::wait_indefinitely()).ok();
    assert_eq!(drawn2, 0, "an empty batch draws nothing — but the pass still ran");

    for (px, py) in [(100, 60), (0, 0), (W - 1, H - 1)] {
        let got = target.read_id(&device, &queue, px, py);
        assert!(
            got.is_nothing(),
            "({px},{py}) still reads {:#010x} from the PREVIOUS frame — the pass is not clearing",
            got.0
        );
    }
}

/// The logical-coordinate entry point lands on the same texel as the physical one, at
/// a non-1.0 `pixels_per_point` — where an unscaled click silently probes the wrong
/// object. A hi-dpi host is the common case, so `ppp = 1.0` is the identity value
/// this test must not sit on.
#[test]
fn a_logical_click_at_hidpi_resolves_the_object_under_the_cursor() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "a_logical_click_at_hidpi_resolves_the_object_under_the_cursor", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    let a = PickId::new(1, 100);
    let b = PickId::new(1, 200);
    let mut batch = PickBatch::new();
    // In PHYSICAL px: a on the left half, b on the right half.
    batch.push_quad(Rect::from_min_max(pos2(0.0, 0.0), pos2(100.0, 120.0)), a);
    batch.push_quad(Rect::from_min_max(pos2(100.0, 0.0), pos2(200.0, 120.0)), b);
    let (target, _) = run_pass(&device, &queue, &batch, false);

    // A cursor at logical x = 60 with ppp = 2.0 is physical x = 120 → object b.
    // Ignoring ppp would probe physical 60 → object a. The two answers differ, which
    // is the only reason this assertion means anything.
    assert_eq!(
        target.read_id_logical(&device, &queue, pos2(60.0, 30.0), 2.0),
        b,
        "a hi-dpi click must scale into physical texels"
    );
    assert_eq!(target.read_id(&device, &queue, 60, 60), a, "physical 60 really is the OTHER object");
    // And logical 30 @ ppp 2 = physical 60 = a, closing the loop.
    assert_eq!(target.read_id_logical(&device, &queue, pos2(30.0, 30.0), 2.0), a);

    // A cursor outside the widget is a miss, not a clamp onto the edge object.
    assert!(target.read_id_logical(&device, &queue, pos2(-4.0, 30.0), 2.0).is_nothing());
}

/// **The two lanes agree, texel by texel.** This is the proof `engine::pick` was
/// designed for: *"it is the same 32-bit id the CPU lane returns, so a test can assert
/// the two lanes agree."*
///
/// The GPU pass and `PickIndex` share nothing but the id encoding — one rasterises
/// quads on a 4090, the other bins anchors into a `ScreenGrid` on the CPU. Two
/// independent implementations returning the same `PickId` at 500 probe pixels is a
/// far stronger statement than either lane checked against its own expectations, and
/// it is the only assertion here that could catch a bug living in the *fixture*.
///
/// **The tie-break is the whole difficulty, and it is a real bug this caught.**
/// `PickShape::Box` documents "the LOWEST feature index that contains the probe wins —
/// paint order"; a colour-encoded pass with no depth answers "whichever quad was
/// submitted last". For overlapping chips those are DIFFERENT objects. So the GPU lane
/// goes through `push_quad_in_painter_order`, which maps paint index to depth
/// (lower = nearer) so the `Less` test reproduces the CPU rule by construction.
#[test]
fn the_gpu_lane_and_the_cpu_lane_return_the_same_id_at_every_probe() {
    let Some((device, queue)) = device() else {
        facett_core::testmatrix::gpu_skip(GATE_COMPONENT, "the_gpu_lane_and_the_cpu_lane_return_the_same_id_at_every_probe", "no WebGPU-class adapter", GATE_DETAIL);
        return;
    };
    use facett_core::engine::pick::{PickIndex, PickShape};
    use facett_core::render::gpu::picking::painter_depth;

    // Chips that OVERLAP — 60x28 px boxes on a 34x16 px pitch. Overlap is mandatory:
    // over disjoint chips every tie-break rule agrees, so the test would pass with
    // the painter-order depth deleted. Item 2's identity-copy trap, in another shape.
    const LAYER: u8 = 5;
    let half = egui::vec2(30.0, 14.0);
    let anchors: Vec<egui::Pos2> =
        (0..24).map(|i| pos2(34.0 + (i % 6) as f32 * 26.0, 30.0 + (i / 6) as f32 * 22.0)).collect();
    let n = anchors.len();

    let mut cpu = PickIndex::default();
    cpu.begin(1);
    cpu.push_layer(LAYER, &anchors, (0..n as u32).collect(), PickShape::Box(half));

    // SUBMITTED IN REVERSE PAINT ORDER — and this is the single most important line
    // in the file. The first version of this test pushed the chips in paint order,
    // and it stayed GREEN with `push_quad_in_painter_order` replaced by a plain
    // `push_quad`: with every quad at depth 0.0, a strict `Less` test keeps the
    // FIRST-submitted fragment, which in paint order happens to be the lowest index —
    // the CPU rule, reproduced by accident. The depth ramp was a no-op and the guard
    // could not see it.
    //
    // That is item 2's IDENTITY-COPY trap in a new shape: when the submission order
    // already equals the intended order, the mapping between them is unobservable.
    // Reversing the submission order is the same remedy item 2 used (select a genuine
    // relocation, not a prefix), and it makes the depth mapping load-bearing: paint
    // order now has to come from the DEPTH VALUE, because submission order actively
    // contradicts it.
    let mut batch = PickBatch::new();
    for (i, a) in anchors.iter().enumerate().rev() {
        batch.push_quad_in_painter_order(Rect::from_center_size(*a, half * 2.0), PickId::new(LAYER, i as u32), i, n);
    }
    // Painter order really is encoded: index 0 must be strictly nearer than index n-1.
    assert!(painter_depth(0, n) < painter_depth(n - 1, n), "the depth ramp must be monotonic");
    let (target, drawn) = run_pass(&device, &queue, &batch, true);
    assert_eq!(drawn as usize, n * 6, "every chip must reach the device");

    // Probe a grid covering the chip field and the empty margin around it.
    let mut agreed_hits = 0usize;
    let mut agreed_misses = 0usize;
    let mut overlap_probes = 0usize;
    for gx in 0..25u32 {
        for gy in 0..20u32 {
            let (px, py) = (gx * 8, gy * 6);
            if px >= W || py >= H {
                continue;
            }
            // The CPU lane probes the PIXEL CENTRE, which is the point the rasteriser
            // tested when it decided texel (px,py)'s coverage. Probing the corner
            // instead disagrees on every boundary texel — a half-pixel convention
            // mismatch, and the reason a naive version of this test is flaky.
            let probe = pos2(px as f32 + 0.5, py as f32 + 0.5);
            let want = cpu.pick(probe).id;
            let got = target.read_id(&device, &queue, px, py);
            assert_eq!(
                got, want,
                "pixel ({px},{py}): GPU says {:#010x} (feature {}), CPU says {:#010x} (feature {})",
                got.0,
                got.feature(),
                want.0,
                want.feature()
            );
            if want.is_nothing() {
                agreed_misses += 1;
            } else {
                agreed_hits += 1;
                // How many chips contain this probe? >1 means the tie-break decided it.
                let covering = anchors
                    .iter()
                    .filter(|c| (probe.x - c.x).abs() <= half.x && (probe.y - c.y).abs() <= half.y)
                    .count();
                if covering > 1 {
                    overlap_probes += 1;
                }
            }
        }
    }
    // NON-VACUITY. A sweep that only ever landed on empty space, or never on an
    // overlap, would agree trivially and prove nothing.
    assert!(agreed_hits > 100, "only {agreed_hits} probes hit a chip — the sweep proves nothing");
    assert!(agreed_misses > 10, "only {agreed_misses} probes missed — the sentinel path is untested");
    assert!(
        overlap_probes > 50,
        "only {overlap_probes} probes landed where chips OVERLAP — the tie-break rule is untested, \
         and it is the one place the two lanes can legitimately disagree"
    );
    eprintln!(
        "[gpu_picking] two lanes agreed on {} hits / {} misses, {} of them contested by >1 chip",
        agreed_hits, agreed_misses, overlap_probes
    );
}