cyborg/src/lib.rs

117 lines
3.2 KiB
Rust

//! Cyborg is a high-performance, modern, experimental rendering engine written
//! in Rust.
use rayon::prelude::*;
use strum::IntoEnumIterator;
pub mod pass;
pub mod phase;
use pass::*;
use phase::*;
pub struct Renderer {
pub render_passes: Vec<Box<dyn RenderPassBoxTrait>>,
}
impl Renderer {
pub fn render(&mut self) {
let frame_index = 0;
let phase_passes = PhaseMultiMap::<usize>::default();
let phase_passes = std::sync::Mutex::new(phase_passes);
self.render_passes
.par_iter_mut()
.enumerate()
.for_each(|(pass_index, rp)| {
let mut phases_buf = PhaseList::default();
phases_buf.clear();
rp.begin_frame(frame_index, &mut phases_buf);
phase_passes
.lock()
.unwrap()
.insert_multi(&phases_buf, pass_index);
});
let phase_passes = phase_passes.into_inner().unwrap();
PrePhase::iter().par_bridge().for_each(|phase| {
for pass_index in phase_passes.iter_pre(&phase) {
let pass = &self.render_passes[*pass_index];
let mut encoder = gpu::RenderBundleEncoder;
pass.render_pre(phase, frame_index, &mut encoder);
}
});
let viewport = ViewportData;
ViewportPhase::iter().par_bridge().for_each(|phase| {
for pass_index in phase_passes.iter_viewport(&phase) {
let pass = &self.render_passes[*pass_index];
let mut encoder = gpu::RenderBundleEncoder;
pass.render_viewport(phase, frame_index, &viewport, &mut encoder);
}
});
}
}
/// Mock GPU API (like Vulkan, WebGPU, or OpenGL) types for prototyping.
pub mod gpu {
/// Thread-safe GPU command recorder that's later executed in a command buffer.
///
/// Also known as a:
/// - RenderBundleEncoder in WebGPU
/// - secondary command buffer in Vulkan
pub struct RenderBundleEncoder;
}
#[cfg(test)]
mod tests {
use super::*;
struct DummyPass;
impl RenderPass for DummyPass {
type FrameData = usize;
fn create_frame_data(&mut self) -> usize {
0
}
fn begin_frame(&mut self, data: &mut Self::FrameData, phases: &mut PhaseList) {
println!("begin_frame()");
}
fn render_pre(
&self,
phase: PrePhase,
data: &Self::FrameData,
cmds: &mut gpu::RenderBundleEncoder,
) {
println!("render_pre(phase: {:?})", phase);
}
fn render_viewport(
&self,
phase: ViewportPhase,
data: &Self::FrameData,
viewport: &ViewportData,
cmds: &mut gpu::RenderBundleEncoder,
) {
println!("render_viewport(phase: {:?})", phase);
}
}
#[test]
fn dummy_pass() {
use std::sync::{Arc, RwLock};
let dummy_pass = DummyPass;
let dummy_pass = Arc::new(RwLock::new(dummy_pass));
let dummy_pass = RenderPassBox::new(dummy_pass, 1);
let render_passes = vec![dummy_pass];
let mut renderer = Renderer { render_passes };
renderer.render();
}
}