From dbd7c517e4d49fb05457a7fe290f7c4e48cdb9cf Mon Sep 17 00:00:00 2001 From: Harald Vistnes Date: Tue, 20 Aug 2019 19:22:25 +0200 Subject: Allow multiple instances of a few render states Allow more than one instance of BlendEquationArgumentsMask and ClipPlaneMask render states. Task-number: QTBUG-77735 Change-Id: I9d2bdc82843e2eaf0f8a781208e4ca10e3a777c7 Reviewed-by: Mike Krus Reviewed-by: Paul Lemire --- src/render/renderers/opengl/jobs/renderviewjobutils.cpp | 10 +++++----- src/render/renderers/opengl/jobs/renderviewjobutils_p.h | 6 +++--- src/render/renderers/opengl/renderer/renderview.cpp | 4 ++-- .../renderers/opengl/renderstates/renderstateset.cpp | 15 +++++++++++++-- .../renderers/opengl/renderstates/renderstateset_p.h | 8 ++++++-- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp index 49e85e1d3..364a04ed3 100644 --- a/src/render/renderers/opengl/jobs/renderviewjobutils.cpp +++ b/src/render/renderers/opengl/jobs/renderviewjobutils.cpp @@ -196,7 +196,7 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN // Add states from new stateSet we might be missing // but don' t override existing states (lower StateSetNode always has priority) if (rStateSet->hasRenderStates()) - addUniqueStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); + addStatesToRenderStateSet(stateSet, rStateSet->renderStates(), manager->renderStateManager()); break; } @@ -420,13 +420,13 @@ void parametersFromMaterialEffectTechnique(ParameterInfoList *infoList, } // Only add states with types we don't already have -void addUniqueStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector stateIds, - RenderStateManager *manager) +void addStatesToRenderStateSet(RenderStateSet *stateSet, + const QVector stateIds, + RenderStateManager *manager) { for (const Qt3DCore::QNodeId &stateId : stateIds) { RenderStateNode *node = manager->lookupResource(stateId); - if (node->isEnabled() && !stateSet->hasStateOfType(node->type())) { + if (node->isEnabled() && stateSet->canAddStateOfType(node->type())) { stateSet->addState(node->impl()); } } diff --git a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h b/src/render/renderers/opengl/jobs/renderviewjobutils_p.h index bd2e12534..b2fa59785 100644 --- a/src/render/renderers/opengl/jobs/renderviewjobutils_p.h +++ b/src/render/renderers/opengl/jobs/renderviewjobutils_p.h @@ -150,9 +150,9 @@ void parametersFromParametersProvider(ParameterInfoList *infoList, Q_AUTOTEST_EXPORT ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *infoList, const int nameId); -Q_AUTOTEST_EXPORT void addUniqueStatesToRenderStateSet(RenderStateSet *stateSet, - const QVector stateIds, - RenderStateManager *manager); +Q_AUTOTEST_EXPORT void addStatesToRenderStateSet(RenderStateSet *stateSet, + const QVector stateIds, + RenderStateManager *manager); typedef QHash UniformBlockValueBuilderHash; diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index 62758bb53..09099ee02 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -603,7 +603,7 @@ QVector RenderView::buildDrawRenderCommands(const QVectorhasRenderStates()) { command->m_stateSet = new RenderStateSet(); - addUniqueStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager()); + addStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager()); if (m_stateSet != nullptr) command->m_stateSet->merge(m_stateSet); command->m_changeCost = m_renderer->defaultRenderState()->changeCost(command->m_stateSet); @@ -723,7 +723,7 @@ QVector RenderView::buildComputeRenderCommands(const QVectorhasRenderStates()) { command->m_stateSet = new RenderStateSet(); - addUniqueStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager()); + addStatesToRenderStateSet(command->m_stateSet, pass->renderStates(), m_manager->renderStateManager()); // Merge per pass stateset with global stateset // so that the local stateset only overrides diff --git a/src/render/renderers/opengl/renderstates/renderstateset.cpp b/src/render/renderers/opengl/renderstates/renderstateset.cpp index b14695c77..d667d9c76 100644 --- a/src/render/renderers/opengl/renderstates/renderstateset.cpp +++ b/src/render/renderers/opengl/renderstates/renderstateset.cpp @@ -112,17 +112,28 @@ void RenderStateSet::merge(RenderStateSet *other) // We only add states which are new (different type) for (const StateVariant &otherState : otherStates) { - const bool hasFoundStateOfSameType = hasStateOfType(otherState.type); - if (!hasFoundStateOfSameType) + const bool canAdd = canAddStateOfType(otherState.type); + if (canAdd) m_states.push_back(otherState); } } +bool RenderStateSet::canAddStateOfType(StateMask type) const +{ + return !hasStateOfType(type) || allowMultipleStatesOfType(type); +} + bool RenderStateSet::hasStateOfType(StateMask type) const { return (type & stateMask()); } +bool RenderStateSet::allowMultipleStatesOfType(StateMask type) const +{ + return (type == BlendEquationArgumentsMask) || + (type == ClipPlaneMask); +} + bool RenderStateSet::contains(const StateVariant &ds) const { // trivial reject using the state mask bits diff --git a/src/render/renderers/opengl/renderstates/renderstateset_p.h b/src/render/renderers/opengl/renderstates/renderstateset_p.h index 29be4d2f1..c2f3a0219 100644 --- a/src/render/renderers/opengl/renderstates/renderstateset_p.h +++ b/src/render/renderers/opengl/renderstates/renderstateset_p.h @@ -93,8 +93,7 @@ public: QVector states() const { return m_states; } - bool hasStateOfType(StateMask type) const; - + bool canAddStateOfType(StateMask type) const; /** * @brief contains - check if this set contains a matching piece of state @@ -102,6 +101,11 @@ public: * @return */ bool contains(const StateVariant &ds) const; + +private: + bool hasStateOfType(StateMask type) const; + bool allowMultipleStatesOfType(StateMask type) const; + private: StateMaskSet m_stateMask; QVector m_states; -- cgit v1.2.3