diff options
-rw-r--r-- | src/render/backend/quniformvalue.cpp | 13 | ||||
-rw-r--r-- | src/render/backend/quniformvalue_p.h | 24 | ||||
-rw-r--r-- | src/render/backend/renderview.cpp | 207 | ||||
-rw-r--r-- | src/render/backend/renderview_p.h | 6 | ||||
-rw-r--r-- | src/render/backend/shadervariables_p.h | 3 | ||||
-rw-r--r-- | src/render/backend/stringtoint_p.h | 2 | ||||
-rw-r--r-- | src/render/graphicshelpers/graphicscontext.cpp | 7 | ||||
-rw-r--r-- | src/render/jobs/renderviewjobutils.cpp | 20 | ||||
-rw-r--r-- | src/render/jobs/renderviewjobutils_p.h | 23 | ||||
-rw-r--r-- | src/render/materialsystem/parameter.cpp | 14 | ||||
-rw-r--r-- | src/render/materialsystem/parameter_p.h | 2 | ||||
-rw-r--r-- | src/render/materialsystem/parametermapping.cpp | 15 | ||||
-rw-r--r-- | src/render/materialsystem/parametermapping_p.h | 4 | ||||
-rw-r--r-- | src/render/materialsystem/shader.cpp | 69 | ||||
-rw-r--r-- | src/render/materialsystem/shader_p.h | 18 | ||||
-rw-r--r-- | tests/auto/render/renderviewutils/tst_renderviewutils.cpp | 23 |
16 files changed, 287 insertions, 163 deletions
diff --git a/src/render/backend/quniformvalue.cpp b/src/render/backend/quniformvalue.cpp index 50de0631e..016bf8d8c 100644 --- a/src/render/backend/quniformvalue.cpp +++ b/src/render/backend/quniformvalue.cpp @@ -86,23 +86,22 @@ ShaderParameterPack::~ShaderParameterPack() m_uniforms.clear(); } -void ShaderParameterPack::setUniform(const QString &glslName, const QUniformValue *val) +void ShaderParameterPack::setUniform(const int glslNameId, const QUniformValue *val) { - m_uniforms.insert(glslName, val); + m_uniforms.insert(glslNameId, val); } -void ShaderParameterPack::setTexture(const QString &glslName, const Qt3DCore::QNodeId &texId) +void ShaderParameterPack::setTexture(const int glslNameId, const Qt3DCore::QNodeId &texId) { for (int t=0; t<m_textures.size(); ++t) { - if (m_textures[t].glslName != glslName) { + if (m_textures[t].glslNameId != glslNameId) continue; - } m_textures[t].texId = texId; return; } - m_textures.append(NamedTexture(glslName, texId)); + m_textures.append(NamedTexture(glslNameId, texId)); } // Contains Uniform Block Index and QNodeId of the ShaderData (UBO) @@ -130,7 +129,7 @@ void TextureUniform::apply(GraphicsContext *ctx, const ShaderUniform &descriptio #endif } else { qCWarning(Render::Backend, "Invalid texture unit supplied for \"%s\"", - qUtf8Printable(description.m_name)); + qUtf8Printable(description.m_nameId)); } } diff --git a/src/render/backend/quniformvalue_p.h b/src/render/backend/quniformvalue_p.h index d07d640b8..6ebcfca8d 100644 --- a/src/render/backend/quniformvalue_p.h +++ b/src/render/backend/quniformvalue_p.h @@ -87,7 +87,7 @@ public: virtual bool operator ==(const QUniformValue &other); bool operator !=(const QUniformValue &other); - virtual bool isTexture() const + virtual bool isTexture() const Q_DECL_NOEXCEPT { return false; } @@ -107,12 +107,12 @@ public : { } - bool isTexture() const Q_DECL_FINAL + bool isTexture() const Q_DECL_NOEXCEPT Q_DECL_FINAL { return true; } - void setTextureId(const Qt3DCore::QNodeId &id) + void setTextureId(const Qt3DCore::QNodeId id) { m_textureId = id; } @@ -150,28 +150,30 @@ struct BlockToSSBO { Qt3DCore::QNodeId m_bufferID; }; +typedef QHash<int, const QUniformValue *> PackUniformHash; + class ShaderParameterPack { public: ~ShaderParameterPack(); - void setUniform(const QString &glslName, const QUniformValue *val); - void setTexture(const QString &glslName, const Qt3DCore::QNodeId &id); + void setUniform(const int glslNameId, const QUniformValue *val); + void setTexture(const int glslNameId, const Qt3DCore::QNodeId &id); void setUniformBuffer(const BlockToUBO &blockToUBO); void setShaderStorageBuffer(const BlockToSSBO &blockToSSBO); - inline const QHash<QString, const QUniformValue* > &uniforms() const { return m_uniforms; } - const QUniformValue *uniform(const QString &glslName) const { return m_uniforms.value(glslName); } + inline const PackUniformHash &uniforms() const { return m_uniforms; } + const QUniformValue *uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); } struct NamedTexture { NamedTexture() {} - NamedTexture(const QString &nm, const Qt3DCore::QNodeId &t) - : glslName(nm) + NamedTexture(const int nm, const Qt3DCore::QNodeId &t) + : glslNameId(nm) , texId(t) { } - QString glslName; + int glslNameId; Qt3DCore::QNodeId texId; }; @@ -179,7 +181,7 @@ public: inline QVector<BlockToUBO> uniformBuffers() const { return m_uniformBuffers; } inline QVector<BlockToSSBO> shaderStorageBuffers() const { return m_shaderStorageBuffers; } private: - QHash<QString, const QUniformValue* > m_uniforms; + PackUniformHash m_uniforms; QVector<NamedTexture> m_textures; QVector<BlockToUBO> m_uniformBuffers; diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index 8103493f2..8a8b14287 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -65,6 +65,8 @@ #include <Qt3DRender/private/viewportnode_p.h> #include <Qt3DRender/private/buffermanager_p.h> +#include <Qt3DRender/private/stringtoint_p.h> + #include <Qt3DRender/qparametermapping.h> #include <Qt3DCore/qentity.h> @@ -80,12 +82,25 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { namespace Render { -static const int MAX_LIGHTS = 8; namespace { const int qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>(); +const int MAX_LIGHTS = 8; + +const QString LIGHT_POSITION_NAME = QStringLiteral(".position"); +const QString LIGHT_TYPE_NAME = QStringLiteral(".type"); +const QString LIGHT_COLOR_NAME = QStringLiteral(".color"); +const QString LIGHT_INTENSITY_NAME = QStringLiteral(".intensity"); + +int LIGHT_COUNT_NAME_ID = 0; +int LIGHT_POSITION_NAMES[MAX_LIGHTS]; +int LIGHT_TYPE_NAMES[MAX_LIGHTS]; +int LIGHT_COLOR_NAMES[MAX_LIGHTS]; +int LIGHT_INTENSITY_NAMES[MAX_LIGHTS]; +QString LIGHT_STRUCT_NAMES[MAX_LIGHTS]; + // TODO: Should we treat lack of layer data as implicitly meaning that an // entity is in all layers? bool isEntityInLayers(const Entity *entity, const QStringList &layers) @@ -124,30 +139,33 @@ void destroyUniformValue(const QUniformValue *value, Qt3DCore::QFrameAllocator * } // anonymouse namespace -RenderView::StandardUniformsPFuncsHash RenderView::ms_standardUniformSetters = RenderView::initializeStandardUniformSetters(); +bool wasInitialized = false; +RenderView::StandardUniformsPFuncsHash RenderView::ms_standardUniformSetters; QStringList RenderView::ms_standardAttributesNames = RenderView::initializeStandardAttributeNames(); + + RenderView::StandardUniformsPFuncsHash RenderView::initializeStandardUniformSetters() { RenderView::StandardUniformsPFuncsHash setters; - setters.insert(QStringLiteral("modelMatrix"), &RenderView::modelMatrix); - setters.insert(QStringLiteral("viewMatrix"), &RenderView::viewMatrix); - setters.insert(QStringLiteral("projectionMatrix"), &RenderView::projectionMatrix); - setters.insert(QStringLiteral("modelView"), &RenderView::modelViewMatrix); - setters.insert(QStringLiteral("modelViewProjection"), &RenderView::modelViewProjectionMatrix); - setters.insert(QStringLiteral("mvp"), &RenderView::modelViewProjectionMatrix); - setters.insert(QStringLiteral("inverseModelMatrix"), &RenderView::inverseModelMatrix); - setters.insert(QStringLiteral("inverViewMatrix"), &RenderView::inverseViewMatrix); - setters.insert(QStringLiteral("inverseProjectionMatrix"), &RenderView::inverseProjectionMatrix); - setters.insert(QStringLiteral("inverseModelView"), &RenderView::inverseModelViewMatrix); - setters.insert(QStringLiteral("inverseModelViewProjection"), &RenderView::inverseModelViewProjectionMatrix); - setters.insert(QStringLiteral("modelNormalMatrix"), &RenderView::modelNormalMatrix); - setters.insert(QStringLiteral("modelViewNormal"), &RenderView::modelViewNormalMatrix); - setters.insert(QStringLiteral("viewportMatrix"), &RenderView::viewportMatrix); - setters.insert(QStringLiteral("inverseViewportMatrix"), &RenderView::inverseViewportMatrix); - setters.insert(QStringLiteral("time"), &RenderView::time); - setters.insert(QStringLiteral("eyePosition"), &RenderView::eyePosition); + setters.insert(StringToInt::lookupId(QStringLiteral("modelMatrix")), &RenderView::modelMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("viewMatrix")), &RenderView::viewMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("projectionMatrix")), &RenderView::projectionMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("modelView")), &RenderView::modelViewMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("modelViewProjection")), &RenderView::modelViewProjectionMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("mvp")), &RenderView::modelViewProjectionMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverseModelMatrix")), &RenderView::inverseModelMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverViewMatrix")), &RenderView::inverseViewMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverseProjectionMatrix")), &RenderView::inverseProjectionMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverseModelView")), &RenderView::inverseModelViewMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverseModelViewProjection")), &RenderView::inverseModelViewProjectionMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("modelNormalMatrix")), &RenderView::modelNormalMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("modelViewNormal")), &RenderView::modelViewNormalMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("viewportMatrix")), &RenderView::viewportMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("inverseViewportMatrix")), &RenderView::inverseViewportMatrix); + setters.insert(StringToInt::lookupId(QStringLiteral("time")), &RenderView::time); + setters.insert(StringToInt::lookupId(QStringLiteral("eyePosition")), &RenderView::eyePosition); return setters; } @@ -288,6 +306,21 @@ RenderView::RenderView() m_workGroups[0] = 1; m_workGroups[1] = 1; m_workGroups[2] = 1; + + if (Q_UNLIKELY(!wasInitialized)) { + // Needed as we can control the init order of static/global variables across compile units + // and this hash relies on the static StringToInt class + wasInitialized = true; + RenderView::ms_standardUniformSetters = RenderView::initializeStandardUniformSetters(); + LIGHT_COUNT_NAME_ID = StringToInt::lookupId(QStringLiteral("lightCount")); + for (int i = 0; i < MAX_LIGHTS; ++i) { + LIGHT_STRUCT_NAMES[i] = QStringLiteral("lights[") + QString::number(i) + QLatin1Char(']'); + LIGHT_POSITION_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_POSITION_NAME); + LIGHT_TYPE_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_TYPE_NAME); + LIGHT_COLOR_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_COLOR_NAME); + LIGHT_INTENSITY_NAMES[i] = StringToInt::lookupId(LIGHT_STRUCT_NAMES[i] + LIGHT_INTENSITY_NAME); + } + } } RenderView::~RenderView() @@ -297,9 +330,9 @@ RenderView::~RenderView() Q_FOREACH (RenderCommand *command, m_commands) { // Deallocate all uniform values of the QUniformPack of each RenderCommand - const QHash<QString, const QUniformValue* > uniforms = command->m_parameterPack.uniforms(); - const QHash<QString, const QUniformValue* >::const_iterator end = uniforms.constEnd(); - QHash<QString, const QUniformValue* >::const_iterator it = uniforms.constBegin(); + const PackUniformHash uniforms = command->m_parameterPack.uniforms(); + const PackUniformHash::const_iterator end = uniforms.constEnd(); + PackUniformHash::const_iterator it = uniforms.constBegin(); for (; it != end; ++it) destroyUniformValue(it.value(), m_allocator); @@ -358,14 +391,16 @@ void RenderView::sort() ++i; if (i - j > 0) { // Several commands have the same shader, so we minimize uniform changes - QHash<QString, const QUniformValue *> cachedUniforms = m_commands[j++]->m_parameterPack.uniforms(); + PackUniformHash cachedUniforms = m_commands[j++]->m_parameterPack.uniforms(); while (j < i) { - QHash<QString, const QUniformValue *> &uniforms = m_commands[j]->m_parameterPack.m_uniforms; - QHash<QString, const QUniformValue *>::iterator it = uniforms.begin(); + // We need the reference here as we are modifying the original container + // not the copy + PackUniformHash &uniforms = m_commands[j]->m_parameterPack.m_uniforms; + PackUniformHash::iterator it = uniforms.begin(); + const PackUniformHash::iterator end = uniforms.end(); - while (it != uniforms.end()) { - bool found = false; + while (it != end) { // We are comparing the values: // - raw uniform values // - the texture Node id if the uniform represents a texture @@ -373,15 +408,11 @@ void RenderView::sort() // sharing the same material (shader) are rendered, we can't have the case // where two uniforms, referencing the same texture eventually have 2 different // texture unit values - if (cachedUniforms.contains(it.key())) { - const QUniformValue *refValue = cachedUniforms.value(it.key()); - if (*const_cast<QUniformValue *>(refValue) == *it.value()) { - destroyUniformValue(it.value(), m_allocator); - it = uniforms.erase(it); - found = true; - } - } - if (!found) { + const QUniformValue *refValue = cachedUniforms.value(it.key(), Q_NULLPTR); + if (refValue != Q_NULLPTR && *const_cast<QUniformValue *>(refValue) == *it.value()) { + destroyUniformValue(it.value(), m_allocator); + it = uniforms.erase(it); + } else { cachedUniforms.insert(it.key(), it.value()); ++it; } @@ -593,9 +624,9 @@ const AttachmentPack &RenderView::attachmentPack() const return m_attachmentPack; } -void RenderView::setUniformValue(ShaderParameterPack &uniformPack, const QString &name, const QVariant &value) +void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value) { - if (const QUniformValue *val = uniformPack.uniform(name)) + if (const QUniformValue *val = uniformPack.uniform(nameId)) destroyUniformValue(val, m_allocator); Texture *tex = Q_NULLPTR; @@ -606,22 +637,22 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, const QString if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) { if ((tex = m_manager->textureManager()->lookupResource(value.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) { - uniformPack.setTexture(name, tex->peerUuid()); + uniformPack.setTexture(nameId, tex->peerUuid()); TextureUniform *texUniform = m_allocator->allocate<TextureUniform>(); texUniform->setTextureId(tex->peerUuid()); - uniformPack.setUniform(name, texUniform); + uniformPack.setUniform(nameId, texUniform); } } else { - uniformPack.setUniform(name, QUniformValue::fromVariant(value, m_allocator)); + uniformPack.setUniform(nameId, QUniformValue::fromVariant(value, m_allocator)); } } -void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, const QString &glslName, const QString &name, const QMatrix4x4 &worldTransform) +void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, int glslNameId, int nameId, const QMatrix4x4 &worldTransform) { - if (const QUniformValue *val = uniformPack.uniform(glslName)) + if (const QUniformValue *val = uniformPack.uniform(glslNameId)) destroyUniformValue(val, m_allocator); - uniformPack.setUniform(glslName, (this->*ms_standardUniformSetters[name])(worldTransform)); + uniformPack.setUniform(glslNameId, (this->*ms_standardUniformSetters[nameId])(worldTransform)); } void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack, @@ -725,8 +756,8 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif // 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 - QHash<QString, QVariant>::const_iterator activeValuesIt = m_data->m_uniformBlockBuilder.activeUniformNamesToValue.constBegin(); - const QHash<QString, QVariant>::const_iterator activeValuesEnd = m_data->m_uniformBlockBuilder.activeUniformNamesToValue.constEnd(); + QHash<int, QVariant>::const_iterator activeValuesIt = m_data->m_uniformBlockBuilder.activeUniformNamesToValue.constBegin(); + const QHash<int, QVariant>::const_iterator activeValuesEnd = m_data->m_uniformBlockBuilder.activeUniformNamesToValue.constEnd(); while (activeValuesIt != activeValuesEnd) { setUniformValue(uniformPack, activeValuesIt.key(), activeValuesIt.value()); @@ -784,10 +815,10 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, // Builds the QUniformPack, sets shader standard uniforms and store attributes name / glname bindings // 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<QString> uniformNames = shader->uniformsNames(); + const QVector<int> uniformNamesIds = shader->uniformsNamesIds(); + const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds(); + const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds(); const QVector<QString> attributeNames = shader->attributesNames(); - const QVector<QString> uniformBlockNames = shader->uniformBlockNames(); - const QVector<QString> shaderStorageBlockNames = shader->storageBlockNames(); // Set fragData Name and index // Later on we might want to relink the shader if attachments have changed @@ -800,12 +831,12 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, } } - if (!uniformNames.isEmpty() || !attributeNames.isEmpty() || !shaderStorageBlockNames.isEmpty()) { + if (!uniformNamesIds.isEmpty() || !attributeNames.isEmpty() || !shaderStorageBlockNamesIds.isEmpty()) { // Set default standard uniforms without bindings - Q_FOREACH (const QString &uniformName, uniformNames) { - if (ms_standardUniformSetters.contains(uniformName)) - setStandardUniformValue(command->m_parameterPack, uniformName, uniformName, worldTransform); + Q_FOREACH (const int uniformNameId, uniformNamesIds) { + if (ms_standardUniformSetters.contains(uniformNameId)) + setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, worldTransform); } // Set default attributes @@ -816,7 +847,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, // Set uniforms and attributes explicitly binded Q_FOREACH (const ParameterMapping &binding, rPass->bindings()) { - ParameterInfoList::iterator it = findParamInfo(¶meters, binding.parameterName()); + const ParameterInfoList::const_iterator it = findParamInfo(¶meters, binding.parameterNameId()); if (it == parameters.end()) { // A Parameters wasn't found with the name binding.parameterName @@ -829,9 +860,9 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, break; } case QParameterMapping::StandardUniform: - if (uniformNames.contains(binding.shaderVariableName()) - && ms_standardUniformSetters.contains(binding.parameterName())) { - setStandardUniformValue(command->m_parameterPack, binding.shaderVariableName(), binding.parameterName(), worldTransform); + if (uniformNamesIds.contains(binding.shaderVariableNameId()) + && ms_standardUniformSetters.contains(binding.parameterNameId())) { + setStandardUniformValue(command->m_parameterPack, binding.shaderVariableNameId(), binding.parameterNameId(), worldTransform); break; } @@ -842,14 +873,14 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, } case QParameterMapping::UniformBufferObject: - if (uniformBlockNames.contains(binding.parameterName())) { - setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlock(it->name), it->value); + if (uniformBlockNamesIds.contains(binding.parameterNameId())) { + setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), it->value); break; } case QParameterMapping::ShaderStorageBufferObject: - if (shaderStorageBlockNames.contains(binding.parameterName())) { - setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlock(it->name), it->value); + if (shaderStorageBlockNamesIds.contains(binding.parameterNameId())) { + setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), it->value); break; } @@ -866,26 +897,24 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, // -> uniform block / array (4.3) // -> ssbo block / array (4.3) - if ((!uniformNames.isEmpty() || !uniformBlockNames.isEmpty() || !shaderStorageBlockNames.isEmpty()) && !parameters.isEmpty()) { - ParameterInfoList::iterator it = parameters.begin(); - const ParameterInfoList::iterator parametersEnd = parameters.end(); + if ((!uniformNamesIds.isEmpty() || !uniformBlockNamesIds.isEmpty() || !shaderStorageBlockNamesIds.isEmpty()) + && !parameters.isEmpty()) { + ParameterInfoList::const_iterator it = parameters.cbegin(); + const ParameterInfoList::const_iterator parametersEnd = parameters.cend(); while (it != parametersEnd) { - if (uniformNames.contains(it->name)) { // Parameter is a regular uniform - setUniformValue(command->m_parameterPack, it->name, it->value); - } else if (uniformBlockNames.indexOf(it->name) != -1) { // Parameter is a uniform block - setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlock(it->name), it->value); - } else if (shaderStorageBlockNames.indexOf(it->name) != -1) { // Parameters is a SSBO - setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlock(it->name), it->value); + if (uniformNamesIds.contains(it->nameId)) { // Parameter is a regular uniform + setUniformValue(command->m_parameterPack, it->nameId, it->value); + } else if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block + setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), it->value); + } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO + setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), it->value); } else { // Parameter is a struct const QVariant &v = it->value; - if (static_cast<QMetaType::Type>(v.userType()) == qNodeIdTypeId) { - const Qt3DCore::QNodeId nodeId = v.value<Qt3DCore::QNodeId>(); - ShaderData *shaderData = Q_NULLPTR; - shaderData = m_manager->shaderDataManager()->lookupResource(nodeId); - if (shaderData) { - // Try to check if we have a struct or array matching a QShaderData parameter - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, it->name); - } + ShaderData *shaderData = Q_NULLPTR; + if (static_cast<QMetaType::Type>(v.type()) == qNodeIdTypeId && + (shaderData = m_manager->shaderDataManager()->lookupResource(v.value<Qt3DCore::QNodeId>())) != Q_NULLPTR) { + // Try to check if we have a struct or array matching a QShaderData parameter + setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId)); } // Otherwise: param unused by current shader } @@ -894,8 +923,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, } // Lights - const QString LIGHT_COUNT_NAME = QStringLiteral("lightCount"); - const QString LIGHT_POSITION_NAME = QStringLiteral(".position"); int lightIdx = 0; Q_FOREACH (const LightSource &lightSource, activeLightSources) { @@ -906,21 +933,23 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass, Q_FOREACH (Light *light, lightSource.lights) { if (lightIdx == MAX_LIGHTS) break; - const QString structName = QStringLiteral("lights[") + QString::number(lightIdx) + QLatin1Char(']'); - setUniformValue(command->m_parameterPack, structName + LIGHT_POSITION_NAME, worldPos); - setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, light, structName); + setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos); + setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QLight::PointLight)); + setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], QVector3D(1.0f, 1.0f, 1.0f)); + setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], QVector3D(0.5f, 0.5f, 0.5f)); + setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, light, LIGHT_STRUCT_NAMES[lightIdx]); ++lightIdx; } } - if (uniformNames.contains(LIGHT_COUNT_NAME)) - setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME, qMax(1, lightIdx)); + if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID)) + setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, qMax(1, lightIdx)); if (activeLightSources.isEmpty()) { - setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].type"), int(QLight::PointLight)); - setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].position"), QVector3D(10.0f, 10.0f, 0.0f)); - setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].color"), QVector3D(1.0f, 1.0f, 1.0f)); - setUniformValue(command->m_parameterPack, QStringLiteral("lights[0].intensity"), QVector3D(0.5f, 0.5f, 0.5f)); + setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], QVector3D(10.0f, 10.0f, 0.0f)); + setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QLight::PointLight)); + setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], QVector3D(1.0f, 1.0f, 1.0f)); + setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[0], QVector3D(0.5f, 0.5f, 0.5f)); } } // Set frag outputs in the shaders if hash not empty diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h index 5df0d9dc7..8579a74a3 100644 --- a/src/render/backend/renderview_p.h +++ b/src/render/backend/renderview_p.h @@ -300,7 +300,7 @@ private: QVector<LightSource> m_lightSources; - typedef QHash<QString, QUniformValue* (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash; + typedef QHash<int, QUniformValue* (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash; static StandardUniformsPFuncsHash ms_standardUniformSetters; static StandardUniformsPFuncsHash initializeStandardUniformSetters(); static QStringList ms_standardAttributesNames; @@ -323,8 +323,8 @@ private: QUniformValue *time(const QMatrix4x4 &model) const; QUniformValue *eyePosition(const QMatrix4x4 &model) const; - void setUniformValue(ShaderParameterPack &uniformPack, const QString &name, const QVariant &value); - void setStandardUniformValue(ShaderParameterPack &uniformPack, const QString &glslName, const QString &name, const QMatrix4x4 &worldTransform); + void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value); + void setStandardUniformValue(ShaderParameterPack &uniformPack, int glslNameId, int nameId, const QMatrix4x4 &worldTransform); void setUniformBlockValue(ShaderParameterPack &uniformPack, Shader *shader, const ShaderUniformBlock &block, diff --git a/src/render/backend/shadervariables_p.h b/src/render/backend/shadervariables_p.h index 1409e6b2d..9fd7efa02 100644 --- a/src/render/backend/shadervariables_p.h +++ b/src/render/backend/shadervariables_p.h @@ -78,6 +78,7 @@ struct ShaderUniform {} QString m_name; + int m_nameId; GLenum m_type; int m_size; int m_offset; // -1 default, >= 0 if uniform defined in uniform block @@ -99,6 +100,7 @@ struct ShaderUniformBlock {} QString m_name; + int m_nameId; int m_index; int m_binding; int m_activeUniformsCount; @@ -115,6 +117,7 @@ struct ShaderStorageBlock {} QString m_name; + int m_nameId; int m_index; int m_binding; int m_size; diff --git a/src/render/backend/stringtoint_p.h b/src/render/backend/stringtoint_p.h index 0c2c5dd09..27a3f6f05 100644 --- a/src/render/backend/stringtoint_p.h +++ b/src/render/backend/stringtoint_p.h @@ -61,7 +61,7 @@ namespace Qt3DRender { namespace Render { -class StringToInt +class Q_AUTOTEST_EXPORT StringToInt { public: static int lookupId(const QString &str); diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp index c069c4a9f..ea3e400f3 100644 --- a/src/render/graphicshelpers/graphicscontext.cpp +++ b/src/render/graphicshelpers/graphicscontext.cpp @@ -971,7 +971,8 @@ void GraphicsContext::setParameters(ShaderParameterPack ¶meterPack) deactivateTexturesWithScope(TextureScopeMaterial); // Update the uniforms with the correct texture unit id's - const QHash<QString, const QUniformValue *> &uniformValues = parameterPack.uniforms(); + const PackUniformHash uniformValues = parameterPack.uniforms(); + for (int i = 0; i < parameterPack.textures().size(); ++i) { const ShaderParameterPack::NamedTexture &namedTex = parameterPack.textures().at(i); Texture *t = manager->lookupResource<Texture, TextureManager>(namedTex.texId); @@ -979,8 +980,8 @@ void GraphicsContext::setParameters(ShaderParameterPack ¶meterPack) // TO DO : Rework the way textures are loaded if (t != Q_NULLPTR) { int texUnit = activateTexture(TextureScopeMaterial, t); - if (uniformValues.contains(namedTex.glslName)) { - texUniform = static_cast<const TextureUniform *>(uniformValues[namedTex.glslName]); + if (uniformValues.contains(namedTex.glslNameId)) { + texUniform = static_cast<const TextureUniform *>(uniformValues[namedTex.glslNameId]); if (texUniform != Q_NULLPTR) const_cast<TextureUniform *>(texUniform)->setTextureUnit(texUnit); } diff --git a/src/render/jobs/renderviewjobutils.cpp b/src/render/jobs/renderviewjobutils.cpp index 773f329d6..2be1558b1 100644 --- a/src/render/jobs/renderviewjobutils.cpp +++ b/src/render/jobs/renderviewjobutils.cpp @@ -62,6 +62,7 @@ #include <Qt3DRender/private/statesetnode_p.h> #include <Qt3DRender/private/dispatchcompute_p.h> #include <Qt3DRender/private/rendersurfaceselector_p.h> +#include <Qt3DRender/private/stringtoint_p.h> QT_BEGIN_NAMESPACE @@ -353,11 +354,12 @@ RenderRenderPassList findRenderPassesForTechnique(NodeManagers *manager, } -ParameterInfoList::iterator findParamInfo(ParameterInfoList *params, const QString &name) +ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *params, const int nameId) { - ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), name); - if (it != params->end() && it->name != name) - return params->end(); + const ParameterInfoList::const_iterator end = params->cend(); + ParameterInfoList::const_iterator it = std::lower_bound(params->cbegin(), end, nameId); + if (it != end && it->nameId != nameId) + return end; return it; } @@ -367,9 +369,9 @@ void addParametersForIds(ParameterInfoList *params, ParameterManager *manager, Q_FOREACH (const QNodeId ¶mId, parameterIds) { Parameter *param = manager->lookupResource(paramId); if (param != Q_NULLPTR) { - ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->name()); - if (it == params->end() || it->name != param->name()) - params->insert(it, ParameterInfo(param->name(), param->value())); + ParameterInfoList::iterator it = std::lower_bound(params->begin(), params->end(), param->nameId()); + if (it == params->end() || it->nameId != param->nameId()) + params->insert(it, ParameterInfo(param->nameId(), param->value())); } } } @@ -437,7 +439,7 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(const QStrin QString varName = blockName + QStringLiteral(".") + qmlPropertyName + QStringLiteral("[0]"); if (uniforms.contains(varName)) { qCDebug(Shaders) << "UBO array member " << varName << " set for update"; - activeUniformNamesToValue.insert(varName, value); + activeUniformNamesToValue.insert(StringToInt::lookupId(varName), value); } } } else if (value.userType() == qNodeIdTypeId) { // Struct qmlPropertyName.structMember @@ -450,7 +452,7 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(const QStrin QString varName = blockName + QStringLiteral(".") + qmlPropertyName; if (uniforms.contains(varName)) { qCDebug(Shaders) << "UBO scalar member " << varName << " set for update"; - activeUniformNamesToValue.insert(varName, value); + activeUniformNamesToValue.insert(StringToInt::lookupId(varName), value); } } } diff --git a/src/render/jobs/renderviewjobutils_p.h b/src/render/jobs/renderviewjobutils_p.h index 8c4f82adf..3c5e25173 100644 --- a/src/render/jobs/renderviewjobutils_p.h +++ b/src/render/jobs/renderviewjobutils_p.h @@ -96,29 +96,25 @@ Q_AUTOTEST_EXPORT RenderRenderPassList findRenderPassesForTechnique(NodeManagers struct ParameterInfo { - ParameterInfo(const QString &name = QString(), const QVariant &value = QVariant()) - : name(name) + ParameterInfo(const int nameId = -1, const QVariant &value = QVariant()) + : nameId(nameId) , value(value) {} - QString name; + int nameId; QVariant value; - bool operator<(const QString &otherName) const + bool operator<(const int otherNameId) const { - return name < otherName; + return nameId < otherNameId; } bool operator<(const ParameterInfo &other) const { - return name < other.name; + return nameId < other.nameId; } }; -inline bool operator<(const QString &otherName, const ParameterInfo &pi) -{ - return otherName < pi.name; -} typedef QVarLengthArray<ParameterInfo, 16> ParameterInfoList; @@ -140,13 +136,14 @@ void parametersFromParametersProvider(ParameterInfoList *infoList, addParametersForIds(infoList, manager, pass->parameters()); } -Q_AUTOTEST_EXPORT ParameterInfoList::iterator findParamInfo(ParameterInfoList *infoList, - const QString &name); +Q_AUTOTEST_EXPORT ParameterInfoList::const_iterator findParamInfo(ParameterInfoList *infoList, + const int nameId); Q_AUTOTEST_EXPORT void addToRenderStateSet(RenderStateSet *stateSet, const RenderStateCollection *collection, RenderStateManager *manager); +typedef QHash<int, QVariant> UniformBlockValueBuilderHash; struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder { @@ -162,7 +159,7 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder bool updatedPropertiesOnly; QHash<QString, ShaderUniform> uniforms; - QHash<QString, QVariant> activeUniformNamesToValue; + UniformBlockValueBuilderHash activeUniformNamesToValue; ShaderDataManager *shaderDataManager; }; diff --git a/src/render/materialsystem/parameter.cpp b/src/render/materialsystem/parameter.cpp index db3f3df19..5933f1d52 100644 --- a/src/render/materialsystem/parameter.cpp +++ b/src/render/materialsystem/parameter.cpp @@ -47,6 +47,7 @@ #include <Qt3DRender/private/buffer_p.h> #include <Qt3DRender/private/managers_p.h> +#include <Qt3DRender/private/stringtoint_p.h> QT_BEGIN_NAMESPACE @@ -57,6 +58,7 @@ namespace Render { Parameter::Parameter() : QBackendNode() + , m_nameId(-1) { } @@ -64,6 +66,7 @@ void Parameter::updateFromPeer(Qt3DCore::QNode *peer) { QParameter *param = static_cast<QParameter *>(peer); m_name = param->name(); + m_nameId = StringToInt::lookupId(m_name); m_value = static_cast<QParameterPrivate *>(QNodePrivate::get(param))->m_backendValue; } @@ -72,10 +75,12 @@ void Parameter::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e); if (e->type() == NodeUpdated) { - if (propertyChange->propertyName() == QByteArrayLiteral("name")) + if (propertyChange->propertyName() == QByteArrayLiteral("name")) { m_name = propertyChange->value().toString(); - else if (propertyChange->propertyName() == QByteArrayLiteral("value")) + m_nameId = StringToInt::lookupId(m_name); + } else if (propertyChange->propertyName() == QByteArrayLiteral("value")) { m_value = propertyChange->value(); + } } } @@ -89,6 +94,11 @@ QVariant Parameter::value() const return m_value; } +int Parameter::nameId() const +{ + return m_nameId; +} + } // namespace Render } // namespace Qt3DRender diff --git a/src/render/materialsystem/parameter_p.h b/src/render/materialsystem/parameter_p.h index 281e1b9e9..e3e2fd663 100644 --- a/src/render/materialsystem/parameter_p.h +++ b/src/render/materialsystem/parameter_p.h @@ -74,10 +74,12 @@ public: QString name() const; QVariant value() const; + int nameId() const; private: QString m_name; QVariant m_value; + int m_nameId; }; } // namespace Render diff --git a/src/render/materialsystem/parametermapping.cpp b/src/render/materialsystem/parametermapping.cpp index 06dd14836..574025030 100644 --- a/src/render/materialsystem/parametermapping.cpp +++ b/src/render/materialsystem/parametermapping.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "parametermapping_p.h" +#include <Qt3DRender/private/stringtoint_p.h> QT_BEGIN_NAMESPACE @@ -46,6 +47,8 @@ namespace Render { ParameterMapping::ParameterMapping() : m_bindingType(QParameterMapping::Uniform) + , m_parameterNameId(-1) + , m_shaderVariableNameId(-1) { } @@ -53,6 +56,8 @@ ParameterMapping::ParameterMapping(QParameterMapping *mapping) : m_id(mapping ? mapping->id() : Qt3DCore::QNodeId()) , m_parameterName(mapping ? mapping->parameterName() : QString()) , m_shaderVariableName(mapping ? mapping->shaderVariableName() : QString()) + , m_parameterNameId(StringToInt::lookupId(m_parameterName)) + , m_shaderVariableNameId(StringToInt::lookupId(m_shaderVariableName)) , m_bindingType(mapping ? mapping->bindingType() : QParameterMapping::Uniform) { } @@ -77,6 +82,16 @@ QString ParameterMapping::shaderVariableName() const return m_shaderVariableName; } +int ParameterMapping::parameterNameId() const +{ + return m_parameterNameId; +} + +int ParameterMapping::shaderVariableNameId() const +{ + return m_shaderVariableNameId; +} + QParameterMapping::Binding ParameterMapping::bindingType() const { return m_bindingType; diff --git a/src/render/materialsystem/parametermapping_p.h b/src/render/materialsystem/parametermapping_p.h index 734fa23ed..975fed18e 100644 --- a/src/render/materialsystem/parametermapping_p.h +++ b/src/render/materialsystem/parametermapping_p.h @@ -70,12 +70,16 @@ public: Qt3DCore::QNodeId id() const; QString parameterName() const; QString shaderVariableName() const; + int parameterNameId() const; + int shaderVariableNameId() const; QParameterMapping::Binding bindingType() const; private: Qt3DCore::QNodeId m_id; QString m_parameterName; QString m_shaderVariableName; + int m_parameterNameId; + int m_shaderVariableNameId; QParameterMapping::Binding m_bindingType; }; diff --git a/src/render/materialsystem/shader.cpp b/src/render/materialsystem/shader.cpp index 396533da3..c5359d41b 100644 --- a/src/render/materialsystem/shader.cpp +++ b/src/render/materialsystem/shader.cpp @@ -48,6 +48,7 @@ #include <Qt3DRender/private/graphicscontext_p.h> #include <Qt3DRender/private/attachmentpack_p.h> #include <Qt3DCore/qscenepropertychange.h> +#include <Qt3DRender/private/stringtoint_p.h> QT_BEGIN_NAMESPACE @@ -188,7 +189,7 @@ QHash<QString, ShaderUniform> Shader::activeUniformsForUniformBlock(int blockInd return m_uniformBlockIndexToShaderUniforms.value(blockIndex); } -ShaderUniformBlock Shader::uniformBlock(int blockIndex) +ShaderUniformBlock Shader::uniformBlockForBlockIndex(int blockIndex) { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_index == blockIndex) { @@ -198,7 +199,17 @@ ShaderUniformBlock Shader::uniformBlock(int blockIndex) return ShaderUniformBlock(); } -ShaderUniformBlock Shader::uniformBlock(const QString &blockName) +ShaderUniformBlock Shader::uniformBlockForBlockNameId(int blockNameId) +{ + for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { + if (m_uniformBlocks[i].m_nameId == blockNameId) { + return m_uniformBlocks[i]; + } + } + return ShaderUniformBlock(); +} + +ShaderUniformBlock Shader::uniformBlockForBlockName(const QString &blockName) { for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) { if (m_uniformBlocks[i].m_name == blockName) { @@ -208,7 +219,7 @@ ShaderUniformBlock Shader::uniformBlock(const QString &blockName) return ShaderUniformBlock(); } -ShaderStorageBlock Shader::storageBlock(int blockIndex) +ShaderStorageBlock Shader::storageBlockForBlockIndex(int blockIndex) { for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { if (m_shaderStorageBlocks[i].m_index == blockIndex) @@ -217,7 +228,16 @@ ShaderStorageBlock Shader::storageBlock(int blockIndex) return ShaderStorageBlock(); } -ShaderStorageBlock Shader::storageBlock(const QString &blockName) +ShaderStorageBlock Shader::storageBlockForBlockNameId(int blockNameId) +{ + for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { + if (m_shaderStorageBlocks[i].m_nameId == blockNameId) + return m_shaderStorageBlocks[i]; + } + return ShaderStorageBlock(); +} + +ShaderStorageBlock Shader::storageBlockForBlockName(const QString &blockName) { for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) { if (m_shaderStorageBlocks[i].m_name == blockName) @@ -243,11 +263,11 @@ QOpenGLShaderProgram *Shader::getOrCreateProgram(GraphicsContext *ctx) void Shader::updateUniforms(GraphicsContext *ctx, const ShaderParameterPack &pack) { - const QHash<QString, const QUniformValue* > &values = pack.uniforms(); - const QHash<QString, const QUniformValue* >::const_iterator valueEnd = values.constEnd(); + const PackUniformHash values = pack.uniforms(); + const PackUniformHash::const_iterator valueEnd = values.constEnd(); Q_FOREACH (const ShaderUniform &uniform, m_uniforms) { - QHash<QString, const QUniformValue* >::const_iterator valueIt = values.constFind(uniform.m_name); + PackUniformHash::const_iterator valueIt = values.constFind(uniform.m_nameId); if (valueIt != valueEnd) valueIt.value()->apply(ctx, uniform); } @@ -262,6 +282,21 @@ void Shader::setFragOutputs(const QHash<QString, int> &fragOutputs) updateDNA(); } +QVector<int> Shader::uniformsNamesIds() const +{ + return m_uniformsNamesIds; +} + +QVector<int> Shader::uniformBlockNamesIds() const +{ + return m_uniformBlockNamesIds; +} + +QVector<int> Shader::storageBlockNamesIds() const +{ + return m_shaderStorageBlockNamesIds; +} + static QOpenGLShader::ShaderType shaderType(QShaderProgram::ShaderType type) { switch (type) { @@ -347,10 +382,13 @@ void Shader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescriptio { m_uniforms = uniformsDescription; m_uniformsNames.resize(uniformsDescription.size()); + m_uniformsNamesIds.resize(uniformsDescription.size()); QHash<QString, ShaderUniform> activeUniformsInDefaultBlock; for (int i = 0, m = uniformsDescription.size(); i < m; i++) { - m_uniformsNames[i] = uniformsDescription[i].m_name; + 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; 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]); @@ -373,8 +411,11 @@ void Shader::initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformB { m_uniformBlocks = uniformBlockDescription; m_uniformBlockNames.resize(uniformBlockDescription.size()); + m_uniformBlockNamesIds.resize(uniformBlockDescription.size()); for (int i = 0, m = uniformBlockDescription.size(); i < m; ++i) { - m_uniformBlockNames[i] = uniformBlockDescription[i].m_name; + m_uniformBlockNames[i] = m_uniformBlocks[i].m_name; + m_uniformBlockNamesIds[i] = StringToInt::lookupId(m_uniformBlockNames[i]); + m_uniformBlocks[i].m_nameId = m_uniformBlockNamesIds[i]; qCDebug(Shaders) << "Initializing Uniform Block {" << m_uniformBlockNames[i] << "}"; // Find all active uniforms for the shader block @@ -405,9 +446,12 @@ void Shader::initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &sh { m_shaderStorageBlocks = shaderStorageBlockDescription; m_shaderStorageBlockNames.resize(shaderStorageBlockDescription.size()); + m_shaderStorageBlockNamesIds.resize(shaderStorageBlockDescription.size()); for (int i = 0, m = shaderStorageBlockDescription.size(); i < m; ++i) { - m_shaderStorageBlockNames[i] = shaderStorageBlockDescription[i].m_name; + m_shaderStorageBlockNames[i] = m_shaderStorageBlocks[i].m_name; + m_shaderStorageBlockNamesIds[i] = StringToInt::lookupId(m_shaderStorageBlockNames[i]); + m_shaderStorageBlocks[i].m_nameId =m_shaderStorageBlockNamesIds[i]; qCDebug(Shaders) << "Initializing Shader Storage Block {" << m_shaderStorageBlockNames[i] << "}"; } } @@ -421,14 +465,19 @@ void Shader::initialize(const Shader &other) { Q_ASSERT(m_dna == other.m_dna); m_program = other.m_program; + m_uniformsNamesIds = other.m_uniformsNamesIds; m_uniformsNames = other.m_uniformsNames; m_uniforms = other.m_uniforms; m_attributesNames = other.m_attributesNames; m_attributes = other.m_attributes; + m_uniformBlockNamesIds = other.m_uniformBlockNamesIds; m_uniformBlockNames = other.m_uniformBlockNames; m_uniformBlocks = other.m_uniformBlocks; m_uniformBlockIndexToShaderUniforms = other.m_uniformBlockIndexToShaderUniforms; m_fragOutputs = other.m_fragOutputs; + m_shaderStorageBlockNamesIds = other.m_shaderStorageBlockNamesIds; + m_shaderStorageBlockNames = other.m_shaderStorageBlockNames; + m_shaderStorageBlocks = other.m_shaderStorageBlocks; m_isLoaded = other.m_isLoaded; } diff --git a/src/render/materialsystem/shader_p.h b/src/render/materialsystem/shader_p.h index 88694fd98..794ccc77d 100644 --- a/src/render/materialsystem/shader_p.h +++ b/src/render/materialsystem/shader_p.h @@ -84,6 +84,10 @@ public: void updateUniforms(GraphicsContext *ctx, const ShaderParameterPack &pack); void setFragOutputs(const QHash<QString, int> &fragOutputs); + QVector<int> uniformsNamesIds() const; + QVector<int> uniformBlockNamesIds() const; + QVector<int> storageBlockNamesIds() const; + QVector<QString> uniformsNames() const; QVector<QString> attributesNames() const; QVector<QString> uniformBlockNames() const; @@ -100,11 +104,14 @@ public: QVector<ShaderStorageBlock> storageBlocks() 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); + ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId); + ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex); + ShaderUniformBlock uniformBlockForBlockName(const QString &blockName); + + ShaderStorageBlock storageBlockForBlockIndex(int blockIndex); + ShaderStorageBlock storageBlockForBlockNameId(int blockNameId); + ShaderStorageBlock storageBlockForBlockName(const QString &blockName); private: QOpenGLShaderProgram *m_program; @@ -113,16 +120,19 @@ private: QOpenGLShaderProgram *createDefaultProgram(); QVector<QString> m_uniformsNames; + QVector<int> m_uniformsNamesIds; QVector<ShaderUniform> m_uniforms; QVector<QString> m_attributesNames; QVector<ShaderAttribute> m_attributes; QVector<QString> m_uniformBlockNames; + QVector<int> m_uniformBlockNamesIds; QVector<ShaderUniformBlock> m_uniformBlocks; QHash<int, QHash<QString, ShaderUniform> > m_uniformBlockIndexToShaderUniforms; QVector<QString> m_shaderStorageBlockNames; + QVector<int> m_shaderStorageBlockNamesIds; QVector<ShaderStorageBlock> m_shaderStorageBlocks; QHash<QString, int> m_fragOutputs; diff --git a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp index 5a742a175..8505dad5c 100644 --- a/tests/auto/render/renderviewutils/tst_renderviewutils.cpp +++ b/tests/auto/render/renderviewutils/tst_renderviewutils.cpp @@ -31,6 +31,7 @@ #include <Qt3DRender/private/renderviewjobutils_p.h> #include <Qt3DRender/private/shaderdata_p.h> #include <Qt3DRender/private/managers_p.h> +#include <Qt3DRender/private/stringtoint_p.h> #include <Qt3DRender/qshaderdata.h> @@ -328,11 +329,11 @@ void tst_RenderViewUtils::topLevelScalarValue() QVERIFY(blockBuilder.uniforms.count() == 1); QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), 1); - QHash<QString, QVariant>::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); - const QHash<QString, QVariant>::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); + Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); + const Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); while (it != end) { - QVERIFY(blockBuilder.uniforms.contains(it.key())); + QVERIFY(blockBuilder.uniforms.contains(Qt3DRender::Render::StringToInt::lookupString(it.key()))); QCOMPARE(it.value(), QVariant(shaderData->scalar())); ++it; } @@ -360,11 +361,11 @@ void tst_RenderViewUtils::topLevelArrayValue() QVERIFY(blockBuilder.uniforms.count() == 1); QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), 1); - QHash<QString, QVariant>::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); - const QHash<QString, QVariant>::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); + Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); + const Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); while (it != end) { - QVERIFY(blockBuilder.uniforms.contains(it.key())); + QVERIFY(blockBuilder.uniforms.contains(Qt3DRender::Render::StringToInt::lookupString(it.key()))); QCOMPARE(it.value(), QVariant(arrayValues)); ++it; } @@ -423,13 +424,13 @@ void tst_RenderViewUtils::topLevelStructValue() QCOMPARE(blockBuilder.activeUniformNamesToValue.count(), blockBuilder.uniforms.count()); - QHash<QString, QVariant>::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); - const QHash<QString, QVariant>::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); + Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator it = blockBuilder.activeUniformNamesToValue.begin(); + const Qt3DRender::Render::UniformBlockValueBuilderHash::const_iterator end = blockBuilder.activeUniformNamesToValue.end(); while (it != end) { - QVERIFY(blockBuilder.uniforms.contains(it.key())); - QVERIFY(expectedValues.contains(it.key())); - QCOMPARE(it.value(), expectedValues.value(it.key())); + QVERIFY(blockBuilder.uniforms.contains(Qt3DRender::Render::StringToInt::lookupString(it.key()))); + QVERIFY(expectedValues.contains(Qt3DRender::Render::StringToInt::lookupString(it.key()))); + QCOMPARE(it.value(), expectedValues.value(Qt3DRender::Render::StringToInt::lookupString(it.key()))); ++it; } } |