diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-05-03 12:02:58 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-05-03 16:10:36 +0200 |
commit | c28e609ff4b863d5b849749d995d503fba365fb7 (patch) | |
tree | 4f90452526c3adb0c85755277f09c19d7d119dcf /src/gui/rhi/qrhigles2.cpp | |
parent | 21b3b54193b9d90ee377fdfa306e21d2fdfe2837 (diff) |
rhi: gl: Sanity check vertex outputs and fragment inputs
Print a warning if the name for a given location does not match. This is
relevant only to OpenGL and only to < 330 GLSL versions: there the
location qualifier is simply not present in the actual shader code and
all matching is name-based. This leads to hard to discover problems in
Qt Quick ShaderEffects for instance, where providing a custom fragment
shader but using a built-in vertex shader is common, and one may be
tempted to use a name other than qt_TexCoord0 for the input variable in
the fragment shader. Unfortunately this breaks, sometimes silently, when
not having location qualifiers. (and we won't, neither in GLSL 120 or
150 which are the standard for Qt Quick)
Make this situation recognizable by printing a warning to the debug
output.
Pick-to: 6.1
Task-number: QTBUG-92500
Task-number: QTBUG-93370
Change-Id: I0d0bcc135e23a228783f7633f872e39c4e43bb93
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhigles2.cpp')
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 8eaf02f817..33f3e0342c 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -3986,6 +3986,29 @@ void QRhiGles2::gatherSamplers(GLuint program, } } +void QRhiGles2::sanityCheckVertexFragmentInterface(const QShaderDescription &vsDesc, const QShaderDescription &fsDesc) +{ + if (!vsDesc.isValid() || !fsDesc.isValid()) + return; + + // Print a warning if the fragment shader input for a given location uses a + // name that does not match the vertex shader output at the same location. + // This is not an error with any other API and not with GLSL >= 330 either, + // but matters for older GLSL code that has no location qualifiers. + for (const QShaderDescription::InOutVariable &outVar : vsDesc.outputVariables()) { + for (const QShaderDescription::InOutVariable &inVar : fsDesc.inputVariables()) { + if (inVar.location == outVar.location) { + if (inVar.name != outVar.name) { + qWarning("Vertex output name '%s' does not match fragment input '%s'. " + "This should be avoided because it causes problems with older GLSL versions.", + outVar.name.constData(), inVar.name.constData()); + } + break; + } + } + } +} + bool QRhiGles2::isProgramBinaryDiskCacheEnabled() const { static QOpenGLProgramBinarySupportCheckWrapper checker; @@ -4886,6 +4909,8 @@ bool QGles2GraphicsPipeline::create() for (const QShaderDescription::InOutVariable &inVar : vsDesc.inputVariables()) rhiD->f->glBindAttribLocation(program, GLuint(inVar.location), inVar.name); + rhiD->sanityCheckVertexFragmentInterface(vsDesc, fsDesc); + if (!rhiD->linkProgram(program)) return false; |