diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-12-10 13:06:33 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2016-01-13 16:10:36 +0000 |
commit | 412a1d9b1d0b73fcc99c73bd89457cc11ece00fa (patch) | |
tree | 0472dcf48168c4903fa6faf148ae08bc1bd3fd13 /src/render/graphicshelpers/graphicscontext.cpp | |
parent | 9add600584ab87c80d439c0d5571994d72af3477 (diff) |
RenderView/GraphicsContext: support SSBO/UBO with buffer used as Parameters
Change-Id: I347aa5deea6521b43b9033e2200ab2f8b272f671
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render/graphicshelpers/graphicscontext.cpp')
-rw-r--r-- | src/render/graphicshelpers/graphicscontext.cpp | 120 |
1 files changed, 58 insertions, 62 deletions
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 ¶meterPack) { // 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) |