rafx_renderer/
render_feature_plugin.rs

1use crate::{Renderer, RendererLoadContext};
2use rafx_api::extra::upload::RafxTransferUpload;
3use rafx_api::RafxResult;
4use rafx_assets::AssetManager;
5use rafx_assets::AssetResource;
6use rafx_framework::render_features::render_features_prelude::*;
7use rafx_framework::RenderResources;
8use std::path::PathBuf;
9use std::sync::Arc;
10
11/// A `RenderFeaturePlugin` defines a `RenderFeature` for the `Renderer`. The `RenderFeaturePlugin`
12/// completely encapsulates the logic needed by the `Renderer`, `RenderFrameJob`, and `RendererThreadPool`.
13///
14/// # Initialization
15///
16/// `configure_render_registry` and `initialize_static_resources` setup the `RenderFeature` for usage with
17/// the `Renderer`.
18///
19/// # Extract
20///
21/// `is_relevant`, `is_view_relevant`, and `requires_visible_render_objects` are used to identify which
22/// `RenderView`s need to be included in the `RenderFeature`'s frame packet. Then, `calculate_frame_packet_size`
23/// is used to size the `FramePacket`, `new_frame_packet` allocates the memory for the `FramePacket`, and
24/// `populate_frame_packet` fills the `FramePacket` with the mapping of `RenderObjectInstance` and
25/// `RenderObjectInstancePerView` for each `ViewPacket`. `new_extract_job` wraps the `FramePacket` to
26/// return a `RenderFeatureExtractJob`.
27///
28/// # Prepare
29///
30/// `new_submit_packet` sizes and allocates the memory for a `SubmitPacket` using the `FramePacket` as
31/// a reference. `new_prepare_job` wraps the `FramePacket` and `SubmitPacket` to return a `RenderFeaturePrepareJob`.
32///
33/// # Write
34///
35/// `new_write_job` wraps the `FramePacket` and `SubmitPacket` to return a `RenderFeatureWriteJob`.
36pub trait RenderFeaturePlugin: Send + Sync {
37    fn feature_debug_constants(&self) -> &'static RenderFeatureDebugConstants;
38    fn feature_index(&self) -> RenderFeatureIndex;
39
40    /// Returns `true` if the `RenderView` represented by the `RenderViewVisibilityQuery` should be
41    /// included in the `FramePacket` for this `RenderFeature`. Most features should only need to
42    /// implement `is_view_relevant` and `requires_visible_render_objects`.
43    fn is_relevant(
44        &self,
45        view_visibility: &RenderViewVisibilityQuery,
46    ) -> bool {
47        let view = &view_visibility.view;
48        if !view.feature_index_is_relevant(self.feature_index()) {
49            return false;
50        }
51
52        if self.is_view_relevant(&view) {
53            return if self.requires_visible_render_objects() {
54                view_visibility
55                    .render_object_instances_per_view(self.feature_index())
56                    .is_some()
57            } else {
58                true
59            };
60        }
61
62        false
63    }
64
65    /// Returns `true` if the `RenderView` should be included in the `FramePacket` for this `RenderFeature`.
66    /// This is normally implemented by checking if the `RenderView`'s `RenderPhaseMask` includes the
67    /// `RenderPhase`s needed by the `RenderFeature`.
68    fn is_view_relevant(
69        &self,
70        view: &RenderView,
71    ) -> bool;
72
73    /// Returns `true` if this `RenderFeature` requires at least one `RenderObject` associated with this
74    /// `RenderFeature` in the `RenderViewVisibilityQuery` in order to include the `RenderView` in the
75    /// `FramePacket` for this `RenderFeature`. This is normally `true` if the `RenderFeature` defines
76    /// a `RenderObjectSet` and `false` otherwise.
77    fn requires_visible_render_objects(&self) -> bool;
78
79    fn add_asset_paths(
80        &self,
81        _asset_paths: &mut Vec<PathBuf>,
82    ) {
83    }
84
85    fn configure_render_registry(
86        &self,
87        render_registry: RenderRegistryBuilder,
88    ) -> RenderRegistryBuilder {
89        render_registry
90    }
91
92    fn initialize_static_resources(
93        &self,
94        _renderer_load_context: &RendererLoadContext,
95        _asset_manager: &mut AssetManager,
96        _asset_resource: &mut AssetResource,
97        _extract_resources: &ExtractResources,
98        _render_resources: &mut RenderResources,
99        _upload: &mut RafxTransferUpload,
100    ) -> RafxResult<()> {
101        Ok(())
102    }
103
104    fn prepare_renderer_destroy(
105        &self,
106        _render_resources: &RenderResources,
107    ) -> RafxResult<()> {
108        Ok(())
109    }
110
111    fn add_render_views(
112        &self,
113        _extract_resources: &ExtractResources,
114        _render_resources: &RenderResources,
115        _render_view_set: &RenderViewSet,
116        _render_views: &mut Vec<RenderView>,
117    ) {
118    }
119
120    /// Determines the unique set of `RenderObjectInstance`s in `FramePacket` and the size of each
121    /// `ViewPacket` in the `FramePacket`.
122    fn calculate_frame_packet_size<'extract>(
123        &self,
124        _extract_context: &RenderJobExtractContext<'extract>,
125        visibility_results: &Vec<RenderViewVisibilityQuery>,
126        render_object_instance_object_ids: &mut RenderObjectInstanceObjectIds,
127        frame_packet_size: &mut FramePacketSize,
128    ) {
129        Renderer::calculate_frame_packet_size(
130            self.feature_debug_constants(),
131            self.feature_index(),
132            |view_visibility| self.is_relevant(view_visibility),
133            visibility_results,
134            render_object_instance_object_ids,
135            frame_packet_size,
136        );
137    }
138
139    /// Allocates the memory for the `FramePacket`.
140    fn new_frame_packet(
141        &self,
142        frame_packet_size: &FramePacketSize,
143    ) -> Box<dyn RenderFeatureFramePacket>;
144
145    /// Creates the mapping of `RenderObjectInstance` and `RenderObjectInstancePerView` in the
146    /// `FramePacket`. This is done separately from `new_frame_packet` so that all of the frame
147    /// packets can be allocated at once and then populated in parallel.
148    fn populate_frame_packet<'extract>(
149        &self,
150        _extract_context: &RenderJobExtractContext<'extract>,
151        visibility_results: &Vec<RenderViewVisibilityQuery>,
152        _frame_packet_size: &FramePacketSize,
153        frame_packet: &mut Box<dyn RenderFeatureFramePacket>,
154    ) {
155        Renderer::populate_frame_packet(
156            self.feature_debug_constants(),
157            self.feature_index(),
158            |view_visibility| self.is_relevant(view_visibility),
159            visibility_results,
160            frame_packet,
161        );
162    }
163
164    /// Returns a `RenderFeatureExtractJob` wrapping the `FramePacket`.
165    fn new_extract_job<'extract>(
166        &self,
167        extract_context: &RenderJobExtractContext<'extract>,
168        frame_packet: Box<dyn RenderFeatureFramePacket>,
169    ) -> Arc<dyn RenderFeatureExtractJob<'extract> + 'extract>;
170
171    /// Determines the size of the `SubmitPacket` according to the size of the `FramePacket` and
172    /// allocates the memory for it. The `SubmitPacket` is populated by the `RenderFeaturePrepareJob`
173    /// so there is no equivalent to `populate_frame_packet`.
174    fn new_submit_packet(
175        &self,
176        frame_packet: &Box<dyn RenderFeatureFramePacket>,
177    ) -> Box<dyn RenderFeatureSubmitPacket>;
178
179    /// Returns a `RenderFeaturePrepareJob` wrapping the `FramePacket` and `SubmitPacket`.
180    fn new_prepare_job<'prepare>(
181        &self,
182        prepare_context: &RenderJobPrepareContext<'prepare>,
183        frame_packet: Box<dyn RenderFeatureFramePacket>,
184        submit_packet: Box<dyn RenderFeatureSubmitPacket>,
185    ) -> Arc<dyn RenderFeaturePrepareJob<'prepare> + 'prepare>;
186
187    /// Returns a `RenderFeatureWriteJob` wrapping the `FramePacket` and `SubmitPacket`.
188    fn new_write_job<'write>(
189        &self,
190        write_context: &RenderJobWriteContext<'write>,
191        frame_packet: Box<dyn RenderFeatureFramePacket>,
192        submit_packet: Box<dyn RenderFeatureSubmitPacket>,
193    ) -> Arc<dyn RenderFeatureWriteJob<'write> + 'write>;
194}