summaryrefslogtreecommitdiffstats
path: root/src/render/backend/rendershaderdata.cpp
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire.ecortex@kdab.com>2014-11-20 14:27:52 +0100
committerSean Harmer <sean.harmer@kdab.com>2014-12-12 14:17:04 +0100
commitaf6f95dd538f06736349ad42305814177aa81d92 (patch)
tree457052cd541807b9f0c28516feaae7f6e49c8d86 /src/render/backend/rendershaderdata.cpp
parent9dd1b0c993873772e2719844be71f86bc0c92a02 (diff)
RenderShaderData completed to build UBO
Contains a UniformBuffer internally. Once initialized created UBO on the GPU. When properties of the QShaderData are updated, updated data is uploaded to the UBO. Some room for improvement, we'll improve that once the whole UBO/QShaderData architecture is in place. Change-Id: I26e55b78ad9633f75b988d8976ba496a7c7738fc Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/backend/rendershaderdata.cpp')
-rw-r--r--src/render/backend/rendershaderdata.cpp52
1 files changed, 51 insertions, 1 deletions
diff --git a/src/render/backend/rendershaderdata.cpp b/src/render/backend/rendershaderdata.cpp
index 7d73977fe..4617caf2a 100644
--- a/src/render/backend/rendershaderdata.cpp
+++ b/src/render/backend/rendershaderdata.cpp
@@ -44,6 +44,7 @@
#include <QMetaProperty>
#include <QMetaObject>
#include <Qt3DCore/qscenepropertychange.h>
+#include <private/qgraphicscontext_p.h>
QT_BEGIN_NAMESPACE
@@ -53,6 +54,8 @@ namespace Render {
RenderShaderData::RenderShaderData()
: QBackendNode()
+ , m_initialized(false)
+ , m_needsBufferUpdate(true)
{
}
@@ -72,12 +75,59 @@ void RenderShaderData::updateFromPeer(QNode *peer)
}
}
+void RenderShaderData::initialize(const ShaderUniformBlock &block)
+{
+ m_block = block;
+ Q_ASSERT(m_block.m_size > 0);
+ // Allocate CPU side buffer
+ m_data = QByteArray(m_block.m_size, 0);
+ m_initialized = true;
+ // Force UBO buffer to be allocated on the GPU when apply is called
+ m_needsBufferUpdate = true;
+}
+
+void RenderShaderData::appendActiveProperty(const char *propertyName, const ShaderUniform &description)
+{
+ m_activeProperties.insert(propertyName, description);
+}
+
+void RenderShaderData::updateUniformBuffer(QGraphicsContext *ctx)
+{
+ if (!m_ubo.isCreated()) {
+ m_ubo.create(ctx);
+ m_ubo.allocate(ctx, m_block.m_size);
+ }
+
+ // TO DO: Only update values that have changed rather than the whole buffer
+ QHash<const char *, ShaderUniform>::const_iterator uniformsIt = m_activeProperties.begin();
+ const QHash<const char *, ShaderUniform>::const_iterator uniformsEnd = m_activeProperties.end();
+
+ while (uniformsIt != uniformsEnd) {
+ ctx->buildUniformBuffer(m_properties.value(uniformsIt.key()), uniformsIt.value(), m_data);
+ ++uniformsIt;
+ }
+ m_ubo.update(ctx, m_data.constData(), m_block.m_size);
+}
+
+// Make sure QGraphicsContext::bindUniformBlock is called prior to this
+void RenderShaderData::apply(QGraphicsContext *ctx, int bindingPoint)
+{
+ // Upload new data to GPU if it has changed
+ if (m_needsBufferUpdate) {
+ updateUniformBuffer(ctx);
+ m_needsBufferUpdate = false;
+ }
+ m_ubo.bindToUniformBlock(ctx, bindingPoint);
+}
+
void RenderShaderData::sceneChangeEvent(const QSceneChangePtr &e)
{
if (e->type() == NodeUpdated) {
QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e);
- if (m_properties.contains(propertyChange->propertyName()))
+ if (m_properties.contains(propertyChange->propertyName())) {
m_properties.insert(propertyChange->propertyName(), propertyChange->value());
+ m_needsBufferUpdate = true;
+ }
}
}