Skip to main content

RenderManager.ixx File

Draft render manager that batches render commands per scene and target. More...

Included Headers

Namespaces Index

namespacehelios
namespaceengine
namespacerendering

Classes Index

classRenderManager<TRenderBackend, TMemberHandle>

Collects render commands into hierarchical batches and forwards them to the backend. More...

structMeshBatch<TDrawMemberHandle>

Lowest-level batch collecting draw contexts for one mesh. More...

structMaterialBatch<TDrawMemberHandle>

Groups mesh batches for one material. More...

structShaderBatch<TDrawMemberHandle>

Groups material batches for one shader. More...

structViewportBatch<TDrawMemberHandle>

Groups shader batches for one viewport. More...

structRenderTargetBatch<TDrawMemberHandle>

Top-level batch grouping viewport batches per render target. More...

Macro Definitions Index

#defineHELIOS_LOG_SCOPE   "helios::engine::rendering::RenderManager"

Description

Draft render manager that batches render commands per scene and target.

Macro Definitions

HELIOS_LOG_SCOPE

#define HELIOS_LOG_SCOPE   "helios::engine::rendering::RenderManager"

Definition at line 62 of file RenderManager.ixx.

62#define HELIOS_LOG_SCOPE "helios::engine::rendering::RenderManager"

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <vector>
8#include <format>
10#include <optional>
11
12export module helios.engine.rendering.RenderManager;
13
14import helios.engine.runtime.world.tags.ManagerRole;
15
16import helios.engine.rendering.renderTarget.types.RenderTargetHandle;
17import helios.engine.rendering.viewport.types.ViewportHandle;
18import helios.engine.scene.types.SceneHandle;
19
20import helios.engine.scene.components;
21
22import helios.engine.rendering.common.commands;
23import helios.engine.rendering.common.types.RenderPassContext;
24import helios.engine.scene.types;
25import helios.engine.runtime.messaging.command.CommandHandlerRegistry;
26
27import helios.ecs.types;
28
29import helios.engine.util.log;
30import helios.engine.runtime.world.UpdateContext;
31
32import helios.engine.rendering.common.concepts.IsRenderBackendLike;
33
34import helios.engine.core.container.HandleMultiMap;
35
36import helios.math;
37
38import helios.engine.rendering.mesh.types;
39import helios.engine.rendering.material.types;
40import helios.engine.rendering.shader.types;
41
53
56using namespace helios::engine::scene::types;
57using namespace helios::ecs::types;
58using namespace helios::engine::scene::types;
59using namespace helios::engine::util::log;
60using namespace helios::engine::rendering::common::concepts;
61
62#define HELIOS_LOG_SCOPE "helios::engine::rendering::RenderManager"
63export namespace helios::engine::rendering {
64
75 template<typename TRenderBackend, typename TMemberHandle>
78
88 template<typename TBatch, typename TChildHandle>
89 static void clearActive(TBatch* batch, std::vector<EntityId>& activeIndices, std::vector<TChildHandle>& batches) {
90 batch->isActive = false;
91 for (auto idx: activeIndices) {
92 batches[idx].clear();
93 }
94 activeIndices.clear();
95 }
96
107 template<typename THandle, typename TChildBatch>
108 static TChildBatch& addToBatch(const THandle handle, std::vector<TChildBatch>& batches, std::vector<EntityId>& activeIndices) {
109 if (handle.entityId >= batches.size()) {
110 batches.resize(handle.entityId + 1);
111 }
112 auto& batch = batches[handle.entityId];
113
114 if (!batches[handle.entityId].isActive) {
115 batch.handle = handle;
116 batches[handle.entityId].isActive = true;
117 activeIndices.push_back(handle.entityId);
118 }
119
120 return batch;
121 }
122
128 template<typename TDrawMemberHandle>
129 struct MeshBatch {
130 bool isActive{false};
131 MeshHandle handle;
132 std::vector<SceneMemberRenderContext<TDrawMemberHandle>> drawContexts;
133 MeshBatch(){drawContexts.reserve(DEFAULT_GAMEOBJECT_CAPACITY);}
134 void clear() {
135 isActive = false;
136 drawContexts.clear();
137 }
138 };
139
145 template<typename TDrawMemberHandle>
146 struct MaterialBatch {
147 bool isActive{false};
148 MaterialHandle handle;
149 std::vector<MeshBatch<TDrawMemberHandle>> batches;
150 std::vector<EntityId> activeIndices;
151 MaterialBatch(){batches.reserve(DEFAULT_MESH_POOL_CAPACITY);}
153 return addToBatch(handle, batches, activeIndices);
154 }
155 void clear() {
156 clearActive(this, activeIndices, batches);
157 }
158 };
159
165 template<typename TDrawMemberHandle>
166 struct ShaderBatch {
167 bool isActive{false};
168 ShaderHandle handle;
169 std::vector<MaterialBatch<TDrawMemberHandle>> batches;
170 std::vector<EntityId> activeIndices;
171 ShaderBatch(){batches.reserve(DEFAULT_MATERIAL_POOL_CAPACITY);}
173 return addToBatch(handle, batches, activeIndices);
174 }
175 void clear() {
176 clearActive(this, activeIndices, batches);
177 }
178 };
179
185 template<typename TDrawMemberHandle>
186 struct ViewportBatch {
187 bool isActive{false};
188 ViewportHandle handle;
189 std::vector<ShaderBatch<TDrawMemberHandle>> batches;
190 std::vector<EntityId> activeIndices;
192 return addToBatch(handle, batches, activeIndices);
193 }
194 ViewportBatch(){batches.reserve(DEFAULT_SHADER_POOL_CAPACITY);}
195 void clear() {
196 clearActive(this, activeIndices, batches);
197 }
198 };
199
205 template<typename TDrawMemberHandle>
206 struct RenderTargetBatch {
207 bool isActive{false};
208 RenderTargetHandle handle;
209 std::vector<ViewportBatch<TDrawMemberHandle>> batches;
210 std::vector<EntityId> activeIndices;
212 return addToBatch(handle, batches, activeIndices);
213 }
214 RenderTargetBatch(){batches.reserve(DEFAULT_VIEWPORT_POOL_CAPACITY);}
215 void clear() {
216 clearActive(this, activeIndices, batches);
217 }
218 };
219
220
221 inline static auto& logger_ = LogManager::loggerForScope(HELIOS_LOG_SCOPE);
222
223
224 std::vector<RenderTargetBatch<TMemberHandle>> renderTargetBatches_;
225 std::vector<EntityId> activeRenderTargetIndices_;
226
227 TRenderBackend& renderBackend_;
228
237 [[nodiscard]] ViewportBatch<TMemberHandle>& ensureViewportBatch(
238 RenderTargetHandle renderTargetHandle, ViewportHandle viewportHandle) {
239
240 auto renderTargetId = renderTargetHandle.entityId;
241
242 if (renderTargetBatches_.size() <= renderTargetHandle.entityId) {
243 renderTargetBatches_.resize(renderTargetId + 1);
244 }
245
246 auto& renderTargetBatch = renderTargetBatches_[renderTargetId];
247
248 if (!renderTargetBatch.isActive) {
249 renderTargetBatch.isActive = true;
250 renderTargetBatch.handle = renderTargetHandle;
251 activeRenderTargetIndices_.push_back(renderTargetId);
252 }
253
254 return renderTargetBatch.getOrAdd(viewportHandle);
255 };
256
257 public:
258
263
270
271 renderTargetBatches_.reserve(DEFAULT_FRAMEBUFFER_POOL_CAPACITY);
272
273 }
274
275
286
287 for (auto renderTargetIdx : activeRenderTargetIndices_) {
288 auto& renderTargetBatch = renderTargetBatches_[renderTargetIdx];
289
290 renderBackend_.beginRenderTargetBatch(renderTargetBatch.handle);
291
292 for (auto viewportIdx : renderTargetBatch.activeIndices) {
294
295 renderBackend_.beginViewportBatch(viewportBatch.handle);
296
297 for (auto shaderIdx : viewportBatch.activeIndices ) {
298 auto& shaderBatch = viewportBatch.batches[shaderIdx];
299
300 renderBackend_.beginShaderBatch(shaderBatch.handle);
301
302 for (auto materialIdx : shaderBatch.activeIndices) {
303 auto& materialBatch = shaderBatch.batches[materialIdx];
304
305 renderBackend_.beginMaterialBatch(materialBatch.handle);
306
307 for (auto meshIdx : materialBatch.activeIndices) {
308 auto& meshBatch = materialBatch.batches[meshIdx];
309
310 renderBackend_.beginMeshBatch(meshBatch.handle);
311
312 renderBackend_.template renderBatch<TMemberHandle>(meshBatch.drawContexts);
313
314 renderBackend_.endMeshBatch(meshBatch.handle);
315 } // materialBatch
316
317 renderBackend_.endMaterialBatch(materialBatch.handle);
318 } //shaderBatch
319
320 renderBackend_.endShaderBatch(shaderBatch.handle);
321 } // viewportBatch
322
323 renderBackend_.endViewportBatch(viewportBatch.handle);
324 } //renderTargetBatch
325
326 renderBackend_.endRenderTargetBatch(renderTargetBatch.handle);
327 }
328
329 for (auto idx : activeRenderTargetIndices_ ) {
330 renderTargetBatches_[idx].clear();
331 }
332 activeRenderTargetIndices_.clear();
333
334
335 }
336
337
350
351 std::ignore = ensureViewportBatch(
352 renderSceneCommand.sceneRenderContext.renderTargetHandle,
353 renderSceneCommand.sceneRenderContext.viewportHandle
354 );
355
356 return true;
357 }
358
359
370
371 auto& sceneMemberRenderContext = std::move(renderCommand.sceneMemberRenderContext);
372
373 auto& renderTargetHandle = sceneMemberRenderContext.renderTargetHandle;
374 auto& viewportHandle = sceneMemberRenderContext.viewportHandle;
375 auto& materialHandle = sceneMemberRenderContext.materialHandle;
376 auto& meshHandle = sceneMemberRenderContext.meshHandle;
377 auto& shaderHandle = sceneMemberRenderContext.shaderHandle;
378
379 auto& viewportBatch = ensureViewportBatch(renderTargetHandle, viewportHandle);
380 auto& shaderBatch = viewportBatch.getOrAdd(shaderHandle);
381 auto& materialBatch = shaderBatch.getOrAdd(materialHandle);
382 auto& meshBatch = materialBatch.getOrAdd(meshHandle);
383
384 meshBatch.drawContexts.push_back(std::move(sceneMemberRenderContext));
385
386 return true;
387 }
388
389
395 void init(CommandHandlerRegistry& commandHandlerRegistry) noexcept {
396
397 commandHandlerRegistry.handleCommands<
400 >(*this);
401
402
403 };
404
405
406 };
407
408
409}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.