Add support for structures in interface and uniform blocks.

Also redesigns the uniform block layout computation to be more general.

TRAC #23018

Signed-off-by: Geoff Lang
Signed-off-by: Nicolas Capens
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2387 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 89bb72d..0992c97 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -194,6 +194,24 @@
     }
 }
 
+TString OutputHLSL::interfaceBlockMemberTypeString(const TType &memberType)
+{
+    // TODO: layout support
+
+    if (memberType.isMatrix())
+    {
+        return " row_major " + typeString(memberType);
+    }
+    else if (memberType.getBasicType() == EbtStruct)
+    {
+        return "rm" + typeString(memberType);
+    }
+    else
+    {
+        return typeString(memberType);
+    }
+}
+
 TString OutputHLSL::interfaceBlockMemberString(const TTypeList &typeList)
 {
     TString hlsl;
@@ -203,7 +221,8 @@
     for (unsigned int typeIndex = 0; typeIndex < typeList.size(); typeIndex++)
     {
         const TType &memberType = *typeList[typeIndex].type;
-        hlsl += "    " + typeString(memberType) + " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
+        hlsl += "    " + interfaceBlockMemberTypeString(memberType) +
+                " " + decorate(memberType.getFieldName()) + arrayString(memberType) + ";\n";
     }
 
     return hlsl;
@@ -305,7 +324,7 @@
         mInterfaceBlockRegister += std::max(1u, interfaceBlock.arraySize);
 
         // TODO: handle other block layouts
-        interfaceBlock.setPackedBlockLayout();
+        interfaceBlock.setBlockLayout(BLOCKLAYOUT_SHARED);
         mActiveInterfaceBlocks.push_back(interfaceBlock);
 
         if (interfaceBlockType.hasInstanceName())
@@ -2920,8 +2939,7 @@
         mStructNames.insert(decorate(name));
 
         TString structure;
-        structure += "struct " + decorate(name) + "\n"
-                     "{\n";
+        structure += "{\n";
 
         const TTypeList &fields = *type.getStruct();
 
@@ -2936,7 +2954,14 @@
 
         if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end())
         {
-            mStructDeclarations.push_back(structure);
+            TString columnMajorString = "struct " + decorate(name) + "\n" + structure;
+            TString rowMajorString = "#pragma pack_matrix(row_major)\n"
+                                     "struct rm" + decorate(name) + "\n" +
+                                     structure +
+                                     "#pragma pack_matrix(column_major)\n";
+
+            mStructDeclarations.push_back(columnMajorString);
+            mStructDeclarations.push_back(rowMajorString);
         }
 
         for (unsigned int i = 0; i < fields.size(); i++)