Compiler - Wrong Result from Matrix Multiply
TRAC #11751
Signed-off-by: Andrew Lewycky
Signed-off-by: Daniel Koch

Author:    Nicolas Capens

git-svn-id: https://angleproject.googlecode.com/svn/trunk@101 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 4a8ad7f..94a9341 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -557,23 +557,33 @@
         {
             out << " = mul(";
             
-            if (node->getOp() == EOpMatrixTimesMatrixAssign)
+            if (node->getLeft()->getQualifier() == EvqUniform)
             {
                 out << "transpose(";
             }
             
             node->getLeft()->traverse(this);
             
-            if (node->getOp() == EOpMatrixTimesMatrixAssign)
+            if (node->getLeft()->getQualifier() == EvqUniform)
             {
                 out << ")";
             }
 
-            out << ", transpose(";
+            out << ", ";
+
+            if (node->getRight()->getQualifier() == EvqUniform)
+            {
+                out << "transpose(";
+            }
         }
         else
         {
-            out << ")))";
+            if (node->getRight()->getQualifier() == EvqUniform)
+            {
+                out << ")";
+            }
+
+            out << "))";
         }
         break;
       case EOpDivAssign:               outputTriplet(visit, "(", " /= ", ")");          break;
@@ -646,9 +656,50 @@
       case EOpGreaterThanEqual:  outputTriplet(visit, "(", " >= ", ")");  break;
       case EOpVectorTimesScalar: outputTriplet(visit, "(", " * ", ")");   break;
       case EOpMatrixTimesScalar: outputTriplet(visit, "(", " * ", ")");   break;
-      case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break;
-      case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break;
-      case EOpMatrixTimesMatrix: outputTriplet(visit, "mul(transpose(", "), transpose(", "))"); break;
+      case EOpVectorTimesMatrix:
+          if (node->getRight()->getQualifier() == EvqUniform)
+          {
+              outputTriplet(visit, "mul(", ", transpose(", "))");
+          }
+          else
+          {
+              outputTriplet(visit, "mul(", ", ", ")");
+          }
+          break;
+      case EOpMatrixTimesVector:
+          if (node->getLeft()->getQualifier() == EvqUniform)
+          {
+              outputTriplet(visit, "mul(transpose(", "), ", ")");
+          }
+          else
+          {
+              outputTriplet(visit, "mul(", ", ", ")");
+          }
+          break;
+      case EOpMatrixTimesMatrix:
+          if (node->getLeft()->getQualifier() == EvqUniform)
+          {
+              if (node->getRight()->getQualifier() == EvqUniform)
+              {
+                  outputTriplet(visit, "mul(transpose(", "), transpose(", "))");
+              }
+              else
+              {
+                  outputTriplet(visit, "mul(transpose(", "), ", ")");
+              }
+          }
+          else
+          {
+              if (node->getRight()->getQualifier() == EvqUniform)
+              {
+                  outputTriplet(visit, "mul(", ", transpose(", "))");
+              }
+              else
+              {
+                  outputTriplet(visit, "mul(", ", ", ")");
+              }
+          }
+          break;
       case EOpLogicalOr:         outputTriplet(visit, "(", " || ", ")");  break;
       case EOpLogicalXor:        outputTriplet(visit, "xor(", ", ", ")"); break;   // FIXME: Prevent name clashes
       case EOpLogicalAnd:        outputTriplet(visit, "(", " && ", ")");  break;