1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 21:00:03 -04:00

[wgpu] Expose wgpu::Adapter via RenderState (#2954)

* [wgpu] Expose adapter, better errors, better docs, more code sharing, use stencil bits

* doc fix

* remove unnecessary unsafe

* handle missing framebuffer format

* better handling of renderstate creation in winit.rs

* remove unnecessary use directive
This commit is contained in:
Andreas Reich
2023-04-25 17:42:13 +02:00
committed by GitHub
parent 20e291d3f6
commit f76eefb98d
9 changed files with 138 additions and 153 deletions

View File

@@ -312,10 +312,6 @@ pub struct NativeOptions {
/// Sets the number of bits in the depth buffer.
///
/// `egui` doesn't need the depth buffer, so the default value is 0.
///
/// On `wgpu` backends, due to limited depth texture format options, this
/// will be interpreted as a boolean (non-zero = true) for whether or not
/// specifically a `Depth32Float` buffer is used.
pub depth_buffer: u8,
/// Sets the number of bits in the stencil buffer.
@@ -475,6 +471,12 @@ pub struct WebOptions {
/// Default: `Theme::Dark`.
pub default_theme: Theme,
/// Sets the number of bits in the depth buffer.
///
/// `egui` doesn't need the depth buffer, so the default value is 0.
/// Unused by webgl context as of writing.
pub depth_buffer: u8,
/// Which version of WebGl context to select
///
/// Default: [`WebGlContextOption::BestFirst`].
@@ -492,6 +494,7 @@ impl Default for WebOptions {
Self {
follow_system_theme: true,
default_theme: Theme::Dark,
depth_buffer: 0,
#[cfg(feature = "glow")]
webgl_context_option: WebGlContextOption::BestFirst,

View File

@@ -1122,9 +1122,7 @@ mod wgpu_integration {
) -> std::result::Result<(), egui_wgpu::WgpuError> {
self.window = Some(window);
if let Some(running) = &mut self.running {
unsafe {
pollster::block_on(running.painter.set_window(self.window.as_ref()))?;
}
pollster::block_on(running.painter.set_window(self.window.as_ref()))?;
}
Ok(())
}
@@ -1134,9 +1132,7 @@ mod wgpu_integration {
fn drop_window(&mut self) -> std::result::Result<(), egui_wgpu::WgpuError> {
self.window = None;
if let Some(running) = &mut self.running {
unsafe {
pollster::block_on(running.painter.set_window(None))?;
}
pollster::block_on(running.painter.set_window(None))?;
}
Ok(())
}
@@ -1148,16 +1144,16 @@ mod wgpu_integration {
window: winit::window::Window,
) -> std::result::Result<(), egui_wgpu::WgpuError> {
#[allow(unsafe_code, unused_mut, unused_unsafe)]
let painter = unsafe {
let mut painter = egui_wgpu::winit::Painter::new(
self.native_options.wgpu_options.clone(),
self.native_options.multisampling.max(1) as _,
let mut painter = egui_wgpu::winit::Painter::new(
self.native_options.wgpu_options.clone(),
self.native_options.multisampling.max(1) as _,
egui_wgpu::depth_format_from_bits(
self.native_options.depth_buffer,
self.native_options.transparent,
);
pollster::block_on(painter.set_window(Some(&window)))?;
painter
};
self.native_options.stencil_buffer,
),
self.native_options.transparent,
);
pollster::block_on(painter.set_window(Some(&window)))?;
let wgpu_render_state = painter.render_state();

View File

@@ -3,7 +3,6 @@ use std::sync::Arc;
use wasm_bindgen::JsValue;
use web_sys::HtmlCanvasElement;
use egui::mutex::RwLock;
use egui_wgpu::{renderer::ScreenDescriptor, RenderState, SurfaceErrorAction};
use crate::WebOptions;
@@ -99,43 +98,20 @@ impl WebPainterWgpu {
}
.map_err(|err| format!("failed to create wgpu surface: {err}"))?;
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: options.wgpu_options.power_preference,
force_fallback_adapter: false,
compatible_surface: None,
})
.await
.ok_or_else(|| "No suitable GPU adapters found on the system".to_owned())?;
let (device, queue) = adapter
.request_device(
&(*options.wgpu_options.device_descriptor)(&adapter),
None, // Capture doesn't work in the browser environment.
)
.await
.map_err(|err| format!("Failed to find wgpu device: {}", err))?;
let target_format =
egui_wgpu::preferred_framebuffer_format(&surface.get_capabilities(&adapter).formats);
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),
target_format,
renderer: Arc::new(RwLock::new(renderer)),
};
let depth_format = egui_wgpu::depth_format_from_bits(options.depth_buffer, 0);
let render_state =
RenderState::create(&options.wgpu_options, &instance, &surface, depth_format, 1)
.await
.map_err(|err| err.to_string())?;
let surface_configuration = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: target_format,
format: render_state.target_format,
width: 0,
height: 0,
present_mode: options.wgpu_options.present_mode,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![target_format],
view_formats: vec![render_state.target_format],
};
log::debug!("wgpu painter initialized.");