summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Michaël Celerier <jean-michael.celerier@kdab.com>2020-04-14 15:23:21 +0200
committerJean-Michaël Celerier <jean-michael.celerier@kdab.com>2020-04-22 11:17:32 +0200
commit0f0392b8d5202ccac56352e3930b4050a0d7e10b (patch)
treec8951e4972d2a83418ec444b56934bcd019370c5
parentd238aed8b9de81d406f13c5db3cc087bee8d64d4 (diff)
rhi: Rework uniform processing
Change-Id: I1dc305b727b148773f1d7dafa3ba8e2b74366aec Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp11
-rw-r--r--src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h6
-rw-r--r--src/plugins/renderers/rhi/renderer/renderview.cpp142
-rw-r--r--src/plugins/renderers/rhi/renderer/renderview_p.h44
-rw-r--r--src/plugins/renderers/rhi/renderer/rhishader.cpp213
-rw-r--r--src/plugins/renderers/rhi/renderer/rhishader_p.h33
-rw-r--r--src/render/materialsystem/shaderdata.cpp2
-rw-r--r--src/render/materialsystem/shaderdata_p.h2
8 files changed, 246 insertions, 207 deletions
diff --git a/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp b/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp
index 730a0060a..8918225cd 100644
--- a/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp
+++ b/src/plugins/renderers/rhi/jobs/renderviewjobutils.cpp
@@ -466,7 +466,11 @@ UniformBlockValueBuilder::~UniformBlockValueBuilder()
{
}
-void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData, const QString &blockName, const QString &qmlPropertyName, const QVariant &value)
+void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(
+ const ShaderData *currentShaderData,
+ const QString &blockName,
+ const QString &qmlPropertyName,
+ const QVariant &value)
{
// In the end, values are either scalar or a scalar array
// Composed elements (structs, structs array) are simplified into simple scalars
@@ -527,7 +531,10 @@ void UniformBlockValueBuilder::buildActiveUniformNameValueMapHelper(ShaderData *
}
}
-void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData, const QString &blockName, const QString &qmlPropertyName)
+void UniformBlockValueBuilder::buildActiveUniformNameValueMapStructHelper(
+ const ShaderData *rShaderData,
+ const QString &blockName,
+ const QString &qmlPropertyName)
{
const QHash<QString, ShaderData::PropertyValue> &properties = rShaderData->properties();
auto it = properties.begin();
diff --git a/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h b/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h
index 2fb441ef9..da4cf5ffa 100644
--- a/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h
+++ b/src/plugins/renderers/rhi/jobs/renderviewjobutils_p.h
@@ -166,16 +166,16 @@ struct Q_AUTOTEST_EXPORT UniformBlockValueBuilder
QT3D_ALIGNED_MALLOC_AND_FREE()
- void buildActiveUniformNameValueMapHelper(ShaderData *currentShaderData,
+ void buildActiveUniformNameValueMapHelper(const ShaderData *currentShaderData,
const QString &blockName,
const QString &qmlPropertyName,
const QVariant &value);
- void buildActiveUniformNameValueMapStructHelper(ShaderData *rShaderData,
+ void buildActiveUniformNameValueMapStructHelper(const ShaderData *rShaderData,
const QString &blockName,
const QString &qmlPropertyName = QString());
bool updatedPropertiesOnly;
- QHash<QString, ShaderUniform> uniforms;
+ QSet<QString> uniforms;
UniformBlockValueBuilderHash activeUniformNamesToValue;
ShaderDataManager *shaderDataManager;
TextureManager *textureManager;
diff --git a/src/plugins/renderers/rhi/renderer/renderview.cpp b/src/plugins/renderers/rhi/renderer/renderview.cpp
index 70020093a..c08be80eb 100644
--- a/src/plugins/renderers/rhi/renderer/renderview.cpp
+++ b/src/plugins/renderers/rhi/renderer/renderview.cpp
@@ -111,41 +111,6 @@ std::atomic_bool wasInitialized{};
} // anonymous namespace
-RenderView::StandardUniformsNameToTypeHash RenderView::ms_standardUniformSetters;
-
-
-RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniformSetters()
-{
- RenderView::StandardUniformsNameToTypeHash setters;
-
- 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::textureTransformMatrixNameId, TextureTransformMatrix);
- 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;
-}
-
// TODO: Move this somewhere global where GraphicsContext::setViewport() can use it too
static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &surfaceSize)
{
@@ -157,8 +122,6 @@ static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &sur
static Matrix4x4 getProjectionMatrix(const CameraLens *lens, bool yIsUp)
{
- if (!lens)
- qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered.";
if (lens)
{
if (yIsUp)
@@ -177,6 +140,7 @@ static Matrix4x4 getProjectionMatrix(const CameraLens *lens, bool yIsUp)
}
else
{
+ qWarning() << "[Qt3D Renderer] No Camera Lens found. Add a CameraSelector to your Frame Graph or make sure that no entities will be rendered.";
return Matrix4x4();
}
}
@@ -958,7 +922,7 @@ void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, c
}
void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
- RHIShader *shader,
+ const RHIShader *shader,
const ShaderUniformBlock &block,
const UniformValue &value) const
{
@@ -979,7 +943,7 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
}
void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
- RHIShader *shader,
+ const RHIShader *shader,
const ShaderStorageBlock &block,
const UniformValue &value) const
{
@@ -997,7 +961,11 @@ void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
}
}
-void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, RHIShader *shader, ShaderData *shaderData, const QString &structName) const
+void RenderView::setDefaultUniformBlockShaderDataValue(
+ ShaderParameterPack &uniformPack,
+ const RHIShader *shader,
+ const ShaderData *shaderData,
+ const QString &structName) const
{
UniformBlockValueBuilder *builder = m_localData.localData();
builder->activeUniformNamesToValue.clear();
@@ -1007,7 +975,7 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
// Force to update the whole block
builder->updatedPropertiesOnly = false;
// Retrieve names and description of each active uniforms in the uniform block
- builder->uniforms = shader->activeUniformsForUniformBlock(-1);
+ builder->uniforms = shader->unqualifiedUniformNames();
// Build name-value map for the block
builder->buildActiveUniformNameValueMapStructHelper(shaderData, structName);
// Set uniform values for each entrie of the block name-value map
@@ -1021,6 +989,39 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
}
}
+void RenderView::applyParameter(
+ const Parameter *param,
+ RenderCommand *command,
+ const RHIShader *shader) const noexcept
+{
+ const int nameId = param->nameId();
+ const UniformValue &uniformValue = param->uniformValue();
+ switch (shader->categorizeVariable(nameId))
+ {
+ case RHIShader::Uniform: {
+ setUniformValue(command->m_parameterPack, nameId, uniformValue);
+ break;
+ }
+ case RHIShader::UBO: {
+ setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(nameId), uniformValue);
+ break;
+ }
+ case RHIShader::SSBO: {
+ setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(nameId), uniformValue);
+ break;
+ }
+ case RHIShader::Struct: {
+ ShaderData *shaderData = nullptr;
+ if (uniformValue.valueType() == UniformValue::NodeId &&
+ (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != nullptr) {
+ // Try to check if we have a struct or array matching a QShaderData parameter
+ setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(nameId));
+ }
+ break;
+ }
+ }
+}
+
void RenderView::setShaderAndUniforms(RenderCommand *command,
ParameterInfoList &parameters,
Entity *entity,
@@ -1043,10 +1044,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
// 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<int> uniformNamesIds = shader->uniformsNamesIds();
- const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
- const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
- const QVector<int> attributeNamesIds = shader->attributeNamesIds();
// Set fragData Name and index
// Later on we might want to relink the shader if attachments have changed
@@ -1063,12 +1060,13 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
shader->setFragOutputs(fragOutputs);
}
- if (!uniformNamesIds.isEmpty() ||
- !attributeNamesIds.isEmpty() ||
- !shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
+ if (shader->hasActiveVariables()) {
+
+ // Unlike the GL engine, the standard uniforms are set a bit before this function,
+ // in RenderView::updateRenderCommand
// Set default attributes
- command->m_activeAttributes = attributeNamesIds;
+ command->m_activeAttributes = shader->attributeNamesIds();
// At this point we know whether the command is a valid draw command or not
// We still need to process the uniforms as the command could be a compute command
@@ -1084,27 +1082,12 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
const ParameterInfoList::const_iterator parametersEnd = parameters.cend();
while (it != parametersEnd) {
- Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
- const UniformValue &uniformValue = param->uniformValue();
- if (uniformBlockNamesIds.indexOf(it->nameId) != -1) { // Parameter is a uniform block
- setUniformBlockValue(command->m_parameterPack, shader, shader->uniformBlockForBlockNameId(it->nameId), uniformValue);
- } else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
- setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), uniformValue);
- } else { // Parameter is a struct
- setUniformValue(command->m_parameterPack, it->nameId, uniformValue);
-// ShaderData *shaderData = nullptr;
-// if (uniformValue.valueType() == UniformValue::NodeId &&
-// (shaderData = m_manager->shaderDataManager()->lookupResource(*uniformValue.constData<Qt3DCore::QNodeId>())) != 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
- }
+ const Parameter *param = m_manager->data<Parameter, ParameterManager>(it->handle);
+ applyParameter(param, command, shader);
++it;
}
// Lights
-
int lightIdx = 0;
for (const LightSource &lightSource : activeLightSources) {
if (lightIdx == MAX_LIGHTS)
@@ -1142,7 +1125,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
}
}
- if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
+ if (shader->hasUniform(LIGHT_COUNT_NAME_ID))
setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax((environmentLight ? 0 : 1), lightIdx)));
// If no active light sources and no environment light, add a default light
@@ -1161,7 +1144,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
static const int specularId = StringToInt::lookupId(QLatin1String("envLight_specular"));
ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData());
if (shaderData) {
- //setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight"));
envLightCount = 1;
// ("specularSize", "irradiance", "irradianceSize", "specular")
@@ -1172,30 +1154,6 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
setUniformValue(command->m_parameterPack, specularId, spec);
}
}
- //if (environmentLight && environmentLight->isEnabled()) {
- // ShaderData *shaderData = m_manager->shaderDataManager()->lookupResource(environmentLight->shaderData());
- // if (shaderData) {
- // setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, QStringLiteral("envLight"));
- // envLightCount = 1;
- // }
- //} else {
- // // with some drivers, samplers (like the envbox sampler) need to be bound even though
- // // they may not be actually used, otherwise draw calls can fail
- // static const int irradianceId = StringToInt::lookupId(QLatin1String("envLight_irradiance"));
- // static const int specularId = StringToInt::lookupId(QLatin1String("envLight_specular"));
- //
- // // for (const auto& sampler : shader->samplers())
- // // {
- // // if (sampler.m_nameId == irradianceId)
- // // {
- // // setUniformValue(command->m_parameterPack, irradianceId, sampler.m_location);
- // // }
- // // else if (sampler.m_nameId == specularId)
- // // {
- // // setUniformValue(command->m_parameterPack, specularId, sampler.m_location);
- // // }
- // // }
- //}
setUniformValue(command->m_parameterPack, StringToInt::lookupId(QStringLiteral("envLightCount")), envLightCount);
}
}
diff --git a/src/plugins/renderers/rhi/renderer/renderview_p.h b/src/plugins/renderers/rhi/renderer/renderview_p.h
index cceefe5e4..b42596498 100644
--- a/src/plugins/renderers/rhi/renderer/renderview_p.h
+++ b/src/plugins/renderers/rhi/renderer/renderview_p.h
@@ -346,54 +346,20 @@ private:
MaterialParameterGathererData m_parameters;
- enum StandardUniform
- {
- ModelMatrix,
- ViewMatrix,
- ProjectionMatrix,
- ModelViewMatrix,
- ViewProjectionMatrix,
- ModelViewProjectionMatrix,
- InverseModelMatrix,
- InverseViewMatrix,
- InverseProjectionMatrix,
- InverseModelViewMatrix,
- InverseViewProjectionMatrix,
- InverseModelViewProjectionMatrix,
- ModelNormalMatrix,
- ModelViewNormalMatrix,
- ViewportMatrix,
- InverseViewportMatrix,
- TextureTransformMatrix,
- AspectRatio,
- Time,
- Exposure,
- Gamma,
- EyePosition,
- SkinningPalette
- };
-
- typedef QHash<int, StandardUniform> StandardUniformsNameToTypeHash;
- static StandardUniformsNameToTypeHash ms_standardUniformSetters;
- static StandardUniformsNameToTypeHash initializeStandardUniformSetters();
-
- UniformValue standardUniformValue(StandardUniform standardUniformType,
- Entity *entity,
- const Matrix4x4 &model) const;
-
void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
void setUniformBlockValue(ShaderParameterPack &uniformPack,
- RHIShader *shader,
+ const RHIShader *shader,
const ShaderUniformBlock &block,
const UniformValue &value) const;
void setShaderStorageValue(ShaderParameterPack &uniformPack,
- RHIShader *shader,
+ const RHIShader *shader,
const ShaderStorageBlock &block,
const UniformValue &value) const;
void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
- RHIShader *shader,
- ShaderData *shaderData,
+ const RHIShader *shader,
+ const ShaderData *shaderData,
const QString &structName) const;
+ void applyParameter(const Parameter* param, RenderCommand* command, const RHIShader* shader) const noexcept;
};
} // namespace Rhi
diff --git a/src/plugins/renderers/rhi/renderer/rhishader.cpp b/src/plugins/renderers/rhi/renderer/rhishader.cpp
index fe8fb6961..ffb74145a 100644
--- a/src/plugins/renderers/rhi/renderer/rhishader.cpp
+++ b/src/plugins/renderers/rhi/renderer/rhishader.cpp
@@ -42,6 +42,7 @@
#include <Qt3DRender/private/stringtoint_p.h>
#include <submissioncontext_p.h>
#include <logging_p.h>
+#include <QRegularExpression>
QT_BEGIN_NAMESPACE
@@ -92,6 +93,8 @@ QVector<QByteArray> RHIShader::shaderCode() const
return m_shaderCode;
}
+namespace
+{
static constexpr QRhiVertexInputAttribute::Format rhiInputType(QShaderDescription::VariableType type)
{
switch (type)
@@ -199,8 +202,120 @@ QVector<T> stableRemoveDuplicates(QVector<T> in, Pred predicate)
}
return out;
}
+
+// Utility function to enumerate an array of dimensions
+// Given dims == [0, 3, 2] and maxs == [4, 4, 4]
+// changes dims into [0, 3, 3]
+// Given dims == [0, 3, 3] and maxs == [4, 4, 4]
+// changes dims into [1, 0, 0]
+bool incrementArray(QVarLengthArray<int>& dims, const QVector<int>& maxs)
+{
+ const int n = dims.size();
+ int i = n;
+ for (; i --> 0 ;)
+ {
+ if (dims[i] == maxs[i] - 1)
+ {
+ if ( i == 0 )
+ {
+ // we're done
+ return false;
+ }
+ continue;
+
+
+ }
+ else
+ {
+ dims[i]++;
+ for (int j = i + 1; j < n; j++) {
+ dims[j] = 0;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+// Call a function with a string such as [0][3][2]
+// for all valable array values, given an array of dimension sizes.
+// Dimensions must all be >= 1
+template<typename F>
+void forEachArrayAccessor(const QVector<int>& maxs, F f)
+{
+ if (std::any_of(maxs.begin(), maxs.end(), [] (int v) { return v <= 0; }))
+ return;
+
+ QVarLengthArray<int> dims;
+ dims.resize(maxs.size());
+
+ // QVarLengthArray does not initialize ints
+ std::fill(dims.begin(), dims.end(), 0);
+
+ QString str;
+
+ do {
+ str.resize(0);
+ for (int k : dims) {
+ str += QStringLiteral("[%1]").arg(k);
+ }
+ f(str);
+ } while (incrementArray(dims, maxs));
+}
+}
+
+void RHIShader::recordAllUniforms(const QShaderDescription::BlockVariable& member, QString parentName)
+{
+ const bool isStruct = !member.structMembers.empty();
+ const bool isArray = !member.arrayDims.empty();
+
+ // "foo.bar"
+ const QString fullMemberName = parentName + member.name;
+ m_unqualifiedUniformNames << fullMemberName;
+
+ if (isStruct && !isArray)
+ {
+ m_structNames << fullMemberName;
+ m_structNamesIds << StringToInt::lookupId(fullMemberName);
+
+ for (const QShaderDescription::BlockVariable& bv : member.structMembers)
+ {
+ // recordAllUniforms("baz", "foo.bar.")
+ recordAllUniforms(bv, fullMemberName + QLatin1Char('.'));
+ }
+ }
+ else if (!isStruct && isArray)
+ {
+ // We iterate through all the [l][n][m] by building [0][0][0] and incrementing
+ forEachArrayAccessor(member.arrayDims, [&] (const QString& str) {
+ // "foo.bar[1][2]"
+ m_unqualifiedUniformNames << (fullMemberName + str);
+ // Question : does it make sense to also record foo[0], foo[0][0], etc...
+ // if there are e.g. 3 dimensions ?
+ });
+ }
+ else if (isStruct && isArray)
+ {
+ // Record the struct names
+ forEachArrayAccessor(member.arrayDims, [&] (const QString& str) {
+ m_structNames << (fullMemberName + str);
+ m_structNamesIds << StringToInt::lookupId(m_structNames.back());
+ });
+
+ // Record the struct members
+ for (const QShaderDescription::BlockVariable& bv : member.structMembers)
+ {
+ forEachArrayAccessor(member.arrayDims, [&] (const QString& str) {
+ //recordAllUniforms("baz", "foo.bar[1][2].")
+ recordAllUniforms(bv, fullMemberName + str + QLatin1Char('.'));
+ });
+ }
+ }
+}
+
void RHIShader::introspect()
{
+ const thread_local QRegularExpression generatedUBOName{"_[0-9]+"};
QVector<QShaderDescription::UniformBlock> rhiUBO;
QVector<QShaderDescription::StorageBlock> rhiSSBO;
@@ -246,6 +361,7 @@ void RHIShader::introspect()
for (const QShaderDescription::UniformBlock& ubo : rhiUBO) {
uniformBlocks.push_back(ShaderUniformBlock{ubo.blockName, StringToInt::lookupId(ubo.blockName), -1, ubo.binding, ubo.members.size(), ubo.size});
+ const bool addUnqualifiedUniforms = ubo.structName.contains(generatedUBOName);
// Parse Uniform Block members so that we can later on map a Parameter name to an actual member
const QVector<QShaderDescription::BlockVariable> members = ubo.members;
@@ -254,8 +370,11 @@ void RHIShader::introspect()
namesIds.reserve(members.size());
for (const QShaderDescription::BlockVariable& member : members) {
- qDebug() << member.name << member.offset << member.size << member.structMembers.size() << member.type;
namesIds << StringToInt::lookupId(member.name);
+ if (addUnqualifiedUniforms)
+ {
+ recordAllUniforms(member, QStringLiteral(""));
+ }
}
m_uniformsNamesIds += namesIds;
m_uboMembers.push_back({uniformBlocks.last(), members});
@@ -277,7 +396,7 @@ QHash<QString, ShaderUniform> RHIShader::activeUniformsForUniformBlock(int block
return m_uniformBlockIndexToShaderUniforms.value(blockIndex);
}
-ShaderUniformBlock RHIShader::uniformBlockForBlockIndex(int blockIndex)
+ShaderUniformBlock RHIShader::uniformBlockForBlockIndex(int blockIndex) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_index == blockIndex) {
@@ -287,7 +406,7 @@ ShaderUniformBlock RHIShader::uniformBlockForBlockIndex(int blockIndex)
return ShaderUniformBlock();
}
-ShaderUniformBlock RHIShader::uniformBlockForBlockNameId(int blockNameId)
+ShaderUniformBlock RHIShader::uniformBlockForBlockNameId(int blockNameId) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_nameId == blockNameId) {
@@ -297,7 +416,7 @@ ShaderUniformBlock RHIShader::uniformBlockForBlockNameId(int blockNameId)
return ShaderUniformBlock();
}
-ShaderUniformBlock RHIShader::uniformBlockForBlockName(const QString &blockName)
+ShaderUniformBlock RHIShader::uniformBlockForBlockName(const QString &blockName) const noexcept
{
for (int i = 0, m = m_uniformBlocks.size(); i < m; ++i) {
if (m_uniformBlocks[i].m_name == blockName) {
@@ -307,7 +426,7 @@ ShaderUniformBlock RHIShader::uniformBlockForBlockName(const QString &blockName)
return ShaderUniformBlock();
}
-ShaderStorageBlock RHIShader::storageBlockForBlockIndex(int blockIndex)
+ShaderStorageBlock RHIShader::storageBlockForBlockIndex(int blockIndex) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_index == blockIndex)
@@ -316,7 +435,7 @@ ShaderStorageBlock RHIShader::storageBlockForBlockIndex(int blockIndex)
return ShaderStorageBlock();
}
-ShaderStorageBlock RHIShader::storageBlockForBlockNameId(int blockNameId)
+ShaderStorageBlock RHIShader::storageBlockForBlockNameId(int blockNameId) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_nameId == blockNameId)
@@ -325,7 +444,7 @@ ShaderStorageBlock RHIShader::storageBlockForBlockNameId(int blockNameId)
return ShaderStorageBlock();
}
-ShaderStorageBlock RHIShader::storageBlockForBlockName(const QString &blockName)
+ShaderStorageBlock RHIShader::storageBlockForBlockName(const QString &blockName) const noexcept
{
for (int i = 0, m = m_shaderStorageBlockNames.size(); i < m; ++i) {
if (m_shaderStorageBlocks[i].m_name == blockName)
@@ -334,6 +453,32 @@ ShaderStorageBlock RHIShader::storageBlockForBlockName(const QString &blockName)
return ShaderStorageBlock();
}
+RHIShader::ParameterKind RHIShader::categorizeVariable(int nameId) const noexcept
+{
+ if (m_uniformsNamesIds.contains(nameId))
+ return ParameterKind::Uniform;
+ else if (m_uniformBlockNamesIds.contains(nameId))
+ return ParameterKind::UBO;
+ else if (m_shaderStorageBlockNamesIds.contains(nameId))
+ return ParameterKind::SSBO;
+ else if (m_structNamesIds.contains(nameId))
+ return ParameterKind::Struct;
+ return ParameterKind::Uniform;
+}
+
+bool RHIShader::hasUniform(int nameId) const noexcept
+{
+ return m_uniformsNamesIds.contains(nameId);
+}
+
+bool RHIShader::hasActiveVariables() const noexcept
+{
+ return !m_attributeNamesIds.empty()
+ || !m_uniformsNamesIds.empty()
+ || !m_uniformBlockNamesIds.empty()
+ || !m_shaderStorageBlockNamesIds.empty();
+}
+
void RHIShader::prepareUniforms(ShaderParameterPack &pack)
{
const PackUniformHash &values = pack.uniforms();
@@ -368,60 +513,6 @@ const QHash<QString, int> RHIShader::fragOutputs() const
return m_fragOutputs;
}
-void RHIShader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescription)
-{
- m_uniforms = uniformsDescription;
- m_uniformsNames.resize(uniformsDescription.size());
- m_uniformsNamesIds.reserve(uniformsDescription.size());
- m_standardUniformNamesIds.reserve(5);
- QHash<QString, ShaderUniform> activeUniformsInDefaultBlock;
-
- static const QVector<int> standardUniformNameIds = {
- Shader::modelMatrixNameId,
- Shader::viewMatrixNameId,
- Shader::projectionMatrixNameId,
- Shader::modelViewMatrixNameId,
- Shader::viewProjectionMatrixNameId,
- Shader::modelViewProjectionNameId,
- Shader::mvpNameId,
- Shader::inverseModelMatrixNameId,
- Shader::inverseViewMatrixNameId,
- Shader::inverseProjectionMatrixNameId,
- Shader::inverseModelViewNameId,
- Shader::inverseViewProjectionMatrixNameId,
- Shader::inverseModelViewProjectionNameId,
- Shader::modelNormalMatrixNameId,
- Shader::modelViewNormalNameId,
- Shader::viewportMatrixNameId,
- Shader::inverseViewportMatrixNameId,
- Shader::textureTransformMatrixNameId,
- Shader::aspectRatioNameId,
- Shader::exposureNameId,
- Shader::gammaNameId,
- Shader::timeNameId,
- Shader::eyePositionNameId,
- Shader::skinningPaletteNameId,
- };
-
- 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?
- 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]);
- }
- }
- m_uniformBlockIndexToShaderUniforms.insert(-1, activeUniformsInDefaultBlock);
-}
-
void RHIShader::initializeAttributes(const QVector<ShaderAttribute> &attributesDescription)
{
m_attributes = attributesDescription;
diff --git a/src/plugins/renderers/rhi/renderer/rhishader_p.h b/src/plugins/renderers/rhi/renderer/rhishader_p.h
index 8d23a6f28..baed31fc2 100644
--- a/src/plugins/renderers/rhi/renderer/rhishader_p.h
+++ b/src/plugins/renderers/rhi/renderer/rhishader_p.h
@@ -109,13 +109,24 @@ public:
QHash<QString, ShaderUniform> activeUniformsForUniformBlock(int blockIndex) const;
- ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId);
- ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex);
- ShaderUniformBlock uniformBlockForBlockName(const QString &blockName);
+ ShaderUniformBlock uniformBlockForBlockIndex(int blockNameId) const noexcept;
+ ShaderUniformBlock uniformBlockForBlockNameId(int blockIndex) const noexcept;
+ ShaderUniformBlock uniformBlockForBlockName(const QString &blockName) const noexcept;
+
+ ShaderStorageBlock storageBlockForBlockIndex(int blockIndex) const noexcept;
+ ShaderStorageBlock storageBlockForBlockNameId(int blockNameId) const noexcept;
+ ShaderStorageBlock storageBlockForBlockName(const QString &blockName) const noexcept;
+
+ enum ParameterKind {
+ Uniform,
+ UBO,
+ SSBO,
+ Struct
+ };
+ ParameterKind categorizeVariable(int nameId) const noexcept;
- ShaderStorageBlock storageBlockForBlockIndex(int blockIndex);
- ShaderStorageBlock storageBlockForBlockNameId(int blockNameId);
- ShaderStorageBlock storageBlockForBlockName(const QString &blockName);
+ bool hasUniform(int nameId) const noexcept;
+ bool hasActiveVariables() const noexcept;
void setShaderCode(const QVector<QByteArray> shaderCode) { m_shaderCode = shaderCode; }
QVector<QByteArray> shaderCode() const;
@@ -123,6 +134,8 @@ public:
const QShader& shaderStage(QShader::Stage stage) const noexcept { return m_stages[stage]; }
QVector<UBO_Member> uboMembers() const { return m_uboMembers; }
+ const QSet<QString>& unqualifiedUniformNames() const noexcept { return m_unqualifiedUniformNames; }
+
void introspect();
private:
bool m_isLoaded;
@@ -141,6 +154,7 @@ private:
QVector<int> m_uniformBlockNamesIds;
QVector<ShaderUniformBlock> m_uniformBlocks;
QHash<int, QHash<QString, ShaderUniform> > m_uniformBlockIndexToShaderUniforms;
+ QSet<QString> m_unqualifiedUniformNames;
QVector<QString> m_shaderStorageBlockNames;
QVector<int> m_shaderStorageBlockNamesIds;
@@ -154,20 +168,23 @@ private:
QVector<int> m_imageIds;
QVector<ShaderAttribute> m_images;
+ QVector<QString> m_structNames;
+ QVector<int> m_structNamesIds;
+
QHash<QString, int> m_fragOutputs;
QVector<QByteArray> m_shaderCode;
// Private so that only SubmissionContext can call it
friend class SubmissionContext;
- void initializeUniforms(const QVector<ShaderUniform> &uniformsDescription);
void initializeAttributes(const QVector<ShaderAttribute> &attributesDescription);
void initializeUniformBlocks(const QVector<ShaderUniformBlock> &uniformBlockDescription);
+ void initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription);
void initializeSamplers(const QVector<ShaderAttribute> &samplerDescription);
void initializeImages(const QVector<ShaderAttribute> &imageDescription);
+ void recordAllUniforms(const QShaderDescription::BlockVariable &ubo, QString parentName);
QVector<UBO_Member> m_uboMembers;
- void initializeShaderStorageBlocks(const QVector<ShaderStorageBlock> &shaderStorageBlockDescription);
mutable QMutex m_mutex;
QMetaObject::Connection m_contextConnection;
diff --git a/src/render/materialsystem/shaderdata.cpp b/src/render/materialsystem/shaderdata.cpp
index 97db303c2..d7a7265a7 100644
--- a/src/render/materialsystem/shaderdata.cpp
+++ b/src/render/materialsystem/shaderdata.cpp
@@ -162,7 +162,7 @@ ShaderData *ShaderData::lookupResource(QNodeId id)
}
// RenderCommand updater jobs
-QVariant ShaderData::getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix) const
+QVariant ShaderData::getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix) const noexcept
{
// Note protecting m_worldMatrix at this point as we assume all world updates
// have been performed when reaching this point
diff --git a/src/render/materialsystem/shaderdata_p.h b/src/render/materialsystem/shaderdata_p.h
index 080d2c85e..6b185d2ea 100644
--- a/src/render/materialsystem/shaderdata_p.h
+++ b/src/render/materialsystem/shaderdata_p.h
@@ -89,7 +89,7 @@ public:
// Called by FramePreparationJob
void updateWorldTransform(const Matrix4x4 &worldMatrix);
- QVariant getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix) const;
+ QVariant getTransformedProperty(const QString &name, const Matrix4x4 &viewMatrix) const noexcept;
// Unit tests purposes only
TransformType propertyTransformType(const QString &name) const;