diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-05-01 16:31:33 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2015-05-12 10:29:55 +0000 |
commit | 3b39eaac6ac3385908dd09c3d12d1b2ae71c8a9f (patch) | |
tree | 3f2297907f4f9b91746ba06c2a072a3b952b9449 | |
parent | 32bcfa372a1669daa261b2b7573bf3cb3aa5b4f9 (diff) |
Renderer: properly merge global stateset with per renderpass stateset
When a RenderPass stateset overriddes the global stateset set by the current
FrameGraph branch at render time, this is done by merging the global
stateset with the RenderPass defined stateset.
Change-Id: I07baca0d50b1c02cf1298b382039aedabd6084cc
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r-- | src/render/backend/renderer.cpp | 6 | ||||
-rw-r--r-- | src/render/backend/renderstate.cpp | 5 | ||||
-rw-r--r-- | src/render/backend/renderstate_p.h | 2 | ||||
-rw-r--r-- | src/render/backend/renderview.cpp | 11 |
4 files changed, 19 insertions, 5 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp index 213598b6b..f11f0e2df 100644 --- a/src/render/backend/renderer.cpp +++ b/src/render/backend/renderer.cpp @@ -523,6 +523,7 @@ void Renderer::enqueueRenderView(Render::RenderView *renderView, int submitOrder { // qDebug() << Q_FUNC_INFO << QThread::currentThread(); m_renderQueues->queueRenderView(renderView, submitOrder); + if (m_renderQueues->isFrameQueueComplete()) { // We can increment the currentProcessingFrameIndex here // That index will then be used by RenderViewJobs to know which QFrameAllocator to use @@ -765,6 +766,7 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands) //// Draw Calls // Set state + RenderStateSet *globalState = m_graphicsContext->currentStateSet(); if (command->m_stateSet != Q_NULLPTR) m_graphicsContext->setCurrentStateSet(command->m_stateSet); @@ -791,6 +793,10 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands) m_graphicsContext->drawArrays(primType, 0, primCount); } + // Reset state if overridden by pass state + if (command->m_stateSet != Q_NULLPTR) + m_graphicsContext->setCurrentStateSet(globalState); + int err = m_graphicsContext->openGLContext()->functions()->glGetError(); if (err) qCWarning(Rendering) << "GL error after drawing mesh:" << QString::number(err, 16); diff --git a/src/render/backend/renderstate.cpp b/src/render/backend/renderstate.cpp index 99981dcca..c92601d6e 100644 --- a/src/render/backend/renderstate.cpp +++ b/src/render/backend/renderstate.cpp @@ -151,6 +151,11 @@ StateMaskSet RenderStateSet::stateMask() const return m_stateMask; } +void RenderStateSet::merge(RenderStateSet *other) +{ + m_stateMask |= other->stateMask(); +} + void RenderStateSet::resetMasked(StateMaskSet maskOfStatesToReset, QGraphicsContext *gc) { // TO DO -> Call gcHelper methods instead of raw GL diff --git a/src/render/backend/renderstate_p.h b/src/render/backend/renderstate_p.h index b0f5d6de7..231c1b534 100644 --- a/src/render/backend/renderstate_p.h +++ b/src/render/backend/renderstate_p.h @@ -102,7 +102,7 @@ public: void apply(QGraphicsContext* gc); StateMaskSet stateMask() const; - + void merge(RenderStateSet *other); void resetMasked(StateMaskSet maskOfStatesToReset, QGraphicsContext* gc); private: /** diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index 71108d76a..20f2f7cfa 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -418,19 +418,22 @@ void RenderView::buildRenderCommands(RenderEntity *node) command->m_depth = m_data->m_eyePos.distanceToPoint(node->worldBoundingVolume()->center()); command->m_meshData = mesh->meshDataHandle(); command->m_instancesCount = 0; - - // TODO: Build the state set for a render pass only once per-pass. Not once per rendercommand and pass. command->m_stateSet = Q_NULLPTR; command->m_changeCost = 0; // For RenderPass based states we use the globally set RenderState // if no renderstates are defined as part of the pass. That means: // RenderPass { renderStates: [] } will use the states defined by // StateSet in the FrameGraph - if (!pass->renderStates().isEmpty()) { + if (!pass->renderStates().isEmpty()) command->m_stateSet = buildRenderStateSet(pass->renderStates(), m_allocator); + if (command->m_stateSet != Q_NULLPTR) { + // Merge per pass stateset with global stateset + // so that the local stateset only overrides + if (m_stateSet != Q_NULLPTR) + command->m_stateSet->merge(m_stateSet); command->m_changeCost = m_renderer->defaultRenderState()->changeCost(command->m_stateSet); } - setShaderAndUniforms(command, pass, globalParameter, *(node->worldTransform())); + setShaderAndUniforms(command, pass, parameters, *(node->worldTransform())); buildSortingKey(command); m_commands.append(command); } |