summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-04-17 12:12:48 +0200
committerPaul Lemire <paul.lemire@kdab.com>2020-04-20 17:11:20 +0200
commit94f3c52839a26b1d5a02b0becf16c456ed3658c4 (patch)
tree68980aedb84b7bca21d95367b6e3ca5be9d0f779
parent0dfd9a3164390b1aab8e6a660eac0f5154ce237f (diff)
Uniform preparation: stop copying the ShaderUniforms around
Those are static and expensive to copy (especially once per RenderCommand) as they contain several QStrings. Instead we sort them by nameIds when the shader is initialized and use indices to reference them. This avoids the copies and the sorting allows to be more efficient at finding the ShaderUniforms based on a nameId. Change-Id: I50008381f1d336ab182f5ac5a08500791e2871e9 Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp16
-rw-r--r--src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h2
-rw-r--r--src/plugins/renderers/opengl/renderer/glshader.cpp22
-rw-r--r--src/plugins/renderers/opengl/renderer/glshader_p.h8
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.cpp4
-rw-r--r--src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp6
-rw-r--r--src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h6
7 files changed, 37 insertions, 27 deletions
diff --git a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
index 1e2aba0fc..7c1467f6e 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -1160,7 +1160,7 @@ void SubmissionContext::setUpdatedTexture(const Qt3DCore::QNodeIdVector &updated
// It will be easier if the QGraphicContext applies the QUniformPack
// than the other way around
-bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
+bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack, GLShader *shader)
{
static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight.irradiance"));
static const int specularId = StringToInt::lookupId(QLatin1String("envLight.specular"));
@@ -1225,7 +1225,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
}
}
- QOpenGLShaderProgram *shader = activeShader();
+ QOpenGLShaderProgram *glShader = activeShader();
// TO DO: We could cache the binding points somehow and only do the binding when necessary
// for SSBO and UBO
@@ -1239,7 +1239,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// This is currently not required as we are introspecting the bindingIndex
// value from the shaders and not replacing them, making such a call useless
// bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex);
- bindShaderStorageBlock(shader->programId(), b.m_blockIndex, b.m_bindingIndex);
+ bindShaderStorageBlock(glShader->programId(), b.m_blockIndex, b.m_bindingIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
bindGLBuffer(ssbo, GLBuffer::ShaderStorageBuffer);
@@ -1254,7 +1254,7 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
for (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);
+ bindUniformBlock(glShader->programId(), b.m_blockIndex, uboIndex);
// Needed to avoid conflict where the buffer would already
// be bound as a VertexArray
bindGLBuffer(ubo, GLBuffer::UniformBuffer);
@@ -1264,11 +1264,11 @@ bool SubmissionContext::setParameters(ShaderParameterPack &parameterPack)
// Update uniforms in the Default Uniform Block
const PackUniformHash values = parameterPack.uniforms();
- const QVector<ShaderUniform> activeUniforms = parameterPack.submissionUniforms();
+ const QVector<int> &activeUniformsIndices = parameterPack.submissionUniformIndices();
+ const QVector<ShaderUniform> &shaderUniforms = shader->uniforms();
- for (const ShaderUniform &uniform : activeUniforms) {
- // We can use [] as we are sure the the uniform wouldn't
- // be un activeUniforms if there wasn't a matching value
+ for (const int shaderUniformIndex : activeUniformsIndices) {
+ const ShaderUniform &uniform = shaderUniforms[shaderUniformIndex];
const UniformValue &v = values.value(uniform.m_nameId);
// skip invalid textures/images
diff --git a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
index d43cae4f8..6e2ac4e18 100644
--- a/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/plugins/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -138,7 +138,7 @@ public:
GLBuffer *glBufferForRenderBuffer(Buffer *buf);
// Parameters
- bool setParameters(ShaderParameterPack &parameterPack);
+ bool setParameters(ShaderParameterPack &parameterPack, GLShader *shader);
// RenderState
void setCurrentStateSet(RenderStateSet* ss);
diff --git a/src/plugins/renderers/opengl/renderer/glshader.cpp b/src/plugins/renderers/opengl/renderer/glshader.cpp
index b4e198863..564e78a8e 100644
--- a/src/plugins/renderers/opengl/renderer/glshader.cpp
+++ b/src/plugins/renderers/opengl/renderer/glshader.cpp
@@ -229,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;
}
}
@@ -319,6 +325,10 @@ void GLShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescript
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)
diff --git a/src/plugins/renderers/opengl/renderer/glshader_p.h b/src/plugins/renderers/opengl/renderer/glshader_p.h
index 28b64b058..ae447cd18 100644
--- a/src/plugins/renderers/opengl/renderer/glshader_p.h
+++ b/src/plugins/renderers/opengl/renderer/glshader_p.h
@@ -99,10 +99,10 @@ public:
QVector<QString> uniformBlockNames() const;
QVector<QString> storageBlockNames() const;
- inline QVector<ShaderUniform> uniforms() const { return m_uniforms; }
- inline QVector<ShaderAttribute> attributes() const { return m_attributes; }
- inline QVector<ShaderUniformBlock> uniformBlocks() const { return m_uniformBlocks; }
- inline QVector<ShaderStorageBlock> storageBlocks() const { return m_shaderStorageBlocks; }
+ inline const QVector<ShaderUniform> &uniforms() const { return m_uniforms; }
+ inline const QVector<ShaderAttribute> &attributes() const { return m_attributes; }
+ inline const QVector<ShaderUniformBlock> &uniformBlocks() const { return m_uniformBlocks; }
+ inline const QVector<ShaderStorageBlock> &storageBlocks() const { return m_shaderStorageBlocks; }
QHash<QString, ShaderUniform> activeUniformsForUniformBlock(int blockIndex) const;
diff --git a/src/plugins/renderers/opengl/renderer/renderer.cpp b/src/plugins/renderers/opengl/renderer/renderer.cpp
index cbfa0515f..fdcc9fd09 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderer.cpp
@@ -2068,7 +2068,7 @@ void Renderer::performCompute(const RenderView *, RenderCommand *command)
}
{
Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler());
- m_submissionContext->setParameters(command->m_parameterPack);
+ m_submissionContext->setParameters(command->m_parameterPack, command->m_glShader);
}
{
Profiling::GLTimeRecorder recorder(Profiling::DispatchCompute, activeProfiler());
@@ -2162,7 +2162,7 @@ bool Renderer::executeCommandsSubmission(const RenderView *rv)
{
Profiling::GLTimeRecorder recorder(Profiling::UniformUpdate, activeProfiler());
//// Update program uniforms
- if (!m_submissionContext->setParameters(command.m_parameterPack)) {
+ if (!m_submissionContext->setParameters(command.m_parameterPack, command.m_glShader)) {
allCommandsIssued = false;
// If we have failed to set uniform (e.g unable to bind a texture)
// we won't perform the draw call which could show invalid content
diff --git a/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp b/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
index 1d0fd6d9c..467ac34c5 100644
--- a/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
+++ b/src/plugins/renderers/opengl/renderer/shaderparameterpack.cpp
@@ -63,7 +63,7 @@ ShaderParameterPack::~ShaderParameterPack()
void ShaderParameterPack::reserve(int uniformCount)
{
m_uniforms.reserve(uniformCount);
- m_submissionUniforms.reserve(uniformCount);
+ m_submissionUniformIndices.reserve(uniformCount);
}
void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val)
@@ -108,9 +108,9 @@ void ShaderParameterPack::setShaderStorageBuffer(BlockToSSBO blockToSSBO)
m_shaderStorageBuffers.push_back(std::move(blockToSSBO));
}
-void ShaderParameterPack::setSubmissionUniform(const ShaderUniform &uniform)
+void ShaderParameterPack::setSubmissionUniformIndex(const int uniformIdx)
{
- m_submissionUniforms.push_back(uniform);
+ m_submissionUniformIndices.push_back(uniformIdx);
}
} // namespace OpenGL
diff --git a/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h b/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
index 10c4da5d4..2ed80ef2a 100644
--- a/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
+++ b/src/plugins/renderers/opengl/renderer/shaderparameterpack_p.h
@@ -157,7 +157,7 @@ public:
void setUniformBuffer(BlockToUBO blockToUBO);
void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
- void setSubmissionUniform(const ShaderUniform &uniform);
+ void setSubmissionUniformIndex(const int shaderUniformIndex);
inline PackUniformHash &uniforms() { return m_uniforms; }
inline const PackUniformHash &uniforms() const { return m_uniforms; }
@@ -203,7 +203,7 @@ public:
inline QVector<NamedResource> images() const { return m_images; }
inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; }
inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; }
- inline QVector<ShaderUniform> submissionUniforms() const { return m_submissionUniforms; }
+ inline QVector<int> submissionUniformIndices() const { return m_submissionUniformIndices; }
private:
PackUniformHash m_uniforms;
@@ -211,7 +211,7 @@ private:
QVector<NamedResource> m_images;
QVector<BlockToUBO> m_uniformBuffers;
QVector<BlockToSSBO> m_shaderStorageBuffers;
- QVector<ShaderUniform> m_submissionUniforms;
+ QVector<int> m_submissionUniformIndices;
friend class RenderView;
};