summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2015-05-01 16:31:33 +0200
committerPaul Lemire <paul.lemire@kdab.com>2015-05-12 10:29:55 +0000
commit3b39eaac6ac3385908dd09c3d12d1b2ae71c8a9f (patch)
tree3f2297907f4f9b91746ba06c2a072a3b952b9449
parent32bcfa372a1669daa261b2b7573bf3cb3aa5b4f9 (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.cpp6
-rw-r--r--src/render/backend/renderstate.cpp5
-rw-r--r--src/render/backend/renderstate_p.h2
-rw-r--r--src/render/backend/renderview.cpp11
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);
}