From 0d555fb68809ce63a6e74fc66e2a486d07401c3d Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Sat, 29 Jun 2019 16:50:41 -0600 Subject: [PATCH 1/2] Add logic to pick highest performance GPU on DirectX 12 Always select the first GPU in Integrated-Low/Discrete-High category, except when querying `LowPower`, in which case the last Discrete GPU is used. --- wgpu-native/src/instance.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index c99818d1ef..a8a24ca867 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -201,10 +201,23 @@ pub fn instance_get_adapter(instance_id: InstanceId, desc: &AdapterDescriptor) - }; let (mut low, mut high, mut other) = (None, None, None); + // On Windows > 1803, dx12 enumerate_adapters returns the adapters in order from highest to + // lowest performance. Therefore, the first found adapter in each category is selected. + // + // TODO: move power/performance policy querying into gfx, which has more context into + // performance policy than wgpu for adapter in adapters { match adapter.info.device_type { - hal::adapter::DeviceType::IntegratedGpu => low = Some(adapter), - hal::adapter::DeviceType::DiscreteGpu => high = Some(adapter), + hal::adapter::DeviceType::IntegratedGpu => low = low.or(Some(adapter)), + hal::adapter::DeviceType::DiscreteGpu => { + high = match desc.power_preference { + // If `LowPower`, prefer lowest power `DiscreteGPU` + PowerPreference::LowPower => Some(adapter), + PowerPreference::HighPerformance | PowerPreference::Default => { + high.or(Some(adapter)) + } + } + } _ => other = Some(adapter), } } From b47f01ea174ada25f5acdb87013113b9e1bf810c Mon Sep 17 00:00:00 2001 From: Andrew Gaspar Date: Mon, 1 Jul 2019 21:13:26 -0600 Subject: [PATCH 2/2] Address code review comments --- wgpu-native/src/instance.rs | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index a8a24ca867..76a44d17a1 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -200,35 +200,40 @@ pub fn instance_get_adapter(instance_id: InstanceId, desc: &AdapterDescriptor) - surface.raw.enumerate_adapters() }; - let (mut low, mut high, mut other) = (None, None, None); + let (mut integrated_first, mut discrete_first, mut discrete_last, mut alternative) = + (None, None, None, None); + // On Windows > 1803, dx12 enumerate_adapters returns the adapters in order from highest to // lowest performance. Therefore, the first found adapter in each category is selected. // // TODO: move power/performance policy querying into gfx, which has more context into // performance policy than wgpu - for adapter in adapters { + for (i, adapter) in adapters.iter().enumerate() { match adapter.info.device_type { - hal::adapter::DeviceType::IntegratedGpu => low = low.or(Some(adapter)), - hal::adapter::DeviceType::DiscreteGpu => { - high = match desc.power_preference { - // If `LowPower`, prefer lowest power `DiscreteGPU` - PowerPreference::LowPower => Some(adapter), - PowerPreference::HighPerformance | PowerPreference::Default => { - high.or(Some(adapter)) - } - } + hal::adapter::DeviceType::IntegratedGpu => { + integrated_first = integrated_first.or(Some(i)); } - _ => other = Some(adapter), + hal::adapter::DeviceType::DiscreteGpu => { + discrete_first = discrete_first.or(Some(i)); + discrete_last = Some(i); + } + _ => alternative = Some(i), } } - let some = match desc.power_preference { - PowerPreference::LowPower => low.or(high), - PowerPreference::HighPerformance | PowerPreference::Default => high.or(low), + let preferred_gpu = match desc.power_preference { + // If `LowPower`, prefer lowest power `DiscreteGPU` + PowerPreference::LowPower => integrated_first.or(discrete_last), + PowerPreference::HighPerformance | PowerPreference::Default => { + discrete_first.or(integrated_first) + } }; - some - .or(other) - .expect("No adapters found. Please enable the feature for one of the graphics backends: vulkan, metal, dx12, dx11, gl") + + let selected = preferred_gpu + .or(alternative) + .expect("No adapters found. Please enable the feature for one of the graphics backends: vulkan, metal, dx12, dx11, gl"); + + adapters.into_iter().nth(selected).unwrap() } #[cfg(feature = "local")]