summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/qt3d/instanced-arrays-qml/main.qml4
-rw-r--r--src/render/backend/quniformvalue.cpp5
-rw-r--r--src/render/backend/quniformvalue_p.h11
-rw-r--r--src/render/backend/rendercommand_p.h2
-rw-r--r--src/render/backend/renderer.cpp4
-rw-r--r--src/render/backend/renderview.cpp140
-rw-r--r--src/render/backend/renderview_p.h4
-rw-r--r--src/render/geometry/qbuffer.h4
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp120
-rw-r--r--src/render/graphicshelpers/graphicscontext_p.h3
-rw-r--r--src/render/graphicshelpers/graphicshelperes2.cpp8
-rw-r--r--src/render/graphicshelpers/graphicshelperes2_p.h1
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2.cpp8
-rw-r--r--src/render/graphicshelpers/graphicshelpergl2_p.h1
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3.cpp8
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3.cpp8
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_3_p.h1
-rw-r--r--src/render/graphicshelpers/graphicshelpergl3_p.h1
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4.cpp5
-rw-r--r--src/render/graphicshelpers/graphicshelpergl4_p.h1
-rw-r--r--src/render/graphicshelpers/graphicshelperinterface_p.h1
-rw-r--r--src/render/io/glbuffer.cpp7
-rw-r--r--src/render/io/glbuffer_p.h3
23 files changed, 233 insertions, 117 deletions
diff --git a/examples/qt3d/instanced-arrays-qml/main.qml b/examples/qt3d/instanced-arrays-qml/main.qml
index 476da0bd6..c10201396 100644
--- a/examples/qt3d/instanced-arrays-qml/main.qml
+++ b/examples/qt3d/instanced-arrays-qml/main.qml
@@ -140,8 +140,8 @@ Entity {
Attribute {
id: instanceDataAttribute
name: "pos"
- attributeType: AbstractAttribute.VertexAttribute
- dataType: AbstractAttribute.Float
+ attributeType: Attribute.VertexAttribute
+ dataType: Attribute.Float
dataSize: 3
divisor: 1
buffer: _instanceBuffer
diff --git a/src/render/backend/quniformvalue.cpp b/src/render/backend/quniformvalue.cpp
index 511720ea1..eb5c9a682 100644
--- a/src/render/backend/quniformvalue.cpp
+++ b/src/render/backend/quniformvalue.cpp
@@ -108,6 +108,11 @@ void ShaderParameterPack::setUniformBuffer(const BlockToUBO &blockToUBO)
m_uniformBuffers.append(blockToUBO);
}
+void ShaderParameterPack::setShaderStorageBuffer(const BlockToSSBO &blockToSSBO)
+{
+ m_shaderStorageBuffers.push_back(blockToSSBO);
+}
+
void TextureUniform::apply(GraphicsContext *ctx, const ShaderUniform &description) const
{
// We assume that the texture has been successfully bound and attache to a texture unit
diff --git a/src/render/backend/quniformvalue_p.h b/src/render/backend/quniformvalue_p.h
index 35a9cca0f..6d8681edf 100644
--- a/src/render/backend/quniformvalue_p.h
+++ b/src/render/backend/quniformvalue_p.h
@@ -137,11 +137,16 @@ private:
struct BlockToUBO {
int m_blockIndex;
- Qt3DCore::QNodeId m_shaderDataID;
+ Qt3DCore::QNodeId m_bufferID;
bool m_needsUpdate;
QHash<QString, QVariant> m_updatedProperties;
};
+struct BlockToSSBO {
+ int m_blockIndex;
+ Qt3DCore::QNodeId m_bufferID;
+};
+
class ShaderParameterPack
{
public:
@@ -150,6 +155,7 @@ public:
void setUniform(const QString &glslName, const QUniformValue *val);
void setTexture(const QString &glslName, const Qt3DCore::QNodeId &id);
void setUniformBuffer(const BlockToUBO &blockToUBO);
+ void setShaderStorageBuffer(const BlockToSSBO &blockToSSBO);
inline const QHash<QString, const QUniformValue* > &uniforms() const { return m_uniforms; }
const QUniformValue *uniform(const QString &glslName) const { return m_uniforms.value(glslName); }
@@ -168,12 +174,13 @@ public:
inline QVector<NamedTexture> textures() const { return m_textures; }
inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; }
-
+ inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; }
private:
QHash<QString, const QUniformValue* > m_uniforms;
QVector<NamedTexture> m_textures;
QVector<BlockToUBO> m_uniformBuffers;
+ QVector<BlockToSSBO> m_shaderStorageBuffers;
friend class RenderView;
};
diff --git a/src/render/backend/rendercommand_p.h b/src/render/backend/rendercommand_p.h
index 6813a6ad7..52afd8da9 100644
--- a/src/render/backend/rendercommand_p.h
+++ b/src/render/backend/rendercommand_p.h
@@ -73,7 +73,7 @@ public:
HVao m_vao; // VAO used during the submission step to store all states and VBOs
HShader m_shader; // Shader for given pass and mesh
- ShaderParameterPack m_uniforms; // Might need to be reworked so as to be able to destroy the
+ ShaderParameterPack m_parameterPack; // Might need to be reworked so as to be able to destroy the
// Texture while submission is happening.
GLint m_instancesCount; // Number of instances of the mesh, if 0 regular draw otherwise glDrawArraysInstanced or glDrawElementsInstanced
RenderStateSet *m_stateSet;
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 98110061d..8140eb7c6 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -809,7 +809,7 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands)
if (shader == Q_NULLPTR) {
shader = m_defaultRenderShader;
command->m_parameterAttributeToShaderNames = m_defaultParameterToGLSLAttributeNames;
- command->m_uniforms = m_defaultUniformPack;
+ command->m_parameterPack = m_defaultUniformPack;
}
// The VAO should be created only once for a QGeometry and a ShaderProgram
@@ -868,7 +868,7 @@ void Renderer::executeCommands(const QVector<RenderCommand *> &commands)
}
//// Update program uniforms
- m_graphicsContext->setUniforms(command->m_uniforms);
+ m_graphicsContext->setParameters(command->m_parameterPack);
//// Bind SSBO Buffers
// Note: how does that behave regarding VAO
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 44b7ca1a3..93802754c 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -60,6 +60,7 @@
#include <Qt3DRender/private/renderstateset_p.h>
#include <Qt3DRender/private/techniquefilternode_p.h>
#include <Qt3DRender/private/viewportnode_p.h>
+#include <Qt3DRender/private/buffermanager_p.h>
#include <Qt3DRender/qparametermapping.h>
@@ -291,7 +292,7 @@ RenderView::~RenderView()
Q_FOREACH (RenderCommand *command, m_commands) {
// Deallocate all uniform values of the QUniformPack of each RenderCommand
- const QHash<QString, const QUniformValue* > uniforms = command->m_uniforms.uniforms();
+ const QHash<QString, const QUniformValue* > uniforms = command->m_parameterPack.uniforms();
const QHash<QString, const QUniformValue* >::const_iterator end = uniforms.constEnd();
QHash<QString, const QUniformValue* >::const_iterator it = uniforms.constBegin();
@@ -352,10 +353,10 @@ void RenderView::sort()
++i;
if (i - j > 0) { // Several commands have the same shader, so we minimize uniform changes
- QHash<QString, const QUniformValue *> cachedUniforms = m_commands[j++]->m_uniforms.uniforms();
+ QHash<QString, const QUniformValue *> cachedUniforms = m_commands[j++]->m_parameterPack.uniforms();
while (j < i) {
- QHash<QString, const QUniformValue *> &uniforms = m_commands[j]->m_uniforms.m_uniforms;
+ QHash<QString, const QUniformValue *> &uniforms = m_commands[j]->m_parameterPack.m_uniforms;
QHash<QString, const QUniformValue *>::iterator it = uniforms.begin();
while (it != uniforms.end()) {
@@ -608,12 +609,27 @@ void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, const
uniformPack.setUniform(glslName, (this->*ms_standardUniformSetters[name])(worldTransform));
}
-void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderUniformBlock &block, const QVariant &value)
+void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
+ Shader *shader,
+ const ShaderUniformBlock &block,
+ const QVariant &value)
{
- ShaderData *shaderData = Q_NULLPTR;
+ Q_UNUSED(shader)
- if (static_cast<QMetaType::Type>(value.type()) == qNodeIdTypeId &&
- (shaderData = m_manager->shaderDataManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) {
+ if (static_cast<QMetaType::Type>(value.type()) == qNodeIdTypeId) {
+
+ Buffer *buffer = Q_NULLPTR;
+ if ((buffer = m_manager->bufferManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) {
+ BlockToUBO uniformBlockUBO;
+ uniformBlockUBO.m_blockIndex = block.m_index;
+ uniformBlockUBO.m_bufferID = buffer->peerUuid();
+ uniformPack.setUniformBuffer(uniformBlockUBO);
+ // Buffer update to GL buffer will be done at render time
+ }
+
+
+ //ShaderData *shaderData = Q_NULLPTR;
+ // if ((shaderData = m_manager->shaderDataManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) {
// UBO are indexed by <ShaderId, ShaderDataId> so that a same QShaderData can be used among different shaders
// while still making sure that if they have a different layout everything will still work
// If two shaders define the same block with the exact same layout, in that case the UBO could be shared
@@ -659,6 +675,25 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, Shader *
// uniformBlockUBO.m_needsUpdate = uboNeedsUpdate;
// uniformPack.setUniformBuffer(uniformBlockUBO);
+ // }
+ }
+}
+
+void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
+ Shader *shader,
+ const ShaderStorageBlock &block,
+ const QVariant &value)
+{
+ Q_UNUSED(shader)
+ if (static_cast<QMetaType::Type>(value.type()) == qNodeIdTypeId) {
+ Buffer *buffer = Q_NULLPTR;
+ if ((buffer = m_manager->bufferManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) {
+ BlockToSSBO shaderStorageBlock;
+ shaderStorageBlock.m_blockIndex = block.m_index;
+ shaderStorageBlock.m_bufferID = buffer->peerUuid();
+ uniformPack.setShaderStorageBuffer(shaderStorageBlock);
+ // Buffer update to GL buffer will be done at render time
+ }
}
}
@@ -755,7 +790,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
// Set default standard uniforms without bindings
Q_FOREACH (const QString &uniformName, uniformNames) {
if (ms_standardUniformSetters.contains(uniformName))
- setStandardUniformValue(command->m_uniforms, uniformName, uniformName, worldTransform);
+ setStandardUniformValue(command->m_parameterPack, uniformName, uniformName, worldTransform);
}
// Set default attributes
@@ -767,23 +802,46 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
// Set uniforms and attributes explicitly binded
Q_FOREACH (const ParameterMapping &binding, rPass->bindings()) {
ParameterInfoList::iterator it = findParamInfo(&parameters, binding.parameterName());
+
if (it == parameters.end()) {
- if (binding.bindingType() == QParameterMapping::Attribute
- && attributeNames.contains(binding.shaderVariableName())) {
- command->m_parameterAttributeToShaderNames.insert(binding.parameterName(), binding.shaderVariableName());
- } else if (binding.bindingType() == QParameterMapping::StandardUniform
- && uniformNames.contains(binding.shaderVariableName())
- && ms_standardUniformSetters.contains(binding.parameterName())) {
- setStandardUniformValue(command->m_uniforms, binding.shaderVariableName(), binding.parameterName(), worldTransform);
- } else if (binding.bindingType() == QParameterMapping::FragmentOutput
- && fragOutputs.contains(binding.parameterName())) {
- fragOutputs.insert(binding.shaderVariableName(), fragOutputs.take(binding.parameterName()));
- } else {
+ // A Parameters wasn't found with the name binding.parameterName
+ // -> we need to use the binding.shaderVariableName
+ switch (binding.bindingType()) {
+
+ case QParameterMapping::Attribute:
+ if (attributeNames.contains(binding.shaderVariableName())) {
+ command->m_parameterAttributeToShaderNames.insert(binding.parameterName(), binding.shaderVariableName());
+ break;
+ }
+ case QParameterMapping::StandardUniform:
+ if (uniformNames.contains(binding.shaderVariableName())
+ && ms_standardUniformSetters.contains(binding.parameterName())) {
+ setStandardUniformValue(command->m_parameterPack, binding.shaderVariableName(), binding.parameterName(), worldTransform);
+ break;
+ }
+
+ case QParameterMapping::FragmentOutput:
+ if (fragOutputs.contains(binding.parameterName())) {
+ fragOutputs.insert(binding.shaderVariableName(), fragOutputs.take(binding.parameterName()));
+ break;
+ }
+
+ case QParameterMapping::UniformBufferObject:
+ if (uniformBlockNames.contains(binding.parameterName())) {
+ setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlock(it->name), it->value);
+ break;
+ }
+
+ case QParameterMapping::ShaderStorageBufferObject:
+ if (shaderStorageBlockNames.contains(binding.parameterName())) {
+ setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlock(it->name), it->value);
+ break;
+ }
+
+ default:
qCWarning(Render::Backend) << Q_FUNC_INFO << "Trying to bind a Parameter that hasn't been defined " << binding.parameterName();
+ break;
}
- } else {
- setUniformValue(command->m_uniforms, binding.shaderVariableName(), it->value);
- parameters.erase(it);
}
}
@@ -791,35 +849,29 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
// -> uniform scalar / vector
// -> uniform struct / arrays
// -> uniform block / array (4.3)
+ // -> ssbo block / array (4.3)
if ((!uniformNames.isEmpty() || !uniformBlockNames.isEmpty()) && !parameters.isEmpty()) {
ParameterInfoList::iterator it = parameters.begin();
- while (it != parameters.end()) {
+ const ParameterInfoList::iterator parametersEnd = parameters.end();
+ while (it != parametersEnd) {
if (uniformNames.contains(it->name)) { // Parameter is a regular uniform
- setUniformValue(command->m_uniforms, it->name, it->value);
- it = parameters.erase(it);
+ setUniformValue(command->m_parameterPack, it->name, it->value);
} else if (uniformBlockNames.indexOf(it->name) != -1) { // Parameter is a uniform block
- const ShaderUniformBlock &block = shader->uniformBlock(it->name);
- setUniformBlockValue(command->m_uniforms, shader, block, it->value);
- it = parameters.erase(it);
+ setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlock(it->name), it->value);
} else if (shaderStorageBlockNames.indexOf(it->name) != -1) { // Parameters is a SSBO
- const ShaderStorageBlock block = shader->storageBlock(it->name);
- // TO DO: Do whatever is needed
- Q_UNUSED(block)
- it = parameters.erase(it);
+ setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlock(it->name), it->value);
} else { // Parameter is a struct
const QVariant &v = it->value;
ShaderData *shaderData = Q_NULLPTR;
if (static_cast<QMetaType::Type>(v.type()) == qNodeIdTypeId &&
(shaderData = m_manager->shaderDataManager()->lookupResource(v.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) {
// Try to check if we have a struct or array matching a QShaderData parameter
- setDefaultUniformBlockShaderDataValue(command->m_uniforms, shader, shaderData, it->name);
- it = parameters.erase(it);
- } else {
- // Else param unused by current shader
- ++it;
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, it->name);
}
+ // Otherwise: param unused by current shader
}
+ ++it;
}
}
@@ -837,20 +889,20 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
if (lightIdx == MAX_LIGHTS)
break;
const QString structName = QStringLiteral("lights[") + QString::number(lightIdx) + QLatin1Char(']');
- setUniformValue(command->m_uniforms, structName + LIGHT_POSITION_NAME, worldPos);
- setDefaultUniformBlockShaderDataValue(command->m_uniforms, shader, light, structName);
+ setUniformValue(command->m_parameterPack, structName + LIGHT_POSITION_NAME, worldPos);
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, light, structName);
++lightIdx;
}
}
if (uniformNames.contains(LIGHT_COUNT_NAME))
- setUniformValue(command->m_uniforms, LIGHT_COUNT_NAME, qMax(1, lightIdx));
+ setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME, qMax(1, lightIdx));
if (activeLightSources.isEmpty()) {
- setUniformValue(command->m_uniforms, QStringLiteral("lights[0].type"), int(QLight::DirectionalLight));
- setUniformValue(command->m_uniforms, QStringLiteral("lights[0].direction"), QVector3D(0.0f, -1.0f, -1.0f));
- setUniformValue(command->m_uniforms, QStringLiteral("lights[0].color"), QVector3D(1.0f, 1.0f, 1.0f));
- setUniformValue(command->m_uniforms, QStringLiteral("lights[0].intensity"), 1.0f);
+ setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].type"), int(QLight::PointLight));
+ setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].position"), QVector3D(10.0f, 10.0f, 0.0f));
+ setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].color"), QVector3D(1.0f, 1.0f, 1.0f));
+ setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].intensity"), QVector3D(0.5f, 0.5f, 0.5f));
}
}
// Set frag outputs in the shaders if hash not empty
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index 6246a32d1..fc63bcf4e 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -318,6 +318,10 @@ private:
Shader *shader,
const ShaderUniformBlock &block,
const QVariant &value);
+ void setShaderStorageValue(ShaderParameterPack &uniformPack,
+ Shader *shader,
+ const ShaderStorageBlock &block,
+ const QVariant &value);
void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
Shader *shader,
ShaderData *shaderData,
diff --git a/src/render/geometry/qbuffer.h b/src/render/geometry/qbuffer.h
index 8b91a3efd..3f64007f3 100644
--- a/src/render/geometry/qbuffer.h
+++ b/src/render/geometry/qbuffer.h
@@ -62,7 +62,9 @@ public:
VertexBuffer = 0x8892, // GL_ARRAY_BUFFER
IndexBuffer = 0x8893, // GL_ELEMENT_ARRAY_BUFFER
PixelPackBuffer = 0x88EB, // GL_PIXEL_PACK_BUFFER
- PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER
+ PixelUnpackBuffer = 0x88EC, // GL_PIXEL_UNPACK_BUFFER
+ UniformBuffer = 0x8A11, // GL_UNIFORM_BUFFER
+ ShaderStorageBuffer = 0x90D2 // GL_SHADER_STORAGE_BUFFER
};
Q_ENUM(BufferType)
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index b91692adc..5279fb191 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -51,6 +51,7 @@
#include <Qt3DRender/private/graphicshelperinterface_p.h>
#include <Qt3DRender/private/renderer_p.h>
#include <Qt3DRender/private/nodemanagers_p.h>
+#include <Qt3DRender/private/buffermanager_p.h>
#include <Qt3DRender/private/managers_p.h>
#include <Qt3DRender/private/attachmentpack_p.h>
#include <QOpenGLShaderProgram>
@@ -91,6 +92,10 @@ GLBuffer::Type bufferTypeToGLBufferType(QBuffer::BufferType type)
return GLBuffer::PixelPackBuffer;
case QBuffer::PixelUnpackBuffer:
return GLBuffer::PixelUnpackBuffer;
+ case QBuffer::UniformBuffer:
+ return GLBuffer::UniformBuffer;
+ case QBuffer::ShaderStorageBuffer:
+ return GLBuffer::ShaderStorageBuffer;
default:
Q_UNREACHABLE();
}
@@ -720,6 +725,11 @@ void GraphicsContext::bindUniformBlock(GLuint programId, GLuint uniformBlockInde
m_glHelper->bindUniformBlock(programId, uniformBlockIndex, uniformBlockBinding);
}
+void GraphicsContext::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ m_glHelper->bindShaderStorageBlock(programId, shaderStorageBlockIndex, shaderStorageBlockBinding);
+}
+
void GraphicsContext::bindBufferBase(GLenum target, GLuint bindingIndex, GLuint buffer)
{
m_glHelper->bindBufferBase(target, bindingIndex, buffer);
@@ -844,7 +854,7 @@ void GraphicsContext::setRenderer(Renderer *renderer)
// It will be easier if the QGraphicContext applies the QUniformPack
// than the other way around
-void GraphicsContext::setUniforms(ShaderParameterPack &uniforms)
+void GraphicsContext::setParameters(ShaderParameterPack &parameterPack)
{
// Activate textures and update TextureUniform in the pack
// with the correct textureUnit
@@ -855,9 +865,9 @@ void GraphicsContext::setUniforms(ShaderParameterPack &uniforms)
deactivateTexturesWithScope(TextureScopeMaterial);
// Update the uniforms with the correct texture unit id's
- const QHash<QString, const QUniformValue *> &uniformValues = uniforms.uniforms();
- for (int i = 0; i < uniforms.textures().size(); ++i) {
- const ShaderParameterPack::NamedTexture &namedTex = uniforms.textures().at(i);
+ const QHash<QString, const QUniformValue *> &uniformValues = parameterPack.uniforms();
+ for (int i = 0; i < parameterPack.textures().size(); ++i) {
+ const ShaderParameterPack::NamedTexture &namedTex = parameterPack.textures().at(i);
Texture *t = manager->lookupResource<Texture, TextureManager>(namedTex.texId);
const TextureUniform *texUniform = Q_NULLPTR;
// TO DO : Rework the way textures are loaded
@@ -871,66 +881,52 @@ void GraphicsContext::setUniforms(ShaderParameterPack &uniforms)
}
}
- // Bind UniformBlocks to UBO and update UBO from ShaderData
- const QVector<BlockToUBO> &blockToUbos = uniforms.uniformBuffers();
- GLBuffer *ubo = Q_NULLPTR;
- bool needsToUnbindUBO = false;
-
- // TEMPORARLY Disabled
-
- // for (int i = 0; i < blockToUbos.length(); ++i) {
- // const ShaderUniformBlock &block = m_activeShader->uniformBlock(blockToUbos[i].m_blockIndex);
- // if (block.m_index != -1 && block.m_size > 0) {
- // ubo = manager->lookupResource<GLBuffer, GLBufferManager>(BufferShaderKey(blockToUbos[i].m_shaderDataID,
- // m_activeShader->peerUuid()));
- // // bind Uniform Block of index ubos[i].m_index to binding point i
- // bindUniformBlock(m_activeShader->getOrCreateProgram(this)->programId(), block.m_index, i);
- // // bind the UBO to the binding point i
- // // Specs specify that there are at least 14 binding points
-
- // // Allocate ubo if not allocated previously
- // if (!ubo->isCreated()) {
- // ubo->create(this);
- // ubo->bind(this, GLBuffer::UniformBuffer);
- // ubo->allocate(this, block.m_size);
- // }
-
- // // update the ubo if needed
-
- // // TO DO: Maybe QShaderData should act as a QBuffer data provider
- // // and internally update a QBuffer which we would then reupload
- // // and the ShaderData updates could then be done in some jobs
- // // rather than at render time ?
- // if (blockToUbos[i].m_needsUpdate) {
- // if (!ubo->isBound())
- // ubo->bind(this, GLBuffer::UniformBuffer);
- // needsToUnbindUBO |= true;
- // const QHash<QString, ShaderUniform> &activeUniformsInBlock = m_activeShader->activeUniformsForUniformBlock(block.m_index);
- // const QHash<QString, ShaderUniform>::const_iterator uniformsEnd = activeUniformsInBlock.end();
- // QHash<QString, ShaderUniform>::const_iterator uniformsIt = activeUniformsInBlock.begin();
-
- // while (uniformsIt != uniformsEnd) {
- // if (blockToUbos[i].m_updatedProperties.contains(uniformsIt.key())) {
- // buildUniformBuffer(blockToUbos[i].m_updatedProperties.value(uniformsIt.key()),
- // uniformsIt.value(),
- // m_uboTempArray);
- // ubo->update(this, m_uboTempArray.constData() + uniformsIt.value().m_offset,
- // uniformsIt.value().m_rawByteSize,
- // uniformsIt.value().m_offset);
- // }
- // ++uniformsIt;
- // }
- // }
- // // bind UBO to binding point
- // ubo->bindToUniformBlock(this, i);
- // }
- // }
-
- if (needsToUnbindUBO)
- ubo->release(this);
+ QOpenGLShaderProgram *shader = m_activeShader->getOrCreateProgram(this);
+
+ // TO DO: We could cache the binding points somehow and only do the binding when necessary
+ // for SSBO and UBO
+
+ // Bind Shader Storage block to SSBO and update SSBO
+ const QVector<BlockToSSBO> blockToSSBOs = parameterPack.shaderStorageBuffers();
+ int ssboIndex = 0;
+ Q_FOREACH (const BlockToSSBO b, blockToSSBOs) {
+ Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
+ GLBuffer *ssbo = glBufferForRenderBuffer(cpuBuffer);
+ bindShaderStorageBlock(shader->programId(), b.m_blockIndex, ssboIndex);
+ // Needed to avoid conflict where the buffer would already
+ // be bound as a VertexArray
+ ssbo->bind(this, GLBuffer::ShaderStorageBuffer);
+ ssbo->bindBufferBase(this, ssboIndex++, GLBuffer::ShaderStorageBuffer);
+ // Perform update if required
+ if (cpuBuffer->isDirty()) {
+ uploadDataToGLBuffer(cpuBuffer, ssbo);
+ cpuBuffer->unsetDirty();
+ }
+ // TO DO: Make sure that there's enough binding points
+ }
+
+ // Bind UniformBlocks to UBO and update UBO from Buffer
+ // TO DO: Convert ShaderData to Buffer so that we can use that generic process
+ const QVector<BlockToUBO> blockToUBOs = parameterPack.uniformBuffers();
+ int uboIndex = 0;
+ Q_FOREACH (const BlockToUBO b, blockToUBOs) {
+ Buffer *cpuBuffer = m_renderer->nodeManagers()->bufferManager()->lookupResource(b.m_bufferID);
+ GLBuffer *ubo = glBufferForRenderBuffer(cpuBuffer);
+ bindUniformBlock(shader->programId(), b.m_blockIndex, uboIndex);
+ // Needed to avoid conflict where the buffer would already
+ // be bound as a VertexArray
+ ubo->bind(this, GLBuffer::UniformBuffer);
+ ubo->bindBufferBase(this, uboIndex++, GLBuffer::UniformBuffer);
+ if (cpuBuffer->isDirty()) {
+ // Perform update if required
+ uploadDataToGLBuffer(cpuBuffer, ubo);
+ cpuBuffer->unsetDirty();
+ }
+ // TO DO: Make sure that there's enough binding points
+ }
// Update uniforms in the Default Uniform Block
- m_activeShader->updateUniforms(this, uniforms);
+ m_activeShader->updateUniforms(this, parameterPack);
}
void GraphicsContext::specifyAttribute(const Attribute *attribute, Buffer *buffer, const QString &shaderName)
diff --git a/src/render/graphicshelpers/graphicscontext_p.h b/src/render/graphicshelpers/graphicscontext_p.h
index 3a4150ea9..bbc93c43d 100644
--- a/src/render/graphicshelpers/graphicscontext_p.h
+++ b/src/render/graphicshelpers/graphicscontext_p.h
@@ -144,7 +144,7 @@ public:
void specifyIndices(Buffer *buffer);
void updateBuffer(Buffer *buffer);
- void setUniforms(ShaderParameterPack &uniforms);
+ void setParameters(ShaderParameterPack &parameterPack);
/**
* @brief glBufferFor - given a client-side (CPU) buffer, provide the
@@ -176,6 +176,7 @@ public:
void bindUniform(const QVariant &v, const ShaderUniform &description);
void blendEquation(GLenum mode);
void blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor);
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding);
GLuint boundFrameBufferObject();
void buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer);
void clearColor(const QColor &color);
diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp
index 1e1e1710a..29fe849d7 100644
--- a/src/render/graphicshelpers/graphicshelperes2.cpp
+++ b/src/render/graphicshelpers/graphicshelperes2.cpp
@@ -460,6 +460,14 @@ void GraphicsHelperES2::bindUniformBlock(GLuint programId, GLuint uniformBlockIn
qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)";
}
+void GraphicsHelperES2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ Q_UNUSED(programId);
+ Q_UNUSED(shaderStorageBlockIndex);
+ Q_UNUSED(shaderStorageBlockBinding);
+ qWarning() << "SSBO are not supported by ES 2.0 (since ES 3.1)";
+}
+
void GraphicsHelperES2::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
Q_UNUSED(target);
diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h
index 5211bb3ac..01d4f59c4 100644
--- a/src/render/graphicshelpers/graphicshelperes2_p.h
+++ b/src/render/graphicshelpers/graphicshelperes2_p.h
@@ -69,6 +69,7 @@ public:
void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp
index 28283928a..55676a6bf 100644
--- a/src/render/graphicshelpers/graphicshelpergl2.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl2.cpp
@@ -453,6 +453,14 @@ void GraphicsHelperGL2::bindUniformBlock(GLuint programId, GLuint uniformBlockIn
qWarning() << "UBO are not supported by OpenGL 2.0 (since OpenGL 3.1)";
}
+void GraphicsHelperGL2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ Q_UNUSED(programId);
+ Q_UNUSED(shaderStorageBlockIndex);
+ Q_UNUSED(shaderStorageBlockBinding);
+ qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)";
+}
+
void GraphicsHelperGL2::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
Q_UNUSED(target);
diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h
index 0ad6a39d8..cb7596f4a 100644
--- a/src/render/graphicshelpers/graphicshelpergl2_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl2_p.h
@@ -71,6 +71,7 @@ public:
void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl3.cpp b/src/render/graphicshelpers/graphicshelpergl3.cpp
index 91339da74..64c0c1b03 100644
--- a/src/render/graphicshelpers/graphicshelpergl3.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl3.cpp
@@ -571,6 +571,14 @@ void GraphicsHelperGL3::bindUniformBlock(GLuint programId, GLuint uniformBlockIn
m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
}
+void GraphicsHelperGL3::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ Q_UNUSED(programId);
+ Q_UNUSED(shaderStorageBlockIndex);
+ Q_UNUSED(shaderStorageBlockBinding);
+ qWarning() << "SSBO are not supported by OpenGL 3.0 (since OpenGL 4.3)";
+}
+
void GraphicsHelperGL3::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
m_funcs->glBindBufferBase(target, index, buffer);
diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp
index 4e916755a..e74968db9 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp
@@ -568,6 +568,14 @@ void GraphicsHelperGL3_3::bindUniformBlock(GLuint programId, GLuint uniformBlock
m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
}
+void GraphicsHelperGL3_3::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ Q_UNUSED(programId);
+ Q_UNUSED(shaderStorageBlockIndex);
+ Q_UNUSED(shaderStorageBlockBinding);
+ qWarning() << "SSBO are not supported by OpenGL 3.3 (since OpenGL 4.3)";
+}
+
void GraphicsHelperGL3_3::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
m_funcs->glBindBufferBase(target, index, buffer);
diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h
index bce7efdd7..837a61673 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h
@@ -72,6 +72,7 @@ public:
void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl3_p.h b/src/render/graphicshelpers/graphicshelpergl3_p.h
index 56bce6f07..11d5c567c 100644
--- a/src/render/graphicshelpers/graphicshelpergl3_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl3_p.h
@@ -72,6 +72,7 @@ public:
void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp
index df9a2f839..86b17e7f3 100644
--- a/src/render/graphicshelpers/graphicshelpergl4.cpp
+++ b/src/render/graphicshelpers/graphicshelpergl4.cpp
@@ -566,6 +566,11 @@ void GraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIn
m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
}
+void GraphicsHelperGL4::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
+{
+ m_funcs->glShaderStorageBlockBinding(programId, shaderStorageBlockIndex, shaderStorageBlockBinding);
+}
+
void GraphicsHelperGL4::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
m_funcs->glBindBufferBase(target, index, buffer);
diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h
index aaf840d10..4077a7828 100644
--- a/src/render/graphicshelpers/graphicshelpergl4_p.h
+++ b/src/render/graphicshelpers/graphicshelpergl4_p.h
@@ -71,6 +71,7 @@ public:
void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) Q_DECL_OVERRIDE;
void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
void bindFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE;
+ void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) Q_DECL_OVERRIDE;
void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) Q_DECL_OVERRIDE;
void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
void blendEquation(GLenum mode) Q_DECL_OVERRIDE;
diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h
index 95264dc49..caeb8f0c0 100644
--- a/src/render/graphicshelpers/graphicshelperinterface_p.h
+++ b/src/render/graphicshelpers/graphicshelperinterface_p.h
@@ -80,6 +80,7 @@ public:
virtual void bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs) = 0;
virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) = 0;
virtual void bindFrameBufferObject(GLuint frameBufferId) = 0;
+ virtual void bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding) = 0;
virtual void bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
virtual void bindUniform(const QVariant &v, const ShaderUniform &description) = 0;
virtual void blendEquation(GLenum mode) = 0;
diff --git a/src/render/io/glbuffer.cpp b/src/render/io/glbuffer.cpp
index 8e7636964..d059949db 100644
--- a/src/render/io/glbuffer.cpp
+++ b/src/render/io/glbuffer.cpp
@@ -133,7 +133,12 @@ void GLBuffer::update(GraphicsContext *ctx, const void *data, uint size, int off
ctx->openGLContext()->functions()->glBufferSubData(m_lastTarget, offset, size, data);
}
-void GLBuffer::bindToUniformBlock(GraphicsContext *ctx, int bindingPoint)
+void GLBuffer::bindBufferBase(GraphicsContext *ctx, int bindingPoint, GLBuffer::Type t)
+{
+ ctx->bindBufferBase(glBufferTypes[t], bindingPoint, m_bufferId);
+}
+
+void GLBuffer::bindBufferBase(GraphicsContext *ctx, int bindingPoint)
{
ctx->bindBufferBase(m_lastTarget, bindingPoint, m_bufferId);
}
diff --git a/src/render/io/glbuffer_p.h b/src/render/io/glbuffer_p.h
index 1dc8adb3c..4eeae9624 100644
--- a/src/render/io/glbuffer_p.h
+++ b/src/render/io/glbuffer_p.h
@@ -81,7 +81,8 @@ public:
void allocate(GraphicsContext *ctx, uint size, bool dynamic = true);
void allocate(GraphicsContext *ctx, const void *data, uint size, bool dynamic = true);
void update(GraphicsContext *ctx, const void *data, uint size, int offset = 0);
- void bindToUniformBlock(GraphicsContext *ctx, int bindingPoint);
+ void bindBufferBase(GraphicsContext *ctx, int bindingPoint, Type t);
+ void bindBufferBase(GraphicsContext *ctx, int bindingPoint);
inline GLuint bufferId() const { return m_bufferId; }
inline bool isCreated() const { return m_isCreated; }