dynamis-world 0.7.0

Host scene registry, step orchestration, and readback
Documentation
pub(crate) mod archive;
mod readback;
pub(crate) mod registry;

pub use registry::StreamCapacity;

#[cfg(feature = "profile")]
use dynamis_gpu::GpuPassTiming;
use dynamis_gpu::{GpuContext, SubmissionEncoder};
use readback::ReadbackBuffers;
use registry::{Live, Plan, Planning, Rest, StepPasses, Streams};
use std::collections::VecDeque;
use wgpu::SubmissionIndex;

pub(crate) use registry::StepFrames;

use crate::World;

pub(crate) struct Backend {
    pub(crate) gpu: GpuContext,
    pub(crate) streams: Streams,
    pub(crate) readback: ReadbackBuffers,
    pub(crate) passes: StepPasses,
    pub(crate) planning: Planning,
    pub(crate) measured: dynamis_abi::Counters,
    pub(crate) declared: VecDeque<(u64, dynamis_abi::DeclaredCounters)>,
    pub(crate) measured_step: Option<u64>,
    pub(crate) published: bool,
    pub(crate) rest: Rest,
    pub(crate) inspect: Option<dynamis_gpu::Readback>,
    pub(crate) submissions: u64,
    #[cfg(feature = "profile")]
    pub(crate) pass_timings: Vec<GpuPassTiming>,
}

impl Backend {
    pub(crate) fn new(gpu: GpuContext) -> Self {
        let plan = Plan::minimum();
        let streams = Streams::new(gpu.device(), gpu.queue(), &plan);
        let readback = ReadbackBuffers::new(gpu.device(), &plan);
        let passes = StepPasses::new(&gpu, &streams);
        Self {
            gpu,
            streams,
            readback,
            passes,
            planning: Planning::new(),
            measured: [0; dynamis_abi::COUNTER_COUNT],
            declared: VecDeque::new(),
            measured_step: None,
            published: false,
            rest: Rest::IDLE,
            inspect: None,
            submissions: 0,
            #[cfg(feature = "profile")]
            pass_timings: Vec::new(),
        }
    }
}

impl World {
    pub fn submissions(&self) -> u64 {
        self.backend.submissions
    }

    pub(crate) fn submit(&mut self, encoder: SubmissionEncoder) -> SubmissionIndex {
        self.backend.submissions += 1;
        encoder.submit(self.backend.gpu.queue())
    }

    pub(crate) fn apply_plan(&mut self, live: &Live) {
        let plan = self
            .backend
            .planning
            .plan(&self.backend.measured, live, &self.backend.streams);
        if self.backend.streams.matches(&plan) && self.backend.readback.matches(&plan) {
            return;
        }
        if !self.backend.readback.matches(&plan) {
            self.sync_events();
            self.drain_readbacks();
        }
        let device = self.backend.gpu.device().clone();
        let mut encoder = SubmissionEncoder::new(&device, "dynamis buffer plan");
        let streams = self.backend.streams.reserve(&device, &mut encoder, &plan);
        let readback = self.backend.readback.reserve(&device, &plan);
        assert!(
            streams | readback,
            "a buffer plan that changes capacity must reallocate"
        );
        self.submit(encoder);
    }
}