From 0a710fdfe5d0aedd5cef8be914fd1f15c39296ab Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 28 Jul 2026 21:07:13 +0200 Subject: [PATCH] refactor(frame): narrow make_device's unsafe to the FFI calls themselves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First slice of the `unsafe_op_in_unsafe_fn` work on the Windows-gated code, and a deliberate demonstration of the shape the rest should take. `cargo fix` is NOT the tool here. Its suggestion for this lint wraps the entire function body: pub unsafe fn make_device(..) -> Result<..> { unsafe { ..40 lines.. }} One block spanning everything, `{ unsafe {` / `}}` bracing, and — the actual problem — zero change in how much code runs unchecked. It makes the status quo explicit rather than smaller, which is the opposite of the goal. Narrowed by hand instead: four blocks, each around the FFI call that needs it (`D3D11CreateDevice`, two `SetGPUThreadPriority`, `SetMaximumFrameLatency`), each with its own SAFETY note. The `Option` handling, the `?`, the `if let Ok(..)` casts and the `tracing!` calls are back outside, where the compiler checks them. Roughly 40 unchecked lines become 6. Fixed two of my own mistakes in the same pass: `elevate_process_gpu_priority` and `auto_priority_gate` are ALREADY safe fns, and I had wrapped their calls in `unsafe` out of momentum. Unnecessary `unsafe` is not free — it is the same "this is scary" noise the lint exists to remove, and the compiler only warns about it. That mistake is a good argument against doing the remaining ~590 sites mechanically. pf-frame drops 23 -> 19 E0133. The remaining three functions in this file need a different answer, not just narrowing: `enable_inc_base_priority` takes no arguments and touches only the current process's own token, so it has NO caller contract and should become a SAFE fn with unsafe blocks inside — which removes an `unsafe fn` rather than decorating it. Same likely for `hags_enabled(LUID)`, whose only argument is a plain value. Verified on Windows .47: pf-frame checks clean at EXITCODE=0, no errors, no unused-unsafe warnings. --- crates/pf-frame/src/dxgi.rs | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/pf-frame/src/dxgi.rs b/crates/pf-frame/src/dxgi.rs index b7baa8f6..8d54dc22 100644 --- a/crates/pf-frame/src/dxgi.rs +++ b/crates/pf-frame/src/dxgi.rs @@ -101,17 +101,21 @@ pub fn pack_luid(luid: LUID) -> i64 { pub unsafe fn make_device(adapter: &IDXGIAdapter1) -> Result<(ID3D11Device, ID3D11DeviceContext)> { let mut device: Option = None; let mut context: Option = None; - D3D11CreateDevice( - adapter, - D3D_DRIVER_TYPE_UNKNOWN, - HMODULE::default(), - D3D11_CREATE_DEVICE_BGRA_SUPPORT, - Some(&[D3D_FEATURE_LEVEL_11_0]), - D3D11_SDK_VERSION, - Some(&mut device), - None, - Some(&mut context), - ) + // SAFETY: `adapter` is live for the call (caller contract). The two out-params are local + // `Option`s the callee only writes, and both are checked below before use. + unsafe { + D3D11CreateDevice( + adapter, + D3D_DRIVER_TYPE_UNKNOWN, + HMODULE::default(), + D3D11_CREATE_DEVICE_BGRA_SUPPORT, + Some(&[D3D_FEATURE_LEVEL_11_0]), + D3D11_SDK_VERSION, + Some(&mut device), + None, + Some(&mut context), + ) + } .context("D3D11CreateDevice")?; let device = device.context("null D3D11 device")?; let context = context.context("null D3D11 context")?; @@ -127,14 +131,17 @@ pub unsafe fn make_device(adapter: &IDXGIAdapter1) -> Result<(ID3D11Device, ID3D elevate_process_gpu_priority(); if let Ok(dxgi_dev) = device.cast::() { // The absolute max GPU thread priority (0x4000001E; the same value Sunshine/Apollo use); fall back to relative +7. - if dxgi_dev.SetGPUThreadPriority(0x4000_001E).is_err() - && dxgi_dev.SetGPUThreadPriority(7).is_err() + // SAFETY: `dxgi_dev` is a live interface just obtained by a checked `cast`; both calls take + // a scalar and only report failure through their return value. + if unsafe { dxgi_dev.SetGPUThreadPriority(0x4000_001E) }.is_err() + && unsafe { dxgi_dev.SetGPUThreadPriority(7) }.is_err() { tracing::warn!("SetGPUThreadPriority failed (run as admin/SYSTEM for GPU priority)"); } } if let Ok(dxgi1) = device.cast::() { - let _ = dxgi1.SetMaximumFrameLatency(1); + // SAFETY: `dxgi1` is a live interface from a checked `cast`; the arg is a scalar. + let _ = unsafe { dxgi1.SetMaximumFrameLatency(1) }; } // REALTIME auto-gate (gpu-contention §5.C / latency plan T2.3) — needs the device's adapter, // so it runs here, after creation; internally once-per-process.