neovide/neovide · error
Failed to set maximum frame latency
Error message
Failed to set maximum frame latency
What it means
This error is thrown in D3DRenderer::new when IDXGISwapChain3::SetMaximumFrameLatency(1) returns a failure HRESULT. The call configures the swap chain (created with the DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT flag) to allow at most one queued frame, enabling the frame-latency waitable object used for pacing. A failure means the swap chain rejected the latency setting, typically because the swap chain was not created with the waitable-object flag, the device/factory is invalid, or the DXGI runtime/driver rejected the request (e.g. Remote Desktop session).
Source
Thrown at src/renderer/d3d.rs:193
window.window_handle().expect("Failed to fetch window handle").as_raw()
{
HWND(handle.hwnd.get() as *mut _)
} else {
panic!("Not a Win32 window");
};
let swap_chain = unsafe {
tracy_zone!("create swap_chain");
dxgi_factory
.CreateSwapChainForComposition(&command_queue, &swap_chain_desc, None)
.expect("Failed to create the Direct3D swap chain")
};
let swap_chain: IDXGISwapChain3 =
IDXGISwapChain1::cast(&swap_chain).expect("Failed to cast");
unsafe {
swap_chain.SetMaximumFrameLatency(1).expect("Failed to set maximum frame latency");
}
let composition_device: IDCompositionDevice = unsafe {
DCompositionCreateDevice2(None).expect("Could not create composition device")
};
let target = unsafe {
composition_device
.CreateTargetForHwnd(hwnd, true)
.expect("Could not create composition target")
};
let visual = unsafe {
composition_device.CreateVisual().expect("Could not create composition visual")
};
unsafe {
visual.SetContent(&swap_chain).expect("Failed to set composition content");
target.SetRoot(&visual).expect("Failed to set composition root");
composition_device.Commit().expect("Failed to commit composition");
}View on GitHub (pinned to ade2d9cda7)
Solutions
- Ensure the swap chain is created with DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT in swap_chain_desc.Flags (it is, in this code) and that CreateSwapChainForComposition succeeded on a valid device
- Update GPU drivers / verify the session has a real DXGI adapter (not WARP/Remote) before creating the renderer
- Check the HRESULT returned for DXG_ERROR_DEVICE_REMOVED and reinitialize the device
- Lower latency expectations or fall back to a non-waitable swap chain path on unsupported platforms
Defensive patterns
Strategy: try-catch
Validate before calling
let hr = unsafe { swap_chain.SetMaximumFrameLatency(1) };
if hr.is_err() {
eprintln!("SetMaximumFrameLatency failed: {:?}", hr); // inspect HRESULT before proceeding
} Type guard
fn swap_chain_supports_latency(sc: &IDXGISwapChain3) -> bool {
let mut desc = Default::default();
unsafe { sc.GetDesc1(&mut desc).is_ok() && (desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT.0 as u32) != 0 }
} Try / catch
match unsafe { swap_chain.SetMaximumFrameLatency(1) } {
Ok(()) => {},
Err(e) => { log::error!("SetMaximumFrameLatency failed: {e}"); return Err(RendererInitError::Latency(e)); }
} Prevention
- Always set DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT when planning to use SetMaximumFrameLatency with a waitable object
- Test the app in RDP/VM environments to catch session-specific DXGI failures
- Update GPU drivers on target machines
- Check device-removed reason before diagnosing DXGI call failures
When it happens
Trigger: Calling SetMaximumFrameLatency(1) on a swap chain lacking DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT or DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING prerequisites; corrupted/lost D3D12 device; swap chain created in an unsupported session (RDP, headless, or missing GPU/driver support).
Common situations: Running the app over Remote Desktop or in a VM without GPU support; old/broken graphics drivers; mixing a swap chain desc missing the frame-latency flag with GetFrameLatencyWaitableObject usage; device removed earlier during adapter enumeration.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Failed to set composition content
- Failed to create the Direct3D swap chain
- Failed to cast
- Could not create composition device
- Could not create composition visual
AI-assisted analysis of neovide/neovide@ade2d9cda7 (2026-09-06).
Data as JSON: /api/errors/0e5742ad05b1ad60.
Report an issue: GitHub.