use crate::rbd::pipeline::RbdPipeline;
use crate::state::NexusState;
use khal::backend::{GpuBackend, GpuBackendError, GpuTimestamps};
bitflags::bitflags! {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct NexusPipelineMask: u8 {
const RBD = 1 << 0;
}
}
#[derive(Default)]
pub struct NexusPipeline {
pub rbd_pipeline: Option<RbdPipeline>,
}
impl NexusPipeline {
pub fn preload_pipelines(
&mut self,
backend: &GpuBackend,
pipelines: NexusPipelineMask,
) -> Result<(), GpuBackendError> {
if pipelines.contains(NexusPipelineMask::RBD) && self.rbd_pipeline.is_none() {
self.rbd_pipeline = Some(RbdPipeline::new(backend)?);
}
Ok(())
}
pub async fn simulate(
&mut self,
backend: &GpuBackend,
state: &mut NexusState,
timestamps: Option<&mut GpuTimestamps>,
) -> Result<(), GpuBackendError> {
state.finalize(backend).await?;
let t0 = web_time::Instant::now();
let mut timestamps = timestamps.filter(|ts| ts.is_idle());
if let Some(rbd) = state.rbd.as_mut() {
self.preload_pipelines(backend, NexusPipelineMask::RBD)?;
let pipeline = self.rbd_pipeline.as_mut().unwrap_or_else(|| unreachable!());
let steps = state.rbd_steps_per_frame.max(1);
for _ in 0..steps {
state.run_stats = pipeline.step(backend, rbd, timestamps.as_deref_mut())?;
}
pipeline.auto_resize_buffers(backend, rbd)?;
}
state.run_stats.encoding_time = t0.elapsed();
if let Some(ts) = timestamps {
ts.request_read(backend);
}
Ok(())
}
}