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
445
446
447
448
//! **wgpu glue for the adapter-selection policy** (feature `wgpu`).
//!
//! The *policy* is pure and lives in [`crate::render::adapter`]; this module is
//! the thin, untestable-without-a-GPU edge that
//!
//! 1. converts a `wgpu::AdapterInfo` into the feature-free [`AdapterFacts`],
//! 2. enumerates + selects over real adapters ([`select_adapter`]),
//! 3. replaces the naive `instance.request_adapter(&Default::default())` every
//!    headless probe in this workspace hand-rolled ([`request_best_adapter`]),
//! 4. builds the `egui_wgpu::WgpuConfiguration` an eframe host installs
//!    ([`facett_wgpu_options`]).
//!
//! ## Why (3) matters
//!
//! `request_adapter` with `PowerPreference::default()` is `LowPower`, which on a
//! workstation with an integrated GPU deliberately prefers the *slow* device, and
//! wgpu's own fallback ordering will happily hand back `llvmpipe` when the
//! surface-compatibility filter rejects the real card. Every one of those call
//! sites should go through here.

use super::pass_clock::PASS_CLOCK_FEATURES;
use crate::render::adapter::{
    classify_unavailable, env_override, env_prefers_low_power, record_gpu_unavailable,
    record_selection, AdapterFacts, AdapterKind, AdapterSelection, GpuUnavailable,
};

/// Map wgpu's `DeviceType` onto the feature-free [`AdapterKind`].
#[must_use]
pub fn kind_of(device_type: wgpu::DeviceType) -> AdapterKind {
    match device_type {
        wgpu::DeviceType::DiscreteGpu => AdapterKind::DiscreteGpu,
        wgpu::DeviceType::IntegratedGpu => AdapterKind::IntegratedGpu,
        wgpu::DeviceType::VirtualGpu => AdapterKind::VirtualGpu,
        wgpu::DeviceType::Cpu => AdapterKind::Cpu,
        wgpu::DeviceType::Other => AdapterKind::Other,
    }
}

/// Convert a live `wgpu::AdapterInfo` into the plain facts the policy ranks.
#[must_use]
pub fn facts_of(info: &wgpu::AdapterInfo) -> AdapterFacts {
    AdapterFacts {
        name: info.name.clone(),
        vendor: info.vendor,
        device: info.device,
        kind: kind_of(info.device_type),
        backend: format!("{:?}", info.backend),
        driver: info.driver.clone(),
    }
}

/// Facts for a whole enumeration, in enumeration order.
#[must_use]
pub fn facts_of_all(adapters: &[wgpu::Adapter]) -> Vec<AdapterFacts> {
    adapters.iter().map(|a| facts_of(&a.get_info())).collect()
}

/// Rank a live adapter list and return the decision (honouring
/// `FACETT_GPU_ADAPTER`). Does **not** record it — [`select_adapter`] does.
#[must_use]
pub fn decide_for(adapters: &[wgpu::Adapter]) -> Option<AdapterSelection> {
    let facts = facts_of_all(adapters);
    AdapterSelection::decide(&facts, env_override().as_deref())
}

/// **THE selector.** Pick the adapter facett should render on, log it loudly and
/// record it for `state_json`. Returns the chosen adapter and the decision.
pub fn select_adapter(adapters: &[wgpu::Adapter]) -> Option<(wgpu::Adapter, AdapterSelection)> {
    let sel = decide_for(adapters)?;
    let chosen = adapters[sel.index].clone();
    record_selection(sel.clone());
    Some((chosen, sel))
}

