wgpu renderer now always requires a RenderPass being passed in, pass command encoder to prepare callback (#2136)
* wgpu renderer now always requires a RenderPass being passed in This also implies that it no longer owns the depth buffer! (why would it anyways!) * wgpu-renderer now passes a command encoder to prepare * add changelog entries * fixup changelogs, fix variable name
This commit is contained in:
parent
7803285221
commit
c414af7aa2
6 changed files with 115 additions and 128 deletions
|
@ -16,6 +16,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C
|
||||||
* Web: You can now use WebGL on top of `wgpu` by enabling the `wgpu` feature (and disabling `glow` via disabling default features) ([#2107](https://github.com/emilk/egui/pull/2107)).
|
* Web: You can now use WebGL on top of `wgpu` by enabling the `wgpu` feature (and disabling `glow` via disabling default features) ([#2107](https://github.com/emilk/egui/pull/2107)).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 0.19.0 - 2022-08-20
|
## 0.19.0 - 2022-08-20
|
||||||
* MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)).
|
* MSRV (Minimum Supported Rust Version) is now `1.61.0` ([#1846](https://github.com/emilk/egui/pull/1846)).
|
||||||
* Added `wgpu` rendering backed ([#1564](https://github.com/emilk/egui/pull/1564)):
|
* Added `wgpu` rendering backed ([#1564](https://github.com/emilk/egui/pull/1564)):
|
||||||
|
|
|
@ -54,12 +54,10 @@ impl WebPainterWgpu {
|
||||||
.await
|
.await
|
||||||
.map_err(|err| format!("Failed to find wgpu device: {}", err))?;
|
.map_err(|err| format!("Failed to find wgpu device: {}", err))?;
|
||||||
|
|
||||||
// TODO(Wumpf): MSAA & depth
|
|
||||||
|
|
||||||
let target_format =
|
let target_format =
|
||||||
egui_wgpu::preferred_framebuffer_format(&surface.get_supported_formats(&adapter));
|
egui_wgpu::preferred_framebuffer_format(&surface.get_supported_formats(&adapter));
|
||||||
|
|
||||||
let renderer = egui_wgpu::Renderer::new(&device, target_format, 1, 0);
|
let renderer = egui_wgpu::Renderer::new(&device, target_format, None, 1);
|
||||||
let render_state = RenderState {
|
let render_state = RenderState {
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
queue: Arc::new(queue),
|
queue: Arc::new(queue),
|
||||||
|
@ -127,9 +125,6 @@ impl WebPainter for WebPainterWgpu {
|
||||||
err
|
err
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let view = frame
|
|
||||||
.texture
|
|
||||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
|
|
||||||
let mut encoder =
|
let mut encoder =
|
||||||
render_state
|
render_state
|
||||||
|
@ -158,24 +153,37 @@ impl WebPainter for WebPainterWgpu {
|
||||||
renderer.update_buffers(
|
renderer.update_buffers(
|
||||||
&render_state.device,
|
&render_state.device,
|
||||||
&render_state.queue,
|
&render_state.queue,
|
||||||
|
&mut encoder,
|
||||||
clipped_primitives,
|
clipped_primitives,
|
||||||
&screen_descriptor,
|
&screen_descriptor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record all render passes.
|
{
|
||||||
render_state.renderer.read().render(
|
let renderer = render_state.renderer.read();
|
||||||
&mut encoder,
|
let frame_view = frame
|
||||||
&view,
|
.texture
|
||||||
clipped_primitives,
|
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
&screen_descriptor,
|
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
Some(wgpu::Color {
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
r: clear_color.r() as f64,
|
view: &frame_view,
|
||||||
g: clear_color.g() as f64,
|
resolve_target: None,
|
||||||
b: clear_color.b() as f64,
|
ops: wgpu::Operations {
|
||||||
a: clear_color.a() as f64,
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
}),
|
r: clear_color.r() as f64,
|
||||||
);
|
g: clear_color.g() as f64,
|
||||||
|
b: clear_color.b() as f64,
|
||||||
|
a: clear_color.a() as f64,
|
||||||
|
}),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
depth_stencil_attachment: None,
|
||||||
|
label: Some("egui_render"),
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.render(&mut render_pass, clipped_primitives, &screen_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut renderer = render_state.renderer.write();
|
let mut renderer = render_state.renderer.write();
|
||||||
|
|
|
@ -5,8 +5,10 @@ All notable changes to the `egui-wgpu` integration will be noted in this file.
|
||||||
## Unreleased
|
## Unreleased
|
||||||
* Renamed `RenderPass` to `Renderer`.
|
* Renamed `RenderPass` to `Renderer`.
|
||||||
* Renamed `RenderPass::execute` to `RenderPass::render`.
|
* Renamed `RenderPass::execute` to `RenderPass::render`.
|
||||||
* Renamed `RenderPass::execute_with_renderpass` to `Renderer::render_onto_renderpass`.
|
* Renamed `RenderPass::execute_with_renderpass` to `Renderer::render` (replacing existing `Renderer::render`)
|
||||||
* Reexported `Renderer`.
|
* Reexported `Renderer`.
|
||||||
|
* `Renderer` no longer handles pass creation and depth buffer creation ([#2136](https://github.com/emilk/egui/pull/2136))
|
||||||
|
* `PrepareCallback` now passes `wgpu::CommandEncoder` ([#2136](https://github.com/emilk/egui/pull/2136))
|
||||||
|
|
||||||
|
|
||||||
## 0.19.0 - 2022-08-20
|
## 0.19.0 - 2022-08-20
|
||||||
|
|
|
@ -15,9 +15,13 @@ use wgpu::util::DeviceExt as _;
|
||||||
///
|
///
|
||||||
/// `prepare` is called every frame before `paint`, and can use the passed-in [`wgpu::Device`] and
|
/// `prepare` is called every frame before `paint`, and can use the passed-in [`wgpu::Device`] and
|
||||||
/// [`wgpu::Buffer`] to allocate or modify GPU resources such as buffers.
|
/// [`wgpu::Buffer`] to allocate or modify GPU resources such as buffers.
|
||||||
|
/// Additionally, a [`wgpu::CommandEncoder`] is provided in order to allow creation of
|
||||||
|
/// custom [`wgpu::RenderPass`]/[`wgpu::ComputePass`] or perform buffer/texture copies
|
||||||
|
/// which may serve as preparation to the final `paint`.
|
||||||
|
/// (This allows reusing the same [`wgpu::CommandEncoder`] for all callbacks and egui rendering itself)
|
||||||
///
|
///
|
||||||
/// `paint` is called after `prepare` and is given access to the the [`wgpu::RenderPass`] so that it
|
/// `paint` is called after `prepare` and is given access to the [`wgpu::RenderPass`] so that it
|
||||||
/// can issue draw commands.
|
/// can issue draw commands into the same [`wgpu::RenderPass`] that is used for all other egui elements.
|
||||||
///
|
///
|
||||||
/// The final argument of both the `prepare` and `paint` callbacks is a the
|
/// The final argument of both the `prepare` and `paint` callbacks is a the
|
||||||
/// [`paint_callback_resources`][crate::renderer::Renderer::paint_callback_resources].
|
/// [`paint_callback_resources`][crate::renderer::Renderer::paint_callback_resources].
|
||||||
|
@ -33,7 +37,8 @@ pub struct CallbackFn {
|
||||||
paint: Box<PaintCallback>,
|
paint: Box<PaintCallback>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrepareCallback = dyn Fn(&wgpu::Device, &wgpu::Queue, &mut TypeMap) + Sync + Send;
|
type PrepareCallback =
|
||||||
|
dyn Fn(&wgpu::Device, &wgpu::Queue, &mut wgpu::CommandEncoder, &mut TypeMap) + Sync + Send;
|
||||||
|
|
||||||
type PaintCallback =
|
type PaintCallback =
|
||||||
dyn for<'a, 'b> Fn(PaintCallbackInfo, &'a mut wgpu::RenderPass<'b>, &'b TypeMap) + Sync + Send;
|
dyn for<'a, 'b> Fn(PaintCallbackInfo, &'a mut wgpu::RenderPass<'b>, &'b TypeMap) + Sync + Send;
|
||||||
|
@ -41,7 +46,7 @@ type PaintCallback =
|
||||||
impl Default for CallbackFn {
|
impl Default for CallbackFn {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
CallbackFn {
|
CallbackFn {
|
||||||
prepare: Box::new(|_, _, _| ()),
|
prepare: Box::new(|_, _, _, _| ()),
|
||||||
paint: Box::new(|_, _, _| ()),
|
paint: Box::new(|_, _, _| ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +60,10 @@ impl CallbackFn {
|
||||||
/// Set the prepare callback
|
/// Set the prepare callback
|
||||||
pub fn prepare<F>(mut self, prepare: F) -> Self
|
pub fn prepare<F>(mut self, prepare: F) -> Self
|
||||||
where
|
where
|
||||||
F: Fn(&wgpu::Device, &wgpu::Queue, &mut TypeMap) + Sync + Send + 'static,
|
F: Fn(&wgpu::Device, &wgpu::Queue, &mut wgpu::CommandEncoder, &mut TypeMap)
|
||||||
|
+ Sync
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
{
|
{
|
||||||
self.prepare = Box::new(prepare) as _;
|
self.prepare = Box::new(prepare) as _;
|
||||||
self
|
self
|
||||||
|
@ -122,7 +130,6 @@ struct SizedBuffer {
|
||||||
/// Renderer for a egui based GUI.
|
/// Renderer for a egui based GUI.
|
||||||
pub struct Renderer {
|
pub struct Renderer {
|
||||||
pipeline: wgpu::RenderPipeline,
|
pipeline: wgpu::RenderPipeline,
|
||||||
depth_texture: Option<(wgpu::Texture, wgpu::TextureView)>,
|
|
||||||
index_buffers: Vec<SizedBuffer>,
|
index_buffers: Vec<SizedBuffer>,
|
||||||
vertex_buffers: Vec<SizedBuffer>,
|
vertex_buffers: Vec<SizedBuffer>,
|
||||||
uniform_buffer: SizedBuffer,
|
uniform_buffer: SizedBuffer,
|
||||||
|
@ -141,13 +148,13 @@ pub struct Renderer {
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
/// Creates a renderer for a egui UI.
|
/// Creates a renderer for a egui UI.
|
||||||
///
|
///
|
||||||
/// `output_format` should preferably be [`wgpu::TextureFormat::Rgba8Unorm`] or
|
/// `output_color_format` should preferably be [`wgpu::TextureFormat::Rgba8Unorm`] or
|
||||||
/// [`wgpu::TextureFormat::Bgra8Unorm`], i.e. in gamma-space.
|
/// [`wgpu::TextureFormat::Bgra8Unorm`], i.e. in gamma-space.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
output_format: wgpu::TextureFormat,
|
output_color_format: wgpu::TextureFormat,
|
||||||
|
output_depth_format: Option<wgpu::TextureFormat>,
|
||||||
msaa_samples: u32,
|
msaa_samples: u32,
|
||||||
depth_bits: u8,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let shader = wgpu::ShaderModuleDescriptor {
|
let shader = wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("egui"),
|
label: Some("egui"),
|
||||||
|
@ -225,8 +232,8 @@ impl Renderer {
|
||||||
push_constant_ranges: &[],
|
push_constant_ranges: &[],
|
||||||
});
|
});
|
||||||
|
|
||||||
let depth_stencil = (depth_bits > 0).then(|| wgpu::DepthStencilState {
|
let depth_stencil = output_depth_format.map(|format| wgpu::DepthStencilState {
|
||||||
format: wgpu::TextureFormat::Depth32Float,
|
format,
|
||||||
depth_write_enabled: false,
|
depth_write_enabled: false,
|
||||||
depth_compare: wgpu::CompareFunction::Always,
|
depth_compare: wgpu::CompareFunction::Always,
|
||||||
stencil: wgpu::StencilState::default(),
|
stencil: wgpu::StencilState::default(),
|
||||||
|
@ -266,14 +273,14 @@ impl Renderer {
|
||||||
|
|
||||||
fragment: Some(wgpu::FragmentState {
|
fragment: Some(wgpu::FragmentState {
|
||||||
module: &module,
|
module: &module,
|
||||||
entry_point: if output_format.describe().srgb {
|
entry_point: if output_color_format.describe().srgb {
|
||||||
tracing::warn!("Detected a linear (sRGBA aware) framebuffer {:?}. egui prefers Rgba8Unorm or Bgra8Unorm", output_format);
|
tracing::warn!("Detected a linear (sRGBA aware) framebuffer {:?}. egui prefers Rgba8Unorm or Bgra8Unorm", output_color_format);
|
||||||
"fs_main_linear_framebuffer"
|
"fs_main_linear_framebuffer"
|
||||||
} else {
|
} else {
|
||||||
"fs_main_gamma_framebuffer" // this is what we prefer
|
"fs_main_gamma_framebuffer" // this is what we prefer
|
||||||
},
|
},
|
||||||
targets: &[Some(wgpu::ColorTargetState {
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
format: output_format,
|
format: output_color_format,
|
||||||
blend: Some(wgpu::BlendState {
|
blend: Some(wgpu::BlendState {
|
||||||
color: wgpu::BlendComponent {
|
color: wgpu::BlendComponent {
|
||||||
src_factor: wgpu::BlendFactor::One,
|
src_factor: wgpu::BlendFactor::One,
|
||||||
|
@ -302,75 +309,11 @@ impl Renderer {
|
||||||
textures: HashMap::new(),
|
textures: HashMap::new(),
|
||||||
next_user_texture_id: 0,
|
next_user_texture_id: 0,
|
||||||
paint_callback_resources: TypeMap::default(),
|
paint_callback_resources: TypeMap::default(),
|
||||||
depth_texture: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_depth_texture(&mut self, device: &wgpu::Device, width: u32, height: u32) {
|
|
||||||
// TODO(wumpf) don't recreate texture if size hasn't changed
|
|
||||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
|
||||||
label: Some("egui_depth_texture"),
|
|
||||||
size: wgpu::Extent3d {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
depth_or_array_layers: 1,
|
|
||||||
},
|
|
||||||
mip_level_count: 1,
|
|
||||||
sample_count: 1,
|
|
||||||
dimension: wgpu::TextureDimension::D2,
|
|
||||||
format: wgpu::TextureFormat::Depth32Float,
|
|
||||||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
|
||||||
});
|
|
||||||
|
|
||||||
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
|
|
||||||
self.depth_texture = Some((texture, view));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Executes the renderer on its own render pass.
|
|
||||||
pub fn render(
|
|
||||||
&self,
|
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
|
||||||
color_attachment: &wgpu::TextureView,
|
|
||||||
paint_jobs: &[egui::epaint::ClippedPrimitive],
|
|
||||||
screen_descriptor: &ScreenDescriptor,
|
|
||||||
clear_color: Option<wgpu::Color>,
|
|
||||||
) {
|
|
||||||
let load_operation = if let Some(color) = clear_color {
|
|
||||||
wgpu::LoadOp::Clear(color)
|
|
||||||
} else {
|
|
||||||
wgpu::LoadOp::Load
|
|
||||||
};
|
|
||||||
|
|
||||||
let depth_stencil_attachment = self.depth_texture.as_ref().map(|(_texture, view)| {
|
|
||||||
wgpu::RenderPassDepthStencilAttachment {
|
|
||||||
view,
|
|
||||||
depth_ops: Some(wgpu::Operations {
|
|
||||||
load: wgpu::LoadOp::Clear(1.0),
|
|
||||||
store: true,
|
|
||||||
}),
|
|
||||||
stencil_ops: None,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
||||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
|
||||||
view: color_attachment,
|
|
||||||
resolve_target: None,
|
|
||||||
ops: wgpu::Operations {
|
|
||||||
load: load_operation,
|
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
})],
|
|
||||||
depth_stencil_attachment,
|
|
||||||
label: Some("egui_render"),
|
|
||||||
});
|
|
||||||
|
|
||||||
self.render_onto_renderpass(&mut render_pass, paint_jobs, screen_descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Executes the egui renderer onto an existing wgpu renderpass.
|
/// Executes the egui renderer onto an existing wgpu renderpass.
|
||||||
pub fn render_onto_renderpass<'rp>(
|
pub fn render<'rp>(
|
||||||
&'rp self,
|
&'rp self,
|
||||||
render_pass: &mut wgpu::RenderPass<'rp>,
|
render_pass: &mut wgpu::RenderPass<'rp>,
|
||||||
paint_jobs: &[egui::epaint::ClippedPrimitive],
|
paint_jobs: &[egui::epaint::ClippedPrimitive],
|
||||||
|
@ -760,6 +703,7 @@ impl Renderer {
|
||||||
&mut self,
|
&mut self,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
paint_jobs: &[egui::epaint::ClippedPrimitive],
|
paint_jobs: &[egui::epaint::ClippedPrimitive],
|
||||||
screen_descriptor: &ScreenDescriptor,
|
screen_descriptor: &ScreenDescriptor,
|
||||||
) {
|
) {
|
||||||
|
@ -821,7 +765,7 @@ impl Renderer {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
(cbfn.prepare)(device, queue, &mut self.paint_callback_resources);
|
(cbfn.prepare)(device, queue, encoder, &mut self.paint_callback_resources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ pub struct Painter<'a> {
|
||||||
device_descriptor: wgpu::DeviceDescriptor<'a>,
|
device_descriptor: wgpu::DeviceDescriptor<'a>,
|
||||||
present_mode: wgpu::PresentMode,
|
present_mode: wgpu::PresentMode,
|
||||||
msaa_samples: u32,
|
msaa_samples: u32,
|
||||||
depth_bits: u8,
|
depth_format: Option<wgpu::TextureFormat>,
|
||||||
|
depth_texture_view: Option<wgpu::TextureView>,
|
||||||
|
|
||||||
instance: Instance,
|
instance: Instance,
|
||||||
adapter: Option<Adapter>,
|
adapter: Option<Adapter>,
|
||||||
|
@ -56,7 +57,8 @@ impl<'a> Painter<'a> {
|
||||||
device_descriptor,
|
device_descriptor,
|
||||||
present_mode,
|
present_mode,
|
||||||
msaa_samples,
|
msaa_samples,
|
||||||
depth_bits,
|
depth_format: (depth_bits > 0).then(|| wgpu::TextureFormat::Depth32Float),
|
||||||
|
depth_texture_view: None,
|
||||||
|
|
||||||
instance,
|
instance,
|
||||||
adapter: None,
|
adapter: None,
|
||||||
|
@ -80,7 +82,7 @@ impl<'a> Painter<'a> {
|
||||||
let (device, queue) =
|
let (device, queue) =
|
||||||
pollster::block_on(adapter.request_device(&self.device_descriptor, None)).unwrap();
|
pollster::block_on(adapter.request_device(&self.device_descriptor, None)).unwrap();
|
||||||
|
|
||||||
let renderer = Renderer::new(&device, target_format, self.msaa_samples, self.depth_bits);
|
let renderer = Renderer::new(&device, target_format, self.depth_format, self.msaa_samples);
|
||||||
|
|
||||||
RenderState {
|
RenderState {
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
|
@ -141,14 +143,6 @@ impl<'a> Painter<'a> {
|
||||||
.configure(&render_state.device, &config);
|
.configure(&render_state.device, &config);
|
||||||
surface_state.width = width_in_pixels;
|
surface_state.width = width_in_pixels;
|
||||||
surface_state.height = height_in_pixels;
|
surface_state.height = height_in_pixels;
|
||||||
|
|
||||||
if self.depth_bits > 0 {
|
|
||||||
render_state.renderer.write().update_depth_texture(
|
|
||||||
&render_state.device,
|
|
||||||
width_in_pixels,
|
|
||||||
height_in_pixels,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates (or clears) the [`winit::window::Window`] associated with the [`Painter`]
|
/// Updates (or clears) the [`winit::window::Window`] associated with the [`Painter`]
|
||||||
|
@ -212,6 +206,25 @@ impl<'a> Painter<'a> {
|
||||||
pub fn on_window_resized(&mut self, width_in_pixels: u32, height_in_pixels: u32) {
|
pub fn on_window_resized(&mut self, width_in_pixels: u32, height_in_pixels: u32) {
|
||||||
if self.surface_state.is_some() {
|
if self.surface_state.is_some() {
|
||||||
self.configure_surface(width_in_pixels, height_in_pixels);
|
self.configure_surface(width_in_pixels, height_in_pixels);
|
||||||
|
let device = &self.render_state.as_ref().unwrap().device;
|
||||||
|
self.depth_texture_view = 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
|
||||||
|
| wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
|
})
|
||||||
|
.create_view(&wgpu::TextureViewDescriptor::default())
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
error!("Ignoring window resize notification with no surface created via Painter::set_window()");
|
error!("Ignoring window resize notification with no surface created via Painter::set_window()");
|
||||||
}
|
}
|
||||||
|
@ -246,9 +259,6 @@ impl<'a> Painter<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let output_view = output_frame
|
|
||||||
.texture
|
|
||||||
.create_view(&wgpu::TextureViewDescriptor::default());
|
|
||||||
|
|
||||||
let mut encoder =
|
let mut encoder =
|
||||||
render_state
|
render_state
|
||||||
|
@ -277,24 +287,46 @@ impl<'a> Painter<'a> {
|
||||||
renderer.update_buffers(
|
renderer.update_buffers(
|
||||||
&render_state.device,
|
&render_state.device,
|
||||||
&render_state.queue,
|
&render_state.queue,
|
||||||
|
&mut encoder,
|
||||||
clipped_primitives,
|
clipped_primitives,
|
||||||
&screen_descriptor,
|
&screen_descriptor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record all render passes.
|
{
|
||||||
render_state.renderer.read().render(
|
let renderer = render_state.renderer.read();
|
||||||
&mut encoder,
|
let frame_view = output_frame
|
||||||
&output_view,
|
.texture
|
||||||
clipped_primitives,
|
.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
&screen_descriptor,
|
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
Some(wgpu::Color {
|
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||||
r: clear_color.r() as f64,
|
view: &frame_view,
|
||||||
g: clear_color.g() as f64,
|
resolve_target: None,
|
||||||
b: clear_color.b() as f64,
|
ops: wgpu::Operations {
|
||||||
a: clear_color.a() as f64,
|
load: wgpu::LoadOp::Clear(wgpu::Color {
|
||||||
}),
|
r: clear_color.r() as f64,
|
||||||
);
|
g: clear_color.g() as f64,
|
||||||
|
b: clear_color.b() as f64,
|
||||||
|
a: clear_color.a() as f64,
|
||||||
|
}),
|
||||||
|
store: true,
|
||||||
|
},
|
||||||
|
})],
|
||||||
|
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: true,
|
||||||
|
}),
|
||||||
|
stencil_ops: None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
label: Some("egui_render"),
|
||||||
|
});
|
||||||
|
|
||||||
|
renderer.render(&mut render_pass, clipped_primitives, &screen_descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut renderer = render_state.renderer.write();
|
let mut renderer = render_state.renderer.write();
|
||||||
|
|
|
@ -138,7 +138,7 @@ impl Custom3d {
|
||||||
// The paint callback is called after prepare and is given access to the render pass, which
|
// The paint callback is called after prepare and is given access to the render pass, which
|
||||||
// can be used to issue draw commands.
|
// can be used to issue draw commands.
|
||||||
let cb = egui_wgpu::CallbackFn::new()
|
let cb = egui_wgpu::CallbackFn::new()
|
||||||
.prepare(move |device, queue, paint_callback_resources| {
|
.prepare(move |device, queue, _encoder, paint_callback_resources| {
|
||||||
let resources: &TriangleRenderResources = paint_callback_resources.get().unwrap();
|
let resources: &TriangleRenderResources = paint_callback_resources.get().unwrap();
|
||||||
resources.prepare(device, queue, angle);
|
resources.prepare(device, queue, angle);
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue