diff --git a/crates/eframe/src/epi/mod.rs b/crates/eframe/src/epi/mod.rs index 75804980..dff01873 100644 --- a/crates/eframe/src/epi/mod.rs +++ b/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(), } } } diff --git a/crates/eframe/src/web/web_painter_wgpu.rs b/crates/eframe/src/web/web_painter_wgpu.rs index 93742133..1dcaf3ec 100644 --- a/crates/eframe/src/web/web_painter_wgpu.rs +++ b/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, on_surface_error: Arc SurfaceErrorAction>, depth_format: Option, @@ -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( diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs index a89539f3..2e76b457 100644 --- a/crates/egui-wgpu/src/lib.rs +++ b/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 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| { diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs index 9382ee44..4210c2f9 100644 --- a/crates/egui-wgpu/src/winit.rs +++ b/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 { adapter - .request_device(&self.configuration.device_descriptor, None) + .request_device(&(*self.configuration.device_descriptor)(adapter), None) .await .map(|(device, queue)| { let renderer =