/// Drop-in replacement for `instance.request_adapter(&Default::default())` in the
/// workspace's headless probes/tests.
///
/// Enumerates **every** adapter over `backends` and applies the policy, instead of
/// letting wgpu's internal preference order hand back an integrated/software
/// device. Falls back to a plain `request_adapter` if enumeration comes back empty
/// (some backends only support the request path).
pub fn request_best_adapter(
    instance: &wgpu::Instance,
    backends: wgpu::Backends,
) -> Option<wgpu::Adapter> {
    let adapters = pollster::block_on(instance.enumerate_adapters(backends));
    if !adapters.is_empty() {
        if let Some((a, _)) = select_adapter(&adapters) {
            return Some(a);
        }
    }
    let power_preference = if env_prefers_low_power() {
        wgpu::PowerPreference::LowPower
    } else {
        wgpu::PowerPreference::HighPerformance
    };
    pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptions {
        power_preference,
        force_fallback_adapter: false,
        compatible_surface: None,
    }))
    .ok()
}

/// **Refuse a measurement taken on a software rasteriser** — the adapter as an ASSERTED
/// fact, not a printed one.
///
/// A GPU test that silently lands on llvmpipe does not fail. It produces *different
/// pixels* and then passes or fails for a reason that has nothing to do with the code, on
/// a box where the real card being busy is not a rare condition. MEASURED 2026-08-31 in a
/// whole-workspace run: `facett-map3d`'s `postfx_bypass` printed
/// `device: llvmpipe (LLVM 21.1.8, 256 bits) (Vulkan, Cpu)` and failed — and its own
/// header already printed the adapter, which is precisely the shape of a hazard that is
/// documented and not enforced. (Re-run on the 4090 the verdict was the same to two
/// decimal places, 6.65 vs 6.66 — so llvmpipe did not decide THAT failure. Nobody could
/// know that without running the experiment by hand, which is the cost this removes.)
///
/// Why it can happen at all: every headless probe that hand-rolls
/// `request_adapter(&Default::default())` asks for `PowerPreference::LowPower` and takes
/// whatever wgpu's internal ordering hands back. [`request_best_adapter`] is the
/// replacement — it enumerates and applies the policy, which ranks software last. This
/// function is the assertion for the sites that get their device from somewhere else
/// (`egui_kittest::wgpu::create_render_state`, say) and can only inspect it afterwards.
///
/// # Panics
///
/// If `info` is a software rasteriser and `$FACETT_ALLOW_SOFTWARE_GPU` is not set to
/// `1`/`true`/`on`/`yes`. A genuinely CPU-only host sets that once and gets its old
/// behaviour back, and the variable's name is in the panic so it is discoverable from the
/// failure alone.
pub fn refuse_software_adapter(who: &str, info: &wgpu::AdapterInfo) {
    let facts = facts_of(info);
    if !crate::render::adapter::is_software_rasteriser(&facts) {
        return;
    }
    let allowed = matches!(
        std::env::var("FACETT_ALLOW_SOFTWARE_GPU").ok().as_deref(),
        Some("1" | "true" | "on" | "yes")
    );
    assert!(
        allowed,
        "{who}: this measurement was taken on a SOFTWARE rasteriser — {}. Whatever it \
         reports is about llvmpipe, not about the GPU lane, and a pass here is as \
         meaningless as a fail. Set FACETT_GPU_ADAPTER=discrete (facett's own adapter policy \
         ranks software last, so this only happens when the real card cannot give a \
         device), or FACETT_ALLOW_SOFTWARE_GPU=1 if this host really has no \
         card and you want the old behaviour back.",
        facts.describe()
    );
}

