aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-02-02 13:57:00 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-08 12:40:18 +0000
commit8f9fdde222e174c934156bdce2fba4c73d41782d (patch)
treea7e66d35d51a5ae42736b85326d0ab90e949a1a1
parent7437ab9139ed3b4b660a17c34e30d8be24a16fb7 (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.cpp2
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp12
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);
}