[WGPU] Allow for depth buffer in web target (#2335)

* Add depth stencil initialization to `Painter`

* Move depth stencil initialization into `resize_and_generate_depth_texture_view`, and call it in `set_window` and `on_window_resized`

* Allow for depth texture in WASM builds

* change `map` to `if let` statement

* use reference for render state

* Clean up descriptors and move texture generation to on resize events

* remove unused field from WebOptions
This commit is contained in:
Lukas Hermann 2022-11-24 11:40:53 -08:00 committed by GitHub
parent 7d8154971b
commit f9066ff285
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 2 deletions

View file

@ -18,6 +18,8 @@ pub(crate) struct WebPainterWgpu {
limits: wgpu::Limits,
render_state: Option<RenderState>,
on_surface_error: Arc<dyn Fn(wgpu::SurfaceError) -> SurfaceErrorAction>,
depth_format: Option<wgpu::TextureFormat>,
depth_texture_view: Option<wgpu::TextureView>,
}
impl WebPainterWgpu {
@ -26,6 +28,32 @@ impl WebPainterWgpu {
self.render_state.clone()
}
pub fn generate_depth_texture_view(
&self,
render_state: &RenderState,
width_in_pixels: u32,
height_in_pixels: u32,
) -> Option<wgpu::TextureView> {
let device = &render_state.device;
self.depth_format.map(|depth_format| {
device
.create_texture(&wgpu::TextureDescriptor {
label: Some("egui_depth_texture"),
size: wgpu::Extent3d {
width: width_in_pixels,
height: height_in_pixels,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: depth_format,
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
})
.create_view(&wgpu::TextureViewDescriptor::default())
})
}
#[allow(unused)] // only used if `wgpu` is the only active feature.
pub async fn new(canvas_id: &str, options: &WebOptions) -> Result<Self, String> {
tracing::debug!("Creating wgpu painter");
@ -55,7 +83,8 @@ impl WebPainterWgpu {
let target_format =
egui_wgpu::preferred_framebuffer_format(&surface.get_supported_formats(&adapter));
let renderer = egui_wgpu::Renderer::new(&device, target_format, None, 1);
let depth_format = options.wgpu_options.depth_format;
let renderer = egui_wgpu::Renderer::new(&device, target_format, depth_format, 1);
let render_state = RenderState {
device: Arc::new(device),
queue: Arc::new(queue),
@ -80,6 +109,8 @@ impl WebPainterWgpu {
render_state: Some(render_state),
surface,
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(),
})
@ -157,6 +188,11 @@ impl WebPainter for WebPainterWgpu {
self.surface_configuration.height = size_in_pixels[1];
self.surface
.configure(&render_state.device, &self.surface_configuration);
self.depth_texture_view = self.generate_depth_texture_view(
render_state,
size_in_pixels[0],
size_in_pixels[1],
);
}
let frame = match self.surface.get_current_texture() {
@ -193,7 +229,16 @@ impl WebPainter for WebPainterWgpu {
store: true,
},
})],
depth_stencil_attachment: None,
depth_stencil_attachment: self.depth_texture_view.as_ref().map(|view| {
wgpu::RenderPassDepthStencilAttachment {
view,
depth_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Clear(1.0),
store: false,
}),
stencil_ops: None,
}
}),
label: Some("egui_render"),
});

View file

@ -55,6 +55,8 @@ pub struct WgpuConfiguration {
/// Callback for surface errors.
pub on_surface_error: Arc<dyn Fn(wgpu::SurfaceError) -> SurfaceErrorAction>,
pub depth_format: Option<wgpu::TextureFormat>,
}
impl Default for WgpuConfiguration {
@ -68,6 +70,7 @@ impl Default for WgpuConfiguration {
backends: wgpu::Backends::PRIMARY | wgpu::Backends::GL,
present_mode: wgpu::PresentMode::AutoVsync,
power_preference: wgpu::PowerPreference::HighPerformance,
depth_format: None,
on_surface_error: Arc::new(|err| {
if err == wgpu::SurfaceError::Outdated {