/// The **backends facett asks for** — WebGPU-class only (GFX_V2 Decision 0).
///
/// Native: `PRIMARY` (Vulkan, DX12, Metal). Wasm: `BROWSER_WEBGPU`. **`Backends::GL`
/// is deliberately absent.** WebGL2 has no compute shaders, no atomics, no storage
/// buffers and no indirect draws, so every item on the GFX_V2 roadmap — GPU culling
/// into an indirect buffer, GPU label collision, OIT, compute tessellation — is
/// *impossible* under it. While GL was in the mask we were either maintaining two
/// renderers or holding the good one back, and paying a standing tax for it (the
/// zero-area-sliver workaround exists only because slivers degrade to LINES on GL).
///
/// A host with no WebGPU-class driver now gets **no adapter**, loudly — the caller
/// surfaces that as a typed error. It does NOT silently soft-render: a wrong picture
/// that looks like a picture is the false-green class this suite keeps getting burned
/// by. The **CPU/egui-painter path is a different thing and stays** — that is how
/// headless tests and no-GPU hosts render, and it is not a WebGL fallback.
#[must_use]
pub fn preferred_backends() -> wgpu::Backends {
    #[cfg(target_arch = "wasm32")]
    {
        wgpu::Backends::BROWSER_WEBGPU
    }
    #[cfg(not(target_arch = "wasm32"))]
    {
        wgpu::Backends::PRIMARY
    }
}

/// Build the `egui_wgpu::WgpuConfiguration` an eframe host installs so the whole
/// app renders on the device the policy chose.
///
/// - `HighPerformance` power preference (or `LowPower` when `WGPU_POWER_PREF=low`),
/// - a `native_adapter_selector` driven by the pure policy — this is what rejects
///   the ASPEED/Matrox BMC console and llvmpipe,
/// - the decision logged loudly and recorded for `state_json`.
#[must_use]
pub fn facett_wgpu_options() -> egui_wgpu::WgpuConfiguration {
    use egui_wgpu::{WgpuConfiguration, WgpuSetup, WgpuSetupCreateNew};

    // `without_display_handle` — eframe's winit integration fills the display handle in
    // for us; everything else here is ours to set. (The old note here said the handle is
    // "needed only for Wayland+GLES". GLES is gone from this workspace entirely — see
    // `tests/webgl_free_law.rs` — so the parenthesis named a backend that no longer exists
    // here; the call is kept because eframe owns the handle, not because of GL.)
    let mut setup = WgpuSetupCreateNew::without_display_handle();
    setup.instance_descriptor.backends = preferred_backends();
    setup.power_preference = if env_prefers_low_power() {
        wgpu::PowerPreference::LowPower
    } else {
        wgpu::PowerPreference::HighPerformance
    };
    // ── Request the pass-clock's timestamp features, WHERE THE ADAPTER HAS THEM. ──
    // egui-wgpu's default `device_descriptor` requests `Features::empty()`, and a
    // feature not requested at device creation is absent from `device.features()`
    // forever — so without this closure the per-lane GPU pass clock
    // (`pass_clock::PassClock`) would honestly report "unavailable" on every box,
    // including the Vulkan/4090 targets it exists for. The intersection with
    // `adapter.features()` keeps bring-up from FAILING on an adapter that lacks them
    // (llvmpipe on some Mesa builds): there the clock reports `None`, which is the
    // designed answer, not an error. The limits mirror egui-wgpu's own default
    // (`max_texture_dimension_2d: 8192` for 4k+ displays).
    //
    // ── LAW 4 residue, removed 2026-08-24 (GFX_V2 §V2.9b named it) ──────────────
    // This closure used to open by asking whether the adapter's backend was GL and, if so,
    // taking wgpu's WebGL2 downlevel limits. That branch was UNREACHABLE.
    // `preferred_backends()` is `PRIMARY` on native and `BROWSER_WEBGPU` on wasm — the GL
    // mask appears in neither — and since GFX_V2 V2.8b the workspace does not even COMPILE
    // wgpu-hal's GLES backend (`tests/webgl_free_law.rs` holds that). So the branch could
    // not fire, and its cost was not cycles: a reader finds live-looking WebGL2 handling in
    // the adapter policy and concludes there is a GL path to maintain. Dead code that
    // describes a lane the product does not have is a documentation defect with a compiler
    // behind it.
    //
    // `webgl_free_law::no_source_branches_on_the_gl_backend` is what keeps it gone.
    setup.device_descriptor = std::sync::Arc::new(|adapter: &wgpu::Adapter| wgpu::DeviceDescriptor {
        label: Some("facett wgpu device"),
        required_features: adapter.features() & PASS_CLOCK_FEATURES,
        required_limits: wgpu::Limits { max_texture_dimension_2d: 8192, ..wgpu::Limits::default() },
        ..Default::default()
    });
    setup.native_adapter_selector = Some(std::sync::Arc::new(
        |adapters: &[wgpu::Adapter], surface: Option<&wgpu::Surface<'_>>| match select_adapter(
            adapters,
        ) {
            Some((a, _)) => {
                // The ONE moment the real window surface and the chosen adapter meet
                // before the first configure: record what the surface can PRESENT with,
                // so the host can pick a present mode it knows is supported instead of
                // guessing (`surface.configure` with an unsupported mode is a wgpu
                // validation panic, not a fallback — see `present_mode_for`).
                if let Some(s) = surface {
                    record_surface_present_modes(s.get_capabilities(&a).present_modes);
                }
                Ok(a)
            }
            // GFX_V2 Decision 0: fail LOUDLY and TYPED. eframe only accepts a
            // String here, so the typed value is recorded first (for `state_json`
            // and the stderr banner) and its Display — which carries the
            // `facet-gpu-<n>` code and the remedy — becomes the message eframe
            // surfaces. Never a silent soft-render fallback.
            None => Err(gpu_unavailable_for(adapters).to_string()),
        },
    ));

    WgpuConfiguration {
        wgpu_setup: WgpuSetup::CreateNew(setup),
        // eframe's OWN default is `SurfaceConfig::LOW_LATENCY` (`AutoVsync` + a
        // presentation queue of ONE frame); `egui_wgpu::WgpuConfiguration::default()`
        // is `desired_maximum_frame_latency: None`, which wgpu resolves to 2. Spelling
        // this struct out with `..Default::default()` therefore silently gave every
        // facett host one extra queued frame of input-to-photon latency that a plain
        // `eframe::NativeOptions::default()` never had. Restored explicitly, and
        // pinned by `wgpu_options_keep_eframes_low_latency_queue`.
        surface: egui_wgpu::SurfaceConfig::LOW_LATENCY,
        ..Default::default()
    }
}

