From 17499453f64811f10f307c26e3df2f3fa7a8f0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=B0=8F=E7=99=BD?= <364772080@qq.com> Date: Mon, 8 Sep 2025 20:22:57 +0800 Subject: [PATCH] windows: Check required GPU/driver feature `StructuredBuffer` (#37776) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check whether the GPU/driver supports the StructuredBuffer feature required by our shaders. If it doesn’t, log an error and skip that GPU/driver, so Windows can fall back to the software renderer. Release Notes: - N/A --- .../src/platform/windows/directx_devices.rs | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/crates/gpui/src/platform/windows/directx_devices.rs b/crates/gpui/src/platform/windows/directx_devices.rs index 005737ca2070ab8a30656493b548c6f3c6e9a3dc..4fa4db827492faffaa0d8912b1f37b52f8cfc88f 100644 --- a/crates/gpui/src/platform/windows/directx_devices.rs +++ b/crates/gpui/src/platform/windows/directx_devices.rs @@ -8,8 +8,9 @@ use windows::Win32::{ D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_11_1, }, Direct3D11::{ - D3D11_CREATE_DEVICE_BGRA_SUPPORT, D3D11_CREATE_DEVICE_DEBUG, D3D11_SDK_VERSION, - D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, + D3D11_CREATE_DEVICE_BGRA_SUPPORT, D3D11_CREATE_DEVICE_DEBUG, + D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS, + D3D11_SDK_VERSION, D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, }, Dxgi::{ CreateDXGIFactory2, DXGI_CREATE_FACTORY_DEBUG, DXGI_CREATE_FACTORY_FLAGS, @@ -54,12 +55,10 @@ impl DirectXDevices { let adapter = get_adapter(&dxgi_factory, debug_layer_available).context("Getting DXGI adapter")?; let (device, device_context) = { - let mut device: Option = None; let mut context: Option = None; let mut feature_level = D3D_FEATURE_LEVEL::default(); - get_device( + let device = get_device( &adapter, - Some(&mut device), Some(&mut context), Some(&mut feature_level), debug_layer_available, @@ -77,7 +76,7 @@ impl DirectXDevices { } _ => unreachable!(), } - (device.unwrap(), context.unwrap()) + (device, context.unwrap()) }; Ok(Self { @@ -134,7 +133,7 @@ fn get_adapter(dxgi_factory: &IDXGIFactory6, debug_layer_available: bool) -> Res } // Check to see whether the adapter supports Direct3D 11, but don't // create the actual device yet. - if get_device(&adapter, None, None, None, debug_layer_available) + if get_device(&adapter, None, None, debug_layer_available) .log_err() .is_some() { @@ -148,11 +147,11 @@ fn get_adapter(dxgi_factory: &IDXGIFactory6, debug_layer_available: bool) -> Res #[inline] fn get_device( adapter: &IDXGIAdapter1, - device: Option<*mut Option>, context: Option<*mut Option>, feature_level: Option<*mut D3D_FEATURE_LEVEL>, debug_layer_available: bool, -) -> Result<()> { +) -> Result { + let mut device: Option = None; let device_flags = if debug_layer_available { D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_DEBUG } else { @@ -171,10 +170,30 @@ fn get_device( D3D_FEATURE_LEVEL_10_1, ]), D3D11_SDK_VERSION, - device, + Some(&mut device), feature_level, context, )?; } - Ok(()) + let device = device.unwrap(); + let mut data = D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS::default(); + unsafe { + device + .CheckFeatureSupport( + D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, + &mut data as *mut _ as _, + std::mem::size_of::() as u32, + ) + .context("Checking GPU device feature support")?; + } + if data + .ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x + .as_bool() + { + Ok(device) + } else { + Err(anyhow::anyhow!( + "Required feature StructuredBuffer is not supported by GPU/driver" + )) + } }