cyborg/src/lib.rs

95 lines
2.7 KiB
Rust
Raw Normal View History

2022-04-04 02:11:38 +00:00
//! Cyborg is a high-performance, modern, experimental rendering engine written
//! in Rust.
2022-04-04 03:56:28 +00:00
use rayon::prelude::*;
2022-04-05 04:21:14 +00:00
use std::sync::{Arc, RwLock};
2022-04-04 02:11:38 +00:00
use strum::IntoEnumIterator;
2022-04-05 05:17:30 +00:00
pub mod handle;
2022-04-04 03:15:05 +00:00
pub mod pass;
2022-04-04 03:56:28 +00:00
pub mod phase;
2022-04-05 05:17:30 +00:00
pub mod scene;
2022-04-04 02:11:38 +00:00
2022-04-04 03:15:05 +00:00
use pass::*;
2022-04-04 02:31:20 +00:00
use phase::*;
2022-04-04 02:11:38 +00:00
pub struct Renderer {
2022-04-05 04:21:14 +00:00
pub frames_in_flight: usize,
2022-04-04 02:11:38 +00:00
pub render_passes: Vec<Box<dyn RenderPassBoxTrait>>,
}
2022-04-05 04:21:14 +00:00
impl Default for Renderer {
fn default() -> Self {
Self {
frames_in_flight: 2,
render_passes: Vec::new(),
}
}
}
2022-04-04 02:11:38 +00:00
impl Renderer {
2022-04-05 04:21:14 +00:00
pub fn add_pass<T: 'static + RenderPass>(&mut self, pass: T) {
let pass = Arc::new(RwLock::new(pass));
self.add_pass_arc(pass);
}
pub fn add_pass_arc<T: 'static + RenderPass>(&mut self, pass: Arc<RwLock<T>>) {
let pass = RenderPassBox::new(pass, self.frames_in_flight);
self.add_pass_box(pass);
}
pub fn add_pass_box(&mut self, pass: Box<dyn RenderPassBoxTrait>) {
self.render_passes.push(pass);
}
2022-04-04 02:11:38 +00:00
pub fn render(&mut self) {
let frame_index = 0;
2022-04-04 03:56:28 +00:00
let phase_passes = PhaseMultiMap::<usize>::default();
let phase_passes = std::sync::Mutex::new(phase_passes);
2022-04-04 02:11:38 +00:00
2022-04-04 03:56:28 +00:00
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);
});
2022-04-04 02:11:38 +00:00
2022-04-04 03:56:28 +00:00
let phase_passes = phase_passes.into_inner().unwrap();
PrePhase::iter().par_bridge().for_each(|phase| {
2022-04-04 02:11:38 +00:00
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);
}
2022-04-04 03:56:28 +00:00
});
2022-04-04 02:11:38 +00:00
let viewport = ViewportData;
2022-04-04 03:56:28 +00:00
ViewportPhase::iter().par_bridge().for_each(|phase| {
2022-04-04 02:11:38 +00:00
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);
}
2022-04-04 03:56:28 +00:00
});
2022-04-04 02:11:38 +00:00
}
}
/// 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;
}