rayon + boxing + dummy_pass() test
This commit is contained in:
parent
9f6f57f6d4
commit
25ef497821
|
@ -4,4 +4,5 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rayon = "1"
|
||||||
strum = { version = "0.24", features = ["derive"] }
|
strum = { version = "0.24", features = ["derive"] }
|
||||||
|
|
83
src/lib.rs
83
src/lib.rs
|
@ -1,10 +1,11 @@
|
||||||
//! Cyborg is a high-performance, modern, experimental rendering engine written
|
//! Cyborg is a high-performance, modern, experimental rendering engine written
|
||||||
//! in Rust.
|
//! in Rust.
|
||||||
|
|
||||||
|
use rayon::prelude::*;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
pub mod phase;
|
|
||||||
pub mod pass;
|
pub mod pass;
|
||||||
|
pub mod phase;
|
||||||
|
|
||||||
use pass::*;
|
use pass::*;
|
||||||
use phase::*;
|
use phase::*;
|
||||||
|
@ -17,32 +18,41 @@ impl Renderer {
|
||||||
pub fn render(&mut self) {
|
pub fn render(&mut self) {
|
||||||
let frame_index = 0;
|
let frame_index = 0;
|
||||||
|
|
||||||
let mut phase_passes = PhaseMultiMap::<usize>::default();
|
let phase_passes = PhaseMultiMap::<usize>::default();
|
||||||
|
let phase_passes = std::sync::Mutex::new(phase_passes);
|
||||||
|
|
||||||
let mut phases_buf = PhaseList::default();
|
self.render_passes
|
||||||
for (pass_index, rp) in self.render_passes.iter_mut().enumerate() {
|
.par_iter_mut()
|
||||||
phases_buf.clear();
|
.enumerate()
|
||||||
rp.begin_frame(frame_index, &mut phases_buf);
|
.for_each(|(pass_index, rp)| {
|
||||||
phase_passes.insert_multi(&phases_buf, pass_index);
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
for phase in PrePhase::iter() {
|
let phase_passes = phase_passes.into_inner().unwrap();
|
||||||
|
|
||||||
|
PrePhase::iter().par_bridge().for_each(|phase| {
|
||||||
for pass_index in phase_passes.iter_pre(&phase) {
|
for pass_index in phase_passes.iter_pre(&phase) {
|
||||||
let pass = &self.render_passes[*pass_index];
|
let pass = &self.render_passes[*pass_index];
|
||||||
let mut encoder = gpu::RenderBundleEncoder;
|
let mut encoder = gpu::RenderBundleEncoder;
|
||||||
pass.render_pre(phase, frame_index, &mut encoder);
|
pass.render_pre(phase, frame_index, &mut encoder);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
let viewport = ViewportData;
|
let viewport = ViewportData;
|
||||||
|
|
||||||
for phase in ViewportPhase::iter() {
|
ViewportPhase::iter().par_bridge().for_each(|phase| {
|
||||||
for pass_index in phase_passes.iter_viewport(&phase) {
|
for pass_index in phase_passes.iter_viewport(&phase) {
|
||||||
let pass = &self.render_passes[*pass_index];
|
let pass = &self.render_passes[*pass_index];
|
||||||
let mut encoder = gpu::RenderBundleEncoder;
|
let mut encoder = gpu::RenderBundleEncoder;
|
||||||
pass.render_viewport(phase, frame_index, &viewport, &mut encoder);
|
pass.render_viewport(phase, frame_index, &viewport, &mut encoder);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,3 +65,52 @@ pub mod gpu {
|
||||||
/// - secondary command buffer in Vulkan
|
/// - secondary command buffer in Vulkan
|
||||||
pub struct RenderBundleEncoder;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
src/pass.rs
14
src/pass.rs
|
@ -15,9 +15,9 @@ pub struct ViewportData;
|
||||||
///
|
///
|
||||||
/// Rendering functions record their GPU commands using the [gpu::RenderBundleEncoder]
|
/// Rendering functions record their GPU commands using the [gpu::RenderBundleEncoder]
|
||||||
/// passed to them.
|
/// passed to them.
|
||||||
pub trait RenderPass {
|
pub trait RenderPass: Send + Sync {
|
||||||
/// A structure that contains a pass's per-frame data.
|
/// A structure that contains a pass's per-frame data.
|
||||||
type FrameData;
|
type FrameData: Send + Sync;
|
||||||
|
|
||||||
/// Sets up a new instance of [Self::FrameData].
|
/// Sets up a new instance of [Self::FrameData].
|
||||||
///
|
///
|
||||||
|
@ -57,7 +57,7 @@ pub trait RenderPass {
|
||||||
///
|
///
|
||||||
/// Functions on this trait map one-to-one with [RenderPass], except that
|
/// Functions on this trait map one-to-one with [RenderPass], except that
|
||||||
/// frame data is passed by index and not by reference.
|
/// frame data is passed by index and not by reference.
|
||||||
pub trait RenderPassBoxTrait {
|
pub trait RenderPassBoxTrait: Send + Sync {
|
||||||
fn begin_frame(&mut self, data_index: usize, phases: &mut PhaseList);
|
fn begin_frame(&mut self, data_index: usize, phases: &mut PhaseList);
|
||||||
|
|
||||||
fn render_pre(&self, phase: PrePhase, data_index: usize, cmds: &mut gpu::RenderBundleEncoder);
|
fn render_pre(&self, phase: PrePhase, data_index: usize, cmds: &mut gpu::RenderBundleEncoder);
|
||||||
|
@ -77,21 +77,21 @@ pub struct RenderPassBox<T: RenderPass> {
|
||||||
frame_data: Vec<T::FrameData>,
|
frame_data: Vec<T::FrameData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RenderPass> RenderPassBox<T> {
|
impl<T: 'static + RenderPass> RenderPassBox<T> {
|
||||||
/// Creates a new boxed render pass.
|
/// Creates a new boxed render pass.
|
||||||
///
|
///
|
||||||
/// Calls to [RenderPassBoxTrait] functions with frame indices greater
|
/// Calls to [RenderPassBoxTrait] functions with frame indices greater
|
||||||
/// than or equal to `frame_num` are out-of-bounds and will panic.
|
/// than or equal to `frame_num` are out-of-bounds and will panic.
|
||||||
pub fn new(render_pass: Arc<RwLock<T>>, frame_num: usize) -> Self {
|
pub fn new(render_pass: Arc<RwLock<T>>, frame_num: usize) -> Box<dyn RenderPassBoxTrait> {
|
||||||
let frame_data = {
|
let frame_data = {
|
||||||
let mut lock = render_pass.write().unwrap();
|
let mut lock = render_pass.write().unwrap();
|
||||||
(0..frame_num).map(|_| lock.create_frame_data()).collect()
|
(0..frame_num).map(|_| lock.create_frame_data()).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Box::new(Self {
|
||||||
render_pass,
|
render_pass,
|
||||||
frame_data,
|
frame_data,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue