diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-12-08 11:42:25 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2016-01-13 10:55:14 +0000 |
commit | 5c89a2c7e43f930758b207acb0e89cd7477c4f60 (patch) | |
tree | fd5be7ec340fd085be1beb24fdeba987a4bbef52 /src | |
parent | 7f308fe0a9ec54d30c886203876d765e284f3826 (diff) |
Shaders: retrieve SSBO block
Change-Id: I62065d30b197367c8e5e03099c3af034892c4038
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/render/backend/renderview.cpp | 4 | ||||
-rw-r--r-- | src/render/backend/shadervariables_p.h | 16 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicscontext.cpp | 4 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperes2.cpp | 8 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperes2_p.h | 1 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl2.cpp | 7 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl2_p.h | 1 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3.cpp | 27 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_3.cpp | 27 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_3_p.h | 1 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl3_p.h | 1 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl4.cpp | 94 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelpergl4_p.h | 1 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicshelperinterface_p.h | 4 | ||||
-rw-r--r-- | src/render/materialsystem/shader.cpp | 54 | ||||
-rw-r--r-- | src/render/materialsystem/shader_p.h | 13 |
16 files changed, 221 insertions, 42 deletions
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index ac7c9cf78..c9f5c9a27 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -596,7 +596,7 @@ void RenderView::setUniformBlockValue(QUniformPack &uniformPack, Shader *shader, // Update only update properties if uboNeedsUpdate is true, otherwise update the whole block m_data->m_uniformBlockBuilder.updatedPropertiesOnly = uboNeedsUpdate; // Retrieve names and description of each active uniforms in the uniform block - m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForBlock(block.m_index); + m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForUniformBlock(block.m_index); // Builds the name-value map for the block m_data->m_uniformBlockBuilder.buildActiveUniformNameValueMapStructHelper(shaderData, block.m_name); if (!uboNeedsUpdate) @@ -620,7 +620,7 @@ void RenderView::setDefaultUniformBlockShaderDataValue(QUniformPack &uniformPack // Force to update the whole block m_data->m_uniformBlockBuilder.updatedPropertiesOnly = false; // Retrieve names and description of each active uniforms in the uniform block - m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForBlock(-1); + m_data->m_uniformBlockBuilder.uniforms = shader->activeUniformsForUniformBlock(-1); // Build name-value map for the block m_data->m_uniformBlockBuilder.buildActiveUniformNameValueMapStructHelper(shaderData, structName); // Set uniform values for each entrie of the block name-value map diff --git a/src/render/backend/shadervariables_p.h b/src/render/backend/shadervariables_p.h index 89dbba965..46c8296a6 100644 --- a/src/render/backend/shadervariables_p.h +++ b/src/render/backend/shadervariables_p.h @@ -102,6 +102,22 @@ struct ShaderUniformBlock int m_size; }; +struct ShaderStorageBlock +{ + ShaderStorageBlock() + : m_index(-1) + , m_binding(-1) + , m_size(0) + , m_activeVariablesCount(0) + {} + + QString m_name; + int m_index; + int m_binding; + int m_size; + int m_activeVariablesCount; +}; + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index e94611010..8dc27f80a 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -348,6 +348,8 @@ void GraphicsContext::activateShader(Shader *shader) shader->initializeAttributes(m_glHelper->programAttributesAndLocations(prog->programId())); if (m_glHelper->supportsFeature(GraphicsHelperInterface::UniformBufferObject)) shader->initializeUniformBlocks(m_glHelper->programUniformBlocks(prog->programId())); + if (m_glHelper->supportsFeature(GraphicsHelperInterface::ShaderStorageObject)) + shader->initializeShaderStorageBlocks(m_glHelper->programShaderStorageBlocks(prog->programId())); m_activeShader = Q_NULLPTR; } else if (!shader->isLoaded()) { // Shader program is already in the m_shaderHash but we still need to @@ -911,7 +913,7 @@ void GraphicsContext::setUniforms(QUniformPack &uniforms) if (!ubo->isBound()) ubo->bind(this); needsToUnbindUBO |= true; - const QHash<QString, ShaderUniform> &activeUniformsInBlock = m_activeShader->activeUniformsForBlock(block.m_index); + 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(); diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp index 86e526d61..1e1e1710a 100644 --- a/src/render/graphicshelpers/graphicshelperes2.cpp +++ b/src/render/graphicshelpers/graphicshelperes2.cpp @@ -208,6 +208,14 @@ QVector<ShaderUniformBlock> GraphicsHelperES2::programUniformBlocks(GLuint progr return blocks; } +QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint programId) +{ + Q_UNUSED(programId); + QVector<ShaderStorageBlock> blocks; + qWarning() << "SSBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.1)"; + return blocks; +} + void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor) { Q_UNUSED(index); diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h index 5d75137e9..5211bb3ac 100644 --- a/src/render/graphicshelpers/graphicshelperes2_p.h +++ b/src/render/graphicshelpers/graphicshelperes2_p.h @@ -100,6 +100,7 @@ public: QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; + QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) Q_DECL_OVERRIDE; void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE; bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl2.cpp b/src/render/graphicshelpers/graphicshelpergl2.cpp index a73833b28..28283928a 100644 --- a/src/render/graphicshelpers/graphicshelpergl2.cpp +++ b/src/render/graphicshelpers/graphicshelpergl2.cpp @@ -190,6 +190,13 @@ QVector<ShaderUniformBlock> GraphicsHelperGL2::programUniformBlocks(GLuint progr return blocks; } +QVector<ShaderStorageBlock> GraphicsHelperGL2::programShaderStorageBlocks(GLuint programId) +{ + Q_UNUSED(programId); + qWarning() << "SSBO are not supported by OpenGL 2.0 (since OpenGL 4.3)"; + return QVector<ShaderStorageBlock>(); +} + void GraphicsHelperGL2::vertexAttribDivisor(GLuint index, GLuint divisor) { diff --git a/src/render/graphicshelpers/graphicshelpergl2_p.h b/src/render/graphicshelpers/graphicshelpergl2_p.h index 62016c9e8..0ad6a39d8 100644 --- a/src/render/graphicshelpers/graphicshelpergl2_p.h +++ b/src/render/graphicshelpers/graphicshelpergl2_p.h @@ -102,6 +102,7 @@ public: QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; + QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) Q_DECL_OVERRIDE; void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE; bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl3.cpp b/src/render/graphicshelpers/graphicshelpergl3.cpp index 181093cbc..91339da74 100644 --- a/src/render/graphicshelpers/graphicshelpergl3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3.cpp @@ -46,6 +46,25 @@ QT_BEGIN_NAMESPACE +# ifndef QT_OPENGL_3 +# define GL_PATCH_VERTICES 36466 +# define GL_ACTIVE_RESOURCES 0x92F5 +# define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +# define GL_BUFFER_BINDING 0x9302 +# define GL_BUFFER_DATA_SIZE 0x9303 +# define GL_NUM_ACTIVE_VARIABLES 0x9304 +# define GL_SHADER_STORAGE_BLOCK 0x92E6 +# define GL_UNIFORM 0x92E1 +# define GL_UNIFORM_BLOCK 0x92E2 +# define GL_UNIFORM_BLOCK_INDEX 0x8A3A +# define GL_UNIFORM_OFFSET 0x8A3B +# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +# define GL_UNIFORM_BLOCK_BINDING 0x8A3F +# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +# endif + namespace Qt3DRender { namespace Render { @@ -218,6 +237,14 @@ QVector<ShaderUniformBlock> GraphicsHelperGL3::programUniformBlocks(GLuint progr return blocks; } +QVector<ShaderStorageBlock> GraphicsHelperGL3::programShaderStorageBlocks(GLuint programId) +{ + Q_UNUSED(programId); + QVector<ShaderStorageBlock> blocks; + qWarning() << "SSBO are not supported by OpenGL 3.2 (since OpenGL 4.3)"; + return blocks; +} + void GraphicsHelperGL3::vertexAttribDivisor(GLuint index, GLuint divisor) { Q_UNUSED(index); diff --git a/src/render/graphicshelpers/graphicshelpergl3_3.cpp b/src/render/graphicshelpers/graphicshelpergl3_3.cpp index e5e7c23e1..4e916755a 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3.cpp +++ b/src/render/graphicshelpers/graphicshelpergl3_3.cpp @@ -43,6 +43,25 @@ #include <private/attachmentpack_p.h> #include <private/qgraphicsutils_p.h> +# ifndef QT_OPENGL_3_2 +# define GL_PATCH_VERTICES 36466 +# define GL_ACTIVE_RESOURCES 0x92F5 +# define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 +# define GL_BUFFER_BINDING 0x9302 +# define GL_BUFFER_DATA_SIZE 0x9303 +# define GL_NUM_ACTIVE_VARIABLES 0x9304 +# define GL_SHADER_STORAGE_BLOCK 0x92E6 +# define GL_UNIFORM 0x92E1 +# define GL_UNIFORM_BLOCK 0x92E2 +# define GL_UNIFORM_BLOCK_INDEX 0x8A3A +# define GL_UNIFORM_OFFSET 0x8A3B +# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +# define GL_UNIFORM_BLOCK_BINDING 0x8A3F +# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 +# endif + QT_BEGIN_NAMESPACE namespace Qt3DRender { @@ -217,6 +236,14 @@ QVector<ShaderUniformBlock> GraphicsHelperGL3_3::programUniformBlocks(GLuint pro return blocks; } +QVector<ShaderStorageBlock> GraphicsHelperGL3_3::programShaderStorageBlocks(GLuint programId) +{ + Q_UNUSED(programId); + QVector<ShaderStorageBlock> blocks; + qWarning() << "SSBO are not supported by OpenGL 3.3 (since OpenGL 4.3)"; + return blocks; +} + void GraphicsHelperGL3_3::vertexAttribDivisor(GLuint index, GLuint divisor) { m_funcs->glVertexAttribDivisor(index, divisor); diff --git a/src/render/graphicshelpers/graphicshelpergl3_3_p.h b/src/render/graphicshelpers/graphicshelpergl3_3_p.h index 625720d06..bce7efdd7 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_3_p.h @@ -103,6 +103,7 @@ public: QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; + QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) Q_DECL_OVERRIDE; void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE; bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl3_p.h b/src/render/graphicshelpers/graphicshelpergl3_p.h index 59337a690..56bce6f07 100644 --- a/src/render/graphicshelpers/graphicshelpergl3_p.h +++ b/src/render/graphicshelpers/graphicshelpergl3_p.h @@ -103,6 +103,7 @@ public: QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; + QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) Q_DECL_OVERRIDE; void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE; bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelpergl4.cpp b/src/render/graphicshelpers/graphicshelpergl4.cpp index 74f7b4d4f..df9a2f839 100644 --- a/src/render/graphicshelpers/graphicshelpergl4.cpp +++ b/src/render/graphicshelpers/graphicshelpergl4.cpp @@ -43,8 +43,22 @@ #include <private/attachmentpack_p.h> #include <private/qgraphicsutils_p.h> -# ifndef QT_OPENGL_4 +# ifndef QT_OPENGL_4_3 # define GL_PATCH_VERTICES 36466 +# define GL_ACTIVE_RESOURCES 0x92F5 +# define GL_BUFFER_BINDING 0x9302 +# define GL_BUFFER_DATA_SIZE 0x9303 +# define GL_NUM_ACTIVE_VARIABLES 0x9304 +# define GL_SHADER_STORAGE_BLOCK 0x92E6 +# define GL_UNIFORM 0x92E1 +# define GL_UNIFORM_BLOCK 0x92E2 +# define GL_UNIFORM_BLOCK_INDEX 0x8A3A +# define GL_UNIFORM_OFFSET 0x8A3B +# define GL_UNIFORM_ARRAY_STRIDE 0x8A3C +# define GL_UNIFORM_MATRIX_STRIDE 0x8A3D +# define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 +# define GL_UNIFORM_BLOCK_BINDING 0x8A3F +# define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 # endif QT_BEGIN_NAMESPACE @@ -58,7 +72,7 @@ GraphicsHelperGL4::GraphicsHelperGL4() } void GraphicsHelperGL4::initializeHelper(QOpenGLContext *context, - QAbstractOpenGLFunctions *functions) + QAbstractOpenGLFunctions *functions) { Q_UNUSED(context); m_funcs = static_cast<QOpenGLFunctions_4_3_Core*>(functions); @@ -68,12 +82,12 @@ void GraphicsHelperGL4::initializeHelper(QOpenGLContext *context, } void GraphicsHelperGL4::drawElementsInstanced(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLsizei instances, - GLint baseVertex, - GLint baseInstance) + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLsizei instances, + GLint baseVertex, + GLint baseInstance) { if (baseInstance != 0) qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2"; @@ -88,9 +102,9 @@ void GraphicsHelperGL4::drawElementsInstanced(GLenum primitiveType, } void GraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType, - GLint first, - GLsizei count, - GLsizei instances) + GLint first, + GLsizei count, + GLsizei instances) { // glDrawArraysInstanced OpenGL 3.1 or greater m_funcs->glDrawArraysInstanced(primitiveType, @@ -100,10 +114,10 @@ void GraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType, } void GraphicsHelperGL4::drawElements(GLenum primitiveType, - GLsizei primitiveCount, - GLint indexType, - void *indices, - GLint baseVertex) + GLsizei primitiveCount, + GLint indexType, + void *indices, + GLint baseVertex) { m_funcs->glDrawElementsBaseVertex(primitiveType, primitiveCount, @@ -113,8 +127,8 @@ void GraphicsHelperGL4::drawElements(GLenum primitiveType, } void GraphicsHelperGL4::drawArrays(GLenum primitiveType, - GLint first, - GLsizei count) + GLint first, + GLsizei count) { m_funcs->glDrawArrays(primitiveType, first, @@ -136,10 +150,10 @@ QVector<ShaderUniform> GraphicsHelperGL4::programUniformsAndLocations(GLuint pro QVector<ShaderUniform> uniforms; GLint nbrActiveUniforms = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms); + m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM, GL_ACTIVE_RESOURCES, &nbrActiveUniforms); uniforms.reserve(nbrActiveUniforms); char uniformName[256]; - for (GLint i = 0; i < nbrActiveUniforms; i++) { + for (GLint i = 0; i < nbrActiveUniforms; ++i) { ShaderUniform uniform; GLsizei uniformNameLength = 0; // Size is 1 for scalar and more for struct or arrays @@ -170,7 +184,7 @@ QVector<ShaderAttribute> GraphicsHelperGL4::programAttributesAndLocations(GLuint m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes); attributes.reserve(nbrActiveAttributes); char attributeName[256]; - for (GLint i = 0; i < nbrActiveAttributes; i++) { + for (GLint i = 0; i < nbrActiveAttributes; ++i) { ShaderAttribute attribute; GLsizei attributeNameLength = 0; // Size is 1 for scalar and more for struct or arrays @@ -189,23 +203,50 @@ QVector<ShaderUniformBlock> GraphicsHelperGL4::programUniformBlocks(GLuint progr { QVector<ShaderUniformBlock> blocks; GLint nbrActiveUniformsBlocks = 0; - m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORM_BLOCKS, &nbrActiveUniformsBlocks); + m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveUniformsBlocks); blocks.reserve(nbrActiveUniformsBlocks); - for (GLint i = 0; i < nbrActiveUniformsBlocks; i++) { + for (GLint i = 0; i < nbrActiveUniformsBlocks; ++i) { QByteArray uniformBlockName(256, '\0'); GLsizei length = 0; ShaderUniformBlock uniformBlock; - m_funcs->glGetActiveUniformBlockName(programId, i, 256, &length, uniformBlockName.data()); + m_funcs->glGetProgramResourceName(programId, GL_UNIFORM_BLOCK, i, 256, &length, uniformBlockName.data()); uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length)); uniformBlock.m_index = i; - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &uniformBlock.m_activeUniformsCount); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_BINDING, &uniformBlock.m_binding); - m_funcs->glGetActiveUniformBlockiv(programId, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlock.m_size); + GLenum prop = GL_BUFFER_BINDING; + m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_binding); + prop = GL_BUFFER_DATA_SIZE; + m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_size); + prop = GL_NUM_ACTIVE_VARIABLES; + m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_activeUniformsCount); blocks.append(uniformBlock); } return blocks; } +QVector<ShaderStorageBlock> GraphicsHelperGL4::programShaderStorageBlocks(GLuint programId) +{ + QVector<ShaderStorageBlock> blocks; + GLint nbrActiveShaderStorageBlocks = 0; + m_funcs->glGetProgramInterfaceiv(programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveShaderStorageBlocks); + blocks.reserve(nbrActiveShaderStorageBlocks); + for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) { + QByteArray storageBlockName(256, '\0'); + GLsizei length = 0; + ShaderStorageBlock storageBlock; + m_funcs->glGetProgramResourceName(programId, GL_SHADER_STORAGE_BLOCK, i, 256, &length, storageBlockName.data()); + storageBlock.m_index = i; + storageBlock.m_name = QString::fromUtf8(storageBlockName.left(length)); + GLenum prop = GL_BUFFER_BINDING; + m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_binding); + prop = GL_BUFFER_DATA_SIZE; + m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_size); + prop = GL_NUM_ACTIVE_VARIABLES; + m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_activeVariablesCount); + blocks.push_back(storageBlock); + } + return blocks; +} + void GraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor) { m_funcs->glVertexAttribDivisor(index, divisor); @@ -321,6 +362,7 @@ bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature case UniformBufferObject: case RenderBufferDimensionRetrieval: case TextureDimensionRetrieval: + case ShaderStorageObject: return true; default: return false; diff --git a/src/render/graphicshelpers/graphicshelpergl4_p.h b/src/render/graphicshelpers/graphicshelpergl4_p.h index 0ed007482..aaf840d10 100644 --- a/src/render/graphicshelpers/graphicshelpergl4_p.h +++ b/src/render/graphicshelpers/graphicshelpergl4_p.h @@ -102,6 +102,7 @@ public: QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) Q_DECL_OVERRIDE; QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) Q_DECL_OVERRIDE; + QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) Q_DECL_OVERRIDE; void releaseFrameBufferObject(GLuint frameBufferId) Q_DECL_OVERRIDE; void setVerticesPerPatch(GLint verticesPerPatch) Q_DECL_OVERRIDE; bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE; diff --git a/src/render/graphicshelpers/graphicshelperinterface_p.h b/src/render/graphicshelpers/graphicshelperinterface_p.h index 15c950253..95264dc49 100644 --- a/src/render/graphicshelpers/graphicshelperinterface_p.h +++ b/src/render/graphicshelpers/graphicshelperinterface_p.h @@ -70,7 +70,8 @@ public: BindableFragmentOutputs, PrimitiveRestart, RenderBufferDimensionRetrieval, - TextureDimensionRetrieval + TextureDimensionRetrieval, + ShaderStorageObject }; virtual ~GraphicsHelperInterface() {} @@ -110,6 +111,7 @@ public: virtual QVector<ShaderAttribute> programAttributesAndLocations(GLuint programId) = 0; virtual QVector<ShaderUniform> programUniformsAndLocations(GLuint programId) = 0; virtual QVector<ShaderUniformBlock> programUniformBlocks(GLuint programId) = 0; + virtual QVector<ShaderStorageBlock> programShaderStorageBlocks(GLuint programId) = 0; virtual void releaseFrameBufferObject(GLuint frameBufferId) = 0; virtual void setVerticesPerPatch(GLint verticesPerPatch) = 0; virtual bool supportsFeature(Feature feature) const = 0; diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index f2e7bce78..47bb0f05d 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -117,6 +117,11 @@ QVector<QString> Shader::uniformBlockNames() const return m_uniformBlockNames; } +QVector<QString> Shader::storageBlockNames() const +{ + return m_shaderStorageBlockNames; +} + QVector<QByteArray> Shader::shaderCode() const { return m_shaderCode; @@ -177,14 +182,14 @@ QVector<ShaderUniformBlock> Shader::uniformBlocks() const return m_uniformBlocks; } -QHash<QString, ShaderUniform> Shader::activeUniformsForBlock(int blockIndex) const +QHash<QString, ShaderUniform> Shader::activeUniformsForUniformBlock(int blockIndex) const { - return m_blockIndexToShaderUniforms.value(blockIndex); + return m_uniformBlockIndexToShaderUniforms.value(blockIndex); } ShaderUniformBlock Shader::uniformBlock(int blockIndex) { - for (int i = 0; i < m_uniformBlocks.size(); ++i) { + for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_index == blockIndex) { return m_uniformBlocks[i]; } @@ -194,7 +199,7 @@ ShaderUniformBlock Shader::uniformBlock(int blockIndex) ShaderUniformBlock Shader::uniformBlock(const QString &blockName) { - for (int i = 0; i < m_uniformBlocks.size(); ++i) { + for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_name == blockName) { return m_uniformBlocks[i]; } @@ -202,6 +207,24 @@ ShaderUniformBlock Shader::uniformBlock(const QString &blockName) return ShaderUniformBlock(); } +ShaderStorageBlock Shader::storageBlock(int blockIndex) +{ + for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { + if (m_shaderStorageBlocks[i].m_index == blockIndex) + return m_shaderStorageBlocks[i]; + } + return ShaderStorageBlock(); +} + +ShaderStorageBlock Shader::storageBlock(const QString &blockName) +{ + for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { + if (m_shaderStorageBlocks[i].m_name == blockName) + return m_shaderStorageBlocks[i]; + } + return ShaderStorageBlock(); +} + /*! * Must be called with a valid, current QOpenGLContext */ @@ -325,21 +348,21 @@ void Shader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescriptio m_uniformsNames.resize(uniformsDescription.size()); QHash<QString, ShaderUniform> activeUniformsInDefaultBlock; - for (int i = 0; i < uniformsDescription.size(); i++) { + for (int i = 0, m = uniformsDescription.size(); i < m; i++) { m_uniformsNames[i] = uniformsDescription[i].m_name; if (uniformsDescription[i].m_blockIndex == -1) { // Uniform is in default block qCDebug(Shaders) << "Active Uniform in Default Block " << uniformsDescription[i].m_name << uniformsDescription[i].m_blockIndex; activeUniformsInDefaultBlock.insert(uniformsDescription[i].m_name, uniformsDescription[i]); } } - m_blockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock); + m_uniformBlockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock); } void Shader::initializeAttributes(const QVector<ShaderAttribute> &attributesDescription) { m_attributes = attributesDescription; m_attributesNames.resize(attributesDescription.size()); - for (int i = 0; i < attributesDescription.size(); i++) { + for (int i = 0, m = attributesDescription.size(); i < m; i++) { m_attributesNames[i] = attributesDescription[i].m_name; qCDebug(Shaders) << "Active Attribute " << attributesDescription[i].m_name; } @@ -349,7 +372,7 @@ void Shader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformB { m_uniformBlocks = uniformBlockDescription; m_uniformBlockNames.resize(uniformBlockDescription.size()); - for (int i = 0; i < uniformBlockDescription.size(); ++i) { + for (int i = 0, m = uniformBlockDescription.size(); i < m; ++i) { m_uniformBlockNames[i] = uniformBlockDescription[i].m_name; qCDebug(Shaders) << "Initializing Uniform Block {" << m_uniformBlockNames[i] << "}"; @@ -373,7 +396,18 @@ void Shader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformB ++uniformsIt; ++uniformNamesIt; } - m_blockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock); + m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock); + } +} + +void Shader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription) +{ + m_shaderStorageBlocks = shaderStorageBlockDescription; + m_shaderStorageBlockNames.resize(shaderStorageBlockDescription.size()); + + for (int i = 0, m = shaderStorageBlockDescription.size(); i < m; ++i) { + m_shaderStorageBlockNames[i] = shaderStorageBlockDescription[i].m_name; + qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}"; } } @@ -392,7 +426,7 @@ void Shader::initialize(const Shader &other) m_attributes = other.m_attributes; m_uniformBlockNames = other.m_uniformBlockNames; m_uniformBlocks = other.m_uniformBlocks; - m_blockIndexToShaderUniforms = other.m_blockIndexToShaderUniforms; + m_uniformBlockIndexToShaderUniforms = other.m_uniformBlockIndexToShaderUniforms; m_fragOutputs = other.m_fragOutputs; m_isLoaded = other.m_isLoaded; } diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index cc38f8c4a..d4839dba4 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -84,6 +84,7 @@ public: QVector<QString> uniformsNames() const; QVector<QString> attributesNames() const; QVector<QString> uniformBlockNames() const; + QVector<QString> storageBlockNames() const; QVector<QByteArray> shaderCode() const; void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; @@ -93,11 +94,15 @@ public: QVector<ShaderUniform> uniforms() const; QVector<ShaderAttribute> attributes() const; QVector<ShaderUniformBlock> uniformBlocks() const; + QVector<ShaderStorageBlock> storageBlocks() const; - QHash<QString, ShaderUniform> activeUniformsForBlock(int blockIndex) const; + QHash<QString, ShaderUniform> activeUniformsForUniformBlock(int blockIndex) const; ShaderUniformBlock uniformBlock(int blockIndex); ShaderUniformBlock uniformBlock(const QString &blockName); + ShaderStorageBlock storageBlock(int blockIndex); + ShaderStorageBlock storageBlock(const QString &blockName); + private: QOpenGLShaderProgram *m_program; @@ -112,7 +117,10 @@ private: QVector<QString> m_uniformBlockNames; QVector<ShaderUniformBlock> m_uniformBlocks; - QHash<int, QHash<QString, ShaderUniform> > m_blockIndexToShaderUniforms; + QHash<int, QHash<QString, ShaderUniform> > m_uniformBlockIndexToShaderUniforms; + + QVector<QString> m_shaderStorageBlockNames; + QVector<ShaderStorageBlock> m_shaderStorageBlocks; QHash<QString, int> m_fragOutputs; @@ -128,6 +136,7 @@ private: void initializeUniforms(const QVector<ShaderUniform> &uniformsDescription); void initializeAttributes(const QVector<ShaderAttribute> &attributesDescription); void initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription); + void initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription); void initialize(const Shader &other); |