Browse Source

[egui-wgpu] Device configuration is now dependent on adapter (#2951)

* [egui-wgpu] Device configuration is now dependent on adapter
Additionally, renamed `backends` into `supported_backends` and improved & unified wgpu config defaults.

* improve wgpu backend default

* clippy fix

* formatting

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
pull/2956/head
Andreas Reich 2 years ago
committed by GitHub
parent
commit
20e291d3f6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      crates/eframe/src/epi/mod.rs
  2. 10
      crates/eframe/src/web/web_painter_wgpu.rs
  3. 37
      crates/egui-wgpu/src/lib.rs
  4. 6
      crates/egui-wgpu/src/winit.rs

16
crates/eframe/src/epi/mod.rs

@ -497,21 +497,7 @@ impl Default for WebOptions {
webgl_context_option: WebGlContextOption::BestFirst,
#[cfg(feature = "wgpu")]
wgpu_options: egui_wgpu::WgpuConfiguration {
// Use WebGPU or WebGL. Note that WebGL needs to be opted in via a wgpu feature.
backends: wgpu::Backends::BROWSER_WEBGPU | wgpu::Backends::GL,
device_descriptor: wgpu::DeviceDescriptor {
label: Some("egui wgpu device"),
features: wgpu::Features::default(),
limits: wgpu::Limits {
// When using a depth buffer, we have to be able to create a texture
// large enough for the entire surface, and we want to support 4k+ displays.
max_texture_dimension_2d: 8192,
..wgpu::Limits::downlevel_webgl2_defaults()
},
},
..Default::default()
},
wgpu_options: egui_wgpu::WgpuConfiguration::default(),
}
}
}

10
crates/eframe/src/web/web_painter_wgpu.rs

@ -33,7 +33,6 @@ pub(crate) struct WebPainterWgpu {
canvas_id: String,
surface: wgpu::Surface,
surface_configuration: wgpu::SurfaceConfiguration,
limits: wgpu::Limits,
render_state: Option<RenderState>,
on_surface_error: Arc<dyn Fn(wgpu::SurfaceError) -> SurfaceErrorAction>,
depth_format: Option<wgpu::TextureFormat>,
@ -78,7 +77,7 @@ impl WebPainterWgpu {
log::debug!("Creating wgpu painter");
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: options.wgpu_options.backends,
backends: options.wgpu_options.supported_backends,
dx12_shader_compiler: Default::default(),
});
@ -111,7 +110,7 @@ impl WebPainterWgpu {
let (device, queue) = adapter
.request_device(
&options.wgpu_options.device_descriptor,
&(*options.wgpu_options.device_descriptor)(&adapter),
None, // Capture doesn't work in the browser environment.
)
.await
@ -149,7 +148,6 @@ impl WebPainterWgpu {
surface_configuration,
depth_format,
depth_texture_view: None,
limits: options.wgpu_options.device_descriptor.limits.clone(),
on_surface_error: options.wgpu_options.on_surface_error.clone(),
})
}
@ -161,7 +159,9 @@ impl WebPainter for WebPainterWgpu {
}
fn max_texture_side(&self) -> usize {
self.limits.max_texture_dimension_2d as _
self.render_state.as_ref().map_or(0, |state| {
state.device.limits().max_texture_dimension_2d as _
})
}
fn paint_and_update_textures(

37
crates/egui-wgpu/src/lib.rs

@ -42,11 +42,11 @@ pub enum SurfaceErrorAction {
/// Configuration for using wgpu with eframe or the egui-wgpu winit feature.
#[derive(Clone)]
pub struct WgpuConfiguration {
/// Configuration passed on device request.
pub device_descriptor: wgpu::DeviceDescriptor<'static>,
/// Backends that should be supported (wgpu will pick one of these)
pub backends: wgpu::Backends,
pub supported_backends: wgpu::Backends,
/// Configuration passed on device request, given an adapter
pub device_descriptor: Arc<dyn Fn(&wgpu::Adapter) -> wgpu::DeviceDescriptor<'static>>,
/// Present mode used for the primary surface.
pub present_mode: wgpu::PresentMode,
@ -63,16 +63,31 @@ pub struct WgpuConfiguration {
impl Default for WgpuConfiguration {
fn default() -> Self {
Self {
device_descriptor: wgpu::DeviceDescriptor {
label: Some("egui wgpu device"),
features: wgpu::Features::default(),
limits: wgpu::Limits::default(),
},
// Add GL backend, primarily because WebGPU is not stable enough yet.
// (note however, that the GL backend needs to be opted-in via a wgpu feature flag)
backends: wgpu::Backends::PRIMARY | wgpu::Backends::GL,
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()
} else {
wgpu::Limits::default()
};
wgpu::DeviceDescriptor {
label: Some("egui wgpu device"),
features: wgpu::Features::default(),
limits: wgpu::Limits {
// When using a depth buffer, we have to be able to create a texture
// large enough for the entire surface, and we want to support 4k+ displays.
max_texture_dimension_2d: 8192,
..base_limits
},
}
}),
present_mode: wgpu::PresentMode::AutoVsync,
power_preference: wgpu::PowerPreference::HighPerformance,
power_preference: wgpu::util::power_preference_from_env()
.unwrap_or(wgpu::PowerPreference::HighPerformance),
depth_format: None,
on_surface_error: Arc::new(|err| {

6
crates/egui-wgpu/src/winit.rs

@ -108,8 +108,8 @@ impl Painter {
support_transparent_backbuffer: bool,
) -> Self {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: configuration.backends,
dx12_shader_compiler: Default::default(), //
backends: configuration.supported_backends,
dx12_shader_compiler: Default::default(),
});
Self {
@ -141,7 +141,7 @@ impl Painter {
target_format: wgpu::TextureFormat,
) -> Result<RenderState, wgpu::RequestDeviceError> {
adapter
.request_device(&self.configuration.device_descriptor, None)
.request_device(&(*self.configuration.device_descriptor)(adapter), None)
.await
.map(|(device, queue)| {
let renderer =

Loading…
Cancel
Save