hal/linux: Work around Intel+Nvidia presentation conflict

This commit is contained in:
Dzmitry Malyshau 2021-09-02 14:27:27 -04:00 committed by Dzmitry Malyshau
parent 62180c3220
commit 0a8675d612
5 changed files with 37 additions and 2 deletions

View File

@ -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 {

View File

@ -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<super::Api> for super::Adapter {
&self,
surface: &super::Surface,
) -> Option<crate::SurfaceCapabilities> {
if !self.private_caps.can_present {
return None;
}
let queue_family_index = 0; //TODO
match surface.functor.get_physical_device_surface_support(
self.raw,

View File

@ -598,10 +598,33 @@ impl crate::Instance<super::Api> for super::Instance {
}
};
raw_devices
let mut exposed_adapters = raw_devices
.into_iter()
.flat_map(|device| self.expose_adapter(device))
.collect()
.collect::<Vec<_>>();
// 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
}
}

View File

@ -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,
}

View File

@ -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))]