Skip to content

Commit

Permalink
Log all available wgpu adapters during startup (#3671)
Browse files Browse the repository at this point in the history
Useful when debugging, e.g. if the default choice is one of many, and
perhaps the other ones would be better.

**EDIT**: Oh, `enumerate_adapters` doesn't work on web… will fix.
  • Loading branch information
emilk authored Dec 4, 2023
1 parent 36c6b63 commit 80d7143
Showing 1 changed file with 112 additions and 1 deletion.
113 changes: 112 additions & 1 deletion crates/egui-wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ impl RenderState {
) -> Result<Self, WgpuError> {
crate::profile_scope!("RenderState::create"); // async yield give bad names using `profile_function`

#[cfg(not(target_arch = "wasm32"))]
let adapters: Vec<_> = instance.enumerate_adapters(wgpu::Backends::all()).collect();

let adapter = {
crate::profile_scope!("request_adapter");
instance
Expand All @@ -78,9 +81,51 @@ impl RenderState {
force_fallback_adapter: false,
})
.await
.ok_or(WgpuError::NoSuitableAdapterFound)?
.ok_or_else(|| {
#[cfg(not(target_arch = "wasm32"))]
if adapters.is_empty() {
log::info!("No wgpu adapters found");
} else if adapters.len() == 1 {
log::info!(
"The only available wgpu adapter was not suitable: {}",
adapter_info_summary(&adapters[0].get_info())
);
} else {
log::info!(
"No suitable wgpu adapter found out of the {} available ones: {}",
adapters.len(),
describe_adapters(&adapters)
);
}

WgpuError::NoSuitableAdapterFound
})?
};

#[cfg(target_arch = "wasm32")]
log::debug!(
"Picked wgpu adapter: {}",
adapter_info_summary(&adapter.get_info())
);

#[cfg(not(target_arch = "wasm32"))]
if adapters.len() == 1 {
log::debug!(
"Picked the only available wgpu adapter: {}",
adapter_info_summary(&adapter.get_info())
);
} else {
log::info!(
"There were {} available wgpu adapters: {}",
adapters.len(),
describe_adapters(&adapters)
);
log::debug!(
"Picked wgpu adapter: {}",
adapter_info_summary(&adapter.get_info())
);
}

let capabilities = {
crate::profile_scope!("get_capabilities");
surface.get_capabilities(&adapter).formats
Expand All @@ -106,6 +151,24 @@ impl RenderState {
}
}

#[cfg(not(target_arch = "wasm32"))]
fn describe_adapters(adapters: &[wgpu::Adapter]) -> String {
if adapters.is_empty() {
"(none)".to_owned()
} else if adapters.len() == 1 {
adapter_info_summary(&adapters[0].get_info())
} else {
let mut list_string = String::new();
for adapter in adapters {
if !list_string.is_empty() {
list_string += ", ";
}
list_string += &format!("{{{}}}", adapter_info_summary(&adapter.get_info()));
}
list_string
}
}

/// Specifies which action should be taken as consequence of a [`wgpu::SurfaceError`]
pub enum SurfaceErrorAction {
/// Do nothing and skip the current frame.
Expand All @@ -116,6 +179,10 @@ pub enum SurfaceErrorAction {
}

/// Configuration for using wgpu with eframe or the egui-wgpu winit feature.
///
/// This can be configured with the environment variables:
/// * `WGPU_BACKEND`: `vulkan`, `dx11`, `dx12`, `metal`, `opengl`, `webgpu`
/// * `WGPU_POWER_PREF`: `low`, `high` or `none`
#[derive(Clone)]
pub struct WgpuConfiguration {
/// Backends that should be supported (wgpu will pick one of these)
Expand Down Expand Up @@ -151,6 +218,7 @@ impl Default for WgpuConfiguration {
// (note however, that the GL backend needs to be opted-in via a wgpu feature flag)
supported_backends: wgpu::util::backend_bits_from_env()
.unwrap_or(wgpu::Backends::PRIMARY | wgpu::Backends::GL),

device_descriptor: Arc::new(|adapter| {
let base_limits = if adapter.get_info().backend == wgpu::Backend::Gl {
wgpu::Limits::downlevel_webgl2_defaults()
Expand All @@ -169,7 +237,9 @@ impl Default for WgpuConfiguration {
},
}
}),

present_mode: wgpu::PresentMode::AutoVsync,

power_preference: wgpu::util::power_preference_from_env()
.unwrap_or(wgpu::PowerPreference::HighPerformance),

Expand Down Expand Up @@ -224,6 +294,47 @@ pub fn depth_format_from_bits(depth_buffer: u8, stencil_buffer: u8) -> Option<wg

// ---------------------------------------------------------------------------

/// A human-readable summary about an adapter
pub fn adapter_info_summary(info: &wgpu::AdapterInfo) -> String {
let wgpu::AdapterInfo {
name,
vendor,
device,
device_type,
driver,
driver_info,
backend,
} = &info;

// Example values:
// > name: "llvmpipe (LLVM 16.0.6, 256 bits)", device_type: Cpu, backend: Vulkan, driver: "llvmpipe", driver_info: "Mesa 23.1.6-arch1.4 (LLVM 16.0.6)"
// > name: "Apple M1 Pro", device_type: IntegratedGpu, backend: Metal, driver: "", driver_info: ""
// > name: "ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)", device_type: IntegratedGpu, backend: Gl, driver: "", driver_info: ""

let mut summary = format!("backend: {backend:?}, device_type: {device_type:?}");

if !name.is_empty() {
summary += &format!(", name: {name:?}");
}
if !driver.is_empty() {
summary += &format!(", driver: {driver:?}");
}
if !driver_info.is_empty() {
summary += &format!(", driver_info: {driver_info:?}");
}
if *vendor != 0 {
// TODO(emilk): decode using https://github.com/gfx-rs/wgpu/blob/767ac03245ee937d3dc552edc13fe7ab0a860eec/wgpu-hal/src/auxil/mod.rs#L7
summary += &format!(", vendor: 0x{vendor:04X}");
}
if *device != 0 {
summary += &format!(", device: 0x{device:02X}");
}

summary
}

// ---------------------------------------------------------------------------

mod profiling_scopes {
#![allow(unused_macros)]
#![allow(unused_imports)]
Expand Down

0 comments on commit 80d7143

Please sign in to comment.