diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2023-02-02 13:57:00 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-02-08 12:40:18 +0000 |
commit | 8f9fdde222e174c934156bdce2fba4c73d41782d (patch) | |
tree | a7e66d35d51a5ae42736b85326d0ab90e949a1a1 | |
parent | 7437ab9139ed3b4b660a17c34e30d8be24a16fb7 (diff) |
Avoid crash updating source of shader-less effect
When a ShaderEffect did not have any shaders, we would
register a "fake" bindPoint for the 'source' property with
bindPoint 0. However, when actually linking the default
shader program, the actual bindPoint is 1 (also matches
what is in shadereffect.frag).
When the property corresponding to the source updated, we
would thus register an update for binding point 0. The
initial value for binding point 1, from when the shader
effect was loaded, would never be overwritten and when we
iterated over the variables later and tried to cast do a
qobject_cast on the (initial, now dangling) pointer stored
for binding point 1, it would crash.
Fixes: QTBUG-110111
Change-Id: I96c3e81908db8cce682b5447800fcb7a3fe5e0b9
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit f70844868a834fe988eb0716f6af4cbaacf89727)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/items/qquickshadereffect.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgrhishadereffectnode.cpp | 12 |
2 files changed, 13 insertions, 1 deletions
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 66b42aa09d..fbf3969e73 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -1387,7 +1387,7 @@ bool QQuickShaderEffectImpl::updateShader(Shader shaderType, const QUrl &fileUrl // provided and monitored like with an application-provided shader. QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; v.name = QByteArrayLiteral("source"); - v.bindPoint = 0; // fake + v.bindPoint = 1; // fake, must match the default source bindPoint in qquickshadereffectnode.cpp v.type = texturesSeparate ? QSGGuiThreadShaderEffectManager::ShaderInfo::Texture : QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler; m_shaders[shaderType].shaderInfo.variables.append(v); diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp index d1ef856ff5..9f9964b78c 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -117,6 +117,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha const QSGShaderEffectNode::VariableData &vd(shader.varData.at(i)); if (var.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler) { Q_ASSERT(vd.specialType == QSGShaderEffectNode::VariableData::Source); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } @@ -125,6 +131,12 @@ void QSGRhiShaderLinker::feedSamplers(const QSGShaderEffectNode::ShaderData &sha for (int idx : *dirtyIndices) { const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &var(shader.shaderInfo.variables.at(idx)); const QSGShaderEffectNode::VariableData &vd(shader.varData.at(idx)); + +#ifndef QT_NO_DEBUG + int existingBindPoint = m_samplerNameMap.value(var.name, -1); + Q_ASSERT(existingBindPoint < 0 || existingBindPoint == var.bindPoint); +#endif + m_samplers.insert(var.bindPoint, vd.value); m_samplerNameMap.insert(var.name, var.bindPoint); } |