diff options
Diffstat (limited to 'src/plugins/renderers/opengl/renderer/glshader.cpp')
-rw-r--r-- | src/plugins/renderers/opengl/renderer/glshader.cpp | 122 |
1 files changed, 108 insertions, 14 deletions
diff --git a/src/plugins/renderers/opengl/renderer/glshader.cpp b/src/plugins/renderers/opengl/renderer/glshader.cpp index 5e92d84c2..564e78a8e 100644 --- a/src/plugins/renderers/opengl/renderer/glshader.cpp +++ b/src/plugins/renderers/opengl/renderer/glshader.cpp @@ -42,6 +42,7 @@ #include <Qt3DRender/private/stringtoint_p.h> #include <graphicscontext_p.h> #include <logging_p.h> +#include <gllights_p.h> QT_BEGIN_NAMESPACE @@ -51,9 +52,51 @@ namespace Render { namespace OpenGL { +namespace { + +QVector<int> getLightUniformNameIds() +{ + QVector<int> names; + names.reserve(MAX_LIGHTS * 18 + 1); + + names << GLLights::LIGHT_COUNT_NAME_ID; + for (int i = 0; i < MAX_LIGHTS; ++i) { + names << GLLights::LIGHT_TYPE_NAMES[i] + << GLLights::LIGHT_COLOR_NAMES[i] + << GLLights::LIGHT_POSITION_NAMES[i] + << GLLights::LIGHT_INTENSITY_NAMES[i] + << GLLights::LIGHT_DIRECTION_NAMES[i] + << GLLights::LIGHT_LINEAR_ATTENUATION_NAMES[i] + << GLLights::LIGHT_QUADRATIC_ATTENUATION_NAMES[i] + << GLLights::LIGHT_CONSTANT_ATTENUATION_NAMES[i] + << GLLights::LIGHT_CUT_OFF_ANGLE_NAMES[i] + << GLLights::LIGHT_TYPE_UNROLL_NAMES[i] + << GLLights::LIGHT_COLOR_UNROLL_NAMES[i] + << GLLights::LIGHT_POSITION_UNROLL_NAMES[i] + << GLLights::LIGHT_INTENSITY_UNROLL_NAMES[i] + << GLLights::LIGHT_DIRECTION_UNROLL_NAMES[i] + << GLLights::LIGHT_LINEAR_ATTENUATION_UNROLL_NAMES[i] + << GLLights::LIGHT_QUADRATIC_ATTENUATION_UNROLL_NAMES[i] + << GLLights::LIGHT_CONSTANT_ATTENUATION_UNROLL_NAMES[i] + << GLLights::LIGHT_CUT_OFF_ANGLE_UNROLL_NAMES[i]; + } + + return names; +} + +template<typename Vector> +bool fastContains(const Vector &v, int value) +{ + return std::binary_search(v.cbegin(), v.cend(), value); +} + +} + GLShader::GLShader() : m_isLoaded(false) , m_graphicsContext(nullptr) + , m_parameterPackSize(0) + , m_hasActiveVariables(false) { m_shaderCode.resize(static_cast<int>(QShaderProgram::Compute) + 1); } @@ -106,7 +149,7 @@ QHash<QString, ShaderUniform> GLShader::activeUniformsForUniformBlock(int blockI return m_uniformBlockIndexToShaderUniforms.value(blockIndex); } -ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex) +ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex) const noexcept { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_index == blockIndex) { @@ -116,7 +159,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockIndex(int blockIndex) return ShaderUniformBlock(); } -ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId) +ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId) const noexcept { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_nameId == blockNameId) { @@ -126,7 +169,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockNameId(int blockNameId) return ShaderUniformBlock(); } -ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName) +ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName) const noexcept { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_name == blockName) { @@ -136,7 +179,7 @@ ShaderUniformBlock GLShader::uniformBlockForBlockName(const QString &blockName) return ShaderUniformBlock(); } -ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex) +ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex) const noexcept { for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { if (m_shaderStorageBlocks[i].m_index == blockIndex) @@ -145,7 +188,7 @@ ShaderStorageBlock GLShader::storageBlockForBlockIndex(int blockIndex) return ShaderStorageBlock(); } -ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId) +ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId) const noexcept { for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { if (m_shaderStorageBlocks[i].m_nameId == blockNameId) @@ -154,7 +197,7 @@ ShaderStorageBlock GLShader::storageBlockForBlockNameId(int blockNameId) return ShaderStorageBlock(); } -ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName) +ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName) const noexcept { for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { if (m_shaderStorageBlocks[i].m_name == blockName) @@ -163,6 +206,22 @@ ShaderStorageBlock GLShader::storageBlockForBlockName(const QString &blockName) return ShaderStorageBlock(); } +GLShader::ParameterKind GLShader::categorizeVariable(int nameId) const noexcept +{ + if (fastContains(m_uniformsNamesIds, nameId)) + return ParameterKind::Uniform; + if (fastContains(m_uniformBlockNamesIds, nameId)) + return ParameterKind::UBO; + if (fastContains(m_shaderStorageBlockNamesIds, nameId)) + return ParameterKind::SSBO; + return ParameterKind::Struct; +} + +bool GLShader::hasUniform(int nameId) const noexcept +{ + return m_uniformsNamesIds.contains(nameId); +} + void GLShader::prepareUniforms(ShaderParameterPack &pack) { const PackUniformHash &values = pack.uniforms(); @@ -170,14 +229,20 @@ void GLShader::prepareUniforms(ShaderParameterPack &pack) auto it = values.keys.cbegin(); const auto end = values.keys.cend(); + const int shaderUniformsCount = m_uniforms.size(); + const auto uIt = m_uniforms.cbegin(); + while (it != end) { // Find if there's a uniform with the same name id - for (const ShaderUniform &uniform : qAsConst(m_uniforms)) { - if (uniform.m_nameId == *it) { - pack.setSubmissionUniform(uniform); - break; - } - } + + int i = 0; + const int targetNameId = *it; + while (i < shaderUniformsCount && (uIt + i)->m_nameId < targetNameId) + ++i; + + if (i < shaderUniformsCount && (uIt + i)->m_nameId == targetNameId) + pack.setSubmissionUniformIndex(i); + ++it; } } @@ -188,7 +253,6 @@ void GLShader::setFragOutputs(const QHash<QString, int> &fragOutputs) QMutexLocker lock(&m_mutex); m_fragOutputs = fragOutputs; } -// updateDNA(); } const QHash<QString, int> GLShader::fragOutputs() const @@ -203,6 +267,7 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript m_uniformsNames.resize(uniformsDescription.size()); m_uniformsNamesIds.reserve(uniformsDescription.size()); m_standardUniformNamesIds.reserve(5); + m_lightUniformsNamesIds.reserve(MAX_LIGHTS * 8 + 1); QHash<QString, ShaderUniform> activeUniformsInDefaultBlock; static const QVector<int> standardUniformNameIds = { @@ -231,14 +296,18 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript Shader::skinningPaletteNameId, }; + static const QVector<int> lightUniformNameIds = getLightUniformNameIds(); + for (int i = 0, m = uniformsDescription.size(); i < m; i++) { m_uniformsNames[i] = m_uniforms[i].m_name; const int nameId = StringToInt::lookupId(m_uniformsNames[i]); m_uniforms[i].m_nameId = nameId; - // Is the uniform a Qt3D "Standard" uniform or a user defined one? + // Is the uniform a Qt3D "Standard" uniform, a light uniform or a user defined one? if (standardUniformNameIds.contains(nameId)) m_standardUniformNamesIds.push_back(nameId); + else if (lightUniformNameIds.contains(nameId)) + m_lightUniformsNamesIds.push_back(nameId); else m_uniformsNamesIds.push_back(nameId); @@ -248,6 +317,18 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript } } m_uniformBlockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock); + + m_parameterPackSize += m_standardUniformNamesIds.size() + m_lightUniformsNamesIds.size() + m_uniformsNamesIds.size(); + m_hasActiveVariables |= (m_parameterPackSize > 0); + + // Sort by ascending order to make contains check faster + std::sort(m_uniformsNamesIds.begin(), m_uniformsNamesIds.end()); + std::sort(m_lightUniformsNamesIds.begin(), m_lightUniformsNamesIds.end()); + std::sort(m_standardUniformNamesIds.begin(), m_standardUniformNamesIds.end()); + std::sort(m_uniforms.begin(), m_uniforms.end(), + [] (const ShaderUniform &a, const ShaderUniform &b) { + return a.m_nameId < b.m_nameId; + }); } void GLShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDescription) @@ -261,6 +342,7 @@ void GLShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDe m_attributeNamesIds[i] = m_attributes[i].m_nameId; qCDebug(Shaders) << "Active Attribute " << attributesDescription[i].m_name; } + m_hasActiveVariables |= (m_attributeNamesIds.size() > 0); } void GLShader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription) @@ -296,6 +378,12 @@ void GLShader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &unifor } m_uniformBlockIndexToShaderUniforms.insert(uniformBlockDescription[i].m_index, activeUniformsInBlock); } + + m_parameterPackSize += m_uniformsNamesIds.size(); + m_hasActiveVariables |= (m_parameterPackSize > 0); + + // Sort by ascending order to make contains check faster + std::sort(m_uniformBlockNamesIds.begin(), m_uniformBlockNamesIds.end()); } void GLShader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription) @@ -310,6 +398,12 @@ void GLShader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> & m_shaderStorageBlocks[i].m_nameId =m_shaderStorageBlockNamesIds[i]; qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}"; } + + m_parameterPackSize += m_shaderStorageBlockNamesIds.size(); + m_hasActiveVariables |= (m_parameterPackSize > 0); + + // Sort by ascending order to make contains check faster + std::sort(m_shaderStorageBlockNamesIds.begin(), m_shaderStorageBlockNamesIds.end()); } } // OpenGL |