Fix handling matrix qualifiers on block members
Individual block member row_major/column_major layout qualifiers may
override the qualifiers set on the block. During parsing, this was
already being handled correctly, so that the qualifier is resolved for
each block member and recorded for each TField / InterfaceBlockField.
Now we always write the qualifiers on a per-member granularity to the
output GLSL shaders, so that the native driver gets the correct
per-member qualifiers. This replaces earlier behavior where the matrix
qualifiers were only written per-block.
Also only use qualifiers from individual members in block layout.
Since the block-level qualifier information is no longer used after
parsing, it is no longer kept in the AST. A dummy value is still set
to the InterfaceBlock structs exposed through the ShaderVars
interface, since that has existing usage in Chromium that needs to be
removed before the field can be removed.
Some AMD OpenGL drivers don't seem to handle matrix layout qualifiers
correctly, so most of the added tests need to be skipped for AMD GL.
On NVIDIA and Intel the tests pass.
BUG=angleproject:2271
TEST=angle_unittests, angle_end2end_tests,
dEQP-GLES31.functional.program_interface_query.uniform.matrix*
Change-Id: I1baa7a633bc2da548743c2190cb72db491b5227a
Reviewed-on: https://chromium-review.googlesource.com/800174
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 6e0f25f..9f0fb68 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -1221,29 +1221,10 @@
break;
}
- out << ", ";
-
if (interfaceBlock->blockBinding() > 0)
{
- out << "binding = " << interfaceBlock->blockBinding();
out << ", ";
- }
-
- switch (interfaceBlock->matrixPacking())
- {
- case EmpUnspecified:
- case EmpColumnMajor:
- // Default matrix packing is column major.
- out << "column_major";
- break;
-
- case EmpRowMajor:
- out << "row_major";
- break;
-
- default:
- UNREACHABLE();
- break;
+ out << "binding = " << interfaceBlock->blockBinding();
}
out << ") ";
@@ -1255,9 +1236,30 @@
out << hashName(TName(interfaceBlock->name())) << "{\n";
const TFieldList &fields = interfaceBlock->fields();
- for (size_t i = 0; i < fields.size(); ++i)
+ for (const TField *field : fields)
{
- const TField *field = fields[i];
+ if (field->type()->isMatrix() || field->type()->isStructureContainingMatrices())
+ {
+ out << "layout(";
+ switch (field->type()->getLayoutQualifier().matrixPacking)
+ {
+ case EmpUnspecified:
+ case EmpColumnMajor:
+ // Default matrix packing is column major.
+ out << "column_major";
+ break;
+
+ case EmpRowMajor:
+ out << "row_major";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ out << ") ";
+ }
+
if (writeVariablePrecision(field->type()->getPrecision()))
out << " ";
out << getTypeName(*field->type()) << " " << hashName(TName(field->name()));