docs(windows-rewrite): M1 step-2 pf-vdisplay port plan (workflow-mapped + critiqued)
apple / swift (push) Failing after 1s
apple / screenshots (push) Has been skipped
android / android (push) Has been cancelled
ci / web (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / rust (push) Has been cancelled
deb / build-publish (push) Has been cancelled
decky / build-publish (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
apple / swift (push) Failing after 1s
apple / screenshots (push) Has been skipped
android / android (push) Has been cancelled
ci / web (push) Has been cancelled
ci / docs-site (push) Has been cancelled
ci / bench (push) Has been cancelled
ci / rust (push) Has been cancelled
deb / build-publish (push) Has been cancelled
decky / build-publish (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
Record the full driver port plan from the iddcx-driver-port-map workflow: the 11
DDIs to wrap, the 15 IDD_CX_CLIENT_CONFIG callbacks, the DeviceContext-owned state
model (single Monitor identity + monitor EvtCleanupCallback RAII), the
pf-vdisplay-proto frame transport, and the 8-step CI/box-gated checklist. Fold in
the adversarial critique: secure-desktop is a BLOCKING gate (do not retire the WGC
relay until proven), define the recreate/concurrency/Reconfigure failure branches,
host<->driver protocol_version lockstep. De-risk status: the full IddCx symbol
surface + .Size machinery is CI-proven present (ae803b2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -701,3 +701,74 @@ swap-chain processor + frame transport, with the clean ownership model (DeviceCo
|
|||||||
First gate: a probe linking `IddCxStub` and calling `IddCxDeviceInitConfig`/`…Initialize`/
|
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 —
|
`…AdapterInitAsync` (CI = compile+link). On-glass load + IDD-push stream needs the RTX box (ephemeral —
|
||||||
currently down/Proxmox).
|
currently down/Proxmox).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. M1 step 2 — pf-vdisplay driver port plan (2026-06-24, workflow-mapped + critiqued)
|
||||||
|
|
||||||
|
**Status of the binding (DONE, CI-green):** the wdk-sys `iddcx` binding is proven *complete for the whole
|
||||||
|
driver*, not just init. `wdk-probe/src/iddcx_surface_assert.rs` (commit `ae803b2`) CI-asserts every `*2`/HDR
|
||||||
|
struct (`IDDCX_TARGET_MODE2`/`PATH2`/`METADATA2`, `IDARG_*RELEASEANDACQUIREBUFFER2` — which embed
|
||||||
|
`DISPLAYCONFIG_*`/`LUID`, both of which **resolve from `crate::types`** — no allowlist gap), all 14 inbound
|
||||||
|
`PFN_IDD_CX_*` callbacks, the `.Size` machinery (`IddStructures`/`IddStructureCount`/
|
||||||
|
`IddClientVersionHigherThanFramework`/`_IDDSTRUCTENUM::INDEX_*` — so `IDD_STRUCTURE_SIZE!` is portable), and
|
||||||
|
`IDDCX_ADAPTER_FLAGS::…CAN_PROCESS_FP16` + `IDDCX_TARGET_CAPS::…HIGH_COLOR_SPACE`. ModuleConsts module
|
||||||
|
naming: the func/struct enums are `_IDDFUNCENUM`/`_IDDSTRUCTENUM` (underscored tag), but the flag/cap enums
|
||||||
|
are `IDDCX_ADAPTER_FLAGS`/`IDDCX_TARGET_CAPS` (no underscore).
|
||||||
|
|
||||||
|
### DDIs to wrap (11 — graduate `wdk-probe/src/iddcx_rt.rs` → a `wdk-iddcx` crate)
|
||||||
|
DeviceInitConfig, DeviceInitialize, AdapterInitAsync (done), MonitorCreate, MonitorArrival,
|
||||||
|
MonitorDeparture, AdapterSetRenderAdapter, SwapChainSetDevice (`other_is_error`; 0x887A0026→retry),
|
||||||
|
**SwapChainReleaseAndAcquireBuffer2** (HDR variant only; `other_is_error`; E_PENDING 0x8000000A → wait on
|
||||||
|
the surface event), SwapChainFinishedProcessingFrame. **Drop** the v1 `ReleaseAndAcquireBuffer` (adapter
|
||||||
|
always sets FP16). **Defer** the hardware-cursor DDIs (cursor baked into video).
|
||||||
|
|
||||||
|
### Callbacks (15 in `IDD_CX_CLIENT_CONFIG`; `*2` mandatory because FP16)
|
||||||
|
parse_monitor_description (+`2`), monitor_query_target_modes (+`2`), adapter_commit_modes (+`2`),
|
||||||
|
adapter_init_finished (stash IDDCX_ADAPTER + start watchdog), monitor_get_default_modes (→NOT_IMPLEMENTED,
|
||||||
|
we always carry EDID), **query_target_info (→HIGH_COLOR_SPACE), set_gamma_ramp (accept-stub — WITHOUT it
|
||||||
|
the adapter fails to init), set_default_hdr_metadata (accept-stub)** — the last three are mandatory under
|
||||||
|
FP16, assign_swap_chain, unassign_swap_chain, device_io_control (the pf-vdisplay-proto control plane).
|
||||||
|
Plus `EvtDeviceD0Entry` (adapter created HERE, not in DeviceAdd) and two `EvtCleanupCallback`s.
|
||||||
|
|
||||||
|
### State model (the rewrite's core change)
|
||||||
|
`DeviceContext` OWNS all state — IDDCX_ADAPTER, session_id-keyed monitor map, watchdog, the per-render-LUID
|
||||||
|
`Direct3DDevice` pool — replacing the oracle's process globals. Reachable from BOTH the WDFDEVICE (strong)
|
||||||
|
and the IDDCX_ADAPTER object (the adapter-side callbacks need it). `MonitorContext` owns the
|
||||||
|
`SwapChainProcessor` + `target_id`; **wire `EvtCleanupCallback` on the IDDCX_MONITOR object** so RAII Drop
|
||||||
|
joins the worker thread + frees D3D (the oracle lacked this → the dominant reconnect leak). **Single Monitor
|
||||||
|
identity** keyed by `session_id` (collapses the oracle's 3-way EDID-serial/map/stamp desync that caused the
|
||||||
|
`target_id=0` recreate bug); `assign_swap_chain` reads `target_id` from the context, never a map lookup.
|
||||||
|
The HOST still owns the control-device handle, the linger/reuse state machine, and ALL `Global\` shared
|
||||||
|
objects (created `D:(A;;GA;;;WD)`); the driver only OPENS them.
|
||||||
|
|
||||||
|
### Frame transport (single-source on `pf_vdisplay_proto::frame::*`)
|
||||||
|
Acquire via `ReleaseAndAcquireBuffer2{AcquireSystemMemoryBuffer=0}` → GPU `ID3D11Texture2D`; borrow
|
||||||
|
`out.MetaData.pSurface` with `IDXGIResource::from_raw_borrowed` (do NOT steal IddCx's refcount), publish
|
||||||
|
BEFORE `FinishedProcessingFrame`. Ring = `RING_LEN`(6) keyed-mutex shared textures opened by name
|
||||||
|
(`frame::{header_name,event_name,texture_name}`); per-frame: GetDesc format-guard (drop on FP16↔BGRA
|
||||||
|
mismatch), `AcquireSync(0,0ms)`, `CopyResource`, `ReleaseSync(0)`, store `FrameToken{gen,seq,slot}.pack()`
|
||||||
|
(Release), `SetEvent`. All-slots-busy → drop, never block. `is_stale()` (header.generation Acquire) → reattach
|
||||||
|
on host ring recreate. Write `DRV_STATUS_OPENED` + render LUID into the header. Drop the old DebugBlock +
|
||||||
|
the locally-duplicated header/MAGIC/name consts.
|
||||||
|
|
||||||
|
### Implementation checklist (each step CI- or box-gated)
|
||||||
|
0. workspace `pf-vdisplay`(cdylib)+`wdk-iddcx` members — **STEP-0 gate must pull in `std::thread`+`OwnedHandle`** (critique: prove std links under the UMDF toolchain *here*, not at STEP 5). CI.
|
||||||
|
1. graduate `iddcx_rt.rs` → `wdk-iddcx` (11 DDIs + `is_nt_error`/`other_is_error`) + **re-export the inbound PFN types**. CI link.
|
||||||
|
1.5 (critique add) the surface-assert (DONE @ `ae803b2`) lives on so the full PFN/`*2`/`DISPLAYCONFIG` surface stays a CI gate.
|
||||||
|
2. DriverEntry + driver_add: full `IDD_CX_CLIENT_CONFIG` (15 callbacks as stubs) + DeviceInitConfig + WdfDeviceCreate(+cleanup) + CreateDeviceInterface(`PF_VDISPLAY_INTERFACE_GUID`) + DeviceInitialize + D0Entry stub; salvage `edid.rs` verbatim. **Resolve `.Size` via `IDD_STRUCTURE_SIZE!` (machinery confirmed present).** CI link + FORCE_INTEGRITY clear.
|
||||||
|
3. DeviceContext + `WDF_DECLARE_CONTEXT_TYPE` Arc<RwLock> blob; init_adapter in D0Entry (caps+FP16) → AdapterInitAsync; the `*2` mode DDIs + query_target_info + gamma/hdr accept-stubs. **Box gate:** loads under Secure Boot, enumerates as IddCx adapter, Status OK (no "Failed to get adapter").
|
||||||
|
4. control plane (GET_INFO version handshake — **host MUST assert `protocol_version`**, ADD/REMOVE/SET_RENDER_ADAPTER/PING/CLEAR_ALL) + create_monitor + real mode DDIs + watchdog + MONITOR_OP_LOCK; **switch host `sudovda.rs`/`idd_push.rs` to `pf_vdisplay_proto` (GUID e5bcc234→70667664, IOCTL 0x800→0x900, GUID-key→session_id) — lockstep**. CI (host build) + box (monitor appears at WxH@Hz).
|
||||||
|
5. Direct3DDevice + assign/unassign + SwapChainProcessor (worker thread, SetDevice 60×@50ms single-borrow retry, top-of-loop terminate, Buffer2 acquire, from_raw_borrowed) WITHOUT publisher; wire monitor `EvtCleanupCallback`. **Box:** swap-chain assigns, acquire loop runs, RAII teardown (no thread/VRAM leak). **Critique: instrument that MonitorContext::Drop actually RAN; if the monitor-object cleanup callback does not fire, keep the oracle's explicit free-before-departure path as the fallback.**
|
||||||
|
6. FramePublisher on `pf_vdisplay_proto::frame::*` + keyed-mutex RAII guard + OwnedHandle/ShmView; wire into run_core. **Box:** full IDD-push glass-to-glass, A/B vs the shipping driver. **Critique: add a BLOCKING secure-desktop gate here** — lock (Win+L)+UAC with serve in the console session / driver in Session 0, confirm frames keep flowing AND input reaches the desktop; until it passes, do NOT delete the WGC-relay/DDA secure path.
|
||||||
|
7. HDR ring-recreate + repeated session recreate (confirm the recreate-crash is gone). **Critique: define the failure branch** — if recreate isn't stable, keep IDD_PERSIST + state that mid-stream Reconfigure stays unsupported on Windows IDD-push (host rejects, as today) rather than crashing; keep `max_concurrent=1`. **Specify the concurrent-monitor D3D model before enabling >1** (two worker threads must not share one SINGLETHREADED immediate context — give each monitor its own device or a deferred/multithreaded context).
|
||||||
|
8. unsafe-reduction pass (one audited `SendPtr`/`ThreadBound`; per-site `// SAFETY`; `AcquiredSurface<'_>` + `KeyedMutexGuard` RAII so the hot loop has zero raw Finish/ReleaseSync) + **delete the old `packaging/windows/vdisplay-driver/` tree only after the secure-desktop gate (step 6) passes**. CI clippy -D warnings + final box A/B.
|
||||||
|
|
||||||
|
### Critique verdict + the big risk
|
||||||
|
Plan is implementation-ready once the 4 CI-checkable unknowns are gates (3 now resolved by the surface-assert
|
||||||
|
+ `.Size` machinery presence; std-under-UMDF is the STEP-0 gate). **SINGLE BIGGEST RISK: the secure-desktop
|
||||||
|
claim** — the plan retires the proven two-process WGC relay + DDA on the *unproven* assertion that one
|
||||||
|
IddPushCapturer captures the lock/UAC secure desktop directly (IDD-push is opt-in today behind
|
||||||
|
`PUNKTFUNK_IDD_PUSH`). Make it a blocking on-glass gate (step 6) and keep the WGC relay recoverable for one
|
||||||
|
release. Other defined-failure-branch items: monitor `EvtCleanupCallback` firing, IDD_PERSIST/Reconfigure,
|
||||||
|
concurrent-monitor device sharing, host↔driver `protocol_version` lockstep.
|
||||||
|
|||||||
Reference in New Issue
Block a user