summaryrefslogtreecommitdiffstats
path: root/src/render/framegraph/framegraphvisitor.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire350@gmail.com>2016-05-16 13:44:43 +0200
committerSean Harmer <sean.harmer@kdab.com>2016-07-03 08:54:20 +0000
commitb246d17fb3e45848ddbfd581d7cb87b9575f7e86 (patch)
treea644489ff9ca0dfba9edac1af302c1d0d1dff1ad /src/render/framegraph/framegraphvisitor.cpp
parent4d94fa74e3422766f8e84e2192d731310b87bd95 (diff)
Split RenderViewJobs
Change-Id: I6c4f8970b14e39085480c029b8acdfcdbfc6fa8d Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/framegraph/framegraphvisitor.cpp')
-rw-r--r--src/render/framegraph/framegraphvisitor.cpp142
1 files changed, 140 insertions, 2 deletions
diff --git a/src/render/framegraph/framegraphvisitor.cpp b/src/render/framegraph/framegraphvisitor.cpp
index 78f6272d8..c43a32e3f 100644
--- a/src/render/framegraph/framegraphvisitor.cpp
+++ b/src/render/framegraph/framegraphvisitor.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 Paul Lemire
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -42,6 +43,14 @@
#include "framegraphnode_p.h"
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/managers_p.h>
+#include <Qt3DRender/private/filterentitybycomponentjob_p.h>
+#include <Qt3DRender/private/filterlayerentityjob_p.h>
+#include <Qt3DRender/private/genericlambdajob_p.h>
+#include <Qt3DRender/private/materialparametergathererjob_p.h>
+#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DRender/private/renderviewbuilderjob_p.h>
+#include <Qt3DRender/private/renderview_p.h>
+#include <Qt3DRender/private/frustumcullingjob_p.h>
QT_BEGIN_NAMESPACE
@@ -95,8 +104,137 @@ void FrameGraphVisitor::visit(Render::FrameGraphNode *node)
// TODO: Pass in only framegraph config that has changed from previous
// index RenderViewJob.
if (fgChildIds.empty()) {
- QAspectJobPtr job = m_renderer->createRenderViewInitializerJob(node, m_renderviewIndex++);
- m_jobs->append(job);
+ // 1) Prepare parameter pack for all possible Pass Filter / Technique Filter
+ // At most 1 of each per RenderView -> not very frequent -> doesn't need to be in a job
+
+ // 1) Update all the ShaderData
+
+ // 1) RenderView initialization from
+ // 2) One job to filter out the Entities in a layers (no dependency)
+ // 2) -> One job to filter out only the Entities with a QDispatchCompute
+ // 2) -> One job to filter out only the Entities with a GeometryRenderer
+ // 2) -> One job to create all ParameterInfoList for each Material
+ // 2) -> One job to perform frustrum culling of layered filtered entities
+
+ // -> 3) Merge Parameter pack 1 / 2 + Material
+ // -> 4) One job to prepare the commands
+ // -> One job to sort the RenderCommands
+ // -> One job to set the active uniforms / build the ParameterPack
+
+ // GenericLambdaJob will be used to sync data between jobs and their dependencies
+ // Prefer linear iteration over tree traversal
+
+ const int currentRenderViewIndex = m_renderviewIndex++;
+ RenderViewInitializerJobPtr renderViewJob = m_renderer->createRenderViewInitializerJob(node, currentRenderViewIndex);
+ auto renderViewCommandBuilder = Render::RenderViewBuilderJobPtr::create();
+ auto filterEntityByLayer = Render::FilterLayerEntityJobPtr::create();
+ auto renderableEntityFilterer = Render::FilterEntityByComponentJobPtr<Render::GeometryRenderer, Render::Material>::create();
+
+ // Note: do it only if OpenGL 4.3+ available
+ auto computeEntityFilterer = Render::FilterEntityByComponentJobPtr<Render::ComputeCommand, Render::Material>::create();
+
+ auto materialGatherer = Render::MaterialParameterGathererJobPtr::create();
+ auto frustumCulling = Render::FrustumCullingJobPtr::create();
+
+ // Init what we can here
+ EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager();
+ filterEntityByLayer->setManager(entityManager);
+ renderableEntityFilterer->setManager(entityManager);
+ computeEntityFilterer->setManager(entityManager);
+ materialGatherer->setNodeManagers(m_renderer->nodeManagers());
+ materialGatherer->setRenderer(m_renderer);
+ frustumCulling->setRoot(m_renderer->sceneRoot());
+ renderViewCommandBuilder->setIndex(currentRenderViewIndex);
+ renderViewCommandBuilder->setRenderer(m_renderer);
+
+ // Copy shared ptr -> this is called once the FrameGraphBranch was used to fill initial data in the RenderView
+ auto syncRenderViewInitialization = [=] () {
+ RenderView *rv = renderViewJob->renderView();
+
+ // Layer filtering
+ filterEntityByLayer->setHasLayerFilter(rv->hasLayerFilter());
+ filterEntityByLayer->setLayers(rv->layerFilter());
+
+ // Material Parameter building
+ materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter()));
+ materialGatherer->setTechniqueFilter(const_cast<TechniqueFilter *>(rv->techniqueFilter()));
+
+ // Frustum culling
+ frustumCulling->setViewProjection(rv->viewProjectionMatrix());
+ };
+
+ // Copy shared ptr -> this is called after filtering / culling / parameter setting has been performed
+ auto syncForRenderCommandBuilding = [=] () {
+ // Set the result of previous job computations
+ // for final RenderCommand building
+ RenderView *rv = renderViewJob->renderView();
+
+ if (!rv->noDraw()) {
+ // Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
+ const QVector<Entity *> filteredEntities = filterEntityByLayer->filteredEntities();
+
+ // Note: this could further be improved if needed
+ // Set the renderable and computable entities
+ if (!rv->isCompute()) {
+ QVector<Entity *> renderableEntities = renderableEntityFilterer->filteredEntities();
+
+ for (auto i = renderableEntities.size() - 1; i >= 0; --i) {
+ if (!filteredEntities.contains(renderableEntities.at(i)))
+ renderableEntities.removeAt(i);
+ }
+
+ if (rv->frustumCulling()) {
+ const QVector<Entity *> visibleEntities = frustumCulling->visibleEntities();
+ for (auto i = renderableEntities.size() - 1; i >= 0; --i) {
+ if (!visibleEntities.contains(renderableEntities.at(i)))
+ renderableEntities.removeAt(i);
+ }
+ }
+
+ rv->setRenderables(std::move(renderableEntities));
+ } else {
+ QVector<Entity *> computableEntities = computeEntityFilterer->filteredEntities();
+ for (auto i = computableEntities.size() - 1; i >= 0; --i) {
+ if (!filteredEntities.contains(computableEntities.at(i)))
+ computableEntities.removeAt(i);
+ }
+ rv->setComputables(std::move(computableEntities));
+ }
+
+ // Set all required data on the RenderView for final processing
+ rv->setMaterialParameterTable(std::move(materialGatherer->materialToPassAndParameter()));
+ }
+ renderViewCommandBuilder->setRenderView(renderViewJob->renderView());
+ };
+
+ auto syncRenderViewCommandBuildingJob = GenericLambdaJobPtr<decltype(syncForRenderCommandBuilding)>::create(syncForRenderCommandBuilding);
+ auto syncRenderViewInitializationJob = GenericLambdaJobPtr<decltype(syncRenderViewInitialization)>::create(syncRenderViewInitialization);
+
+ // Set dependencies
+ syncRenderViewInitializationJob->addDependency(renderViewJob);
+
+ filterEntityByLayer->addDependency(syncRenderViewInitializationJob);
+ materialGatherer->addDependency(syncRenderViewInitializationJob);
+ frustumCulling->addDependency(syncRenderViewInitializationJob);
+
+ syncRenderViewCommandBuildingJob->addDependency(syncRenderViewInitializationJob);
+ syncRenderViewCommandBuildingJob->addDependency(materialGatherer);
+ syncRenderViewCommandBuildingJob->addDependency(renderableEntityFilterer);
+ syncRenderViewCommandBuildingJob->addDependency(computeEntityFilterer);
+ syncRenderViewCommandBuildingJob->addDependency(filterEntityByLayer);
+
+ renderViewCommandBuilder->addDependency(syncRenderViewCommandBuildingJob);
+
+ // Add jobs
+ m_jobs->push_back(renderViewJob);
+ m_jobs->push_back(filterEntityByLayer);
+ m_jobs->push_back(renderableEntityFilterer);
+ m_jobs->push_back(computeEntityFilterer);
+ m_jobs->push_back(syncRenderViewInitializationJob);
+ m_jobs->push_back(syncRenderViewCommandBuildingJob);
+ m_jobs->push_back(renderViewCommandBuilder);
+ m_jobs->push_back(materialGatherer);
+ m_jobs->push_back(frustumCulling);
}
}