diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2023-02-02 13:57:00 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2023-02-08 07:26:17 +0000 |
commit | f70844868a834fe988eb0716f6af4cbaacf89727 (patch) | |
tree | 7edf305554b8095d94ef20362df6e42e9306018e | |
parent | a8f353747cd7098e7606fe325cebe29df5fd8fa0 (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.
Pick-to: 6.2 6.4 6.5
Fixes: QTBUG-110111
Change-Id: I96c3e81908db8cce682b5447800fcb7a3fe5e0b9
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-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 d47203057f..ae35a20088 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -1274,7 +1274,7 @@ bool QQuickShaderEffectPrivate::updateShader(Shader shaderType, const QUrl &file // 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 6d6e774918..9f634067d5 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -86,6 +86,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); } @@ -94,6 +100,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); } |