Add parsing support for global and interface block scoped matrix packing qualifiers.

TRAC #23271

Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Authored-by: Jamie Madill
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 4de4509..3f8f39d 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -1445,7 +1445,12 @@
         return;
     }
 
-    // TODO: global matrix packing and block storage
+    if (layoutQualifier.matrixPacking != EmpUnspecified)
+    {
+        defaultMatrixPacking = layoutQualifier.matrixPacking;
+    }
+
+    // TODO: block storage
 }
 
 TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
@@ -1899,12 +1904,17 @@
         recover();
     }
 
-    const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
-    if (layoutLocationErrorCheck(typeQualifier.line, layoutQualifier))
+    TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
+    if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier))
     {
         recover();
     }
 
+    if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
+    {
+        blockLayoutQualifier.matrixPacking = defaultMatrixPacking;
+    }
+
     TSymbol* blockNameSymbol = new TInterfaceBlockName(&blockName);
     if (!symbolTable.declare(*blockNameSymbol)) {
         error(nameLine, "redefinition", blockName.c_str(), "interface block name");
@@ -1933,16 +1943,29 @@
         }
 
         // check layout qualifiers
-        if (layoutLocationErrorCheck(memberTypeLine.line, memberType->getLayoutQualifier()))
+        TLayoutQualifier memberLayoutQualifier = memberType->getLayoutQualifier();
+        if (layoutLocationErrorCheck(memberTypeLine.line, memberLayoutQualifier))
         {
             recover();
         }
+
+        if (memberLayoutQualifier.matrixPacking == EmpUnspecified)
+        {
+            memberLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
+        }
+        else if (!memberType->isMatrix())
+        {
+            error(memberTypeLine.line, "invalid layout qualifier:", getMatrixPackingString(memberLayoutQualifier.matrixPacking), "can only be used on matrix types");
+            recover();
+        }
+
+        memberType->setLayoutQualifier(memberLayoutQualifier);
     }
 
     TType* interfaceBlock = new TType(typeList, blockName);
     interfaceBlock->setBasicType(EbtInterfaceBlock);
     interfaceBlock->setQualifier(typeQualifier.qualifier);
-    interfaceBlock->setLayoutQualifier(layoutQualifier);
+    interfaceBlock->setLayoutQualifier(blockLayoutQualifier);
 
     TString symbolName = "";
     int symbolId = 0;