diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2020-07-07 12:04:44 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2020-07-08 17:18:19 +0200 |
commit | e8a6190d781da8ba4d11dcf5962d21055f2bcce8 (patch) | |
tree | 68e35c032958a56a0564201988fa8524e1f89a42 /src | |
parent | 6e02bb60dc53de68098aa502ed58bbc493ef5967 (diff) |
Move RenderViewInitializer,Builder/Updater jobs to a common place
All the renderer plugins are doing differently really is the submission
part and the way commands are built which we can hide entirely in the
RenderView/RenderCommands
Change-Id: If4d6a472f1ce1b36ffa5b4ca75e3420e42a165f5
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
30 files changed, 659 insertions, 1592 deletions
diff --git a/src/plugins/renderers/opengl/CMakeLists.txt b/src/plugins/renderers/opengl/CMakeLists.txt index e0c9412a4..478f7b9d0 100644 --- a/src/plugins/renderers/opengl/CMakeLists.txt +++ b/src/plugins/renderers/opengl/CMakeLists.txt @@ -15,9 +15,6 @@ set(openGLRendererSources graphicshelpers/graphicscontext.cpp graphicshelpers/gr graphicshelpers/submissioncontext.cpp graphicshelpers/submissioncontext_p.h graphicshelpers/texturesubmissioncontext.cpp graphicshelpers/texturesubmissioncontext_p.h io/glbuffer.cpp io/glbuffer_p.h - jobs/renderviewcommandbuilderjob.cpp jobs/renderviewcommandbuilderjob_p.h - jobs/renderviewcommandupdaterjob.cpp jobs/renderviewcommandupdaterjob_p.h - jobs/renderviewinitializerjob.cpp jobs/renderviewinitializerjob_p.h managers/gl_handle_types_p.h managers/glresourcemanagers.cpp managers/glresourcemanagers_p.h renderer/commandexecuter.cpp renderer/commandexecuter_p.h diff --git a/src/plugins/renderers/opengl/jobs/jobs.pri b/src/plugins/renderers/opengl/jobs/jobs.pri deleted file mode 100644 index 7f6bdd9e0..000000000 --- a/src/plugins/renderers/opengl/jobs/jobs.pri +++ /dev/null @@ -1,11 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/renderviewcommandbuilderjob.cpp \ - $$PWD/renderviewcommandupdaterjob.cpp \ - $$PWD/renderviewinitializerjob.cpp - -HEADERS += \ - $$PWD/renderviewcommandbuilderjob_p.h \ - $$PWD/renderviewcommandupdaterjob_p.h \ - $$PWD/renderviewinitializerjob_p.h diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp deleted file mode 100644 index 973aa7512..000000000 --- a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandbuilderjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace OpenGL { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -class RenderViewCommandBuilderJobPrivate : public Qt3DCore::QAspectJobPrivate -{ -public: - RenderViewCommandBuilderJobPrivate(RenderViewCommandBuilderJob *q) : q_ptr(q) { } - ~RenderViewCommandBuilderJobPrivate() override = default; - - bool isRequired() const override; - void postFrame(Qt3DCore::QAspectManager *manager) override; - - RenderViewCommandBuilderJob *q_ptr; - Q_DECLARE_PUBLIC(RenderViewCommandBuilderJob) -}; - -bool RenderViewCommandBuilderJobPrivate::isRequired() const -{ - return q_ptr->m_renderView && !q_ptr->m_renderView->noDraw() && q_ptr->m_count > 0; -} - -void RenderViewCommandBuilderJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) -{ - Q_UNUSED(manager); - renderViewInstanceCounter = 0; -} - -RenderViewCommandBuilderJob::RenderViewCommandBuilderJob() - : Qt3DCore::QAspectJob(*new RenderViewCommandBuilderJobPrivate(this)) - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) - , m_entities(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, renderViewInstanceCounter++) -} - -void RenderViewCommandBuilderJob::run() -{ - const bool isDraw = !m_renderView->isCompute(); - if (isDraw) - m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count); - else - m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count); -} - - -} // OpenGL - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp deleted file mode 100644 index 2cff31866..000000000 --- a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandupdaterjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <renderer_p.h> -#include <renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace OpenGL { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -class RenderViewCommandUpdaterJobPrivate : public Qt3DCore::QAspectJobPrivate -{ -public: - RenderViewCommandUpdaterJobPrivate(RenderViewCommandUpdaterJob *q) : q_ptr(q) { } - ~RenderViewCommandUpdaterJobPrivate() override = default; - - bool isRequired() const override; - void postFrame(Qt3DCore::QAspectManager *manager) override; - - RenderViewCommandUpdaterJob *q_ptr; - Q_DECLARE_PUBLIC(RenderViewCommandUpdaterJob) -}; - -bool RenderViewCommandUpdaterJobPrivate::isRequired() const -{ - Q_Q(const RenderViewCommandUpdaterJob); - return q->m_renderView && !q->m_renderView->noDraw() && q->m_renderablesSubView.count > 0; -} - -void RenderViewCommandUpdaterJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) -{ - Q_UNUSED(manager); - - // reset to 0 after every frame, stops the number growing indefinitely - renderViewInstanceCounter = 0; -} - -RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob() - : Qt3DCore::QAspectJob(*new RenderViewCommandUpdaterJobPrivate(this)) - , m_renderView(nullptr) - , m_renderer(nullptr) - , m_renderablesSubView() -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++) -} - -void RenderViewCommandUpdaterJob::run() -{ - // Build RenderCommand should perform the culling as we have no way to determine - // if a child has a mesh in the view frustum while its parent isn't contained in it. - if (!m_renderView->noDraw()) { - if (m_renderablesSubView.count == 0) - return; - // Update Render Commands (Uniform Change, Depth Change) - m_renderView->updateRenderCommand(m_renderablesSubView); - } -} - -} // OpenGL - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/opengl/jobs/renderviewinitializerjob.cpp b/src/plugins/renderers/opengl/jobs/renderviewinitializerjob.cpp deleted file mode 100644 index b5eb98d4b..000000000 --- a/src/plugins/renderers/opengl/jobs/renderviewinitializerjob.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** -** -** 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. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewinitializerjob_p.h" - -#include <renderview_p.h> -#include <renderer_p.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/job_common_p.h> - -#include <Qt3DRender/private/cameraselectornode_p.h> -#include <Qt3DRender/private/clearbuffers_p.h> -#include <Qt3DRender/private/layerfilternode_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/effect_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/rendertargetselectornode_p.h> -#include <Qt3DRender/private/sortpolicy_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/viewportnode_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/shaderdata_p.h> -#include <Qt3DRender/private/statesetnode_p.h> -#include <Qt3DRender/private/dispatchcompute_p.h> -#include <Qt3DRender/private/rendersurfaceselector_p.h> -#include <Qt3DRender/private/rendercapture_p.h> -#include <Qt3DRender/private/buffercapture_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/techniquemanager_p.h> -#include <Qt3DRender/private/memorybarrier_p.h> -#include <Qt3DRender/private/blitframebuffer_p.h> -#include <Qt3DRender/private/waitfence_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/rendercapture_p.h> - -#include <QElapsedTimer> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { -namespace OpenGL { - -namespace { -// only accessed in ctor and dtor of RenderViewJob -// which are always being called in a non concurrent manner -int renderViewInstanceCounter = 0; -} // anonymous - - -/*! - \internal - Walks up the framegraph tree from \a fgLeaf and builds up as much state - as possible and populates \a rv. For cases where we can't get the specific state - (e.g. because it depends upon more than just the framegraph) we store the data from - the framegraph that will be needed to later when the rest of the data becomes available -*/ -void RenderViewInitializerJob::setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphNode *fgLeaf) -{ - // The specific RenderPass to be used is also dependent upon the Effect and TechniqueFilter - // which is referenced by the Material which is referenced by the RenderMesh. So we can - // only store the filter info in the RenderView structure and use it to do the resolving - // when we build the RenderCommand list. - const NodeManagers *manager = rv->nodeManagers(); - const FrameGraphNode *node = fgLeaf; - - while (node) { - FrameGraphNode::FrameGraphNodeType type = node->nodeType(); - if (node->isEnabled()) - switch (type) { - case FrameGraphNode::InvalidNodeType: - // A base FrameGraphNode, can be used for grouping purposes - break; - case FrameGraphNode::CameraSelector: - // Can be set only once and we take camera nearest to the leaf node - if (!rv->renderCameraLens()) { - const CameraSelector *cameraSelector = static_cast<const CameraSelector *>(node); - Entity *camNode = manager->renderNodesManager()->lookupResource(cameraSelector->cameraUuid()); - if (camNode) { - CameraLens *lens = camNode->renderComponent<CameraLens>(); - rv->setRenderCameraEntity(camNode); - if (lens && lens->isEnabled()) { - rv->setRenderCameraLens(lens); - // ViewMatrix and ProjectionMatrix are computed - // later in updateMatrices() - // since at this point the transformation matrices - // may not yet have been updated - } - } - } - break; - - case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree - rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId()); - break; - - case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree - rv->appendProximityFilterId(node->peerId()); - break; - - case FrameGraphNode::RenderPassFilter: - // Can be set once - // TODO: Amalgamate all render pass filters from leaf to root - if (!rv->renderPassFilter()) - rv->setRenderPassFilter(static_cast<const RenderPassFilter *>(node)); - break; - - case FrameGraphNode::RenderTarget: { - // Can be set once and we take render target nearest to the leaf node - const RenderTargetSelector *targetSelector = static_cast<const RenderTargetSelector *>(node); - Qt3DCore::QNodeId renderTargetUid = targetSelector->renderTargetUuid(); - HTarget renderTargetHandle = manager->renderTargetManager()->lookupHandle(renderTargetUid); - - // Add renderTarget Handle and build renderCommand AttachmentPack - if (!rv->renderTargetId()) { - rv->setRenderTargetId(renderTargetUid); - - RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle); - if (renderTarget) - rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs())); - } - break; - } - - case FrameGraphNode::ClearBuffers: { - const ClearBuffers *cbNode = static_cast<const ClearBuffers *>(node); - rv->addClearBuffers(cbNode); - break; - } - - case FrameGraphNode::TechniqueFilter: - // Can be set once - // TODO Amalgamate all technique filters from leaf to root - if (!rv->techniqueFilter()) - rv->setTechniqueFilter(static_cast<const TechniqueFilter *>(node)); - break; - - case FrameGraphNode::Viewport: { - // If the Viewport has already been set in a lower node - // Make it so that the new viewport is actually - // a subregion relative to that of the parent viewport - const ViewportNode *vpNode = static_cast<const ViewportNode *>(node); - rv->setViewport(ViewportNode::computeViewport(rv->viewport(), vpNode)); - rv->setGamma(vpNode->gamma()); - break; - } - - case FrameGraphNode::SortMethod: { - const Render::SortPolicy *sortPolicy = static_cast<const Render::SortPolicy *>(node); - rv->addSortType(sortPolicy->sortTypes()); - break; - } - - case FrameGraphNode::SubtreeEnabler: - // Has no meaning here. SubtreeEnabler was used - // in a prior step to filter the list of RenderViewJobs - break; - - case FrameGraphNode::StateSet: { - const Render::StateSetNode *rStateSet = static_cast<const Render::StateSetNode *>(node); - // Add states from new stateSet we might be missing - // but don' t override existing states (lower StateSetNode always has priority) - if (rStateSet->hasRenderStates()) { - // Create global RenderStateSet for renderView if no stateSet was set before - RenderStateSet *stateSet = rv->getOrCreateStateSet(); - addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); - } - break; - } - - case FrameGraphNode::NoDraw: { - rv->setNoDraw(true); - break; - } - - case FrameGraphNode::FrustumCulling: { - rv->setFrustumCulling(true); - break; - } - - case FrameGraphNode::ComputeDispatch: { - const Render::DispatchCompute *dispatchCompute = static_cast<const Render::DispatchCompute *>(node); - rv->setCompute(true); - rv->setComputeWorkgroups(dispatchCompute->x(), - dispatchCompute->y(), - dispatchCompute->z()); - break; - } - - case FrameGraphNode::Lighting: { - // TODO - break; - } - - case FrameGraphNode::Surface: { - // Use the surface closest to leaf node - if (rv->surface() == nullptr) { - const Render::RenderSurfaceSelector *surfaceSelector - = static_cast<const Render::RenderSurfaceSelector *>(node); - rv->setSurface(surfaceSelector->surface()); - rv->setSurfaceSize(surfaceSelector->renderTargetSize() * surfaceSelector->devicePixelRatio()); - rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); - } - break; - } - - case FrameGraphNode::DebugOverlay: - rv->setShowDebugOverlay(true); - break; - - case FrameGraphNode::RenderCapture: { - auto *renderCapture = const_cast<Render::RenderCapture *>( - static_cast<const Render::RenderCapture *>(node)); - if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { - rv->setRenderCaptureNodeId(renderCapture->peerId()); - rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); - } - break; - } - - case FrameGraphNode::MemoryBarrier: { - const Render::MemoryBarrier *barrier = static_cast<const Render::MemoryBarrier *>(node); - rv->setMemoryBarrier(barrier->waitOperations()|rv->memoryBarrier()); - break; - } - - case FrameGraphNode::BufferCapture: { - auto *bufferCapture = const_cast<Render::BufferCapture *>( - static_cast<const Render::BufferCapture *>(node)); - if (bufferCapture != nullptr) - rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); - break; - } - - case FrameGraphNode::BlitFramebuffer: { - const Render::BlitFramebuffer *blitFramebufferNode = - static_cast<const Render::BlitFramebuffer *>(node); - rv->setHasBlitFramebufferInfo(true); - BlitFramebufferInfo bfbInfo; - bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); - bfbInfo.destinationRenderTargetId = blitFramebufferNode->destinationRenderTargetId(); - bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); - bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); - bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); - bfbInfo.destinationAttachmentPoint = blitFramebufferNode->destinationAttachmentPoint(); - bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); - rv->setBlitFrameBufferInfo(bfbInfo); - break; - } - - case FrameGraphNode::WaitFence: { - const Render::WaitFence *waitFence = static_cast<const Render::WaitFence *>(node); - rv->appendWaitFence(waitFence->data()); - break; - } - - case FrameGraphNode::SetFence: { - rv->appendInsertFenceId(node->peerId()); - break; - } - - case FrameGraphNode::NoPicking: - // Nothing to do RenderView wise for NoPicking - break; - - default: - // Should never get here - qCWarning(Backend) << "Unhandled FrameGraphNode type"; - } - - node = node->parent(); - } -} - -RenderViewInitializerJob::RenderViewInitializerJob() - : m_renderer(nullptr) - , m_fgLeaf(nullptr) - , m_index(0) - , m_renderView(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, renderViewInstanceCounter++) -} - -RenderViewInitializerJob::~RenderViewInitializerJob() -{ - renderViewInstanceCounter--; -} - -void RenderViewInitializerJob::run() -{ - qCDebug(Jobs) << Q_FUNC_INFO << m_index; -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - QElapsedTimer timer; - timer.start(); - qint64 gatherLightsTime; - qint64 buildCommandsTime; -#endif - - // Create a RenderView object - m_renderView = new RenderView; - - // RenderView should allocate heap resources using only the currentFrameAllocator - m_renderView->setRenderer(m_renderer); - - // Populate the renderview's configuration from the framegraph - setRenderViewConfigFromFrameGraphLeafNode(m_renderView, m_fgLeaf); -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - qint64 gatherStateTime = timer.nsecsElapsed(); - timer.restart(); -#endif -} - -} // namespace OpenGL -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/opengl/opengl.pri b/src/plugins/renderers/opengl/opengl.pri index e484383fc..37da69a1f 100644 --- a/src/plugins/renderers/opengl/opengl.pri +++ b/src/plugins/renderers/opengl/opengl.pri @@ -11,7 +11,6 @@ DISTFILES += \ openglrenderer.json include (renderer/renderer.pri) -include (jobs/jobs.pri) include (io/io.pri) include (textures/textures.pri) include (graphicshelpers/graphicshelpers.pri) diff --git a/src/plugins/renderers/opengl/renderer/renderer_p.h b/src/plugins/renderers/opengl/renderer/renderer_p.h index 847609066..a5e52e4e7 100644 --- a/src/plugins/renderers/opengl/renderer/renderer_p.h +++ b/src/plugins/renderers/opengl/renderer/renderer_p.h @@ -70,8 +70,8 @@ #include <Qt3DRender/private/filtercompatibletechniquejob_p.h> #include <Qt3DRender/private/renderqueue_p.h> #include <Qt3DRender/private/renderercache_p.h> +#include <Qt3DRender/private/renderviewinitializerjob_p.h> #include <shaderparameterpack_p.h> -#include <renderviewinitializerjob_p.h> #include <logging_p.h> #include <gl_handle_types_p.h> #include <glfence_p.h> @@ -160,6 +160,7 @@ class SubmissionContext; class RenderCommand; class GLShader; class GLResourceManagers; +class RenderView; class Q_AUTOTEST_EXPORT Renderer : public AbstractRenderer { diff --git a/src/plugins/renderers/opengl/renderer/renderview.cpp b/src/plugins/renderers/opengl/renderer/renderview.cpp index b1918d002..75f48827a 100644 --- a/src/plugins/renderers/opengl/renderer/renderview.cpp +++ b/src/plugins/renderers/opengl/renderer/renderview.cpp @@ -69,6 +69,23 @@ #include <Qt3DRender/private/renderstateset_p.h> #include <Qt3DRender/private/renderviewjobutils_p.h> #include <Qt3DRender/private/uniformblockbuilder_p.h> +#include <Qt3DRender/private/clearbuffers_p.h> +#include <Qt3DRender/private/rendertargetselectornode_p.h> +#include <Qt3DRender/private/sortpolicy_p.h> +#include <Qt3DRender/private/techniquefilternode_p.h> +#include <Qt3DRender/private/managers_p.h> +#include <Qt3DRender/private/shaderdata_p.h> +#include <Qt3DRender/private/statesetnode_p.h> +#include <Qt3DRender/private/dispatchcompute_p.h> +#include <Qt3DRender/private/rendersurfaceselector_p.h> +#include <Qt3DRender/private/rendercapture_p.h> +#include <Qt3DRender/private/buffercapture_p.h> +#include <Qt3DRender/private/techniquemanager_p.h> +#include <Qt3DRender/private/memorybarrier_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> +#include <Qt3DRender/private/waitfence_p.h> +#include <Qt3DRender/private/rendercapture_p.h> + #include <rendercommand_p.h> #include <renderer_p.h> #include <graphicscontext_p.h> @@ -222,6 +239,231 @@ UniformValue RenderView::standardUniformValue(RenderView::StandardUniform standa } } +/*! + \internal + Walks up the framegraph tree from \a fgLeaf and builds up as much state + as possible and populates \a rv. For cases where we can't get the specific state + (e.g. because it depends upon more than just the framegraph) we store the data from + the framegraph that will be needed to later when the rest of the data becomes available +*/ +void RenderView::setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphNode *fgLeaf) +{ + // The specific RenderPass to be used is also dependent upon the Effect and TechniqueFilter + // which is referenced by the Material which is referenced by the RenderMesh. So we can + // only store the filter info in the RenderView structure and use it to do the resolving + // when we build the RenderCommand list. + const NodeManagers *manager = rv->nodeManagers(); + const FrameGraphNode *node = fgLeaf; + + while (node) { + FrameGraphNode::FrameGraphNodeType type = node->nodeType(); + if (node->isEnabled()) + switch (type) { + case FrameGraphNode::InvalidNodeType: + // A base FrameGraphNode, can be used for grouping purposes + break; + case FrameGraphNode::CameraSelector: + // Can be set only once and we take camera nearest to the leaf node + if (!rv->renderCameraLens()) { + const CameraSelector *cameraSelector = static_cast<const CameraSelector *>(node); + Entity *camNode = manager->renderNodesManager()->lookupResource(cameraSelector->cameraUuid()); + if (camNode) { + CameraLens *lens = camNode->renderComponent<CameraLens>(); + rv->setRenderCameraEntity(camNode); + if (lens && lens->isEnabled()) { + rv->setRenderCameraLens(lens); + // ViewMatrix and ProjectionMatrix are computed + // later in updateMatrices() + // since at this point the transformation matrices + // may not yet have been updated + } + } + } + break; + + case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree + rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId()); + break; + + case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree + rv->appendProximityFilterId(node->peerId()); + break; + + case FrameGraphNode::RenderPassFilter: + // Can be set once + // TODO: Amalgamate all render pass filters from leaf to root + if (!rv->renderPassFilter()) + rv->setRenderPassFilter(static_cast<const RenderPassFilter *>(node)); + break; + + case FrameGraphNode::RenderTarget: { + // Can be set once and we take render target nearest to the leaf node + const RenderTargetSelector *targetSelector = static_cast<const RenderTargetSelector *>(node); + Qt3DCore::QNodeId renderTargetUid = targetSelector->renderTargetUuid(); + HTarget renderTargetHandle = manager->renderTargetManager()->lookupHandle(renderTargetUid); + + // Add renderTarget Handle and build renderCommand AttachmentPack + if (!rv->renderTargetId()) { + rv->setRenderTargetId(renderTargetUid); + + RenderTarget *renderTarget = manager->renderTargetManager()->data(renderTargetHandle); + if (renderTarget) + rv->setAttachmentPack(AttachmentPack(renderTarget, manager->attachmentManager(), targetSelector->outputs())); + } + break; + } + + case FrameGraphNode::ClearBuffers: { + const ClearBuffers *cbNode = static_cast<const ClearBuffers *>(node); + rv->addClearBuffers(cbNode); + break; + } + + case FrameGraphNode::TechniqueFilter: + // Can be set once + // TODO Amalgamate all technique filters from leaf to root + if (!rv->techniqueFilter()) + rv->setTechniqueFilter(static_cast<const TechniqueFilter *>(node)); + break; + + case FrameGraphNode::Viewport: { + // If the Viewport has already been set in a lower node + // Make it so that the new viewport is actually + // a subregion relative to that of the parent viewport + const ViewportNode *vpNode = static_cast<const ViewportNode *>(node); + rv->setViewport(ViewportNode::computeViewport(rv->viewport(), vpNode)); + rv->setGamma(vpNode->gamma()); + break; + } + + case FrameGraphNode::SortMethod: { + const Render::SortPolicy *sortPolicy = static_cast<const Render::SortPolicy *>(node); + rv->addSortType(sortPolicy->sortTypes()); + break; + } + + case FrameGraphNode::SubtreeEnabler: + // Has no meaning here. SubtreeEnabler was used + // in a prior step to filter the list of RenderViewJobs + break; + + case FrameGraphNode::StateSet: { + const Render::StateSetNode *rStateSet = static_cast<const Render::StateSetNode *>(node); + // Add states from new stateSet we might be missing + // but don' t override existing states (lower StateSetNode always has priority) + if (rStateSet->hasRenderStates()) { + // Create global RenderStateSet for renderView if no stateSet was set before + RenderStateSet *stateSet = rv->getOrCreateStateSet(); + addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); + } + break; + } + + case FrameGraphNode::NoDraw: { + rv->setNoDraw(true); + break; + } + + case FrameGraphNode::FrustumCulling: { + rv->setFrustumCulling(true); + break; + } + + case FrameGraphNode::ComputeDispatch: { + const Render::DispatchCompute *dispatchCompute = static_cast<const Render::DispatchCompute *>(node); + rv->setCompute(true); + rv->setComputeWorkgroups(dispatchCompute->x(), + dispatchCompute->y(), + dispatchCompute->z()); + break; + } + + case FrameGraphNode::Lighting: { + // TODO + break; + } + + case FrameGraphNode::Surface: { + // Use the surface closest to leaf node + if (rv->surface() == nullptr) { + const Render::RenderSurfaceSelector *surfaceSelector + = static_cast<const Render::RenderSurfaceSelector *>(node); + rv->setSurface(surfaceSelector->surface()); + rv->setSurfaceSize(surfaceSelector->renderTargetSize() * surfaceSelector->devicePixelRatio()); + rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); + } + break; + } + + case FrameGraphNode::DebugOverlay: + rv->setShowDebugOverlay(true); + break; + + case FrameGraphNode::RenderCapture: { + auto *renderCapture = const_cast<Render::RenderCapture *>( + static_cast<const Render::RenderCapture *>(node)); + if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { + rv->setRenderCaptureNodeId(renderCapture->peerId()); + rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); + } + break; + } + + case FrameGraphNode::MemoryBarrier: { + const Render::MemoryBarrier *barrier = static_cast<const Render::MemoryBarrier *>(node); + rv->setMemoryBarrier(barrier->waitOperations()|rv->memoryBarrier()); + break; + } + + case FrameGraphNode::BufferCapture: { + auto *bufferCapture = const_cast<Render::BufferCapture *>( + static_cast<const Render::BufferCapture *>(node)); + if (bufferCapture != nullptr) + rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); + break; + } + + case FrameGraphNode::BlitFramebuffer: { + const Render::BlitFramebuffer *blitFramebufferNode = + static_cast<const Render::BlitFramebuffer *>(node); + rv->setHasBlitFramebufferInfo(true); + BlitFramebufferInfo bfbInfo; + bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); + bfbInfo.destinationRenderTargetId = blitFramebufferNode->destinationRenderTargetId(); + bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); + bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); + bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); + bfbInfo.destinationAttachmentPoint = blitFramebufferNode->destinationAttachmentPoint(); + bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); + rv->setBlitFrameBufferInfo(bfbInfo); + break; + } + + case FrameGraphNode::WaitFence: { + const Render::WaitFence *waitFence = static_cast<const Render::WaitFence *>(node); + rv->appendWaitFence(waitFence->data()); + break; + } + + case FrameGraphNode::SetFence: { + rv->appendInsertFenceId(node->peerId()); + break; + } + + case FrameGraphNode::NoPicking: + // Nothing to do RenderView wise for NoPicking + break; + + default: + // Should never get here + qCWarning(Backend) << "Unhandled FrameGraphNode type"; + } + + node = node->parent(); + } +} + + RenderView::RenderView() { if (Q_UNLIKELY(!wasInitialized.exchange(true))) { diff --git a/src/plugins/renderers/opengl/renderer/renderview_p.h b/src/plugins/renderers/opengl/renderer/renderview_p.h index ef3f5ed0e..34a0526cc 100644 --- a/src/plugins/renderers/opengl/renderer/renderview_p.h +++ b/src/plugins/renderers/opengl/renderer/renderview_p.h @@ -133,6 +133,9 @@ public: QT3D_ALIGNED_MALLOC_AND_FREE() + static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, + const FrameGraphNode *fgLeaf); + // TODO: Add a way to specify a sort predicate for the RenderCommands void sort(); diff --git a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp index 59bb9b817..05db19770 100644 --- a/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp +++ b/src/plugins/renderers/opengl/renderer/renderviewbuilder.cpp @@ -645,9 +645,7 @@ void RenderViewBuilder::prepareJobs() // Estimate the number of jobs to create based on the number of entities m_renderViewCommandUpdaterJobs.reserve(m_optimalParallelJobCount); for (auto i = 0; i < m_optimalParallelJobCount; ++i) { - auto renderViewCommandUpdater = Render::OpenGL::RenderViewCommandUpdaterJobPtr::create(); - renderViewCommandUpdater->setRenderer(m_renderer); - renderViewCommandUpdater->setRebuildFlags(m_rebuildFlags); + auto renderViewCommandUpdater = RenderViewCommandUpdaterJobPtr::create(); m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater); } diff --git a/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h b/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h index 82b52ce57..b7d3ed270 100644 --- a/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h +++ b/src/plugins/renderers/opengl/renderer/renderviewbuilder_p.h @@ -59,8 +59,8 @@ #include <Qt3DRender/private/frustumcullingjob_p.h> #include <Qt3DRender/private/filterproximitydistancejob_p.h> #include <Qt3DRender/private/materialparametergathererjob_p.h> -#include <renderviewcommandbuilderjob_p.h> -#include <renderviewcommandupdaterjob_p.h> +#include <Qt3DRender/private/renderviewcommandbuilderjob_p.h> +#include <Qt3DRender/private/renderviewcommandupdaterjob_p.h> #include <renderview_p.h> QT_BEGIN_NAMESPACE @@ -77,6 +77,10 @@ using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; #define CreateSynchronizerJobPtr(lambda, type) \ SynchronizerJobPtr::create(lambda, type, #type) +using RenderViewCommandBuilderJobPtr = Render::RenderViewCommandBuilderJobPtr<RenderView, RenderCommand>; +using RenderViewCommandUpdaterJobPtr = Render::RenderViewCommandUpdaterJobPtr<RenderView, RenderCommand>; +using RenderViewInitializerJobPtr = Render::RenderViewInitializerJobPtr<RenderView, Renderer>; + class Q_AUTOTEST_EXPORT RenderViewBuilder { public: diff --git a/src/plugins/renderers/rhi/CMakeLists.txt b/src/plugins/renderers/rhi/CMakeLists.txt index 1ac326870..93bca55c3 100644 --- a/src/plugins/renderers/rhi/CMakeLists.txt +++ b/src/plugins/renderers/rhi/CMakeLists.txt @@ -10,9 +10,6 @@ qt_internal_add_plugin(RhiRendererPlugin SOURCES graphicshelpers/submissioncontext.cpp graphicshelpers/submissioncontext_p.h io/rhibuffer.cpp io/rhibuffer_p.h - jobs/renderviewcommandbuilderjob.cpp jobs/renderviewcommandbuilderjob_p.h - jobs/renderviewcommandupdaterjob.cpp jobs/renderviewcommandupdaterjob_p.h - jobs/renderviewinitializerjob.cpp jobs/renderviewinitializerjob_p.h main.cpp managers/rhihandle_types_p.h managers/rhiresourcemanagers.cpp managers/rhiresourcemanagers_p.h diff --git a/src/plugins/renderers/rhi/jobs/jobs.pri b/src/plugins/renderers/rhi/jobs/jobs.pri deleted file mode 100644 index 7f6bdd9e0..000000000 --- a/src/plugins/renderers/rhi/jobs/jobs.pri +++ /dev/null @@ -1,11 +0,0 @@ -INCLUDEPATH += $$PWD - -SOURCES += \ - $$PWD/renderviewcommandbuilderjob.cpp \ - $$PWD/renderviewcommandupdaterjob.cpp \ - $$PWD/renderviewinitializerjob.cpp - -HEADERS += \ - $$PWD/renderviewcommandbuilderjob_p.h \ - $$PWD/renderviewcommandupdaterjob_p.h \ - $$PWD/renderviewinitializerjob_p.h diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp deleted file mode 100644 index aba4ab1f2..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandbuilderjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace Rhi { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -class RenderViewCommandBuilderJobPrivate : public Qt3DCore::QAspectJobPrivate -{ -public: - RenderViewCommandBuilderJobPrivate(RenderViewCommandBuilderJob *q) : q_ptr(q) { } - ~RenderViewCommandBuilderJobPrivate() override = default; - - bool isRequired() const override; - void postFrame(Qt3DCore::QAspectManager *manager) override; - - RenderViewCommandBuilderJob *q_ptr; - Q_DECLARE_PUBLIC(RenderViewCommandBuilderJob) -}; - -bool RenderViewCommandBuilderJobPrivate::isRequired() const -{ - return q_ptr->m_renderView && !q_ptr->m_renderView->noDraw() && q_ptr->m_count > 0; -} - -void RenderViewCommandBuilderJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) -{ - Q_UNUSED(manager); - renderViewInstanceCounter = 0; -} - -RenderViewCommandBuilderJob::RenderViewCommandBuilderJob() - : Qt3DCore::QAspectJob(*new RenderViewCommandBuilderJobPrivate(this)) - , m_offset(0) - , m_count(0) - , m_renderView(nullptr) - , m_entities(nullptr) -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, renderViewInstanceCounter++) -} - -void RenderViewCommandBuilderJob::run() -{ - const bool isDraw = !m_renderView->isCompute(); - if (isDraw) - m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count); - else - m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count); -} - - -} // Rhi - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob_p.h b/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob_p.h deleted file mode 100644 index 21139d964..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandbuilderjob_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDBUILDERJOB_P_H -#define QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDBUILDERJOB_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/renderercache_p.h> -#include <rendercommand_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace Rhi { - -class RenderView; -class RenderViewCommandBuilderJobPrivate; -using EntityRenderCommandData = Render::EntityRenderCommandData<RenderCommand>; - -class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewCommandBuilderJob(); - - inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } - inline void setEntities(const Entity **entities, int offset, int count) - { - m_offset = offset; - m_count = count; - m_entities = entities; - } - inline EntityRenderCommandData &commandData() { return m_commandData; } - - void run() final; - -private: - int m_offset; - int m_count; - RenderView *m_renderView; - const Entity **m_entities; - EntityRenderCommandData m_commandData; - - Q_DECLARE_PRIVATE(RenderViewCommandBuilderJob) -}; - -typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr; - -} // Rhi - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDBUILDERJOB_P_H diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp deleted file mode 100644 index 334b0cc6b..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewcommandupdaterjob_p.h" -#include <Qt3DRender/private/job_common_p.h> -#include <renderer_p.h> -#include <renderview_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace Rhi { - -namespace { -int renderViewInstanceCounter = 0; -} // anonymous - -class RenderViewCommandUpdaterJobPrivate : public Qt3DCore::QAspectJobPrivate -{ -public: - RenderViewCommandUpdaterJobPrivate(RenderViewCommandUpdaterJob *q) : q_ptr(q) { } - ~RenderViewCommandUpdaterJobPrivate() override = default; - - bool isRequired() const override; - void postFrame(Qt3DCore::QAspectManager *manager) override; - - RenderViewCommandUpdaterJob *q_ptr; - Q_DECLARE_PUBLIC(RenderViewCommandUpdaterJob) -}; - -bool RenderViewCommandUpdaterJobPrivate::isRequired() const -{ - Q_Q(const RenderViewCommandUpdaterJob); - return q->m_renderView && !q->m_renderView->noDraw() && q->m_renderablesSubView.count > 0; -} - -void RenderViewCommandUpdaterJobPrivate::postFrame(Qt3DCore::QAspectManager *manager) -{ - Q_UNUSED(manager); - - // reset to 0 after every frame, stops the number growing indefinitely - renderViewInstanceCounter = 0; -} - -RenderViewCommandUpdaterJob::RenderViewCommandUpdaterJob() - : Qt3DCore::QAspectJob(*new RenderViewCommandUpdaterJobPrivate(this)) - , m_renderView(nullptr) - , m_renderer(nullptr) - , m_renderablesSubView() -{ - SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++) -} - -void RenderViewCommandUpdaterJob::run() -{ - // Build RenderCommand should perform the culling as we have no way to determine - // if a child has a mesh in the view frustum while its parent isn't contained in it. - if (!m_renderView->noDraw()) { - if (m_renderablesSubView.count == 0) - return; - // Update Render Commands (Uniform Change, Depth Change) - m_renderView->updateRenderCommand(m_renderablesSubView); - } -} - -} // Rhi - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h b/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h deleted file mode 100644 index 82c5bed03..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewcommandupdaterjob_p.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDUPDATEJOB_P_H -#define QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDUPDATEJOB_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DRender/private/handle_types_p.h> -#include <Qt3DRender/private/renderercache_p.h> -#include <rendercommand_p.h> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -namespace Rhi { - -class RenderView; -class Renderer; -class RenderViewCommandUpdaterJobPrivate; - -using EntityRenderCommandDataSubView = Render::EntityRenderCommandDataSubView<RenderCommand>; - -class Q_AUTOTEST_EXPORT RenderViewCommandUpdaterJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewCommandUpdaterJob(); - - inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } - inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; } - inline void setRenderablesSubView(const EntityRenderCommandDataSubView &renderablesSubView) Q_DECL_NOTHROW - { - m_renderablesSubView = renderablesSubView; - } - EntityRenderCommandDataSubView renderablesSubView() const { return m_renderablesSubView; } - - inline void setRebuildFlags(RebuildFlagSet rebuildFlags) { m_rebuildFlags = rebuildFlags; } - void run() final; - -private: - RebuildFlagSet m_rebuildFlags; - RenderView *m_renderView; - Renderer *m_renderer; - EntityRenderCommandDataSubView m_renderablesSubView; - - Q_DECLARE_PRIVATE(RenderViewCommandUpdaterJob) -}; - -typedef QSharedPointer<RenderViewCommandUpdaterJob> RenderViewCommandUpdaterJobPtr; - -} // Rhi - -} // Render - -} // Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RHI_RENDERVIEWCOMMANDUPDATEJOB_P_H diff --git a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp deleted file mode 100644 index 1332cd1bd..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob.cpp +++ /dev/null @@ -1,362 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 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. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderviewinitializerjob_p.h" - -#include <renderview_p.h> -#include <renderer_p.h> -#include <Qt3DRender/private/renderviewjobutils_p.h> -#include <Qt3DRender/private/renderlogging_p.h> -#include <Qt3DRender/private/job_common_p.h> - -#include <Qt3DRender/private/cameraselectornode_p.h> -#include <Qt3DRender/private/clearbuffers_p.h> -#include <Qt3DRender/private/layerfilternode_p.h> -#include <Qt3DRender/private/nodemanagers_p.h> -#include <Qt3DRender/private/effect_p.h> -#include <Qt3DRender/private/renderpassfilternode_p.h> -#include <Qt3DRender/private/rendertargetselectornode_p.h> -#include <Qt3DRender/private/sortpolicy_p.h> -#include <Qt3DRender/private/techniquefilternode_p.h> -#include <Qt3DRender/private/viewportnode_p.h> -#include <Qt3DRender/private/managers_p.h> -#include <Qt3DRender/private/shaderdata_p.h> -#include <Qt3DRender/private/statesetnode_p.h> -#include <Qt3DRender/private/dispatchcompute_p.h> -#include <Qt3DRender/private/rendersurfaceselector_p.h> -#include <Qt3DRender/private/rendercapture_p.h> -#include <Qt3DRender/private/buffercapture_p.h> -#include <Qt3DRender/private/stringtoint_p.h> -#include <Qt3DRender/private/techniquemanager_p.h> -#include <Qt3DRender/private/memorybarrier_p.h> -#include <Qt3DRender/private/blitframebuffer_p.h> -#include <Qt3DRender/private/waitfence_p.h> -#include <Qt3DRender/private/renderstateset_p.h> -#include <Qt3DRender/private/rendercapture_p.h> - -#include <QElapsedTimer> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { -namespace Render { -namespace Rhi { - -namespace { -// only accessed in ctor and dtor of RenderViewJob -// which are always being called in a non concurrent manner -int renderViewInstanceCounter = 0; -} // anonymous - -/*! - \internal - Walks up the framegraph tree from \a fgLeaf and builds up as much state - as possible and populates \a rv. For cases where we can't get the specific state - (e.g. because it depends upon more than just the framegraph) we store the data from - the framegraph that will be needed to later when the rest of the data becomes available -*/ -void RenderViewInitializerJob::setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphNode *fgLeaf) -{ - // The specific RenderPass to be used is also dependent upon the Effect and TechniqueFilter - // which is referenced by the Material which is referenced by the RenderMesh. So we can - // only store the filter info in the RenderView structure and use it to do the resolving - // when we build the RenderCommand list. - const NodeManagers *manager = rv->nodeManagers(); - const FrameGraphNode *node = fgLeaf; - - while (node) { - FrameGraphNode::FrameGraphNodeType type = node->nodeType(); - if (node->isEnabled()) - switch (type) { - case FrameGraphNode::InvalidNodeType: - // A base FrameGraphNode, can be used for grouping purposes - break; - case FrameGraphNode::CameraSelector: - // Can be set only once and we take camera nearest to the leaf node - if (!rv->renderCameraLens()) { - const CameraSelector *cameraSelector = - static_cast<const CameraSelector *>(node); - Entity *camNode = manager->renderNodesManager()->lookupResource( - cameraSelector->cameraUuid()); - if (camNode) { - CameraLens *lens = camNode->renderComponent<CameraLens>(); - rv->setRenderCameraEntity(camNode); - if (lens && lens->isEnabled()) { - rv->setRenderCameraLens(lens); - // ViewMatrix and ProjectionMatrix are computed - // later in updateMatrices() - // since at this point the transformation matrices - // may not yet have been updated - } - } - } - break; - - case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree - rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId()); - break; - - case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree - rv->appendProximityFilterId(node->peerId()); - break; - - case FrameGraphNode::RenderPassFilter: - // Can be set once - // TODO: Amalgamate all render pass filters from leaf to root - if (!rv->renderPassFilter()) - rv->setRenderPassFilter(static_cast<const RenderPassFilter *>(node)); - break; - - case FrameGraphNode::RenderTarget: { - // Can be set once and we take render target nearest to the leaf node - const RenderTargetSelector *targetSelector = - static_cast<const RenderTargetSelector *>(node); - Qt3DCore::QNodeId renderTargetUid = targetSelector->renderTargetUuid(); - HTarget renderTargetHandle = - manager->renderTargetManager()->lookupHandle(renderTargetUid); - - // Add renderTarget Handle and build renderCommand AttachmentPack - if (!rv->renderTargetId()) { - rv->setRenderTargetId(renderTargetUid); - - RenderTarget *renderTarget = - manager->renderTargetManager()->data(renderTargetHandle); - if (renderTarget) - rv->setAttachmentPack(AttachmentPack(renderTarget, - manager->attachmentManager(), - targetSelector->outputs())); - } - break; - } - - case FrameGraphNode::ClearBuffers: { - const ClearBuffers *cbNode = static_cast<const ClearBuffers *>(node); - rv->addClearBuffers(cbNode); - break; - } - - case FrameGraphNode::TechniqueFilter: - // Can be set once - // TODO Amalgamate all technique filters from leaf to root - if (!rv->techniqueFilter()) - rv->setTechniqueFilter(static_cast<const TechniqueFilter *>(node)); - break; - - case FrameGraphNode::Viewport: { - // If the Viewport has already been set in a lower node - // Make it so that the new viewport is actually - // a subregion relative to that of the parent viewport - const ViewportNode *vpNode = static_cast<const ViewportNode *>(node); - rv->setViewport(ViewportNode::computeViewport(rv->viewport(), vpNode)); - rv->setGamma(vpNode->gamma()); - break; - } - - case FrameGraphNode::SortMethod: { - const Render::SortPolicy *sortPolicy = - static_cast<const Render::SortPolicy *>(node); - rv->addSortType(sortPolicy->sortTypes()); - break; - } - - case FrameGraphNode::SubtreeEnabler: - // Has no meaning here. SubtreeEnabler was used - // in a prior step to filter the list of RenderViewJobs - break; - - case FrameGraphNode::StateSet: { - const Render::StateSetNode *rStateSet = static_cast<const Render::StateSetNode *>(node); - // Add states from new stateSet we might be missing - // but don' t override existing states (lower StateSetNode always has priority) - if (rStateSet->hasRenderStates()) { - // Create global RenderStateSet for renderView if no stateSet was set before - RenderStateSet *stateSet = rv->getOrCreateStateSet(); - addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); - } - break; - } - - case FrameGraphNode::NoDraw: { - rv->setNoDraw(true); - break; - } - - case FrameGraphNode::FrustumCulling: { - rv->setFrustumCulling(true); - break; - } - - case FrameGraphNode::ComputeDispatch: { - const Render::DispatchCompute *dispatchCompute = - static_cast<const Render::DispatchCompute *>(node); - rv->setCompute(true); - rv->setComputeWorkgroups(dispatchCompute->x(), dispatchCompute->y(), - dispatchCompute->z()); - break; - } - - case FrameGraphNode::Lighting: { - // TODO - break; - } - - case FrameGraphNode::Surface: { - // Use the surface closest to leaf node - if (rv->surface() == nullptr) { - const Render::RenderSurfaceSelector *surfaceSelector = - static_cast<const Render::RenderSurfaceSelector *>(node); - rv->setSurface(surfaceSelector->surface()); - rv->setSurfaceSize(surfaceSelector->renderTargetSize() - * surfaceSelector->devicePixelRatio()); - rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); - } - break; - } - case FrameGraphNode::RenderCapture: { - auto *renderCapture = const_cast<Render::RenderCapture *>( - static_cast<const Render::RenderCapture *>(node)); - if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { - rv->setRenderCaptureNodeId(renderCapture->peerId()); - rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); - } - break; - } - - case FrameGraphNode::MemoryBarrier: { - // Not available in rhi - break; - } - - case FrameGraphNode::BufferCapture: { - auto *bufferCapture = const_cast<Render::BufferCapture *>( - static_cast<const Render::BufferCapture *>(node)); - if (bufferCapture != nullptr) - rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); - break; - } - - case FrameGraphNode::BlitFramebuffer: { - const Render::BlitFramebuffer *blitFramebufferNode = - static_cast<const Render::BlitFramebuffer *>(node); - rv->setHasBlitFramebufferInfo(true); - BlitFramebufferInfo bfbInfo; - bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); - bfbInfo.destinationRenderTargetId = - blitFramebufferNode->destinationRenderTargetId(); - bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); - bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); - bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); - bfbInfo.destinationAttachmentPoint = - blitFramebufferNode->destinationAttachmentPoint(); - bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); - rv->setBlitFrameBufferInfo(bfbInfo); - break; - } - - case FrameGraphNode::WaitFence: { - // Not available in rhi - break; - } - - case FrameGraphNode::SetFence: { - // Not available in rhi - break; - } - - case FrameGraphNode::NoPicking: - // Nothing to do RenderView wise for NoPicking - break; - - case FrameGraphNode::DebugOverlay: - // Not supported yet with RHI - break; - - default: - // Should never get here - qCWarning(Backend) << "Unhandled FrameGraphNode type"; - } - - node = node->parent(); - } -} - - -RenderViewInitializerJob::RenderViewInitializerJob() - : m_renderer(nullptr), - m_fgLeaf(nullptr), - m_index(0), - m_renderView(nullptr) { SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, - renderViewInstanceCounter++) } - - RenderViewInitializerJob::~RenderViewInitializerJob() -{ - renderViewInstanceCounter--; -} - -void RenderViewInitializerJob::run() -{ - qCDebug(Jobs) << Q_FUNC_INFO << m_index; -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - QElapsedTimer timer; - timer.start(); - qint64 gatherLightsTime; - qint64 buildCommandsTime; -#endif - - // Create a RenderView object - // The RenderView are created from a QFrameAllocator stored in the current Thread local storage - m_renderView = new RenderView; - - // RenderView should allocate heap resources using only the currentFrameAllocator - m_renderView->setRenderer(m_renderer); - - // Populate the renderview's configuration from the framegraph - setRenderViewConfigFromFrameGraphLeafNode(m_renderView, m_fgLeaf); -#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) - qint64 gatherStateTime = timer.nsecsElapsed(); - timer.restart(); -#endif -} - -} // namespace Rhi -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE diff --git a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h b/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h deleted file mode 100644 index 5dfe1ab30..000000000 --- a/src/plugins/renderers/rhi/jobs/renderviewinitializerjob_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Paul Lemire -** Copyright (C) 2020 Klaralvdalens Datakonsult AB (KDAB). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt3D module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT3DRENDER_RENDER_RHI_RENDERVIEWINITIALIZERJOB_H -#define QT3DRENDER_RENDER_RHI_RENDERVIEWINITIALIZERJOB_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <Qt3DCore/qaspectjob.h> -#include <Qt3DCore/private/qframeallocator_p.h> -#include <QSize> - -QT_BEGIN_NAMESPACE - -namespace Qt3DRender { - -namespace Render { - -class FrameGraphNode; - -namespace Rhi { - -class Renderer; -class RenderView; - -class Q_AUTOTEST_EXPORT RenderViewInitializerJob : public Qt3DCore::QAspectJob -{ -public: - RenderViewInitializerJob(); - ~RenderViewInitializerJob(); - - static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, - const FrameGraphNode *fgLeaf); - - inline void setRenderer(Renderer *renderer) { m_renderer = renderer; } - inline RenderView *renderView() const Q_DECL_NOTHROW { return m_renderView; } - - inline void setFrameGraphLeafNode(FrameGraphNode *fgLeaf) { m_fgLeaf = fgLeaf; } - - // Sets the position in the queue of RenderViews that the - // RenderView generated by this job should be inserted. This is - // used to ensure that for example a RenderView for creating - // a shadow map texture is submitted before the RenderView that - // contains commands making use of the shadow map - inline void setSubmitOrderIndex(int index) { m_index = index; } - inline int submitOrderIndex() const { return m_index; } - - void run() override; - -private: - Renderer *m_renderer; - FrameGraphNode *m_fgLeaf; - int m_index; - RenderView *m_renderView; -}; - -typedef QSharedPointer<RenderViewInitializerJob> RenderViewInitializerJobPtr; - -} // namespace Rhi -} // namespace Render -} // namespace Qt3DRender - -QT_END_NAMESPACE - -#endif // QT3DRENDER_RENDER_RHI_RENDERVIEWINITIALIZERJOB_H diff --git a/src/plugins/renderers/rhi/renderer/renderer_p.h b/src/plugins/renderers/rhi/renderer/renderer_p.h index 4e1780f56..d5c432b30 100644 --- a/src/plugins/renderers/rhi/renderer/renderer_p.h +++ b/src/plugins/renderers/rhi/renderer/renderer_p.h @@ -71,11 +71,11 @@ #include <Qt3DRender/private/filtercompatibletechniquejob_p.h> #include <Qt3DRender/private/renderqueue_p.h> #include <Qt3DRender/private/renderercache_p.h> +#include <Qt3DRender/private/renderviewinitializerjob_p.h> #include <QtGui/private/qrhi_p.h> #include <shaderparameterpack_p.h> -#include <renderviewinitializerjob_p.h> #include <logging_p.h> #include <rhihandle_types_p.h> #include <renderview_p.h> @@ -157,6 +157,7 @@ class RenderCommand; struct RHIRenderTarget; class RHIShader; class RHIResourceManagers; +class RenderView; class Q_AUTOTEST_EXPORT Renderer : public AbstractRenderer { diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp index 3094b7c54..7c8b795f0 100644 --- a/src/plugins/renderers/rhi/renderer/renderview.cpp +++ b/src/plugins/renderers/rhi/renderer/renderview.cpp @@ -68,6 +68,21 @@ #include <Qt3DRender/private/renderlogging_p.h> #include <Qt3DRender/private/renderstateset_p.h> #include <Qt3DRender/private/uniformblockbuilder_p.h> +#include <Qt3DRender/private/clearbuffers_p.h> +#include <Qt3DRender/private/rendertargetselectornode_p.h> +#include <Qt3DRender/private/sortpolicy_p.h> +#include <Qt3DRender/private/techniquefilternode_p.h> +#include <Qt3DRender/private/managers_p.h> +#include <Qt3DRender/private/shaderdata_p.h> +#include <Qt3DRender/private/statesetnode_p.h> +#include <Qt3DRender/private/dispatchcompute_p.h> +#include <Qt3DRender/private/rendersurfaceselector_p.h> +#include <Qt3DRender/private/rendercapture_p.h> +#include <Qt3DRender/private/buffercapture_p.h> +#include <Qt3DRender/private/techniquemanager_p.h> +#include <Qt3DRender/private/blitframebuffer_p.h> +#include <Qt3DRender/private/rendercapture_p.h> + #include <rendercommand_p.h> #include <renderer_p.h> #include <submissioncontext_p.h> @@ -141,6 +156,238 @@ static Matrix4x4 getProjectionMatrix(const CameraLens *lens, bool yIsUp) } } +/*! + \internal + Walks up the framegraph tree from \a fgLeaf and builds up as much state + as possible and populates \a rv. For cases where we can't get the specific state + (e.g. because it depends upon more than just the framegraph) we store the data from + the framegraph that will be needed to later when the rest of the data becomes available +*/ +void RenderView::setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphNode *fgLeaf) +{ + // The specific RenderPass to be used is also dependent upon the Effect and TechniqueFilter + // which is referenced by the Material which is referenced by the RenderMesh. So we can + // only store the filter info in the RenderView structure and use it to do the resolving + // when we build the RenderCommand list. + const NodeManagers *manager = rv->nodeManagers(); + const FrameGraphNode *node = fgLeaf; + + while (node) { + FrameGraphNode::FrameGraphNodeType type = node->nodeType(); + if (node->isEnabled()) + switch (type) { + case FrameGraphNode::InvalidNodeType: + // A base FrameGraphNode, can be used for grouping purposes + break; + case FrameGraphNode::CameraSelector: + // Can be set only once and we take camera nearest to the leaf node + if (!rv->renderCameraLens()) { + const CameraSelector *cameraSelector = + static_cast<const CameraSelector *>(node); + Entity *camNode = manager->renderNodesManager()->lookupResource( + cameraSelector->cameraUuid()); + if (camNode) { + CameraLens *lens = camNode->renderComponent<CameraLens>(); + rv->setRenderCameraEntity(camNode); + if (lens && lens->isEnabled()) { + rv->setRenderCameraLens(lens); + // ViewMatrix and ProjectionMatrix are computed + // later in updateMatrices() + // since at this point the transformation matrices + // may not yet have been updated + } + } + } + break; + + case FrameGraphNode::LayerFilter: // Can be set multiple times in the tree + rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId()); + break; + + case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree + rv->appendProximityFilterId(node->peerId()); + break; + + case FrameGraphNode::RenderPassFilter: + // Can be set once + // TODO: Amalgamate all render pass filters from leaf to root + if (!rv->renderPassFilter()) + rv->setRenderPassFilter(static_cast<const RenderPassFilter *>(node)); + break; + + case FrameGraphNode::RenderTarget: { + // Can be set once and we take render target nearest to the leaf node + const RenderTargetSelector *targetSelector = + static_cast<const RenderTargetSelector *>(node); + Qt3DCore::QNodeId renderTargetUid = targetSelector->renderTargetUuid(); + HTarget renderTargetHandle = + manager->renderTargetManager()->lookupHandle(renderTargetUid); + + // Add renderTarget Handle and build renderCommand AttachmentPack + if (!rv->renderTargetId()) { + rv->setRenderTargetId(renderTargetUid); + + RenderTarget *renderTarget = + manager->renderTargetManager()->data(renderTargetHandle); + if (renderTarget) + rv->setAttachmentPack(AttachmentPack(renderTarget, + manager->attachmentManager(), + targetSelector->outputs())); + } + break; + } + + case FrameGraphNode::ClearBuffers: { + const ClearBuffers *cbNode = static_cast<const ClearBuffers *>(node); + rv->addClearBuffers(cbNode); + break; + } + + case FrameGraphNode::TechniqueFilter: + // Can be set once + // TODO Amalgamate all technique filters from leaf to root + if (!rv->techniqueFilter()) + rv->setTechniqueFilter(static_cast<const TechniqueFilter *>(node)); + break; + + case FrameGraphNode::Viewport: { + // If the Viewport has already been set in a lower node + // Make it so that the new viewport is actually + // a subregion relative to that of the parent viewport + const ViewportNode *vpNode = static_cast<const ViewportNode *>(node); + rv->setViewport(ViewportNode::computeViewport(rv->viewport(), vpNode)); + rv->setGamma(vpNode->gamma()); + break; + } + + case FrameGraphNode::SortMethod: { + const Render::SortPolicy *sortPolicy = + static_cast<const Render::SortPolicy *>(node); + rv->addSortType(sortPolicy->sortTypes()); + break; + } + + case FrameGraphNode::SubtreeEnabler: + // Has no meaning here. SubtreeEnabler was used + // in a prior step to filter the list of RenderViewJobs + break; + + case FrameGraphNode::StateSet: { + const Render::StateSetNode *rStateSet = static_cast<const Render::StateSetNode *>(node); + // Add states from new stateSet we might be missing + // but don' t override existing states (lower StateSetNode always has priority) + if (rStateSet->hasRenderStates()) { + // Create global RenderStateSet for renderView if no stateSet was set before + RenderStateSet *stateSet = rv->getOrCreateStateSet(); + addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); + } + break; + } + + case FrameGraphNode::NoDraw: { + rv->setNoDraw(true); + break; + } + + case FrameGraphNode::FrustumCulling: { + rv->setFrustumCulling(true); + break; + } + + case FrameGraphNode::ComputeDispatch: { + const Render::DispatchCompute *dispatchCompute = + static_cast<const Render::DispatchCompute *>(node); + rv->setCompute(true); + rv->setComputeWorkgroups(dispatchCompute->x(), dispatchCompute->y(), + dispatchCompute->z()); + break; + } + + case FrameGraphNode::Lighting: { + // TODO + break; + } + + case FrameGraphNode::Surface: { + // Use the surface closest to leaf node + if (rv->surface() == nullptr) { + const Render::RenderSurfaceSelector *surfaceSelector = + static_cast<const Render::RenderSurfaceSelector *>(node); + rv->setSurface(surfaceSelector->surface()); + rv->setSurfaceSize(surfaceSelector->renderTargetSize() + * surfaceSelector->devicePixelRatio()); + rv->setDevicePixelRatio(surfaceSelector->devicePixelRatio()); + } + break; + } + case FrameGraphNode::RenderCapture: { + auto *renderCapture = const_cast<Render::RenderCapture *>( + static_cast<const Render::RenderCapture *>(node)); + if (rv->renderCaptureNodeId().isNull() && renderCapture->wasCaptureRequested()) { + rv->setRenderCaptureNodeId(renderCapture->peerId()); + rv->setRenderCaptureRequest(renderCapture->takeCaptureRequest()); + } + break; + } + + case FrameGraphNode::MemoryBarrier: { + // Not available in rhi + break; + } + + case FrameGraphNode::BufferCapture: { + auto *bufferCapture = const_cast<Render::BufferCapture *>( + static_cast<const Render::BufferCapture *>(node)); + if (bufferCapture != nullptr) + rv->setIsDownloadBuffersEnable(bufferCapture->isEnabled()); + break; + } + + case FrameGraphNode::BlitFramebuffer: { + const Render::BlitFramebuffer *blitFramebufferNode = + static_cast<const Render::BlitFramebuffer *>(node); + rv->setHasBlitFramebufferInfo(true); + BlitFramebufferInfo bfbInfo; + bfbInfo.sourceRenderTargetId = blitFramebufferNode->sourceRenderTargetId(); + bfbInfo.destinationRenderTargetId = + blitFramebufferNode->destinationRenderTargetId(); + bfbInfo.sourceRect = blitFramebufferNode->sourceRect(); + bfbInfo.destinationRect = blitFramebufferNode->destinationRect(); + bfbInfo.sourceAttachmentPoint = blitFramebufferNode->sourceAttachmentPoint(); + bfbInfo.destinationAttachmentPoint = + blitFramebufferNode->destinationAttachmentPoint(); + bfbInfo.interpolationMethod = blitFramebufferNode->interpolationMethod(); + rv->setBlitFrameBufferInfo(bfbInfo); + break; + } + + case FrameGraphNode::WaitFence: { + // Not available in rhi + break; + } + + case FrameGraphNode::SetFence: { + // Not available in rhi + break; + } + + case FrameGraphNode::NoPicking: + // Nothing to do RenderView wise for NoPicking + break; + + case FrameGraphNode::DebugOverlay: + // Not supported yet with RHI + break; + + default: + // Should never get here + qCWarning(Backend) << "Unhandled FrameGraphNode type"; + } + + node = node->parent(); + } +} + RenderView::RenderView() { if (Q_UNLIKELY(!wasInitialized.exchange(true))) { diff --git a/src/plugins/renderers/rhi/renderer/renderview_p.h b/src/plugins/renderers/rhi/renderer/renderview_p.h index 12f1b29ae..558992c4f 100644 --- a/src/plugins/renderers/rhi/renderer/renderview_p.h +++ b/src/plugins/renderers/rhi/renderer/renderview_p.h @@ -155,6 +155,9 @@ public: QT3D_ALIGNED_MALLOC_AND_FREE() + static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, + const FrameGraphNode *fgLeaf); + // TODO: Add a way to specify a sort predicate for the RenderCommands void sort(); diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp index 84d3e91f1..7040a3b08 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder.cpp @@ -644,9 +644,7 @@ void RenderViewBuilder::prepareJobs() // Estimate the number of jobs to create based on the number of entities m_renderViewCommandUpdaterJobs.reserve(m_optimalParallelJobCount); for (auto i = 0; i < m_optimalParallelJobCount; ++i) { - auto renderViewCommandUpdater = Render::Rhi::RenderViewCommandUpdaterJobPtr::create(); - renderViewCommandUpdater->setRenderer(m_renderer); - renderViewCommandUpdater->setRebuildFlags(m_rebuildFlags); + auto renderViewCommandUpdater = RenderViewCommandUpdaterJobPtr::create(); m_renderViewCommandUpdaterJobs.push_back(renderViewCommandUpdater); } diff --git a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h index 9b769c0fb..db1d1b897 100644 --- a/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h +++ b/src/plugins/renderers/rhi/renderer/renderviewbuilder_p.h @@ -59,8 +59,8 @@ #include <Qt3DRender/private/frustumcullingjob_p.h> #include <Qt3DRender/private/filterproximitydistancejob_p.h> #include <Qt3DRender/private/materialparametergathererjob_p.h> -#include <renderviewcommandbuilderjob_p.h> -#include <renderviewcommandupdaterjob_p.h> +#include <Qt3DRender/private/renderviewcommandbuilderjob_p.h> +#include <Qt3DRender/private/renderviewcommandupdaterjob_p.h> #include <renderview_p.h> QT_BEGIN_NAMESPACE @@ -77,6 +77,10 @@ using SynchronizerJobPtr = GenericLambdaJobPtr<std::function<void()>>; #define CreateSynchronizerJobPtr(lambda, type) \ SynchronizerJobPtr::create(lambda, type, #type) +using RenderViewCommandBuilderJobPtr = Render::RenderViewCommandBuilderJobPtr<RenderView, RenderCommand>; +using RenderViewCommandUpdaterJobPtr = Render::RenderViewCommandUpdaterJobPtr<RenderView, RenderCommand>; +using RenderViewInitializerJobPtr = Render::RenderViewInitializerJobPtr<RenderView, Renderer>; + class Q_AUTOTEST_EXPORT RenderViewBuilder { public: diff --git a/src/plugins/renderers/rhi/rhi.pri b/src/plugins/renderers/rhi/rhi.pri index 8ae4a11af..5fdb77c00 100644 --- a/src/plugins/renderers/rhi/rhi.pri +++ b/src/plugins/renderers/rhi/rhi.pri @@ -1,6 +1,5 @@ include (renderer/renderer.pri) -include (jobs/jobs.pri) include (io/io.pri) include (textures/textures.pri) include (graphicshelpers/graphicshelpers.pri) diff --git a/src/render/CMakeLists.txt b/src/render/CMakeLists.txt index e0703b656..4a509645b 100644 --- a/src/render/CMakeLists.txt +++ b/src/render/CMakeLists.txt @@ -167,6 +167,9 @@ qt_add_module(3DRender jobs/uniformblockbuilder.cpp jobs/uniformblockbuilder_p.h jobs/renderqueue_p.h jobs/renderercache_p.h + jobs/renderviewcommandbuilderjob_p.h + jobs/renderviewcommandupdaterjob_p.h + jobs/renderviewinitializerjob_p.h lights/environmentlight.cpp lights/environmentlight_p.h lights/light.cpp lights/light_p.h lights/lightsource.cpp lights/lightsource_p.h diff --git a/src/render/jobs/jobs.pri b/src/render/jobs/jobs.pri index 31abdf42d..20dc9d1f9 100644 --- a/src/render/jobs/jobs.pri +++ b/src/render/jobs/jobs.pri @@ -28,11 +28,14 @@ HEADERS += \ $$PWD/raycastingjob_p.h \ $$PWD/updateentitylayersjob_p.h \ $$PWD/filtercompatibletechniquejob_p.h \ - $$PWD/jobs/materialparametergathererjob_p.h \ + $$PWD/materialparametergathererjob_p.h \ $$PWD/renderviewjobutils_p.h \ $$PWD/uniformblockbuilder_p.h \ $$PWD/renderqueue_p.h \ - $$PWD/renderercache_p.h + $$PWD/renderercache_p.h \ + $$PWD/renderviewcommandbuilderjob_p.h \ + $$PWD/renderviewcommandupdaterjob_p.h \ + $$PWD/renderviewinitializerjob_p.h SOURCES += \ $$PWD/updateworldtransformjob.cpp \ @@ -63,3 +66,4 @@ SOURCES += \ $$PWD/renderviewjobutils.cpp \ $$PWD/uniformblockbuilder.cpp + diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h b/src/render/jobs/renderviewcommandbuilderjob_p.h index 8645f7827..4d235c98e 100644 --- a/src/plugins/renderers/opengl/jobs/renderviewcommandbuilderjob_p.h +++ b/src/render/jobs/renderviewcommandbuilderjob_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H -#define QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H +#ifndef QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H +#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H // // W A R N I N G @@ -54,7 +54,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/renderercache_p.h> -#include <rendercommand_p.h> +#include <Qt3DRender/private/job_common_p.h> QT_BEGIN_NAMESPACE @@ -62,16 +62,14 @@ namespace Qt3DRender { namespace Render { -namespace OpenGL { - -class RenderView; -class RenderViewCommandBuilderJobPrivate; -using EntityRenderCommandData = Render::EntityRenderCommandData<RenderCommand>; - -class Q_AUTOTEST_EXPORT RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob +template<class RenderView, class RenderCommand> +class RenderViewCommandBuilderJob : public Qt3DCore::QAspectJob { public: - RenderViewCommandBuilderJob(); + RenderViewCommandBuilderJob() + { + SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderViewCommandBuilder, RenderViewCommandBuilderJob::renderViewInstanceCounter++) + } inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } inline void setEntities(const Entity **entities, int offset, int count) @@ -80,23 +78,42 @@ public: m_count = count; m_entities = entities; } - inline EntityRenderCommandData &commandData() { return m_commandData; } + inline EntityRenderCommandData<RenderCommand> &commandData() { return m_commandData; } - void run() final; + void run() final + { + const bool isDraw = !m_renderView->isCompute(); + if (isDraw) + m_commandData = m_renderView->buildDrawRenderCommands(m_entities, m_offset, m_count); + else + m_commandData = m_renderView->buildComputeRenderCommands(m_entities, m_offset, m_count); + } -private: - int m_offset; - int m_count; - RenderView *m_renderView; - const Entity **m_entities; - EntityRenderCommandData m_commandData; + bool isRequired() override + { + return m_renderView && !m_renderView->noDraw() && m_count > 0; + } + + void postFrame(Qt3DCore::QAspectEngine *engine) override + { + Q_UNUSED(engine); + RenderViewCommandBuilderJob::renderViewInstanceCounter = 0; + } - Q_DECLARE_PRIVATE(RenderViewCommandBuilderJob) +private: + RenderView *m_renderView = nullptr; + const Entity **m_entities = nullptr; + EntityRenderCommandData<RenderCommand> m_commandData; + int m_offset = 0; + int m_count = 0; + static int renderViewInstanceCounter; }; -typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobPtr; +template<class RenderView, class RenderCommand> +int RenderViewCommandBuilderJob<RenderView, RenderCommand>::renderViewInstanceCounter = 0; -} // OpenGL +template<class RenderView, class RenderCommand> +using RenderViewCommandBuilderJobPtr = QSharedPointer<RenderViewCommandBuilderJob<RenderView, RenderCommand>>; } // Render @@ -104,4 +121,4 @@ typedef QSharedPointer<RenderViewCommandBuilderJob> RenderViewCommandBuilderJobP QT_END_NAMESPACE -#endif // QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDBUILDERJOB_P_H +#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDBUILDERJOB_P_H diff --git a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h b/src/render/jobs/renderviewcommandupdaterjob_p.h index 5032b3146..b97ad4d5a 100644 --- a/src/plugins/renderers/opengl/jobs/renderviewcommandupdaterjob_p.h +++ b/src/render/jobs/renderviewcommandupdaterjob_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDUPDATEJOB_P_H -#define QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDUPDATEJOB_P_H +#ifndef QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H +#define QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H // // W A R N I N G @@ -54,7 +54,7 @@ #include <Qt3DCore/qaspectjob.h> #include <Qt3DRender/private/handle_types_p.h> #include <Qt3DRender/private/renderercache_p.h> -#include <rendercommand_p.h> +#include <Qt3DRender/private/job_common_p.h> QT_BEGIN_NAMESPACE @@ -62,41 +62,62 @@ namespace Qt3DRender { namespace Render { -namespace OpenGL { - -class RenderView; -class Renderer; -class RenderViewCommandUpdaterJobPrivate; -using EntityRenderCommandDataSubView = Render::EntityRenderCommandDataSubView<RenderCommand>; - -class Q_AUTOTEST_EXPORT RenderViewCommandUpdaterJob : public Qt3DCore::QAspectJob +template<class RenderView, class RenderCommand> +class RenderViewCommandUpdaterJob : public Qt3DCore::QAspectJob { public: - RenderViewCommandUpdaterJob(); + RenderViewCommandUpdaterJob() + : Qt3DCore::QAspectJob() + { + SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderCommandUpdater, renderViewInstanceCounter++) + } + + ~RenderViewCommandUpdaterJob() + { + } inline void setRenderView(RenderView *rv) Q_DECL_NOTHROW { m_renderView = rv; } - inline void setRenderer(Renderer *renderer) Q_DECL_NOTHROW { m_renderer = renderer; } - inline void setRenderablesSubView(const EntityRenderCommandDataSubView &renderablesSubView) Q_DECL_NOTHROW + inline void setRenderablesSubView(const EntityRenderCommandDataSubView<RenderCommand> &renderablesSubView) Q_DECL_NOTHROW { m_renderablesSubView = renderablesSubView; } - EntityRenderCommandDataSubView renderablesSubView() const { return m_renderablesSubView; } + EntityRenderCommandDataSubView<RenderCommand> renderablesSubView() const { return m_renderablesSubView; } + + void run() final + { + // Build RenderCommand should perform the culling as we have no way to determine + // if a child has a mesh in the view frustum while its parent isn't contained in it. + if (!m_renderView->noDraw()) { + if (m_renderablesSubView.count == 0) + return; + // Update Render Commands (Uniform Change, Depth Change) + m_renderView->updateRenderCommand(m_renderablesSubView); + } + } + + void postFrame(Qt3DCore::QAspectEngine *aspectEngine) override + { + Q_UNUSED(aspectEngine); + // reset to 0 after every frame, stops the number growing indefinitely + renderViewInstanceCounter = 0; + } - inline void setRebuildFlags(RebuildFlagSet rebuildFlags) { m_rebuildFlags = rebuildFlags; } - void run() final; + bool isRequired() override + { + return m_renderView && !m_renderView->noDraw() && m_renderablesSubView.count > 0; + } private: - RebuildFlagSet m_rebuildFlags; - RenderView *m_renderView; - Renderer *m_renderer; - EntityRenderCommandDataSubView m_renderablesSubView; - - Q_DECLARE_PRIVATE(RenderViewCommandUpdaterJob) + RenderView *m_renderView = nullptr; + EntityRenderCommandDataSubView<RenderCommand> m_renderablesSubView; + static int renderViewInstanceCounter; }; -typedef QSharedPointer<RenderViewCommandUpdaterJob> RenderViewCommandUpdaterJobPtr; +template<class RenderView, class RenderCommand> +int RenderViewCommandUpdaterJob<RenderView, RenderCommand>::renderViewInstanceCounter = 0; -} // OpenGL +template<class RenderView, class RenderCommand> +using RenderViewCommandUpdaterJobPtr = QSharedPointer<RenderViewCommandUpdaterJob<RenderView, RenderCommand>>; } // Render @@ -104,4 +125,4 @@ typedef QSharedPointer<RenderViewCommandUpdaterJob> RenderViewCommandUpdaterJobP QT_END_NAMESPACE -#endif // QT3DRENDER_RENDER_OPENGL_RENDERVIEWCOMMANDUPDATEJOB_P_H +#endif // QT3DRENDER_RENDER_RENDERVIEWCOMMANDUPDATEJOB_P_H diff --git a/src/plugins/renderers/opengl/jobs/renderviewinitializerjob_p.h b/src/render/jobs/renderviewinitializerjob_p.h index f6ae13525..4c307dc3e 100644 --- a/src/plugins/renderers/opengl/jobs/renderviewinitializerjob_p.h +++ b/src/render/jobs/renderviewinitializerjob_p.h @@ -38,8 +38,8 @@ ** ****************************************************************************/ -#ifndef QT3DRENDER_RENDER_OPENGL_RENDERVIEWINITIALIZERJOB_H -#define QT3DRENDER_RENDER_OPENGL_RENDERVIEWINITIALIZERJOB_H +#ifndef QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H +#define QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H // // W A R N I N G @@ -53,7 +53,10 @@ // #include <Qt3DCore/qaspectjob.h> +#include <Qt3DRender/private/renderlogging_p.h> +#include <Qt3DRender/private/job_common_p.h> #include <QSize> +#include <QElapsedTimer> QT_BEGIN_NAMESPACE @@ -63,19 +66,19 @@ namespace Render { class FrameGraphNode; -namespace OpenGL { - -class Renderer; -class RenderView; - -class Q_AUTOTEST_EXPORT RenderViewInitializerJob : public Qt3DCore::QAspectJob +template<class RenderView, class Renderer> +class RenderViewInitializerJob : public Qt3DCore::QAspectJob { public: - RenderViewInitializerJob(); - ~RenderViewInitializerJob(); - - static void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, - const FrameGraphNode *fgLeaf); + RenderViewInitializerJob() + : Qt3DCore::QAspectJob() + { + SET_JOB_RUN_STAT_TYPE(this, JobTypes::RenderView, RenderViewInitializerJob::renderViewInstanceCounter++) + } + ~RenderViewInitializerJob() + { + RenderViewInitializerJob::renderViewInstanceCounter--; + } inline void setRenderer(Renderer *renderer) { m_renderer = renderer; } inline RenderView *renderView() const Q_DECL_NOTHROW { return m_renderView; } @@ -93,21 +96,47 @@ public: inline void setSubmitOrderIndex(int index) { m_index = index; } inline int submitOrderIndex() const { return m_index; } - void run() override; + void run() override + { +#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) + QElapsedTimer timer; + timer.start(); + qint64 gatherLightsTime; + qint64 buildCommandsTime; +#endif + + // Create a RenderView object + m_renderView = new RenderView; + + // RenderView should allocate heap resources using only the currentFrameAllocator + m_renderView->setRenderer(m_renderer); + + // Populate the renderview's configuration from the framegraph + RenderView::setRenderViewConfigFromFrameGraphLeafNode(m_renderView, m_fgLeaf); +#if defined(QT3D_RENDER_VIEW_JOB_TIMINGS) + qint64 gatherStateTime = timer.nsecsElapsed(); + timer.restart(); +#endif + } private: - Renderer *m_renderer; - FrameGraphNode *m_fgLeaf; - int m_index; - RenderView *m_renderView; + Renderer *m_renderer = nullptr; + FrameGraphNode *m_fgLeaf = nullptr; + RenderView *m_renderView = nullptr; + int m_index = 0; + + static int renderViewInstanceCounter; }; -typedef QSharedPointer<RenderViewInitializerJob> RenderViewInitializerJobPtr; +template<class RenderView, class Renderer> +int RenderViewInitializerJob<RenderView, Renderer>::renderViewInstanceCounter = 0; + +template<class RenderView, class Renderer> +using RenderViewInitializerJobPtr = QSharedPointer<RenderViewInitializerJob<RenderView, Renderer>>; -} // namespace OpenGL } // namespace Render } // namespace Qt3DRender QT_END_NAMESPACE -#endif // QT3DRENDER_RENDER_OPENGL_RENDERVIEWINITIALIZERJOB_H +#endif // QT3DRENDER_RENDER_RENDERVIEWINITIALIZERJOB_H |