ITADN

[hal/dx12] Hook to customize the DXGI factory after creation (interposer/proxy interop, e.g. NVIDIA Streamline / DLSS Frame Generation)

#9614Openjtbirdsell 创建于 2026-06-01
backend: dx12
J
jtbirdsellcommented
**Problem** Some native D3D12 SDKs work by *interposing* the DXGI factory: the application's `IDXGIFactory` must be replaced with the SDK's proxy **immediately after it's created and before any swapchain is created from it**, so the SDK can hook `IDXGISwapChain::Present`. The prime example is **NVIDIA Streamline** (`slUpgradeInterface`), which is the only supported way to use **DLSS Frame Generation**. In the dx12 backend the factory is created inside `wgpu_hal::dx12::Instance::init` (via `auxil::dxgi::factory::create_factory`) and is never exposed for modification — `Instance::raw_factory4()` is read-only. So there's currently **no way to install such a proxy without forking** wgpu-hal to edit `Instance::init`. **Proposal** A vendor-neutral hook to transform (or supply) the dx12 DXGI factory right after wgpu creates it, mirroring the Vulkan backend's existing `wgpu_hal::vulkan::Instance::init_with_callback` / `Adapter::open_with_callback` (#7829). Two possible shapes — I'd like guidance on which fits best: 1. `wgpu_hal::dx12::Instance::init_with_callback(desc, callback)`, where `callback` receives the freshly-created factory to wrap/replace before wgpu uses it (direct analog of the Vulkan callback). 2. An opt-in `factory_transform` hook on the dx12 backend options, called at the same point. Either keeps wgpu vendor-neutral — no Streamline/NVIDIA code in wgpu; the proxy install lives entirely in the integrator's callback. **Why this fits** Same class of cross-API interop escape hatch wgpu already accepts: Vulkan `init_with_callback`/`open_with_callback` (#7829, the closest analog), dx12 `Queue::add_wait_fence`/`add_signal_fence` (#9463), `texture_from_raw`/`buffer_from_raw` (#3355), and the in-review `dx12::CommandEncoder::raw_command_list()` (#9613, #8888). **Proof it works** I have a working downstream implementation that does exactly this via a small `Instance::init` patch, hardware-validated: DLSS Frame Generation generates interpolated frames over wgpu's own DX12 swapchain on an RTX 4090 (`numFramesActuallyPresented == 2`), with the patch a runtime-guarded no-op when the interposer isn't loaded. So the mechanism is proven — this issue is about the **upstream API shape** so the proxy install can live in user code instead of a fork. Happy to implement whichever shape you prefer.
2 条评论