From 8c4e7b07bfac6a0b2d8938f8e05da422ab176b69 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Wed, 24 Jun 2026 15:04:46 +0000 Subject: [PATCH] docs(windows-rewrite): M1 IddCx make-or-break RESOLVED (the 6 working knobs) CI-green @ 6d8c7a5 (run 5548): IddCx bindgens + compiles in wdk-sys with WDF type-identity. Record the exact generate_iddcx recipe (c++ parse, IDD_STUB, allowlist_recursively(false), DXGI/OPM/D3D local emit, UINT alias, translate_enum_integer_types) and that the wdf-umdf fallback is unneeded. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/windows-host-rewrite.md | 43 +++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/docs/windows-host-rewrite.md b/docs/windows-host-rewrite.md index 9a8857b..45f9c5c 100644 --- a/docs/windows-host-rewrite.md +++ b/docs/windows-host-rewrite.md @@ -665,18 +665,39 @@ versioned-subpath subsets exactly. iddcx — glob, don't trust max) + `static=IddCxStub`; hand-declare `#[no_mangle] pub static IddMinimumVersionRequired: ULONG = 4;`; keep the FORCE_INTEGRITY clear. -**Make-or-break (the spike to run FIRST):** can `IddCx.h` bindgen in wdk-sys's config without a header -conflict? (upstream #514/#516; clean-fix PR #654 is **unmerged**.) Validate by adding the subset + an -`iddcx-probe` that calls `IddCxDeviceInitConfig`/`IddCxDeviceInitialize`/`IddCxAdapterInitAsync` → -**CI gate**: cdylib compiles + links IddCxStub. **On-glass gate (RTX box)**: self-signed driver loads + -the IddCx adapter initializes (runtime table/struct-index correctness only surfaces here). Possible gotcha: -IddCx.h may need an `IDD_STUB` preprocessor define to emit the table model (the oracle's wrapper.h set it). +**Make-or-break — RESOLVED ✅ (CI-green @ `6d8c7a5`, run 5548, no fallback).** `IddCx.h` bindgens AND the +generated module compiles inside wdk-sys with WDF **type-identity**; the #515/#516 header conflict NEVER +materialized. Vendored the **published windows-drivers-rs 0.5.1** crates (wdk-build + wdk-sys) under +`packaging/windows/drivers/vendor/`, `[patch.crates-io]`'d. The six knobs `generate_iddcx` actually +needed (each a real gotcha, all CI-proven; the recipe above was close but the codegen/scope details +differed): -**Fallback** if the bindgen header-conflict can't be resolved: keep the proven vendored unified -`wdf-umdf-sys` as a second `-sys` crate for `pf-vdisplay` only (a second stack, contra Decision C, but -already green + on-glass-proven) and track upstream #654. **Reject** Option 2 (standalone `iddcx-sys` + -`use wdk_sys::*` + giant WDF/DXGI blocklist) — version-fragile, structs embed WDF/DXGI by value. +1. **`--language=c++`** — `wdk_default` parses **C**; IddCx.h's `IDARG_*` typedefs need C++ or you get a + "must use 'struct' tag" cascade (verified by direct `clang` on the box: 0 errors as C++, fails as C). +2. **`-DIDD_STUB`** — table-dispatch mode; skips `IddCxFuncEnum.h`'s `#error IDDCX_VERSION_MAJOR is not + defined` (it lives inside `#ifndef IDD_STUB`). **Do NOT add `WDF_STUB`** — wdk-sys parses `wdf.h` + non-stubbed, and stubbing it only here would desync the shared WDF types (breaking type-identity). +3. **`allowlist_recursively(false)` + `allowlist_file("(?i).*iddcx.*")`, full codegen (no + `.complement()`)** — emit ONLY IddCx items; WDF/Win types resolve to wdk-sys's via + `use crate::types::*` in `src/iddcx.rs`. No giant blocklist (Option 2 avoided). +4. **`allowlist_type("_?DXGI_.*" / "IDXGI.*" / "_?OPM_.*" / "_?D3DCOLORVALUE")`** — emit the non-WDF types + wdk-sys doesn't bindgen, locally (absent from `crate::types`, so non-conflicting). The `_?` is + load-bearing: `typedef struct _OPM_X {} OPM_X` needs the tag AND the alias (recursively(false) won't + pull the tag from the typedef). +5. **`pub type UINT = ::core::ffi::c_uint;` in `src/iddcx.rs`** — `UINT` (unsigned int) is absent from + `crate::types`; covers the top-level struct-field uses. +6. **`translate_enum_integer_types(true)`** — C++ parsing kept `UINT` as the underlying repr of the + DXGI/OPM ModuleConsts enums (`pub mod _X { pub type Type = UINT; }`), and nested modules can't see the + parent `UINT`. This emits native `u32` reprs → self-contained enum modules. -Only after the spike passes: port the full ~30-DDI / ~40-struct surface (incl. the HDR `*2` DDIs) + the +The wrapper note still holds: table dispatch via `wdk_sys::iddcx::_IDDFUNCENUM::TableIndex as usize` +(ModuleConsts const, **not** the oracle's NewType `.0`); NTSTATUS = plain `i32` (`wdk_sys::NT_SUCCESS`). +Driver build.rs will add the IddCxStub link-search + `IddMinimumVersionRequired` + keep the +FORCE_INTEGRITY clear. **Option 2 stays rejected; the `wdf-umdf-sys` fallback is unneeded.** + +**NEXT (M1 cont.):** port the full ~30-DDI / ~40-struct surface (incl. the HDR `*2` DDIs) + the swap-chain processor + frame transport, with the clean ownership model (DeviceContext-owned state, `EvtCleanupCallback` on `MonitorContext`, single `Monitor` identity, the owned `pf-vdisplay-proto` plane). +First gate: a probe linking `IddCxStub` and calling `IddCxDeviceInitConfig`/`…Initialize`/ +`…AdapterInitAsync` (CI = compile+link). On-glass load + IDD-push stream needs the RTX box (ephemeral — +currently down/Proxmox).