WIP gpu timer thing (not for squashing!)

This commit is contained in:
Imbris 2021-02-26 23:18:01 -05:00
parent 4aa10a95e0
commit 0b2702878b
6 changed files with 163 additions and 79 deletions

3
Cargo.lock generated
View File

@ -5062,6 +5062,9 @@ name = "strum"
version = "0.20.0" version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c" checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
dependencies = [
"strum_macros",
]
[[package]] [[package]]
name = "strum_macros" name = "strum_macros"

View File

@ -93,7 +93,8 @@ rand = "0.8"
rodio = {version = "0.13", default-features = false, features = ["vorbis"]} rodio = {version = "0.13", default-features = false, features = ["vorbis"]}
ron = {version = "0.6", default-features = false} ron = {version = "0.6", default-features = false}
serde = {version = "1.0", features = [ "rc", "derive" ]} serde = {version = "1.0", features = [ "rc", "derive" ]}
strum = "0.20" # strum = "0.20"
strum = { version = "0.20.0", features = ["derive"] }
strum_macros = "0.20" strum_macros = "0.20"
treeculler = "0.2" treeculler = "0.2"
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] } tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }

View File

@ -9,6 +9,7 @@ pub mod model;
pub mod pipelines; pub mod pipelines;
pub mod renderer; pub mod renderer;
pub mod texture; pub mod texture;
mod time;
// Reexports // Reexports
pub use self::{ pub use self::{

View File

@ -1,5 +1,6 @@
mod binding; mod binding;
pub(super) mod drawer; pub(super) mod drawer;
mod spans;
use super::{ use super::{
consts::Consts, consts::Consts,
@ -284,6 +285,8 @@ pub struct Renderer {
mode: RenderMode, mode: RenderMode,
resolution: Vec2<u32>, resolution: Vec2<u32>,
tracer: super::time::GpuTracer<spans::Id>,
} }
impl Renderer { impl Renderer {
@ -330,7 +333,8 @@ impl Renderer {
label: None, label: None,
features: wgpu::Features::DEPTH_CLAMPING features: wgpu::Features::DEPTH_CLAMPING
| wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER | wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER
| wgpu::Features::PUSH_CONSTANTS, | wgpu::Features::PUSH_CONSTANTS
| super::time::required_features(),
limits, limits,
}, },
None, None,
@ -505,6 +509,9 @@ impl Renderer {
&depth_sampler, &depth_sampler,
); );
let tracer =
super::time::GpuTracer::new(&device, &queue, "voxygen_gpu_chrome_trace.json").unwrap();
Ok(Self { Ok(Self {
device, device,
queue, queue,
@ -545,6 +552,8 @@ impl Renderer {
mode, mode,
resolution: Vec2::new(dims.width, dims.height), resolution: Vec2::new(dims.width, dims.height),
tracer,
}) })
} }
@ -1037,7 +1046,7 @@ impl Renderer {
Err(wgpu::SwapChainError::Timeout) => { Err(wgpu::SwapChainError::Timeout) => {
// This will probably be resolved on the next frame // This will probably be resolved on the next frame
// NOTE: we don't log this because it happens very frequently with // NOTE: we don't log this because it happens very frequently with
// PresentMode::Fifo and unlimited FPS // PresentMode::Fifo on certain machines
return Ok(None); return Ok(None);
}, },
Err(err @ wgpu::SwapChainError::Outdated) => { Err(err @ wgpu::SwapChainError::Outdated) => {

View File

@ -9,26 +9,29 @@ use super::{
terrain, ui, ColLights, GlobalsBindGroup, Light, Shadow, terrain, ui, ColLights, GlobalsBindGroup, Light, Shadow,
}, },
}, },
spans::{self, OwningSpan, Span},
Renderer, ShadowMap, ShadowMapRenderer, Renderer, ShadowMap, ShadowMapRenderer,
}; };
use core::{num::NonZeroU32, ops::Range}; use core::{num::NonZeroU32, ops::Range};
use std::sync::Arc; use std::sync::Arc;
use vek::Aabr; use vek::Aabr;
pub struct Drawer<'a> { pub struct Drawer<'frame> {
encoder: Option<wgpu::CommandEncoder>, encoder: Option<wgpu::CommandEncoder>,
pub renderer: &'a mut Renderer, pub renderer: &'frame mut Renderer,
tex: wgpu::SwapChainTexture, tex: wgpu::SwapChainTexture,
globals: &'a GlobalsBindGroup, globals: &'frame GlobalsBindGroup,
} }
impl<'a> Drawer<'a> { impl<'frame> Drawer<'frame> {
pub fn new( pub fn new(
encoder: wgpu::CommandEncoder, mut encoder: wgpu::CommandEncoder,
renderer: &'a mut Renderer, renderer: &'frame mut Renderer,
tex: wgpu::SwapChainTexture, tex: wgpu::SwapChainTexture,
globals: &'a GlobalsBindGroup, globals: &'frame GlobalsBindGroup,
) -> Self { ) -> Self {
renderer.tracer.start_span(&mut encoder, &spans::Id::Frame);
Self { Self {
encoder: Some(encoder), encoder: Some(encoder),
renderer, renderer,
@ -58,6 +61,11 @@ impl<'a> Drawer<'a> {
), ),
}); });
let mut render_pass = OwningSpan::start(
&self.renderer.tracer,
render_pass,
spans::Id::DirectedShadows,
);
render_pass.set_bind_group(0, &self.globals.bind_group, &[]); render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
Some(ShadowPassDrawer { Some(ShadowPassDrawer {
@ -71,7 +79,7 @@ impl<'a> Drawer<'a> {
} }
pub fn first_pass(&mut self) -> FirstPassDrawer { pub fn first_pass(&mut self) -> FirstPassDrawer {
let mut render_pass = let render_pass =
self.encoder self.encoder
.as_mut() .as_mut()
.unwrap() .unwrap()
@ -97,17 +105,21 @@ impl<'a> Drawer<'a> {
), ),
}); });
let mut render_pass =
OwningSpan::start(&self.renderer.tracer, render_pass, spans::Id::PassOne);
render_pass.set_bind_group(0, &self.globals.bind_group, &[]); render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
render_pass.set_bind_group(1, &self.renderer.shadow_bind.bind_group, &[]); render_pass.set_bind_group(1, &self.renderer.shadow_bind.bind_group, &[]);
FirstPassDrawer { FirstPassDrawer {
render_pass, render_pass,
renderer: &self.renderer, renderer: &self.renderer,
figures_called: false,
} }
} }
pub fn second_pass(&mut self) -> SecondPassDrawer { pub fn second_pass(&mut self) -> SecondPassDrawer {
let mut render_pass = let render_pass =
self.encoder self.encoder
.as_mut() .as_mut()
.unwrap() .unwrap()
@ -124,6 +136,9 @@ impl<'a> Drawer<'a> {
depth_stencil_attachment: None, depth_stencil_attachment: None,
}); });
let mut render_pass =
OwningSpan::start(&self.renderer.tracer, render_pass, spans::Id::PassTwo);
render_pass.set_bind_group(0, &self.globals.bind_group, &[]); render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
render_pass.set_bind_group(1, &self.renderer.shadow_bind.bind_group, &[]); render_pass.set_bind_group(1, &self.renderer.shadow_bind.bind_group, &[]);
@ -134,7 +149,7 @@ impl<'a> Drawer<'a> {
} }
pub fn third_pass(&mut self) -> ThirdPassDrawer { pub fn third_pass(&mut self) -> ThirdPassDrawer {
let mut render_pass = let render_pass =
self.encoder self.encoder
.as_mut() .as_mut()
.unwrap() .unwrap()
@ -151,6 +166,9 @@ impl<'a> Drawer<'a> {
depth_stencil_attachment: None, depth_stencil_attachment: None,
}); });
let mut render_pass =
OwningSpan::start(&self.renderer.tracer, render_pass, spans::Id::PassThree);
render_pass.set_bind_group(0, &self.globals.bind_group, &[]); render_pass.set_bind_group(0, &self.globals.bind_group, &[]);
ThirdPassDrawer { ThirdPassDrawer {
@ -159,13 +177,16 @@ impl<'a> Drawer<'a> {
} }
} }
pub fn draw_point_shadows<'data: 'a>( pub fn draw_point_shadows<'data: 'frame>(
&mut self, &mut self,
matrices: &[shadow::PointLightMatrix; 126], matrices: &[shadow::PointLightMatrix; 126],
chunks: impl Clone chunks: impl Clone
+ Iterator<Item = (&'data Model<terrain::Vertex>, &'data terrain::BoundLocals)>, + Iterator<Item = (&'data Model<terrain::Vertex>, &'data terrain::BoundLocals)>,
) { ) {
if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map { if let ShadowMap::Enabled(ref shadow_renderer) = self.renderer.shadow_map {
self.renderer
.tracer
.start_span(self.encoder.as_mut().unwrap(), &spans::Id::PointShadows);
const STRIDE: usize = std::mem::size_of::<shadow::PointLightMatrix>(); const STRIDE: usize = std::mem::size_of::<shadow::PointLightMatrix>();
let data = bytemuck::cast_slice(matrices); let data = bytemuck::cast_slice(matrices);
@ -223,6 +244,9 @@ impl<'a> Drawer<'a> {
}); });
}); });
} }
self.renderer
.tracer
.end_span(self.encoder.as_mut().unwrap(), &spans::Id::PointShadows);
} }
} }
@ -293,45 +317,59 @@ impl<'a> Drawer<'a> {
} }
} }
impl<'a> Drop for Drawer<'a> { impl<'frame> Drop for Drawer<'frame> {
fn drop(&mut self) { fn drop(&mut self) {
// TODO: submitting things to the queue can let the gpu start on them sooner // TODO: submitting things to the queue can let the gpu start on them sooner
// maybe we should submit each render pass to the queue as they are produced? // maybe we should submit each render pass to the queue as they are produced?
self.renderer
.tracer
.end_span(self.encoder.as_mut().unwrap(), &spans::Id::Frame);
self.renderer
.tracer
.resolve_timestamps(self.encoder.as_mut().unwrap());
self.renderer self.renderer
.queue .queue
.submit(std::iter::once(self.encoder.take().unwrap().finish())); .submit(std::iter::once(self.encoder.take().unwrap().finish()));
// NOTE: this introduces blocking on GPU work
self.renderer
.tracer
.record_timestamps(&self.renderer.device)
} }
} }
// Shadow pass // Shadow pass
pub struct ShadowPassDrawer<'pass> { pub struct ShadowPassDrawer<'pass> {
render_pass: wgpu::RenderPass<'pass>, render_pass: OwningSpan<'pass, wgpu::RenderPass<'pass>>,
pub renderer: &'pass Renderer, pub renderer: &'pass Renderer,
shadow_renderer: &'pass ShadowMapRenderer, shadow_renderer: &'pass ShadowMapRenderer,
} }
impl<'pass> ShadowPassDrawer<'pass> { impl<'pass> ShadowPassDrawer<'pass> {
pub fn draw_figure_shadows(&mut self) -> FigureShadowDrawer<'_, 'pass> { pub fn draw_figure_shadows(&mut self) -> FigureShadowDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.shadow_renderer.figure_directed_pipeline.pipeline); &self.renderer.tracer,
&mut *self.render_pass,
spans::Id::DirectedFigureShadows,
);
render_pass.set_pipeline(&self.shadow_renderer.figure_directed_pipeline.pipeline);
FigureShadowDrawer { FigureShadowDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
pub fn draw_terrain_shadows(&mut self) -> TerrainShadowDrawer<'_, 'pass> { pub fn draw_terrain_shadows(&mut self) -> TerrainShadowDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.shadow_renderer.terrain_directed_pipeline.pipeline); &self.renderer.tracer,
&mut *self.render_pass,
spans::Id::DirectedTerrainShadows,
);
render_pass.set_pipeline(&self.shadow_renderer.terrain_directed_pipeline.pipeline);
TerrainShadowDrawer { TerrainShadowDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
} }
pub struct FigureShadowDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct FigureShadowDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> FigureShadowDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> FigureShadowDrawer<'pass_ref, 'pass> {
@ -347,7 +385,7 @@ impl<'pass_ref, 'pass: 'pass_ref> FigureShadowDrawer<'pass_ref, 'pass> {
} }
pub struct TerrainShadowDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct TerrainShadowDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> TerrainShadowDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> TerrainShadowDrawer<'pass_ref, 'pass> {
@ -364,83 +402,112 @@ impl<'pass_ref, 'pass: 'pass_ref> TerrainShadowDrawer<'pass_ref, 'pass> {
// First pass // First pass
pub struct FirstPassDrawer<'pass> { pub struct FirstPassDrawer<'pass> {
pub(super) render_pass: wgpu::RenderPass<'pass>, pub(super) render_pass: OwningSpan<'pass, wgpu::RenderPass<'pass>>,
pub renderer: &'pass Renderer, pub renderer: &'pass Renderer,
// TODO: hack
figures_called: bool,
} }
impl<'pass> FirstPassDrawer<'pass> { impl<'pass> FirstPassDrawer<'pass> {
pub fn draw_skybox<'data: 'pass>(&mut self, model: &'data Model<skybox::Vertex>) { pub fn draw_skybox<'data: 'pass>(&mut self, model: &'data Model<skybox::Vertex>) {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.skybox_pipeline.pipeline); &self.renderer.tracer,
self.render_pass.set_vertex_buffer(0, model.buf().slice(..)); &mut *self.render_pass,
self.render_pass.draw(0..model.len() as u32, 0..1); spans::Id::Skybox,
);
render_pass.set_pipeline(&self.renderer.skybox_pipeline.pipeline);
render_pass.set_vertex_buffer(0, model.buf().slice(..));
render_pass.draw(0..model.len() as u32, 0..1);
} }
pub fn draw_lod_terrain<'data: 'pass>(&mut self, model: &'data Model<lod_terrain::Vertex>) { pub fn draw_lod_terrain<'data: 'pass>(&mut self, model: &'data Model<lod_terrain::Vertex>) {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.lod_terrain_pipeline.pipeline); &self.renderer.tracer,
self.render_pass.set_vertex_buffer(0, model.buf().slice(..)); &mut *self.render_pass,
self.render_pass.draw(0..model.len() as u32, 0..1); spans::Id::Lod,
);
render_pass.set_pipeline(&self.renderer.lod_terrain_pipeline.pipeline);
render_pass.set_vertex_buffer(0, model.buf().slice(..));
render_pass.draw(0..model.len() as u32, 0..1);
} }
pub fn draw_figures(&mut self) -> FigureDrawer<'_, 'pass> { pub fn draw_figures(&mut self) -> FigureDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.figure_pipeline.pipeline); &self.renderer.tracer,
&mut *self.render_pass,
if !self.figures_called {
spans::Id::Figures1
} else {
spans::Id::Figures2
},
);
self.figures_called = true;
render_pass.set_pipeline(&self.renderer.figure_pipeline.pipeline);
FigureDrawer { FigureDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
pub fn draw_terrain<'data: 'pass>(&mut self) -> TerrainDrawer<'_, 'pass> { pub fn draw_terrain<'data: 'pass>(&mut self) -> TerrainDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.terrain_pipeline.pipeline); &self.renderer.tracer,
&mut *self.render_pass,
spans::Id::Terrain,
);
render_pass.set_pipeline(&self.renderer.terrain_pipeline.pipeline);
TerrainDrawer { TerrainDrawer {
render_pass: &mut self.render_pass, render_pass,
col_lights: None, col_lights: None,
} }
} }
pub fn draw_particles(&mut self) -> ParticleDrawer<'_, 'pass> { pub fn draw_particles(&mut self) -> ParticleDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.particle_pipeline.pipeline); &self.renderer.tracer,
&mut *self.render_pass,
spans::Id::Particles,
);
render_pass.set_pipeline(&self.renderer.particle_pipeline.pipeline);
ParticleDrawer { ParticleDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
pub fn draw_sprites<'data: 'pass>( pub fn draw_sprites<'data: 'pass>(
&mut self, &mut self,
col_lights: &'data ColLights<sprite::Locals>, col_lights: &'data ColLights<sprite::Locals>,
) -> SpriteDrawer<'_, 'pass> { ) -> SpriteDrawer<'_, 'pass> {
let mut render_pass = Span::start(
&self.renderer.tracer,
&mut *self.render_pass,
spans::Id::Sprites,
);
self.render_pass self.render_pass
.set_pipeline(&self.renderer.sprite_pipeline.pipeline); .set_pipeline(&self.renderer.sprite_pipeline.pipeline);
self.render_pass self.render_pass
.set_bind_group(4, &col_lights.bind_group, &[]); .set_bind_group(4, &col_lights.bind_group, &[]);
SpriteDrawer { SpriteDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
pub fn draw_fluid<'data: 'pass>( pub fn draw_fluid<'data: 'pass>(
&mut self, &mut self,
waves: &'data fluid::BindGroup, waves: &'data fluid::BindGroup,
) -> FluidDrawer<'_, 'pass> { ) -> FluidDrawer<'_, 'pass> {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.fluid_pipeline.pipeline); &self.renderer.tracer,
self.render_pass.set_bind_group(2, &waves.bind_group, &[]); &mut *self.render_pass,
spans::Id::Fluid,
);
render_pass.set_pipeline(&self.renderer.fluid_pipeline.pipeline);
render_pass.set_bind_group(2, &waves.bind_group, &[]);
FluidDrawer { FluidDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
} }
pub struct FigureDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct FigureDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> FigureDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> FigureDrawer<'pass_ref, 'pass> {
@ -460,7 +527,7 @@ impl<'pass_ref, 'pass: 'pass_ref> FigureDrawer<'pass_ref, 'pass> {
} }
pub struct TerrainDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct TerrainDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
col_lights: Option<&'pass_ref Arc<ColLights<terrain::Locals>>>, col_lights: Option<&'pass_ref Arc<ColLights<terrain::Locals>>>,
} }
@ -492,7 +559,7 @@ impl<'pass_ref, 'pass: 'pass_ref> TerrainDrawer<'pass_ref, 'pass> {
} }
pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct ParticleDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
@ -513,7 +580,7 @@ impl<'pass_ref, 'pass: 'pass_ref> ParticleDrawer<'pass_ref, 'pass> {
} }
pub struct SpriteDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct SpriteDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> SpriteDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> SpriteDrawer<'pass_ref, 'pass> {
@ -550,7 +617,7 @@ impl<'pass_ref, 'pass: 'pass_ref> ChunkSpriteDrawer<'pass_ref, 'pass> {
} }
pub struct FluidDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct FluidDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> { impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> {
@ -567,8 +634,8 @@ impl<'pass_ref, 'pass: 'pass_ref> FluidDrawer<'pass_ref, 'pass> {
// Second pass: clouds // Second pass: clouds
pub struct SecondPassDrawer<'pass> { pub struct SecondPassDrawer<'pass> {
pub(super) render_pass: wgpu::RenderPass<'pass>, render_pass: OwningSpan<'pass, wgpu::RenderPass<'pass>>,
pub renderer: &'pass Renderer, renderer: &'pass Renderer,
} }
impl<'pass> SecondPassDrawer<'pass> { impl<'pass> SecondPassDrawer<'pass> {
@ -583,31 +650,33 @@ impl<'pass> SecondPassDrawer<'pass> {
// Third pass: postprocess + ui // Third pass: postprocess + ui
pub struct ThirdPassDrawer<'pass> { pub struct ThirdPassDrawer<'pass> {
render_pass: wgpu::RenderPass<'pass>, render_pass: OwningSpan<'pass, wgpu::RenderPass<'pass>>,
renderer: &'pass Renderer, renderer: &'pass Renderer,
} }
impl<'pass> ThirdPassDrawer<'pass> { impl<'pass> ThirdPassDrawer<'pass> {
pub fn draw_post_process(&mut self) { pub fn draw_post_process(&mut self) {
self.render_pass let mut render_pass = Span::start(
.set_pipeline(&self.renderer.postprocess_pipeline.pipeline); &self.renderer.tracer,
self.render_pass &mut *self.render_pass,
.set_bind_group(1, &self.renderer.locals.postprocess_bind.bind_group, &[]); spans::Id::Postprocess,
self.render_pass.draw(0..3, 0..1); );
render_pass.set_pipeline(&self.renderer.postprocess_pipeline.pipeline);
render_pass.set_bind_group(1, &self.renderer.locals.postprocess_bind.bind_group, &[]);
render_pass.draw(0..3, 0..1);
} }
pub fn draw_ui(&mut self) -> UiDrawer<'_, 'pass> { pub fn draw_ui(&mut self) -> UiDrawer<'_, 'pass> {
self.render_pass let mut render_pass =
.set_pipeline(&self.renderer.ui_pipeline.pipeline); Span::start(&self.renderer.tracer, &mut *self.render_pass, spans::Id::Ui);
render_pass.set_pipeline(&self.renderer.ui_pipeline.pipeline);
UiDrawer { UiDrawer { render_pass }
render_pass: &mut self.render_pass,
}
} }
} }
pub struct UiDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct UiDrawer<'pass_ref, 'pass: 'pass_ref> {
render_pass: &'pass_ref mut wgpu::RenderPass<'pass>, render_pass: Span<'pass_ref, wgpu::RenderPass<'pass>>,
} }
pub struct PreparedUiDrawer<'pass_ref, 'pass: 'pass_ref> { pub struct PreparedUiDrawer<'pass_ref, 'pass: 'pass_ref> {
@ -628,7 +697,7 @@ impl<'pass_ref, 'pass: 'pass_ref> UiDrawer<'pass_ref, 'pass> {
// Note: not actually prepared yet // Note: not actually prepared yet
// we do this to avoid having to write extra code for the set functions // we do this to avoid having to write extra code for the set functions
let mut prepared = PreparedUiDrawer { let mut prepared = PreparedUiDrawer {
render_pass: self.render_pass, render_pass: &mut *self.render_pass,
}; };
// Prepare // Prepare
prepared.set_locals(locals); prepared.set_locals(locals);

View File

@ -381,6 +381,7 @@ impl Scene {
&self.col_lights.texture(model), &self.col_lights.texture(model),
); );
} }
drop(figure_drawer);
drawer.draw_skybox(&self.skybox.model); drawer.draw_skybox(&self.skybox.model);
} }