blade_render/util/
frame_pacer.rs1use crate::render::FrameResources;
2use std::mem;
3
4pub struct FramePacer {
8 frame_index: usize,
9 prev_resources: FrameResources,
10 prev_sync_point: Option<blade_graphics::SyncPoint>,
11 command_encoder: blade_graphics::CommandEncoder,
12 next_resources: FrameResources,
13}
14
15impl FramePacer {
16 pub fn new(context: &blade_graphics::Context) -> Self {
17 let encoder = context.create_command_encoder(blade_graphics::CommandEncoderDesc {
18 name: "main",
19 buffer_count: 2,
20 });
21 Self {
22 frame_index: 0,
23 prev_resources: FrameResources::default(),
24 prev_sync_point: None,
25 command_encoder: encoder,
26 next_resources: FrameResources::default(),
27 }
28 }
29
30 #[profiling::function]
31 pub fn wait_for_previous_frame(&mut self, context: &blade_graphics::Context) {
32 if let Some(sp) = self.prev_sync_point.take() {
33 context.wait_for(&sp, !0);
34 }
35 for buffer in self.prev_resources.buffers.drain(..) {
36 context.destroy_buffer(buffer);
37 }
38 for accel_structure in self.prev_resources.acceleration_structures.drain(..) {
39 context.destroy_acceleration_structure(accel_structure);
40 }
41 }
42
43 pub fn last_sync_point(&self) -> Option<&blade_graphics::SyncPoint> {
44 self.prev_sync_point.as_ref()
45 }
46
47 pub fn destroy(&mut self, context: &blade_graphics::Context) {
48 self.wait_for_previous_frame(context);
49 context.destroy_command_encoder(&mut self.command_encoder);
50 }
51
52 pub fn begin_frame(&mut self) -> (&mut blade_graphics::CommandEncoder, &mut FrameResources) {
53 self.command_encoder.start();
54 (&mut self.command_encoder, &mut self.next_resources)
55 }
56
57 pub fn end_frame(&mut self, context: &blade_graphics::Context) -> &blade_graphics::SyncPoint {
58 let sync_point = context.submit(&mut self.command_encoder);
59 self.frame_index += 1;
60 self.wait_for_previous_frame(context);
63 self.prev_sync_point = Some(sync_point);
64 mem::swap(&mut self.prev_resources, &mut self.next_resources);
65 self.prev_sync_point.as_ref().unwrap()
66 }
67
68 pub fn timings(&self) -> &blade_graphics::Timings {
69 self.command_encoder.timings()
70 }
71}