1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
use crate::render_features::render_features_prelude::*;
/// The `ID` of a `SubmitNode` in a specific `RenderFeature` in the current frame.
pub type SubmitNodeId = u32;
/// A generic key usable by the `SubmitNodeSortFunction` for the purpose of sorting the collection of
/// `RenderFeatureSubmitNode` in a particular `ViewPhase`. This can be used to minimize state changes
/// in the rendering pipeline, e.g. by setting the bits of the key so that higher bits represent more
/// expensive state changes like shaders and lower bits represent cheaper state changes like uniforms.
///
/// Example: https://web.archive.org/web/20210110113523/https://realtimecollisiondetection.net/blog/?p=86
pub type SubmitNodeSortKey = u32;
/// The sort function used by a particular `RenderPhase`. This is usually one of the following:
/// 1. front-to-back
/// 2. back-to-front
/// 3. by feature index
/// 4. unsorted
pub type SubmitNodeSortFunction = fn(&mut Vec<RenderFeatureSubmitNode>);
/// A combination of a particular `RenderView` and `RenderPhase`. The `ViewPhaseSubmitNodeBlock`s
/// in the `PreparedRenderData` are indexed by the `ViewPhase`.
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
pub struct ViewPhase {
pub view_index: RenderViewIndex,
pub phase_index: RenderPhaseIndex,
}
/// The `ViewPhaseSubmitNodeBlock` is a collection of `RenderFeatureSubmitNode` associated with
/// a particular `RenderView`, and `RenderPhase`. In other words, the `ViewPhaseSubmitNodeBlock`
/// is the combination of all the feature-specific `RenderFeatureSubmitNodeBlock`s with the same
/// `RenderView` and `RenderPhase`.
#[derive(Debug)]
pub struct ViewPhaseSubmitNodeBlock {
view_phase: ViewPhase,
submit_nodes: Vec<RenderFeatureSubmitNode>,
}
impl ViewPhaseSubmitNodeBlock {
pub fn new(
view_phase: ViewPhase,
num_submit_nodes: usize,
) -> Self {
Self {
view_phase,
submit_nodes: Vec::with_capacity(num_submit_nodes),
}
}
pub fn view_phase(&self) -> &ViewPhase {
&self.view_phase
}
pub fn len(&self) -> usize {
self.submit_nodes.len()
}
pub fn push_submit_node(
&mut self,
submit_node: RenderFeatureSubmitNode,
) {
self.submit_nodes.push(submit_node)
}
pub fn sort_submit_nodes(
&mut self,
sort_function: SubmitNodeSortFunction,
) {
sort_function(&mut self.submit_nodes)
}
pub fn submit_nodes(&self) -> &[RenderFeatureSubmitNode] {
self.submit_nodes.as_slice()
}
}
/// A type-erased struct representing some `RenderFeature`'s `SubmitNode`. The `PreparedRenderData`
/// will iterate through the sorted slice of `RenderFeatureSubmitNode` in a `ViewPhaseSubmitNodeBlock`
/// and call the functions on the `RenderFeatureWriteJob` specified by the `RenderFeatureIndex`.
#[derive(Copy, Clone, Debug)]
pub struct RenderFeatureSubmitNode {
feature_index: RenderFeatureIndex,
submit_node_id: SubmitNodeId,
sort_key: SubmitNodeSortKey,
distance: f32,
}
impl RenderFeatureSubmitNode {
pub fn new(
feature_index: RenderFeatureIndex,
submit_node_id: SubmitNodeId,
sort_key: SubmitNodeSortKey,
distance: f32,
) -> Self {
Self {
feature_index,
submit_node_id,
sort_key,
distance,
}
}
pub fn feature_index(&self) -> RenderFeatureIndex {
self.feature_index
}
pub fn submit_node_id(&self) -> SubmitNodeId {
self.submit_node_id
}
pub fn sort_key(&self) -> SubmitNodeSortKey {
self.sort_key
}
pub fn distance(&self) -> f32 {
self.distance
}
}