aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-02-02 13:57:00 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-02-08 07:26:17 +0000
commitf70844868a834fe988eb0716f6af4cbaacf89727 (patch)
tree7edf305554b8095d94ef20362df6e42e9306018e
parenta8f353747cd7098e7606fe325cebe29df5fd8fa0 (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.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 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);
}