diff --git a/wgpu-hal/src/auxil/mod.rs b/wgpu-hal/src/auxil/mod.rs index bf4470f8e..6a0e99a74 100644 --- a/wgpu-hal/src/auxil/mod.rs +++ b/wgpu-hal/src/auxil/mod.rs @@ -7,6 +7,9 @@ pub mod db { pub const DEVICE_KABY_LAKE_MASK: u32 = 0x5900; pub const DEVICE_SKY_LAKE_MASK: u32 = 0x1900; } + pub mod nvidia { + pub const VENDOR: u32 = 0x10DE; + } } pub fn map_naga_stage(stage: naga::ShaderStage) -> wgt::ShaderStages { diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 45e84c6a3..0262dd61e 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -697,6 +697,7 @@ impl super::Instance { .contains(vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT) }, non_coherent_map_mask: phd_capabilities.properties.limits.non_coherent_atom_size - 1, + can_present: true, }; let capabilities = crate::Capabilities { @@ -1018,6 +1019,10 @@ impl crate::Adapter for super::Adapter { &self, surface: &super::Surface, ) -> Option { + if !self.private_caps.can_present { + return None; + } + let queue_family_index = 0; //TODO match surface.functor.get_physical_device_surface_support( self.raw, diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 9aaed7a95..0ac44cbc1 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -598,10 +598,33 @@ impl crate::Instance for super::Instance { } }; - raw_devices + let mut exposed_adapters = raw_devices .into_iter() .flat_map(|device| self.expose_adapter(device)) - .collect() + .collect::>(); + + // detect if it's an Intel + NVidia configuration + if cfg!(target_os = "linux") { + use crate::auxil::db; + let has_nvidia_dgpu = exposed_adapters.iter().any(|exposed| { + exposed.info.device_type == wgt::DeviceType::DiscreteGpu + && exposed.info.vendor == db::nvidia::VENDOR as usize + }); + if has_nvidia_dgpu { + for exposed in exposed_adapters.iter_mut() { + if exposed.info.device_type == wgt::DeviceType::IntegratedGpu + && exposed.info.vendor == db::intel::VENDOR as usize + { + // See https://gitlab.freedesktop.org/mesa/mesa/-/issues/4688 + log::warn!("Disabling presentation on '{}' (id {:?}) because of an Nvidia dGPU (on Linux)", + exposed.info.name, exposed.adapter.raw); + exposed.adapter.private_caps.can_present = false; + } + } + } + } + + exposed_adapters } } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index ddb350c60..8a8b732c5 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -158,6 +158,8 @@ struct PrivateCapabilities { timeline_semaphores: bool, texture_d24: bool, texture_d24_s8: bool, + /// Ability to present contents to any screen. Only needed to work around broken platform configurations. + can_present: bool, non_coherent_map_mask: wgt::BufferAddress, } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index c58764390..5647ec294 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -809,6 +809,8 @@ pub enum DeviceType { Cpu, } +//TODO: convert `vendor` and `device` to `u32` + /// Information about an adapter. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "trace", derive(serde::Serialize))]