diff --git a/CHANGELOG.md b/CHANGELOG.md index 310ce48d42..9bbb499b50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log -## wgpu-hal-0.11.1 (2021-10-07) +## wgpu-hal-0.11.1 (2021-10-09) + - Vulkan: fix NV optimus detection on Linux - WebGL: fix querying storage-related limits ## wgpu-0.11 (2021-10-07) diff --git a/Cargo.lock b/Cargo.lock index 262f4ce9b7..a657e579a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1838,7 +1838,7 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.11.0" +version = "0.11.1" dependencies = [ "arrayvec", "ash", diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index 4e62313e8b..af4cc03b0f 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -193,6 +193,7 @@ impl super::Instance { driver_api_version: u32, extensions: Vec<&'static CStr>, flags: crate::InstanceFlags, + has_nv_optimus: bool, drop_guard: Option, ) -> Result { if driver_api_version == vk::API_VERSION_1_0 @@ -239,6 +240,7 @@ impl super::Instance { debug_utils, get_physical_device_properties, entry, + has_nv_optimus, }), extensions, }) @@ -478,6 +480,11 @@ impl crate::Instance for super::Instance { crate::InstanceError })?; + let nv_optimus_layer = CStr::from_bytes_with_nul(b"VK_LAYER_NV_optimus\0").unwrap(); + let has_nv_optimus = instance_layers + .iter() + .any(|inst_layer| CStr::from_ptr(inst_layer.layer_name.as_ptr()) == nv_optimus_layer); + // Check requested layers against the available layers let layers = { let mut layers: Vec<&'static CStr> = Vec::new(); @@ -528,6 +535,7 @@ impl crate::Instance for super::Instance { driver_api_version, extensions, desc.flags, + has_nv_optimus, Some(Box::new(())), // `Some` signals that wgpu-hal is in charge of destroying vk_instance ) } @@ -611,23 +619,20 @@ impl crate::Instance for super::Instance { .flat_map(|device| self.expose_adapter(device)) .collect::>(); - // detect if it's an Intel + NVidia configuration - if cfg!(target_os = "linux") { + // Detect if it's an Intel + NVidia configuration with Optimus + if cfg!(target_os = "linux") && self.shared.has_nv_optimus { 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; - } + 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 NV Optimus (on Linux)", + exposed.info.name, + exposed.adapter.raw + ); + exposed.adapter.private_caps.can_present = false; } } } diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 53c2f0b996..10ae248526 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -86,6 +86,7 @@ struct InstanceShared { debug_utils: Option, get_physical_device_properties: Option, entry: ash::Entry, + has_nv_optimus: bool, } pub struct Instance {