rafx_framework/resources/
resource_manager.rs1use super::dyn_resources;
2use super::pipeline_cache;
3use super::resource_lookup;
4use crate::{
5 DescriptorSetAllocatorProvider, DescriptorSetAllocatorRef, DynResourceAllocatorSet,
6 GraphicsPipelineCache, MAX_FRAMES_IN_FLIGHT,
7};
8
9use crate::graph::RenderGraphCache;
10use crate::render_features::RenderRegistry;
11use crate::resources::builtin_pipelines::BuiltinPipelines;
12use crate::resources::descriptor_sets::DescriptorSetAllocatorManager;
13use crate::resources::dyn_commands::DynCommandPoolAllocator;
14use crate::resources::dyn_resources::{
15 DynResourceAllocatorSetManager, DynResourceAllocatorSetProvider,
16};
17use crate::resources::resource_lookup::ResourceLookupSet;
18use rafx_api::{RafxDeviceContext, RafxResult};
19use std::sync::Arc;
20
21#[derive(Debug)]
26pub struct ResourceManagerMetrics {
27 pub dyn_resource_metrics: dyn_resources::ResourceMetrics,
28 pub resource_metrics: resource_lookup::ResourceMetrics,
29 pub graphics_pipeline_cache_metrics: pipeline_cache::GraphicsPipelineCacheMetrics,
30}
31
32struct ResourceContextInner {
33 descriptor_set_allocator_provider: DescriptorSetAllocatorProvider,
34 dyn_resources_allocator_provider: DynResourceAllocatorSetProvider,
35 dyn_command_pool_allocator: DynCommandPoolAllocator,
36 resources: ResourceLookupSet,
37 graphics_pipeline_cache: GraphicsPipelineCache,
38 render_graph_cache: RenderGraphCache,
39 builtin_pipelines: BuiltinPipelines,
40}
41
42#[derive(Clone)]
43pub struct ResourceContext {
44 inner: Arc<ResourceContextInner>,
45}
46
47impl ResourceContext {
48 pub fn device_context(&self) -> &RafxDeviceContext {
49 self.inner.resources.device_context()
50 }
51
52 pub fn resources(&self) -> &ResourceLookupSet {
53 &self.inner.resources
54 }
55
56 pub fn graphics_pipeline_cache(&self) -> &GraphicsPipelineCache {
57 &self.inner.graphics_pipeline_cache
58 }
59
60 pub fn render_graph_cache(&self) -> &RenderGraphCache {
61 &self.inner.render_graph_cache
62 }
63
64 pub fn create_dyn_command_pool_allocator(&self) -> DynCommandPoolAllocator {
65 self.inner.dyn_command_pool_allocator.clone()
66 }
67
68 pub fn create_dyn_resource_allocator_set(&self) -> DynResourceAllocatorSet {
69 self.inner.dyn_resources_allocator_provider.get_allocator()
70 }
71
72 pub fn create_descriptor_set_allocator(&self) -> DescriptorSetAllocatorRef {
73 self.inner.descriptor_set_allocator_provider.get_allocator()
74 }
75
76 pub fn builtin_pipelines(&self) -> &BuiltinPipelines {
77 &self.inner.builtin_pipelines
78 }
79}
80
81pub struct ResourceManager {
82 render_registry: RenderRegistry,
83 dyn_resource_allocators: DynResourceAllocatorSetManager,
84 dyn_command_pool_allocator: DynCommandPoolAllocator,
85 resources: ResourceLookupSet,
86 render_graph_cache: RenderGraphCache,
87 descriptor_set_allocator: DescriptorSetAllocatorManager,
88 graphics_pipeline_cache: GraphicsPipelineCache,
89
90 builtin_pipelines: Option<BuiltinPipelines>,
92}
93
94impl ResourceManager {
95 pub fn new(
96 device_context: &RafxDeviceContext,
97 render_registry: &RenderRegistry,
98 ) -> Self {
99 let resources = ResourceLookupSet::new(device_context, MAX_FRAMES_IN_FLIGHT as u32);
100 let builtin_pipelines =
101 BuiltinPipelines::new(&resources).expect("Failed to load a built-in resource");
102
103 let reuse_resources = !device_context.is_dx12();
107
108 ResourceManager {
109 render_registry: render_registry.clone(),
110 dyn_command_pool_allocator: DynCommandPoolAllocator::new(MAX_FRAMES_IN_FLIGHT as u32),
111 dyn_resource_allocators: DynResourceAllocatorSetManager::new(
112 device_context,
113 MAX_FRAMES_IN_FLIGHT as u32,
114 ),
115 resources: resources.clone(),
116 render_graph_cache: RenderGraphCache::new(MAX_FRAMES_IN_FLIGHT as u32, reuse_resources),
117 descriptor_set_allocator: DescriptorSetAllocatorManager::new(device_context),
118 graphics_pipeline_cache: GraphicsPipelineCache::new(render_registry, resources),
119 builtin_pipelines: Some(builtin_pipelines),
120 }
121 }
122
123 pub fn device_context(&self) -> &RafxDeviceContext {
124 self.resources.device_context()
125 }
126
127 pub fn resource_context(&self) -> ResourceContext {
128 let inner = ResourceContextInner {
129 descriptor_set_allocator_provider: self
130 .descriptor_set_allocator
131 .create_allocator_provider(),
132 dyn_resources_allocator_provider: self
133 .dyn_resource_allocators
134 .create_allocator_provider(),
135 dyn_command_pool_allocator: self.dyn_command_pool_allocator.clone(),
136 resources: self.resources.clone(),
137 graphics_pipeline_cache: self.graphics_pipeline_cache.clone(),
138 render_graph_cache: self.render_graph_cache.clone(),
139 builtin_pipelines: self.builtin_pipelines.as_ref().unwrap().clone(),
140 };
141
142 ResourceContext {
143 inner: Arc::new(inner),
144 }
145 }
146
147 pub fn resources(&self) -> &ResourceLookupSet {
148 &self.resources
149 }
150
151 pub fn graphics_pipeline_cache(&self) -> &GraphicsPipelineCache {
152 &self.graphics_pipeline_cache
153 }
154
155 pub fn dyn_command_pool_allocator(&self) -> &DynCommandPoolAllocator {
156 &self.dyn_command_pool_allocator
157 }
158
159 pub fn create_dyn_resource_allocator_set(&self) -> DynResourceAllocatorSet {
160 self.dyn_resource_allocators.get_allocator()
161 }
162
163 pub fn create_dyn_resource_allocator_provider(&self) -> DynResourceAllocatorSetProvider {
164 self.dyn_resource_allocators.create_allocator_provider()
165 }
166
167 pub fn create_descriptor_set_allocator(&self) -> DescriptorSetAllocatorRef {
168 self.descriptor_set_allocator.get_allocator()
169 }
170
171 pub fn create_descriptor_set_allocator_provider(&self) -> DescriptorSetAllocatorProvider {
172 self.descriptor_set_allocator.create_allocator_provider()
173 }
174
175 pub fn render_registry(&self) -> &RenderRegistry {
176 &self.render_registry
177 }
178
179 pub fn metrics(&self) -> ResourceManagerMetrics {
180 let dyn_resource_metrics = self.dyn_resource_allocators.metrics();
181 let resource_metrics = self.resources.metrics();
182 let graphics_pipeline_cache_metrics = self.graphics_pipeline_cache.metrics();
183
184 ResourceManagerMetrics {
185 dyn_resource_metrics,
186 resource_metrics,
187 graphics_pipeline_cache_metrics,
188 }
189 }
190
191 #[profiling::function]
192 pub fn on_frame_complete(&mut self) -> RafxResult<()> {
193 self.render_graph_cache.on_frame_complete();
194 self.graphics_pipeline_cache.on_frame_complete();
195 self.resources.on_frame_complete()?;
196 self.dyn_command_pool_allocator.on_frame_complete()?;
197 self.dyn_resource_allocators.on_frame_complete()?;
198 self.descriptor_set_allocator.on_frame_complete();
199 Ok(())
200 }
201}
202
203impl Drop for ResourceManager {
204 fn drop(&mut self) {
205 log::info!("Cleaning up resource manager");
206 log::trace!("Resource Manager Metrics:\n{:#?}", self.metrics());
207
208 self.builtin_pipelines = None;
209
210 self.render_graph_cache.clear();
212 self.graphics_pipeline_cache.clear_all_pipelines();
213
214 self.descriptor_set_allocator.destroy().unwrap();
217
218 self.resources.destroy().unwrap();
220 self.dyn_resource_allocators.destroy().unwrap();
221
222 log::info!("Dropping resource manager");
223 log::trace!("Resource Manager Metrics:\n{:#?}", self.metrics());
224 }
225}