/// Process-global record of the present modes the window surface reported for the
/// adapter facett opened — written once by the adapter selector, read by the host
/// when it settles its present mode.
static PRESENT_MODES: std::sync::OnceLock<std::sync::Mutex<Option<Vec<wgpu::PresentMode>>>> =
    std::sync::OnceLock::new();

fn present_modes_slot() -> &'static std::sync::Mutex<Option<Vec<wgpu::PresentMode>>> {
    PRESENT_MODES.get_or_init(|| std::sync::Mutex::new(None))
}

/// Record the surface's supported present modes (the selector calls this; a host
/// that brings its surface up some other way may call it too).
pub fn record_surface_present_modes(modes: Vec<wgpu::PresentMode>) {
    if let Ok(mut g) = present_modes_slot().lock() {
        *g = Some(modes);
    }
}

/// The present modes the window surface supports for the opened adapter — `None`
/// until a surface has been seen (headless, or before bring-up).
#[must_use]
pub fn surface_present_modes() -> Option<Vec<wgpu::PresentMode>> {
    present_modes_slot().lock().ok().and_then(|g| g.clone())
}

/// **The present mode a host may SAFELY configure**: `preferred` when the surface
/// reports it, else [`wgpu::PresentMode::AutoVsync`] — the mode wgpu resolves
/// against the surface itself and that every surface accepts.
///
/// Pure, so the fallback is a unit-tested fact rather than a crash report:
/// `wgpu::Surface::configure` with a mode absent from the capabilities is a
/// validation PANIC inside eframe's paint, so "try Mailbox" without this gate is
/// "crash on the boxes that lack it" (Mailbox is common on Vulkan/NVIDIA and X11,
/// and absent on many Wayland/Mesa and all FIFO-only stacks). The `Auto*` modes are
/// not in a capability list (they are wgpu-side policies), so asking for one is
/// always honoured as-is.
#[must_use]
pub fn present_mode_for(supported: Option<&[wgpu::PresentMode]>, preferred: wgpu::PresentMode) -> wgpu::PresentMode {
    match preferred {
        wgpu::PresentMode::AutoVsync | wgpu::PresentMode::AutoNoVsync => preferred,
        _ => match supported {
            Some(modes) if modes.contains(&preferred) => preferred,
            _ => wgpu::PresentMode::AutoVsync,
        },
    }
}

