summaryrefslogtreecommitdiffstats
path: root/src/plugins/renderers/opengl/renderer/glshader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/renderers/opengl/renderer/glshader.cpp')
-rw-r--r--src/plugins/renderers/opengl/renderer/glshader.cpp122
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