From 2881c450f8ca5700c8bc8f77a77d6e4725015bbe Mon Sep 17 00:00:00 2001 From: Craig Date: Tue, 5 Jul 2022 21:11:22 -0700 Subject: [PATCH] Prevent OpenGL from taking preference over Vulkan (#2853) * Prevent OpenGL from taking preference over Vulkan * update changelog * fix wasm build of example --- CHANGELOG.md | 3 ++- wgpu-core/src/instance.rs | 6 +++++- wgpu-hal/src/gles/adapter.rs | 5 +++++ wgpu-types/src/lib.rs | 2 +- wgpu/examples/hello/README.md | 8 ++++++-- wgpu/examples/hello/main.rs | 20 +++++++++++++++----- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 636030b459..06fb43920f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ Bottom level categories: ## Unreleased ### Bug Fixes +- Prefer `DeviceType::DiscreteGpu` over `DeviceType::Other` for `PowerPreference::LowPower` so Vulkan is preferred over OpenGL again by @Craig-Macomber in [#2853](https://github.com/gfx-rs/wgpu/pull/2853) #### DX12 - `DownlevelCapabilities::default()` now returns the `ANISOTROPIC_FILTERING` flag set to true so DX12 lists `ANISOTROPIC_FILTERING` as true again by @cwfitzgerald in [#2851](https://github.com/gfx-rs/wgpu/pull/2851) @@ -134,7 +135,7 @@ is an under-documented area that we hope to improve in the future. ```diff - let future = buffer.slice(..).map_async(MapMode::Read); + buffer.slice(..).map_async(MapMode::Read, || { -+ // Called when buffer is mapped. ++ // Called when buffer is mapped. + }) ``` diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index d7d86ea25a..4bf542f6d9 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -786,7 +786,11 @@ impl Global { } let preferred_gpu = match desc.power_preference { - PowerPreference::LowPower => integrated.or(other).or(discrete).or(virt).or(cpu), + // Since devices of type "Other" might really be "Unknown" and come from APIs like OpenGL that don't specify device type, + // Prefer more Specific types over Other. + // This means that backends which do provide accurate device types will be preferred + // if their device type indicates an actual hardware GPU (integrated or discrete). + PowerPreference::LowPower => integrated.or(discrete).or(other).or(virt).or(cpu), PowerPreference::HighPerformance => discrete.or(integrated).or(other).or(virt).or(cpu), }; diff --git a/wgpu-hal/src/gles/adapter.rs b/wgpu-hal/src/gles/adapter.rs index 99976c8172..2d073acaa1 100644 --- a/wgpu-hal/src/gles/adapter.rs +++ b/wgpu-hal/src/gles/adapter.rs @@ -135,6 +135,11 @@ impl super::Adapter { } else if strings_that_imply_cpu.iter().any(|&s| renderer.contains(s)) { wgt::DeviceType::Cpu } else { + // At this point the Device type is Unknown. + // It's most likely DiscreteGpu, but we do not know for sure. + // Use "Other" to avoid possibly making incorrect assumptions. + // Note that if this same device is available under some other API (ex: Vulkan), + // It will mostly likely get a different device type (probably DiscreteGpu). wgt::DeviceType::Other }; diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index be804147d2..dcdc02b2fb 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -1109,7 +1109,7 @@ pub enum ShaderModel { #[cfg_attr(feature = "trace", derive(serde::Serialize))] #[cfg_attr(feature = "replay", derive(serde::Deserialize))] pub enum DeviceType { - /// Other. + /// Other or Unknown. Other, /// Integrated GPU with shared CPU/GPU memory. IntegratedGpu, diff --git a/wgpu/examples/hello/README.md b/wgpu/examples/hello/README.md index a24ad33b2e..2fbd367788 100644 --- a/wgpu/examples/hello/README.md +++ b/wgpu/examples/hello/README.md @@ -11,6 +11,10 @@ cargo run --example hello ## Example output ``` -# You might see different output as it depends on your graphics card -AdapterInfo { name: "Intel(R) UHD Graphics 630", vendor: 0, device: 0, device_type: IntegratedGpu, backend: Metal } +# You might see different output as it depends on your graphics card and drivers +Available adapters: + AdapterInfo { name: "AMD RADV VEGA10", vendor: 4098, device: 26751, device_type: DiscreteGpu, backend: Vulkan } + AdapterInfo { name: "llvmpipe (LLVM 12.0.0, 256 bits)", vendor: 65541, device: 0, device_type: Cpu, backend: Vulkan } + AdapterInfo { name: "Radeon RX Vega (VEGA10, DRM 3.41.0, 5.13.0-52-generic, LLVM 12.0.0)", vendor: 4098, device: 0, device_type: Other, backend: Gl } +Selected adapter: AdapterInfo { name: "AMD RADV VEGA10", vendor: 4098, device: 26751, device_type: DiscreteGpu, backend: Vulkan } ``` diff --git a/wgpu/examples/hello/main.rs b/wgpu/examples/hello/main.rs index 1a9928d21b..4f2c6dd914 100644 --- a/wgpu/examples/hello/main.rs +++ b/wgpu/examples/hello/main.rs @@ -1,13 +1,23 @@ /// This example shows how to describe the adapter in use. async fn run() { #[cfg_attr(target_arch = "wasm32", allow(unused_variables))] - let adapter = wgpu::Instance::new(wgpu::Backends::all()) - .request_adapter(&wgpu::RequestAdapterOptions::default()) - .await - .unwrap(); + let adapter = { + let instance = wgpu::Instance::new(wgpu::Backends::all()); + #[cfg(not(target_arch = "wasm32"))] + { + println!("Available adapters:"); + for a in instance.enumerate_adapters(wgpu::Backends::all()) { + println!(" {:?}", a.get_info()) + } + } + instance + .request_adapter(&wgpu::RequestAdapterOptions::default()) + .await + .unwrap() + }; #[cfg(not(target_arch = "wasm32"))] - println!("{:?}", adapter.get_info()) + println!("Selected adapter: {:?}", adapter.get_info()) } fn main() {