/// Classify a failed bring-up over the CURRENT adapter list, record it, and hand
/// back the typed error.
///
/// The distinction is the whole value: "nothing enumerated" means no driver or no
/// device, while "all rejected" means hardware exists and the policy refused it
/// (llvmpipe, an ASPEED/Matrox BMC console). Collapsing both into one message —
/// as the previous bare `"no wgpu adapters enumerated"` string did, even when
/// adapters plainly HAD been enumerated — sends the operator down the wrong path.
/// ⚠ In practice this only ever returns [`GpuUnavailable::NothingEnumerated`]: its one
/// caller is the selector below, which is reached only when `select_adapter` returned
/// `None`, and that happens **only for an empty list** (see
/// [`GpuUnavailable::AllRejected`]'s note). The branch is kept because the distinction is
/// what a stricter policy would need; `the_policy_never_refuses_a_non_empty_adapter_list`
/// in [`crate::render::adapter`] states that invariant so it cannot change silently.
#[must_use]
pub fn gpu_unavailable_for(adapters: &[wgpu::Adapter]) -> GpuUnavailable {
    // ONE classification, and it is the PURE one — so the reachability of each branch is
    // testable without a GPU. This edge only converts wgpu types into facts.
    let err = classify_unavailable(format!("{:?}", preferred_backends()), facts_of_all(adapters));
    record_gpu_unavailable(err.clone());
    err
}

#[cfg(test)]
mod tests {
    use super::*;

    /// The wgpu→facts mapping must be exhaustive and lossless for the fields the
    /// policy ranks on. RED if a wgpu upgrade adds a device type we silently drop
    /// into the wrong tier.
    #[test]
    fn device_type_mapping_is_exact() {
        assert_eq!(kind_of(wgpu::DeviceType::DiscreteGpu), AdapterKind::DiscreteGpu);
        assert_eq!(kind_of(wgpu::DeviceType::IntegratedGpu), AdapterKind::IntegratedGpu);
        assert_eq!(kind_of(wgpu::DeviceType::VirtualGpu), AdapterKind::VirtualGpu);
        assert_eq!(kind_of(wgpu::DeviceType::Cpu), AdapterKind::Cpu);
        assert_eq!(kind_of(wgpu::DeviceType::Other), AdapterKind::Other);
    }

    fn info(name: &str, dt: wgpu::DeviceType, vendor: u32) -> wgpu::AdapterInfo {
        wgpu::AdapterInfo {
            name: name.to_owned(),
            vendor,
            device: 0,
            device_type: dt,
            device_pci_bus_id: String::new(),
            driver: String::new(),
            driver_info: String::new(),
            backend: wgpu::Backend::Vulkan,
            subgroup_min_size: 0,
            subgroup_max_size: 0,
            transient_saves_memory: false,
        }
    }

