rafx_framework/render_features/jobs/extract/
render_job_extract_context.rs

1use crate::render_features::render_features_prelude::*;
2use crate::visibility::{ViewFrustumId, VisibilityConfig};
3use crate::RenderResources;
4use fnv::{FnvHashMap, FnvHashSet};
5use rafx_base::owned_pool::{OwnedPool, Pooled};
6
7pub type ExtractResources<'extract> = rafx_base::resource_ref_map::ResourceRefMap<'extract>;
8pub type RenderObjectInstanceObjectIds = FnvHashSet<RenderObjectInstance>;
9
10#[derive(Clone)]
11pub struct ViewPacketSize {
12    pub view: RenderView,
13    pub num_render_object_instances: usize,
14    pub num_volumes: usize,
15}
16
17impl ViewPacketSize {
18    pub fn size_of(view_packet: &dyn RenderFeatureViewPacket) -> Self {
19        Self {
20            view: view_packet.view().clone(),
21            num_render_object_instances: view_packet.num_render_object_instances(),
22            num_volumes: 0,
23        }
24    }
25}
26
27#[derive(Default, Clone)]
28pub struct FramePacketSize {
29    pub num_render_object_instances: usize,
30    pub view_packet_sizes: Vec<ViewPacketSize>,
31}
32
33#[derive(Default, Clone)]
34pub struct FramePacketMetadata {
35    pub feature_index: RenderFeatureIndex,
36    pub is_relevant: bool,
37    pub frame_packet_size: FramePacketSize,
38}
39
40pub type VisibilityVecs = Vec<Vec<RenderObjectInstance>>;
41
42pub struct RenderJobExtractAllocationContext {
43    pub frame_packet_metadata: Vec<TrustCell<FramePacketMetadata>>,
44    pub frame_packets: Vec<TrustCell<Option<Box<dyn RenderFeatureFramePacket>>>>,
45    pub render_object_instances: Vec<TrustCell<RenderObjectInstanceObjectIds>>,
46    visibility_vecs: Mutex<FnvHashMap<ViewFrustumId, OwnedPool<VisibilityVecs>>>,
47    num_features: usize,
48}
49
50impl RenderJobExtractAllocationContext {
51    pub fn new(num_features: usize) -> Self {
52        let mut allocation_context = Self {
53            frame_packet_metadata: Vec::with_capacity(num_features),
54            frame_packets: Vec::with_capacity(num_features),
55            render_object_instances: Vec::with_capacity(num_features),
56            visibility_vecs: Default::default(),
57            num_features,
58        };
59
60        allocation_context.clear();
61        allocation_context
62    }
63
64    pub fn clear(&mut self) {
65        self.frame_packet_metadata.clear();
66        self.frame_packets.clear();
67        self.render_object_instances.clear();
68
69        for _ in 0..self.num_features {
70            self.frame_packet_metadata
71                .push(TrustCell::new(FramePacketMetadata::default()));
72            self.frame_packets.push(TrustCell::new(None));
73            self.render_object_instances
74                .push(TrustCell::new(RenderObjectInstanceObjectIds::default()));
75        }
76
77        self.visibility_vecs.lock().clear();
78    }
79
80    pub fn query_visibility_vecs(
81        &self,
82        view: &RenderView,
83    ) -> Pooled<VisibilityVecs> {
84        let id = view.view_frustum().view_frustum_id();
85
86        let mut visibility_vecs = self.visibility_vecs.lock();
87        let pool = visibility_vecs.entry(id).or_insert_with(|| {
88            OwnedPool::with_capacity(
89                1,
90                || vec![Vec::default(); RenderRegistry::registered_feature_count() as usize],
91                |val| {
92                    for feature in val.iter_mut() {
93                        feature.clear();
94                    }
95                },
96            )
97        });
98
99        pool.try_recv();
100        pool.borrow()
101    }
102}
103
104/// Holds references to resources valid for the entirety of the `extract` step as
105/// represented by the `'extract` lifetime. `RenderFeatureExtractJob`s should cache
106/// any resources needed from the `RenderJobExtractContext` during their `new` function.
107#[derive(Clone)]
108pub struct RenderJobExtractContext<'extract> {
109    pub allocation_context: &'extract RenderJobExtractAllocationContext,
110    pub extract_resources: &'extract ExtractResources<'extract>,
111    pub render_resources: &'extract RenderResources,
112    pub visibility_config: &'extract VisibilityConfig,
113}
114
115impl<'extract> RenderJobExtractContext<'extract> {
116    pub fn new(
117        allocation_context: &'extract RenderJobExtractAllocationContext,
118        extract_resources: &'extract ExtractResources<'extract>,
119        render_resources: &'extract RenderResources,
120        visibility_config: &'extract VisibilityConfig,
121    ) -> Self {
122        RenderJobExtractContext {
123            allocation_context,
124            extract_resources,
125            render_resources,
126            visibility_config,
127        }
128    }
129}