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 `SubmitPacket` is the data that must be prepared from
/// in order for the `RenderFeature`'s `WriteJob` to create each
/// draw call. The draw calls may reference data in either the
/// `FramePacket` or the `SubmitPacket`. Each draw call is represented
/// by exactly 1 `SubmitNode`. In order to allocate the `SubmitPacket`,
/// the `RenderFeature` is given a reference to the populated `FramePacket`
/// from that frame. The `RenderFeature` **must** size the `SubmitPacket`
/// appropriately. The `SubmitPacket` **must** be considered
/// immutable after the `Prepare` step has finished.
pub trait SubmitPacketData {
/// All data that is either unassociated with or shared by
/// any of the submit nodes across each `RenderView`.
type PerFrameSubmitData: Sync + Send;
/// All data for any submit nodes associated with a particular
/// `Entity` and `RenderObject`.
type RenderObjectInstanceSubmitData: Sync + Send;
/// All data that can be shared by the submit nodes for
/// this `RenderFeature`'s `WriteJob` in this `RenderView`
/// and `RenderPhase`.
type PerViewSubmitData: Sync + Send;
/// All data for any submit nodes associated with a particular
/// `Entity`, `RenderObject`, and `RenderView`.
type RenderObjectInstancePerViewSubmitData: Sync + Send;
/// The data needed by this `RenderFeature`'s `WriteJob` for
/// each draw call in this `RenderView` and `RenderPhase` .
type SubmitNodeData: Sync + Send;
/// The `RenderFeature` associated with the `SubmitNodeBlock`s.
/// This is used to find the correct `WriteJob` when writing
/// the `PreparedRenderData`.
type RenderFeature: RenderFeature;
// TODO(dvd): see issue #29661 <https://github.com/rust-lang/rust/issues/29661> for more information
// type SubmitPacket = SubmitPacket<Self>;
}
/// Read documentation on `SubmitPacketData`.
pub struct SubmitPacket<SubmitPacketDataT: SubmitPacketData> {
feature_index: RenderFeatureIndex,
pub(crate) per_frame_submit_data: AtomicOnceCell<SubmitPacketDataT::PerFrameSubmitData>,
pub(crate) render_object_instances_submit_data:
AtomicOnceCellArray<SubmitPacketDataT::RenderObjectInstanceSubmitData>,
view_submit_packets: Vec<ViewSubmitPacket<SubmitPacketDataT>>,
}
impl<SubmitPacketDataT: SubmitPacketData + Send + Sync + 'static> SubmitPacket<SubmitPacketDataT> {
pub fn new(
feature_index: RenderFeatureIndex,
num_render_object_instances: usize,
view_submit_packets: Vec<ViewSubmitPacket<SubmitPacketDataT>>,
) -> Self {
#[cfg(debug_assertions)]
for (i, vp) in view_submit_packets.iter().enumerate() {
assert_eq!(i, vp.view_frame_index() as usize);
}
Self {
feature_index,
per_frame_submit_data: AtomicOnceCell::new(),
render_object_instances_submit_data: AtomicOnceCellArray::with_capacity(
num_render_object_instances,
),
view_submit_packets,
}
}
pub fn view_submit_packets(&self) -> &Vec<ViewSubmitPacket<SubmitPacketDataT>> {
&self.view_submit_packets
}
pub fn view_submit_packet(
&self,
view_frame_index: ViewFrameIndex,
) -> &ViewSubmitPacket<SubmitPacketDataT> {
self.view_submit_packets
.get(view_frame_index as usize)
.unwrap_or_else(|| {
panic!(
"ViewSubmitPacket with ViewFrameIndex {} was not found in {}.",
view_frame_index,
std::any::type_name::<SubmitPacketDataT>()
)
})
}
pub fn render_object_instances_submit_data(
&self
) -> &AtomicOnceCellArray<SubmitPacketDataT::RenderObjectInstanceSubmitData> {
&self.render_object_instances_submit_data
}
pub fn per_frame_submit_data(&self) -> &AtomicOnceCell<SubmitPacketDataT::PerFrameSubmitData> {
&self.per_frame_submit_data
}
}
impl<SubmitPacketDataT: 'static + Send + Sync + SubmitPacketData> RenderFeatureSubmitPacket
for SubmitPacket<SubmitPacketDataT>
{
fn render_feature_view_submit_packet(
&self,
view_index: ViewFrameIndex,
) -> &dyn RenderFeatureViewSubmitPacket {
self.view_submit_packet(view_index)
}
fn feature_index(&self) -> u32 {
self.feature_index
}
}