windows: Check required GPU/driver feature StructuredBuffer (#37776)
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
This commit is contained in:
@@ -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<ID3D11Device> = None;
|
||||
let mut context: Option<ID3D11DeviceContext> = 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<ID3D11Device>>,
|
||||
context: Option<*mut Option<ID3D11DeviceContext>>,
|
||||
feature_level: Option<*mut D3D_FEATURE_LEVEL>,
|
||||
debug_layer_available: bool,
|
||||
) -> Result<()> {
|
||||
) -> Result<ID3D11Device> {
|
||||
let mut device: Option<ID3D11Device> = 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::<D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS>() 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"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user