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}