    /// **RED-when-broken:** the real oden enumeration expressed in *wgpu* types
    /// (the shape eframe hands the selector) must still resolve to the 4090. This
    /// is the same assertion as the pure test but through the conversion, so a
    /// broken `facts_of` is caught too. No GPU needed — `AdapterInfo` is a plain
    /// struct.
    #[test]
    fn oden_enumeration_resolves_to_the_discrete_gpu() {
        use crate::render::adapter::{choose_adapter_index, VENDOR_ASPEED, VENDOR_NVIDIA};
        let infos = [
            info("ASPEED Graphics Family", wgpu::DeviceType::Other, VENDOR_ASPEED),
            info("llvmpipe (LLVM 21.1.8, 256 bits)", wgpu::DeviceType::Cpu, 0x1_0005),
            info("NVIDIA GeForce RTX 4090", wgpu::DeviceType::DiscreteGpu, VENDOR_NVIDIA),
        ];
        let facts: Vec<_> = infos.iter().map(facts_of).collect();
        assert_eq!(facts[2].backend, "Vulkan");
        let pick = choose_adapter_index(&facts).expect("must pick");
        assert_eq!(facts[pick].name, "NVIDIA GeForce RTX 4090");
        let sel = AdapterSelection::decide(&facts, None).expect("decides");
        assert!(!sel.software);
        assert_eq!(sel.index, 2);
    }

    /// The eframe configuration must be a freshly-created setup with the policy
    /// selector installed and high-performance requested. If someone drops the
    /// selector, the app silently falls back to whatever wgpu picks (software on
    /// this box) — this goes red first, with no GPU.
    #[test]
    fn wgpu_options_install_the_policy() {
        use egui_wgpu::WgpuSetup;
        let cfg = facett_wgpu_options();
        match cfg.wgpu_setup {
            WgpuSetup::CreateNew(setup) => {
                assert!(
                    setup.native_adapter_selector.is_some(),
                    "the adapter-selection policy must be installed"
                );
                assert_eq!(setup.power_preference, wgpu::PowerPreference::HighPerformance);
                assert!(
                    setup.instance_descriptor.backends.contains(wgpu::Backends::VULKAN),
                    "Vulkan must be among the requested backends"
                );
            }
            _ => panic!("expected CreateNew"),
        }
    }

    /// The facett configuration must carry eframe's own `LOW_LATENCY` surface config
    /// (present queue depth 1). Seen RED on the code this replaces: the struct was
    /// `..Default::default()`, i.e. `desired_maximum_frame_latency: None` → wgpu's 2.
    #[test]
    fn wgpu_options_keep_eframes_low_latency_queue() {
        let cfg = facett_wgpu_options();
        assert_eq!(
            cfg.surface.desired_maximum_frame_latency,
            Some(1),
            "one queued frame, as eframe's NativeOptions::default() has — not wgpu's 2"
        );
        assert_eq!(cfg.surface.present_mode, wgpu::PresentMode::AutoVsync, "the safe boot mode");
    }

    /// A host asks for Mailbox; the answer is Mailbox ONLY where the surface lists it,
    /// and the always-valid `AutoVsync` everywhere else — never `Immediate` (tearing),
    /// never a raw `Fifo` guess, never a mode the surface never reported.
    #[test]
    fn present_mode_for_falls_back_to_vsync_when_mailbox_is_unsupported() {
        use wgpu::PresentMode as P;
        assert_eq!(present_mode_for(Some(&[P::Fifo, P::Mailbox, P::Immediate]), P::Mailbox), P::Mailbox);
        assert_eq!(present_mode_for(Some(&[P::Fifo, P::Immediate]), P::Mailbox), P::AutoVsync);
        assert_eq!(present_mode_for(Some(&[P::Fifo]), P::Mailbox), P::AutoVsync);
        assert_eq!(present_mode_for(None, P::Mailbox), P::AutoVsync, "no surface seen = no claim");
        assert_eq!(present_mode_for(Some(&[]), P::Mailbox), P::AutoVsync);
        // The wgpu policies are honoured as-is: they are resolved against the surface by wgpu.
        assert_eq!(present_mode_for(Some(&[P::Fifo]), P::AutoVsync), P::AutoVsync);
        assert_eq!(present_mode_for(None, P::AutoNoVsync), P::AutoNoVsync);
        // A concrete mode the surface lists is honoured too (an operator forcing Immediate).
        assert_eq!(present_mode_for(Some(&[P::Fifo, P::Immediate]), P::Immediate), P::Immediate);
    }
}