Skip to content

Commit

Permalink
hal/vk: check for NV optimus
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Oct 9, 2021
1 parent 44f488e commit d48bc62
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 18 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 21 additions & 16 deletions wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<super::DropGuard>,
) -> Result<Self, crate::InstanceError> {
if driver_api_version == vk::API_VERSION_1_0
Expand Down Expand Up @@ -239,6 +240,7 @@ impl super::Instance {
debug_utils,
get_physical_device_properties,
entry,
has_nv_optimus,
}),
extensions,
})
Expand Down Expand Up @@ -478,6 +480,11 @@ impl crate::Instance<super::Api> 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();
Expand Down Expand Up @@ -528,6 +535,7 @@ impl crate::Instance<super::Api> 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
)
}
Expand Down Expand Up @@ -611,23 +619,20 @@ impl crate::Instance<super::Api> for super::Instance {
.flat_map(|device| self.expose_adapter(device))
.collect::<Vec<_>>();

// 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;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct InstanceShared {
debug_utils: Option<DebugUtils>,
get_physical_device_properties: Option<vk::KhrGetPhysicalDeviceProperties2Fn>,
entry: ash::Entry,
has_nv_optimus: bool,
}

pub struct Instance {
Expand Down

0 comments on commit d48bc62

Please sign in to comment.