Skip to main content

dynamis_world/backend/
mod.rs

1pub(crate) mod archive;
2mod readback;
3pub(crate) mod registry;
4
5pub use registry::StreamCapacity;
6
7#[cfg(feature = "profile")]
8use dynamis_gpu::GpuPassTiming;
9use dynamis_gpu::{GpuContext, SubmissionEncoder};
10use readback::ReadbackBuffers;
11use registry::{Live, Plan, Planning, Rest, StepPasses, Streams};
12use std::collections::VecDeque;
13use wgpu::SubmissionIndex;
14
15pub(crate) use registry::StepFrames;
16
17use crate::World;
18
19pub(crate) struct Backend {
20    pub(crate) gpu: GpuContext,
21    pub(crate) streams: Streams,
22    pub(crate) readback: ReadbackBuffers,
23    pub(crate) passes: StepPasses,
24    pub(crate) planning: Planning,
25    pub(crate) measured: dynamis_abi::Counters,
26    pub(crate) declared: VecDeque<(u64, dynamis_abi::DeclaredCounters)>,
27    pub(crate) measured_step: Option<u64>,
28    pub(crate) published: bool,
29    pub(crate) rest: Rest,
30    pub(crate) inspect: Option<dynamis_gpu::Readback>,
31    pub(crate) submissions: u64,
32    #[cfg(feature = "profile")]
33    pub(crate) pass_timings: Vec<GpuPassTiming>,
34}
35
36impl Backend {
37    pub(crate) fn new(gpu: GpuContext) -> Self {
38        let plan = Plan::minimum();
39        let streams = Streams::new(gpu.device(), gpu.queue(), &plan);
40        let readback = ReadbackBuffers::new(gpu.device(), &plan);
41        let passes = StepPasses::new(&gpu, &streams);
42        Self {
43            gpu,
44            streams,
45            readback,
46            passes,
47            planning: Planning::new(),
48            measured: [0; dynamis_abi::COUNTER_COUNT],
49            declared: VecDeque::new(),
50            measured_step: None,
51            published: false,
52            rest: Rest::IDLE,
53            inspect: None,
54            submissions: 0,
55            #[cfg(feature = "profile")]
56            pass_timings: Vec::new(),
57        }
58    }
59}
60
61impl World {
62    pub fn submissions(&self) -> u64 {
63        self.backend.submissions
64    }
65
66    pub(crate) fn submit(&mut self, encoder: SubmissionEncoder) -> SubmissionIndex {
67        self.backend.submissions += 1;
68        encoder.submit(self.backend.gpu.queue())
69    }
70
71    pub(crate) fn apply_plan(&mut self, live: &Live) {
72        let plan = self
73            .backend
74            .planning
75            .plan(&self.backend.measured, live, &self.backend.streams);
76        if self.backend.streams.matches(&plan) && self.backend.readback.matches(&plan) {
77            return;
78        }
79        if !self.backend.readback.matches(&plan) {
80            self.sync_events();
81            self.drain_readbacks();
82        }
83        let device = self.backend.gpu.device().clone();
84        let mut encoder = SubmissionEncoder::new(&device, "dynamis buffer plan");
85        let streams = self.backend.streams.reserve(&device, &mut encoder, &plan);
86        let readback = self.backend.readback.reserve(&device, &plan);
87        assert!(
88            streams | readback,
89            "a buffer plan that changes capacity must reallocate"
90        );
91        self.submit(encoder);
92    }
93}