From 804cea39c2041033af26f6326e25b69cfe7345bf Mon Sep 17 00:00:00 2001 From: $invides <162040889+sinvides@users.noreply.github.com> Date: Thu, 12 Nov 2026 01:41:36 +0800 Subject: [PATCH 1/2] feat(compositor): accept Direct3D 11 feature level 11_0 on Windows GPUs that top out at feature level 11_0, such as the GTX 650 Ti, were refused at device creation and fell back to the CPU backend. Ask for 11_1 first, then 11_0, so those GPUs get the hardware device. --- crates/compositor/src/d3d_windows.rs | 11 ++++++----- crates/compositor/src/pipeline_windows.rs | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/crates/compositor/src/d3d_windows.rs b/crates/compositor/src/d3d_windows.rs index 9733b86e02..c0553fad31 100644 --- a/crates/compositor/src/d3d_windows.rs +++ b/crates/compositor/src/d3d_windows.rs @@ -9,6 +9,7 @@ use windows::core::Interface; use windows::Win32::Foundation::HMODULE; use windows::Win32::Graphics::Direct3D::{ D3D_DRIVER_TYPE, D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_FEATURE_LEVEL, + D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, }; use windows::Win32::Graphics::Direct3D11::{ @@ -72,7 +73,7 @@ fn try_create( driver: D3D_DRIVER_TYPE, flags: D3D11_CREATE_DEVICE_FLAG, ) -> windows::core::Result<(ID3D11Device, ID3D11DeviceContext, D3D_FEATURE_LEVEL)> { - let levels = [D3D_FEATURE_LEVEL_11_1]; + let levels = [D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0]; let mut device: Option = None; let mut context: Option = None; let mut got = D3D_FEATURE_LEVEL::default(); @@ -130,9 +131,9 @@ fn diagnose(err: &windows::core::Error) -> String { ); } format!( - "no Direct3D 11 feature level 11_1 display adapter ({err}). OpenScreen's compositor \ + "no Direct3D 11 feature level 11_0 display adapter ({err}). OpenScreen's compositor \ requires one for both preview and export. Update the display driver, or run on a \ - machine with a GPU that reaches feature level 11_1." + machine with a GPU that reaches feature level 11_0." ) } @@ -201,8 +202,8 @@ impl Gpu { Err(err) => bail!("{}", diagnose(&err)), }; - if got != D3D_FEATURE_LEVEL_11_1 { - bail!("feature level obtenu {:?} != 11_1", got); + if got.0 < D3D_FEATURE_LEVEL_11_0.0 { + bail!("feature level obtenu {:?} < 11_0", got); } // §2 : multithread-protected. Le décodeur ffmpeg soumet depuis son thread, diff --git a/crates/compositor/src/pipeline_windows.rs b/crates/compositor/src/pipeline_windows.rs index 4c59cf73c4..b050cca572 100644 --- a/crates/compositor/src/pipeline_windows.rs +++ b/crates/compositor/src/pipeline_windows.rs @@ -1971,14 +1971,15 @@ mod tests { fn raw_hardware_prerequisite() -> windows::core::Result<()> { use windows::Win32::Foundation::{E_UNEXPECTED, HMODULE}; use windows::Win32::Graphics::Direct3D::{ - D3D_DRIVER_TYPE_HARDWARE, D3D_FEATURE_LEVEL, D3D_FEATURE_LEVEL_11_1, + D3D_DRIVER_TYPE_HARDWARE, D3D_FEATURE_LEVEL, D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_11_1, }; use windows::Win32::Graphics::Direct3D11::{ D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, D3D11_CREATE_DEVICE_BGRA_SUPPORT, D3D11_CREATE_DEVICE_VIDEO_SUPPORT, D3D11_SDK_VERSION, }; - let levels = [D3D_FEATURE_LEVEL_11_1]; + let levels = [D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0]; let mut device: Option = None; let mut context: Option = None; let mut got = D3D_FEATURE_LEVEL::default(); @@ -1995,7 +1996,7 @@ mod tests { Some(&mut context), )?; } - if device.is_none() || context.is_none() || got != D3D_FEATURE_LEVEL_11_1 { + if device.is_none() || context.is_none() || got.0 < D3D_FEATURE_LEVEL_11_0.0 { return Err(windows::core::Error::from(E_UNEXPECTED)); } Ok(()) From 1bd4c22bdecaeb91cbd21063cf4124d67d5417ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E8=B6=85=E8=B6=85=E8=B6=85=E8=B6=85=E7=BA=A7?= =?UTF-8?q?=E5=96=9C=E6=AC=A2=E4=BD=A0=E7=9A=84=E8=BE=BE=E5=A6=AE=E5=A8=85?= <176143450+My-Denia@users.noreply.github.com> Date: Thu, 12 Nov 2026 01:41:43 +0800 Subject: [PATCH 2/2] docs(compositor): say 11_0 in the device creation comments --- crates/compositor/src/d3d_windows.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/compositor/src/d3d_windows.rs b/crates/compositor/src/d3d_windows.rs index c0553fad31..95c8bec157 100644 --- a/crates/compositor/src/d3d_windows.rs +++ b/crates/compositor/src/d3d_windows.rs @@ -1,5 +1,5 @@ //! Le device D3D11 unique du POC (§2). -//! Un seul `ID3D11Device`, feature level 11_1, flag VIDEO_SUPPORT (décodeur), +//! Un seul `ID3D11Device`, feature level 11_1 ou 11_0, flag VIDEO_SUPPORT (décodeur), //! et `ID3D10Multithread::SetMultithreadProtected(TRUE)` — parce que le décodeur //! ffmpeg et notre boucle de rendu toucheront le device depuis des threads distincts. @@ -66,8 +66,8 @@ pub struct Gpu { pub backend: Backend, } -/// Une tentative `D3D11CreateDevice` à FL 11_1. Extraite pour que le chemin d'échec -/// puisse re-sonder avec d'autres flags/driver et dire POURQUOI la vraie tentative +/// Une tentative `D3D11CreateDevice` à FL 11_1, puis 11_0 en repli. Extraite pour que le +/// chemin d'échec puisse re-sonder avec d'autres flags/driver et dire POURQUOI la vraie tentative /// a échoué (voir `diagnose`), au lieu de remonter un HRESULT nu. fn try_create( driver: D3D_DRIVER_TYPE,