127 lines
3.7 KiB
Rust
127 lines
3.7 KiB
Rust
//! Definitions and containers for render 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.
|
|
///
|
|
/// These variants are temporary and for testing purposes.
|
|
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
|
|
pub enum PrePhase {
|
|
VertexSkinning,
|
|
}
|
|
|
|
/// The main viewport rendering phase group.
|
|
///
|
|
/// These variants are temporary and for testing purposes.
|
|
#[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd, strum::EnumIter)]
|
|
pub enum ViewportPhase {
|
|
CullLights,
|
|
CullPolys,
|
|
ShadowRendering,
|
|
Depth,
|
|
DepthMips,
|
|
AO,
|
|
Opaque,
|
|
Transparent,
|
|
Bloom,
|
|
Overlay,
|
|
Composite,
|
|
}
|
|
|
|
/// 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();
|
|
}
|
|
|
|
/// Inserts a [PrePhase].
|
|
pub fn insert_pre(&mut self, phase: PrePhase) {
|
|
self.pre.push(phase);
|
|
}
|
|
|
|
/// Inserts a [ViewportPhase].
|
|
pub fn insert_viewport(&mut self, phase: ViewportPhase) {
|
|
self.viewport.push(phase);
|
|
}
|
|
}
|
|
|
|
/// 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()
|
|
}
|
|
}
|
|
}
|