Refactor and document phases

This commit is contained in:
mars 2022-04-03 20:31:20 -06:00
parent dbad5cebd3
commit 4b1dd0fb22
2 changed files with 100 additions and 68 deletions

View File

@ -1,78 +1,12 @@
//! Cyborg is a high-performance, modern, experimental rendering engine written
//! in Rust.
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use strum::IntoEnumIterator;
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
pub enum PrePhase {}
pub mod phase;
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
pub enum ViewportPhase {}
#[derive(Debug, Default)]
pub struct PhaseList {
pub pre: Vec<PrePhase>,
pub viewport: Vec<ViewportPhase>,
}
impl PhaseList {
pub fn clear(&mut self) {
self.pre.clear();
self.viewport.clear();
}
}
#[derive(Debug, Default)]
pub struct PhaseMultiMap<T> {
pub pre: HashMap<PrePhase, Vec<T>>,
pub viewport: HashMap<ViewportPhase, Vec<T>>,
}
impl<T: Copy + PartialEq> PhaseMultiMap<T> {
pub fn insert_multi(&mut self, keys: &PhaseList, val: T) {
for pre in keys.pre.iter() {
Self::insert(&mut self.pre, pre, val);
}
for viewport in keys.viewport.iter() {
Self::insert(&mut self.viewport, viewport, val);
}
}
pub fn iter_pre<'a>(&'a self, phase: &'a PrePhase) -> std::slice::Iter<'a, T> {
Self::iter(&self.pre, phase)
}
pub fn iter_viewport<'a>(&'a self, phase: &'a ViewportPhase) -> std::slice::Iter<'a, T> {
Self::iter(&self.viewport, phase)
}
fn insert<K>(map: &mut HashMap<K, Vec<T>>, key: &K, val: T)
where
K: std::hash::Hash + Eq + Copy,
{
if let Some(existing) = map.get_mut(key) {
if !existing.contains(&val) {
existing.push(val);
}
} else {
map.insert(*key, vec![val]);
}
}
fn iter<'a, K>(map: &'a HashMap<K, Vec<T>>, key: &'a K) -> std::slice::Iter<'a, T>
where
K: std::hash::Hash + Eq + Copy,
{
if let Some(vals) = map.get(key) {
vals.iter()
} else {
[].iter()
}
}
}
use phase::*;
pub struct ViewportData;

98
src/phase.rs Normal file
View File

@ -0,0 +1,98 @@
//! Definitions and containers for rendering phase identifiers.
//!
//! Rendering phases are organized into different groups, which represent
//! different kinds of external data becoming available as the frame progresses.
//! For example, OpenXR encourages applications to acquire its viewport poses
//! as late into the frame as possible, to maximize the accuracy of pose
//! prediction in the time before the frame is presented.
//!
//! The definitions in this module are meant to be expanded upon over time, so
//! the containers make heavy use of generics to abstract functionality across
//! different groups of phases.
use std::collections::HashMap;
/// The rendering pre-phase group; before viewport acquisition.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
pub enum PrePhase {}
/// The main viewport rendering phase group.
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
pub enum ViewportPhase {}
/// A container of phases of each group.
///
/// Can be used with the [PhaseMultiMap] container to insert a value into
/// multiple phases at once.
#[derive(Debug, Default)]
pub struct PhaseList {
pre: Vec<PrePhase>,
viewport: Vec<ViewportPhase>,
}
impl PhaseList {
/// Clears the list, removing all phases.
pub fn clear(&mut self) {
self.pre.clear();
self.viewport.clear();
}
}
/// Maps phases of each group to sets of values.
///
/// Used by the frame scheduler to organize which phases execute which render
/// passes.
#[derive(Debug, Default)]
pub struct PhaseMultiMap<T> {
pre: HashMap<PrePhase, Vec<T>>,
viewport: HashMap<ViewportPhase, Vec<T>>,
}
impl<T: Copy + PartialEq> PhaseMultiMap<T> {
/// Inserts a value into multiple phases at once, keyed with a [PhaseList].
pub fn insert_multi(&mut self, keys: &PhaseList, val: T) {
for pre in keys.pre.iter() {
Self::insert(&mut self.pre, pre, val);
}
for viewport in keys.viewport.iter() {
Self::insert(&mut self.viewport, viewport, val);
}
}
/// Iterates over all values matching a [PrePhase].
pub fn iter_pre<'a>(&'a self, phase: &'a PrePhase) -> std::slice::Iter<'a, T> {
Self::iter(&self.pre, phase)
}
/// Iterates over all values matching a [ViewportPhase].
pub fn iter_viewport<'a>(&'a self, phase: &'a ViewportPhase) -> std::slice::Iter<'a, T> {
Self::iter(&self.viewport, phase)
}
/// Generic helper function for inserting a single value into a phase group map.
fn insert<K>(map: &mut HashMap<K, Vec<T>>, key: &K, val: T)
where
K: std::hash::Hash + Eq + Copy,
{
if let Some(existing) = map.get_mut(key) {
if !existing.contains(&val) {
existing.push(val);
}
} else {
map.insert(*key, vec![val]);
}
}
/// Generic helper function that iterates over a group's phase, if available.
fn iter<'a, K>(map: &'a HashMap<K, Vec<T>>, key: &'a K) -> std::slice::Iter<'a, T>
where
K: std::hash::Hash + Eq + Copy,
{
if let Some(vals) = map.get(key) {
vals.iter()
} else {
[].iter()
}
}
}