rafx_renderer/
renderer_builder.rs

1use super::Renderer;
2use super::{RenderFeaturePlugin, RendererPipelinePlugin};
3use crate::renderer_thread_pool_none::RendererThreadPoolNone;
4use crate::{RendererAssetPlugin, RendererThreadPool};
5use rafx_api::{RafxApi, RafxQueueType, RafxResult};
6use rafx_assets::AssetManager;
7use rafx_assets::AssetResource;
8use rafx_framework::render_features::{ExtractResources, RenderRegistryBuilder};
9use rafx_framework::upload::UploadQueueConfig;
10use rafx_framework::RenderResources;
11use std::sync::Arc;
12
13pub enum AssetSource {
14    BuildDir(std::path::PathBuf),
15}
16
17pub struct RendererBuilderResult {
18    pub asset_resource: AssetResource,
19    pub asset_manager: AssetManager,
20    pub renderer: Renderer,
21}
22
23pub struct RendererBuilder {
24    feature_plugins: Vec<Arc<dyn RenderFeaturePlugin>>,
25    asset_plugins: Vec<Arc<dyn RendererAssetPlugin>>,
26    allow_use_render_thread: bool,
27}
28
29impl Default for RendererBuilder {
30    fn default() -> Self {
31        RendererBuilder {
32            feature_plugins: Default::default(),
33            asset_plugins: Default::default(),
34            allow_use_render_thread: true,
35        }
36    }
37}
38
39impl RendererBuilder {
40    pub fn add_render_feature_plugin(
41        mut self,
42        plugin: Arc<dyn RenderFeaturePlugin>,
43    ) -> Self {
44        self.feature_plugins.push(plugin);
45        self
46    }
47
48    pub fn add_asset_plugin(
49        mut self,
50        plugin: Arc<dyn RendererAssetPlugin>,
51    ) -> Self {
52        self.asset_plugins.push(plugin);
53        self
54    }
55
56    pub fn allow_use_render_thread(
57        mut self,
58        allow_use_render_thread: bool,
59    ) -> Self {
60        self.allow_use_render_thread = allow_use_render_thread;
61        self
62    }
63
64    pub fn build(
65        self,
66        extract_resources: ExtractResources,
67        rafx_api: &RafxApi,
68        asset_source: AssetSource,
69        pipeline_plugin: Arc<dyn RendererPipelinePlugin>,
70        renderer_thread_pool: fn() -> Option<Box<dyn RendererThreadPool>>, // TODO(dvd): Change to threading type enum with options None, RenderThread, or ThreadPool.
71    ) -> RafxResult<RendererBuilderResult> {
72        let mut asset_resource = match asset_source {
73            AssetSource::BuildDir(build_dir) => {
74                log::info!("Renderer build dir: {:?}", build_dir);
75                AssetResource::new(build_dir).unwrap()
76            }
77        };
78        // let mut asset_resource = match asset_source {
79        //     AssetSource::Packfile(packfile) => {
80        //         log::info!("Reading from packfile {:?}", packfile);
81        //
82        //         // Initialize the packfile loader with the packfile path
83        //         daemon::init_distill_packfile(&packfile)
84        //     }
85        //     AssetSource::Daemon {
86        //         external_daemon,
87        //         daemon_args,
88        //     } => {
89        //         if !external_daemon {
90        //             log::info!("Hosting local daemon at {:?}", daemon_args.address);
91        //
92        //             let mut asset_dirs = FnvHashSet::default();
93        //             for path in daemon_args.asset_dirs {
94        //                 log::info!("Added asset path {:?}", path);
95        //                 asset_dirs.insert(path);
96        //             }
97        //
98        //             for plugin in &self.asset_plugins {
99        //                 let mut paths = Default::default();
100        //                 plugin.add_asset_paths(&mut paths);
101        //                 for path in paths {
102        //                     log::info!(
103        //                         "Added asset path {:?} from asset plugin {}",
104        //                         path,
105        //                         plugin.plugin_name()
106        //                     );
107        //                     asset_dirs.insert(path);
108        //                 }
109        //             }
110        //
111        //             for plugin in &self.feature_plugins {
112        //                 let mut paths = Default::default();
113        //                 plugin.add_asset_paths(&mut paths);
114        //                 for path in paths {
115        //                     log::info!(
116        //                         "Added asset path {:?} from feature plugin {:?}",
117        //                         path,
118        //                         plugin.feature_debug_constants().feature_name
119        //                     );
120        //                     asset_dirs.insert(path);
121        //                 }
122        //             }
123        //
124        //             {
125        //                 let mut paths = Default::default();
126        //                 pipeline_plugin.add_asset_paths(&mut paths);
127        //                 for path in paths {
128        //                     log::info!(
129        //                         "Added asset path {:?} from pipeline plugin {:?}",
130        //                         path,
131        //                         pipeline_plugin.plugin_name()
132        //                     );
133        //                     asset_dirs.insert(path);
134        //                 }
135        //             }
136        //
137        //             let mut asset_daemon = rafx_assets::hydrate_impl::default_daemon()
138        //                 .with_db_path(daemon_args.db_dir)
139        //                 .with_address(daemon_args.address)
140        //                 .with_asset_dirs(asset_dirs.into_iter().collect());
141        //
142        //             for plugin in &self.asset_plugins {
143        //                 asset_daemon = plugin.configure_asset_daemon(asset_daemon);
144        //             }
145        //
146        //             // Spawn the daemon in a background thread.
147        //             std::thread::spawn(move || {
148        //                 asset_daemon.run();
149        //             });
150        //         } else {
151        //             log::info!("Connecting to daemon at {:?}", daemon_args.address);
152        //         }
153        //
154        //         // Connect to the daemon we just launched
155        //         daemon::init_distill_daemon(daemon_args.address.to_string())
156        //     }
157        // };
158
159        let mut render_registry_builder = RenderRegistryBuilder::default();
160        for plugin in &self.feature_plugins {
161            render_registry_builder = plugin.configure_render_registry(render_registry_builder);
162        }
163        for plugin in &self.asset_plugins {
164            render_registry_builder = plugin.configure_render_registry(render_registry_builder);
165        }
166        render_registry_builder =
167            pipeline_plugin.configure_render_registry(render_registry_builder);
168
169        let render_registry = render_registry_builder.build();
170
171        let device_context = rafx_api.device_context();
172
173        let graphics_queue = device_context.create_queue(RafxQueueType::Graphics)?;
174        let transfer_queue = device_context.create_queue(RafxQueueType::Transfer)?;
175
176        let mut asset_manager = AssetManager::new(
177            &device_context,
178            &render_registry,
179            UploadQueueConfig {
180                max_concurrent_uploads: 2,
181                max_new_uploads_in_single_frame: 1,
182                max_bytes_per_upload: 64 * 1024 * 1024,
183            },
184            &graphics_queue,
185            &transfer_queue,
186        )?;
187
188        let mut render_resources = RenderResources::default();
189
190        asset_manager.register_default_asset_types(&mut asset_resource, &mut render_resources)?;
191
192        for plugin in &self.asset_plugins {
193            plugin.register_asset_types(
194                &mut asset_manager,
195                &mut asset_resource,
196                &mut render_resources,
197            )?;
198        }
199
200        let renderer = Renderer::new(
201            extract_resources,
202            render_resources,
203            &mut asset_resource,
204            &mut asset_manager,
205            &graphics_queue,
206            &transfer_queue,
207            self.feature_plugins,
208            self.asset_plugins,
209            pipeline_plugin,
210            renderer_thread_pool()
211                .or_else(|| Some(Box::new(RendererThreadPoolNone::new())))
212                .unwrap(),
213            self.allow_use_render_thread,
214        );
215
216        match renderer {
217            Ok(renderer) => Ok(RendererBuilderResult {
218                asset_resource,
219                asset_manager,
220                renderer,
221            }),
222            Err(e) => {
223                std::mem::drop(asset_resource);
224                std::mem::drop(asset_manager);
225                Err(e)
226            }
227        }
228    }
229}