From 3019497559328d2fd0c0c9548f512fba9fe1f94e Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Fri, 27 Sep 2019 07:16:58 +0200 Subject: Shader: record standard uniform at loading time Avoids having to check for each uniform (for each frame, each geometry) whether it is a standard uniform or a user defined one. Change-Id: I76cff7869aacc1343a9acf991f8035b8118581ed Reviewed-by: Mike Krus --- src/render/backend/stringtoint.cpp | 39 ++++++++----- src/render/materialsystem/shader.cpp | 64 +++++++++++++++++++++- src/render/materialsystem/shader_p.h | 26 +++++++++ .../renderers/opengl/renderer/renderview.cpp | 54 +++++++++--------- 4 files changed, 139 insertions(+), 44 deletions(-) (limited to 'src/render') diff --git a/src/render/backend/stringtoint.cpp b/src/render/backend/stringtoint.cpp index 5659da394..0e0d38c9c 100644 --- a/src/render/backend/stringtoint.cpp +++ b/src/render/backend/stringtoint.cpp @@ -50,9 +50,18 @@ namespace Render { namespace { -QReadWriteLock lock; -QHash map = QHash(); -QVector reverseMap = QVector(); +struct StringToIntCache +{ + QReadWriteLock lock; + QHash map = QHash(); + QVector reverseMap = QVector(); + + static StringToIntCache& instance() + { + static StringToIntCache c; + return c; + } +}; } // anonymous @@ -64,20 +73,21 @@ int StringToInt::lookupId(QLatin1String str) int StringToInt::lookupId(const QString &str) { + auto& cache = StringToIntCache::instance(); int idx; { - QReadLocker readLocker(&lock); - idx = map.value(str, -1); + QReadLocker readLocker(&cache.lock); + idx = cache.map.value(str, -1); } if (Q_UNLIKELY(idx < 0)) { - QWriteLocker writeLocker(&lock); - idx = map.value(str, -1); + QWriteLocker writeLocker(&cache.lock); + idx = cache.map.value(str, -1); if (idx < 0) { - idx = reverseMap.size(); - Q_ASSERT(map.size() == reverseMap.size()); - map.insert(str, idx); - reverseMap.append(str); + idx = cache.reverseMap.size(); + Q_ASSERT(cache.map.size() == cache.reverseMap.size()); + cache.map.insert(str, idx); + cache.reverseMap.append(str); } } return idx; @@ -85,9 +95,10 @@ int StringToInt::lookupId(const QString &str) QString StringToInt::lookupString(int idx) { - QReadLocker readLocker(&lock); - if (Q_LIKELY(reverseMap.size() > idx)) - return reverseMap.at(idx); + auto& cache = StringToIntCache::instance(); + QReadLocker readLocker(&cache.lock); + if (Q_LIKELY(cache.reverseMap.size() > idx)) + return cache.reverseMap.at(idx); return QString(); } diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index 300a71b84..0d4b5edba 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -57,6 +57,29 @@ using namespace Qt3DCore; namespace Qt3DRender { namespace Render { +const int Shader::modelMatrixNameId = StringToInt::lookupId(QLatin1String("modelMatrix")); +const int Shader::viewMatrixNameId = StringToInt::lookupId(QLatin1String("viewMatrix")); +const int Shader::projectionMatrixNameId = StringToInt::lookupId(QLatin1String("projectionMatrix")); +const int Shader::modelViewMatrixNameId = StringToInt::lookupId(QLatin1String("modelView")); +const int Shader::viewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("viewProjectionMatrix")); +const int Shader::modelViewProjectionNameId = StringToInt::lookupId(QLatin1String("modelViewProjection")); +const int Shader::mvpNameId = StringToInt::lookupId(QLatin1String("mvp")); +const int Shader::inverseModelMatrixNameId = StringToInt::lookupId(QLatin1String("inverseModelMatrix")); +const int Shader::inverseViewMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewMatrix")); +const int Shader::inverseProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")); +const int Shader::inverseModelViewNameId = StringToInt::lookupId(QLatin1String("inverseModelView")); +const int Shader::inverseViewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")); +const int Shader::inverseModelViewProjectionNameId = StringToInt::lookupId(QLatin1String("inverseModelViewProjection")); +const int Shader::modelNormalMatrixNameId = StringToInt::lookupId(QLatin1String("modelNormalMatrix")); +const int Shader::modelViewNormalNameId = StringToInt::lookupId(QLatin1String("modelViewNormal")); +const int Shader::viewportMatrixNameId = StringToInt::lookupId(QLatin1String("viewportMatrix")); +const int Shader::inverseViewportMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewportMatrix")); +const int Shader::aspectRatioNameId = StringToInt::lookupId(QLatin1String("aspectRatio")); +const int Shader::exposureNameId = StringToInt::lookupId(QLatin1String("exposure")); +const int Shader::gammaNameId = StringToInt::lookupId(QLatin1String("gamma")); +const int Shader::timeNameId = StringToInt::lookupId(QLatin1String("time")); +const int Shader::eyePositionNameId = StringToInt::lookupId(QLatin1String("eyePosition")); +const int Shader::skinningPaletteNameId = StringToInt::lookupId(QLatin1String("skinningPalette[0]")); Shader::Shader() : BackendNode(ReadWrite) @@ -308,13 +331,47 @@ void Shader::initializeUniforms(const QVector &uniformsDescriptio { m_uniforms = uniformsDescription; m_uniformsNames.resize(uniformsDescription.size()); - m_uniformsNamesIds.resize(uniformsDescription.size()); + m_uniformsNamesIds.reserve(uniformsDescription.size()); + m_standardUniformNamesIds.reserve(5); QHash activeUniformsInDefaultBlock; + static const QVector standardUniformNameIds = { + modelMatrixNameId, + viewMatrixNameId, + projectionMatrixNameId, + modelViewMatrixNameId, + viewProjectionMatrixNameId, + modelViewProjectionNameId, + mvpNameId, + inverseModelMatrixNameId, + inverseViewMatrixNameId, + inverseProjectionMatrixNameId, + inverseModelViewNameId, + inverseViewProjectionMatrixNameId, + inverseModelViewProjectionNameId, + modelNormalMatrixNameId, + modelViewNormalNameId, + viewportMatrixNameId, + inverseViewportMatrixNameId, + aspectRatioNameId, + exposureNameId, + gammaNameId, + timeNameId, + eyePositionNameId, + skinningPaletteNameId, + }; + for (int i = 0, m = uniformsDescription.size(); i < m; i++) { m_uniformsNames[i] = m_uniforms[i].m_name; - m_uniforms[i].m_nameId = StringToInt::lookupId(m_uniformsNames[i]); - m_uniformsNamesIds[i] = m_uniforms[i].m_nameId; + 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? + if (standardUniformNameIds.contains(nameId)) + m_standardUniformNamesIds.push_back(nameId); + else + m_uniformsNamesIds.push_back(nameId); + 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]); @@ -394,6 +451,7 @@ void Shader::initializeFromReference(const Shader &other) { Q_ASSERT(m_dna == other.m_dna); m_uniformsNamesIds = other.m_uniformsNamesIds; + m_standardUniformNamesIds = other.m_standardUniformNamesIds; m_uniformsNames = other.m_uniformsNames; m_uniforms = other.m_uniforms; m_attributesNames = other.m_attributesNames; diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index fe1a401d9..298b09c6c 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -75,6 +75,30 @@ typedef uint ProgramDNA; class Q_AUTOTEST_EXPORT Shader : public BackendNode { public: + static const int modelMatrixNameId; + static const int viewMatrixNameId; + static const int projectionMatrixNameId; + static const int modelViewMatrixNameId; + static const int viewProjectionMatrixNameId; + static const int modelViewProjectionNameId; + static const int mvpNameId; + static const int inverseModelMatrixNameId; + static const int inverseViewMatrixNameId; + static const int inverseProjectionMatrixNameId; + static const int inverseModelViewNameId; + static const int inverseViewProjectionMatrixNameId; + static const int inverseModelViewProjectionNameId; + static const int modelNormalMatrixNameId; + static const int modelViewNormalNameId; + static const int viewportMatrixNameId; + static const int inverseViewportMatrixNameId; + static const int aspectRatioNameId; + static const int exposureNameId; + static const int gammaNameId; + static const int timeNameId; + static const int eyePositionNameId; + static const int skinningPaletteNameId; + Shader(); ~Shader(); @@ -88,6 +112,7 @@ public: const QHash fragOutputs() const; inline QVector uniformsNamesIds() const { return m_uniformsNamesIds; } + inline QVector standardUniformNameIds() const { return m_standardUniformNamesIds; } inline QVector uniformBlockNamesIds() const { return m_uniformBlockNamesIds; } inline QVector storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; } inline QVector attributeNamesIds() const { return m_attributeNamesIds; } @@ -128,6 +153,7 @@ public: private: QVector m_uniformsNames; QVector m_uniformsNamesIds; + QVector m_standardUniformNamesIds; QVector m_uniforms; QVector m_attributesNames; diff --git a/src/render/renderers/opengl/renderer/renderview.cpp b/src/render/renderers/opengl/renderer/renderview.cpp index 042b60163..3612d8767 100644 --- a/src/render/renderers/opengl/renderer/renderview.cpp +++ b/src/render/renderers/opengl/renderer/renderview.cpp @@ -119,29 +119,29 @@ RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniform { RenderView::StandardUniformsNameToTypeHash setters; - setters.insert(StringToInt::lookupId(QLatin1String("modelMatrix")), ModelMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("viewMatrix")), ViewMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("projectionMatrix")), ProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("modelView")), ModelViewMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("viewProjectionMatrix")), ViewProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("modelViewProjection")), ModelViewProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("mvp")), ModelViewProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseModelMatrix")), InverseModelMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseViewMatrix")), InverseViewMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")), InverseProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseModelView")), InverseModelViewMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")), InverseViewProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseModelViewProjection")), InverseModelViewProjectionMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("modelNormalMatrix")), ModelNormalMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix); - setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio); - setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure); - setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma); - setters.insert(StringToInt::lookupId(QLatin1String("time")), Time); - setters.insert(StringToInt::lookupId(QLatin1String("eyePosition")), EyePosition); - setters.insert(StringToInt::lookupId(QLatin1String("skinningPalette[0]")), SkinningPalette); + setters.insert(Shader::modelMatrixNameId, ModelMatrix); + setters.insert(Shader::viewMatrixNameId, ViewMatrix); + setters.insert(Shader::projectionMatrixNameId, ProjectionMatrix); + setters.insert(Shader::modelViewMatrixNameId, ModelViewMatrix); + setters.insert(Shader::viewProjectionMatrixNameId, ViewProjectionMatrix); + setters.insert(Shader::modelViewProjectionNameId, ModelViewProjectionMatrix); + setters.insert(Shader::mvpNameId, ModelViewProjectionMatrix); + setters.insert(Shader::inverseModelMatrixNameId, InverseModelMatrix); + setters.insert(Shader::inverseViewMatrixNameId, InverseViewMatrix); + setters.insert(Shader::inverseProjectionMatrixNameId, InverseProjectionMatrix); + setters.insert(Shader::inverseModelViewNameId, InverseModelViewMatrix); + setters.insert(Shader::inverseViewProjectionMatrixNameId, InverseViewProjectionMatrix); + setters.insert(Shader::inverseModelViewProjectionNameId, InverseModelViewProjectionMatrix); + setters.insert(Shader::modelNormalMatrixNameId, ModelNormalMatrix); + setters.insert(Shader::modelViewNormalNameId, ModelViewNormalMatrix); + setters.insert(Shader::viewportMatrixNameId, ViewportMatrix); + setters.insert(Shader::inverseViewportMatrixNameId, InverseViewportMatrix); + setters.insert(Shader::aspectRatioNameId, AspectRatio); + setters.insert(Shader::exposureNameId, Exposure); + setters.insert(Shader::gammaNameId, Gamma); + setters.insert(Shader::timeNameId, Time); + setters.insert(Shader::eyePositionNameId, EyePosition); + setters.insert(Shader::skinningPaletteNameId, SkinningPalette); return setters; } @@ -1023,6 +1023,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, // If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name // equals to the parameter name const QVector uniformNamesIds = shader->uniformsNamesIds(); + const QVector standardUniformNamesIds = shader->standardUniformNameIds(); const QVector uniformBlockNamesIds = shader->uniformBlockNamesIds(); const QVector shaderStorageBlockNamesIds = shader->storageBlockNamesIds(); const QVector attributeNamesIds = shader->attributeNamesIds(); @@ -1042,16 +1043,15 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, shader->setFragOutputs(fragOutputs); } - if (!uniformNamesIds.isEmpty() || !attributeNamesIds.isEmpty() || + if (!uniformNamesIds.isEmpty() || !standardUniformNamesIds.isEmpty() || + !attributeNamesIds.isEmpty() || !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) { // Set default standard uniforms without bindings const Matrix4x4 worldTransform = *(entity->worldTransform()); - for (const int uniformNameId : uniformNamesIds) { - if (ms_standardUniformSetters.contains(uniformNameId)) + for (const int uniformNameId : standardUniformNamesIds) setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform); - } // Set default attributes command->m_activeAttributes = attributeNamesIds; -- cgit v1.2.3