Implement non-square matrices, and make a few type improvements. Cleaned up a few...
authorJohn Kessenich <cepheus@frii.com>
Mon, 4 Feb 2013 23:54:58 +0000 (23:54 +0000)
committerJohn Kessenich <cepheus@frii.com>
Mon, 4 Feb 2013 23:54:58 +0000 (23:54 +0000)
Details
 - added all the new non-square types
 - separated concepts of matrix size and vector size
 - removed VS 6.0 comments/workarounds
 - removed obsolete concept of matrix fields

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20436 e7fa87d3-cd2b-0410-9028-fcbf551c1848

17 files changed:
Test/matrixError.vert [new file with mode: 0644]
Test/nonSquare.vert [new file with mode: 0644]
Test/testlist
glslang/Include/Common.h
glslang/Include/PoolAlloc.h
glslang/Include/Types.h
glslang/Include/intermediate.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/PoolAlloc.cpp
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/SymbolTable.cpp
glslang/MachineIndependent/glslang.y
glslang/MachineIndependent/intermOut.cpp
glslang/MachineIndependent/parseConst.cpp

diff --git a/Test/matrixError.vert b/Test/matrixError.vert
new file mode 100644 (file)
index 0000000..eb4b439
--- /dev/null
@@ -0,0 +1,22 @@
+#version 120
+
+attribute vec3 v3;
+
+uniform mat3x2 m32;
+
+const mat2x4 m24 = mat2x4(1.0, 2.0, 
+                          3.0, 4.0,
+                          3.0, 4.0,
+                          3.0, 4.0, 5.0);
+
+void main()
+{
+    mat2x3 m23;
+    vec3 a, b;
+
+    a = v3 * m23;
+    b = m32 * v3;
+    m23.xy;
+
+    gl_Position = vec4(m23 * m32 * v3, m24[2][4]);
+}
diff --git a/Test/nonSquare.vert b/Test/nonSquare.vert
new file mode 100644 (file)
index 0000000..0974425
--- /dev/null
@@ -0,0 +1,25 @@
+#version 120
+
+attribute vec3 v3;
+attribute vec4 v4;
+
+uniform mat3x2 m32;
+
+const vec2 cv2 = vec2(10.0, 20.0);
+const mat2x4 m24 = mat2x4(3.0);
+const mat4x2 m42 = mat4x2(1.0, 2.0, 
+                          3.0, 4.0,
+                          5.0, 6.0, 
+                          7.0, 8.0);
+
+void main()
+{
+    mat2x3 m23;
+    vec2 a, b;
+
+    a = v3 * m23;
+    b = m32 * v3;
+
+    gl_Position = vec4(m23 * m32 * v3, m24[1][3]) + 
+                  (m24 * m42) * v4 + cv2 * m42 + m24 * cv2 + vec4(cv2[1], cv2.x, m42[2][1], m42[2][0]);
+}
index c9a1513..93766c6 100644 (file)
@@ -10,3 +10,6 @@ versionsErrors.vert
 130.frag
 140.frag
 precision.frag
+nonSquare.vert
+matrixError.vert
+
index 81c042f..f3f5fd2 100644 (file)
     #pragma warning(disable : 4201) // nameless union
 #endif
 
-//
-// Doing the push and pop below for warnings does not leave the warning state
-// the way it was.  This seems like a defect in the compiler.  We would like
-// to do this, but since it does not work correctly right now, it is turned
-// off.
-//
-//??#pragma warning(push, 3)
-
-       #include <set>
-    #include <vector>
-    #include <map>
-    #include <list>
-    #include <string>
-    #include <stdio.h>
-
-//??#pragma warning(pop)
+#include <set>
+#include <vector>
+#include <map>
+#include <list>
+#include <string>
+#include <stdio.h>
 
 typedef int TSourceLoc;
 
index 14c5985..2a34c78 100644 (file)
@@ -113,7 +113,6 @@ private:
     unsigned char* mem;           // beginning of our allocation (pts to header)
     TAllocation* prevAlloc;       // prior allocation in the chain
 
-    // Support MSVC++ 6.0
     const static unsigned char guardBlockBeginVal;
     const static unsigned char guardBlockEndVal;
     const static unsigned char userDataFill;
index a755cd0..dd28d40 100644 (file)
@@ -74,8 +74,9 @@ class TPublicType {
 public:
     TBasicType type;
     TQualifier qualifier;
-    int size;          // size of vector or matrix, not size of array
-    bool matrix;
+    int vectorSize : 4;
+    int matrixCols : 4;
+    int matrixRows : 4;
     bool array;
     int arraySize;
     TType* userDef;
@@ -84,8 +85,9 @@ public:
     void initType(int ln = 0)
     {
         type = EbtVoid;
-        size = 1;
-        matrix = false;
+        vectorSize = 1;
+        matrixRows = 0;
+        matrixCols = 0;
         array = false;
         arraySize = 0;
         userDef = 0;
@@ -104,10 +106,16 @@ public:
         initQualifiers(global);
     }
 
-    void setAggregate(int s, bool m = false)
+    void setVector(int s)
     {
-        size = s;
-        matrix = m;
+        vectorSize = s;
+    }
+
+    void setMatrix(int c, int r)
+    {
+        matrixRows = r;
+        matrixCols = c;
+        vectorSize = 0;
     }
 
     void setArray(bool a, int s = 0)
@@ -125,15 +133,16 @@ typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
 class TType {
 public:
     POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-    explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
-                            type(t), size(s), matrix(m), array(a), arraySize(0),
+    explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
+                            type(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), array(false), arraySize(0),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
-                            fieldName(0), mangled(0), typeName(0) {
+                            fieldName(0), mangled(0), typeName(0) 
+                            {
                                 qualifier.storage = q;
                                 qualifier.precision = EpqNone;
                             }
     explicit TType(const TPublicType &p) :
-                            type(p.type), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
+                            type(p.type), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), array(p.array), arraySize(p.arraySize),
                             structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
                             {
                                 qualifier = p.qualifier;
@@ -143,8 +152,9 @@ public:
                                 }
                             }
     explicit TType(TTypeList* userDef, const TString& n) :
-                            type(EbtStruct), size(1), matrix(false), array(false), arraySize(0),
-                            structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
+                            type(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), array(false), arraySize(0),
+                            structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) 
+                            {
                                 qualifier.storage = EvqTemporary;
                                 qualifier.precision = EpqNone;
                                                                typeName = NewPoolTString(n.c_str());
@@ -158,8 +168,9 @@ public:
        {
                type = copyOf.type;
                qualifier = copyOf.qualifier;
-               size = copyOf.size;
-               matrix = copyOf.matrix;
+               vectorSize = copyOf.vectorSize;
+               matrixCols = copyOf.matrixCols;
+               matrixRows = copyOf.matrixRows;
                array = copyOf.array;
                arraySize = copyOf.arraySize;
                
@@ -205,16 +216,30 @@ public:
                return newType;
        }
 
-    virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
-                            { type = t; size = s; matrix = m; array = a; arraySize = aS; }
-    virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
-                            { type = t;
-                              size = s;
-                              matrix = m;
-                              if (userDef)
-                                  structure = userDef->getStruct();
-                              // leave array information intact.
-                            }
+    virtual void dereference()
+    {
+        if (array) {
+            array = false;
+            arraySize = 0;
+            maxArraySize = 0;
+        } else if (matrixCols > 0) {
+            vectorSize = matrixRows;
+            matrixCols = 0;
+            matrixRows = 0;
+        } else if (vectorSize > 1)
+            vectorSize = 1;
+    }
+
+    virtual void setElementType(TBasicType t, int s, int mc, int mr, TType* userDef)
+    { 
+        type = t;
+        vectorSize = s;
+        matrixCols = mc;
+        matrixRows = mr;
+        if (userDef)
+            structure = userDef->getStruct();
+        // leave array information intact.
+    }
     virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
     virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
     virtual const TString& getTypeName() const
@@ -232,29 +257,20 @@ public:
     virtual TBasicType getBasicType() const { return type; }
     virtual TQualifier& getQualifier() { return qualifier; }
     virtual const TQualifier& getQualifier() const { return qualifier; }
+    
+    virtual int getVectorSize() const { return vectorSize; }
+    virtual int getMatrixCols() const { return matrixCols; }
+    virtual int getMatrixRows() const { return matrixRows; }
 
-    // One-dimensional size of single instance type
-    virtual int getNominalSize() const { return size; }
-
-    // Full-dimensional size of single instance of type
-    virtual int getInstanceSize() const
-    {
-        if (matrix)
-            return size * size;
-        else
-            return size;
-    }
-
-       virtual bool isMatrix() const { return matrix ? true : false; }
+       virtual bool isMatrix() const { return matrixCols ? true : false; }
     virtual bool isArray() const  { return array ? true : false; }
     int getArraySize() const { return arraySize; }
     void setArraySize(int s) { array = true; arraySize = s; }
     void setMaxArraySize (int s) { maxArraySize = s; }
     int getMaxArraySize () const { return maxArraySize; }
-    void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
     void setArrayInformationType(TType* t) { arrayInformationType = t; }
     TType* getArrayInformationType() { return arrayInformationType; }
-    virtual bool isVector() const { return size > 1 && !matrix; }
+    virtual bool isVector() const { return vectorSize > 1; }
     static char* getBasicString(TBasicType t) {
         switch (t) {
         case EbtVoid:              return "void";              break;
@@ -285,10 +301,10 @@ public:
 
         if (getBasicType() == EbtStruct)
             totalSize = getStructSize();
-        else if (matrix)
-            totalSize = size * size;
+        else if (matrixCols)
+            totalSize = matrixCols * matrixRows;
         else
-            totalSize = size;
+            totalSize = vectorSize;
 
         if (isArray())
             totalSize *= Max(getArraySize(), getMaxArraySize());
@@ -307,17 +323,19 @@ public:
         return *mangled;
     }
     bool sameElementType(const TType& right) const {
-        return      type == right.type   &&
-                    size == right.size   &&
-                  matrix == right.matrix &&
-               structure == right.structure;
+        return       type == right.type       &&
+               vectorSize == right.vectorSize &&
+               matrixCols == right.matrixCols &&
+               matrixRows == right.matrixRows &&
+                structure == right.structure;
     }
     bool operator==(const TType& right) const {
-        return      type == right.type   &&
-                    size == right.size   &&
-                  matrix == right.matrix &&
-                   array == right.array  && (!array || arraySize == right.arraySize) &&
-               structure == right.structure;
+        return       type == right.type       &&
+               vectorSize == right.vectorSize &&
+               matrixCols == right.matrixCols &&
+               matrixRows == right.matrixRows &&
+                    array == right.array      && (!array || arraySize == right.arraySize) &&
+                structure == right.structure;
         // don't check the qualifier, it's not ever what's being sought after
     }
     bool operator!=(const TType& right) const {
@@ -330,8 +348,9 @@ protected:
     int getStructSize() const;
 
        TBasicType type      : 8;
-       int size             : 8; // size of vector or matrix, not size of array
-       unsigned int matrix  : 1;
+    int vectorSize       : 4;
+    int matrixCols       : 4;
+    int matrixRows       : 4;
        unsigned int array   : 1;
     TQualifier qualifier;
 
index c6e234c..c71244c 100644 (file)
@@ -184,6 +184,7 @@ enum TOperator {
     // Constructors
     //
 
+    EOpConstructGuardStart,
     EOpConstructInt,
     EOpConstructBool,
     EOpConstructFloat,
@@ -191,16 +192,35 @@ enum TOperator {
     EOpConstructVec2,
     EOpConstructVec3,
     EOpConstructVec4,
+    EOpConstructDVec2,
+    EOpConstructDVec3,
+    EOpConstructDVec4,
     EOpConstructBVec2,
     EOpConstructBVec3,
     EOpConstructBVec4,
     EOpConstructIVec2,
     EOpConstructIVec3,
     EOpConstructIVec4,
-    EOpConstructMat2,
-    EOpConstructMat3,
-    EOpConstructMat4,
+    EOpConstructMat2x2,
+    EOpConstructMat2x3,
+    EOpConstructMat2x4,
+    EOpConstructMat3x2,
+    EOpConstructMat3x3,
+    EOpConstructMat3x4,
+    EOpConstructMat4x2,
+    EOpConstructMat4x3,
+    EOpConstructMat4x4,
+    EOpConstructDMat2x2,
+    EOpConstructDMat2x3,
+    EOpConstructDMat2x4,
+    EOpConstructDMat3x2,
+    EOpConstructDMat3x3,
+    EOpConstructDMat3x4,
+    EOpConstructDMat4x2,
+    EOpConstructDMat4x3,
+    EOpConstructDMat4x4,
     EOpConstructStruct,
+    EOpConstructGuardEnd,
 
     //
     // moves
@@ -286,8 +306,10 @@ public:
     virtual TBasicType getBasicType() const { return type.getBasicType(); }
     virtual TQualifier& getQualifier() { return type.getQualifier(); }
     virtual void propagatePrecision(TPrecisionQualifier);
-    virtual int getNominalSize() const { return type.getNominalSize(); }
-    virtual int getSize() const { return type.getInstanceSize(); }
+    virtual int getVectorSize() const { return type.getVectorSize(); }
+    virtual int getMatrixCols() const { return type.getMatrixCols(); }
+    virtual int getMatrixRows() const { return type.getMatrixRows(); }
+    //virtual int getSize() const { return type.getInstanceSize(); }
     virtual bool isMatrix() const { return type.isMatrix(); }
     virtual bool isArray()  const { return type.isArray(); }
     virtual bool isVector() const { return type.isVector(); }
index 67702b7..60795f6 100644 (file)
@@ -934,7 +934,7 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBu
 
     case EShLangFragment: {
             // Set up gl_FragData.  The array size.
-            TType fragData(EbtFloat, EvqFragColor,   4, false, true);
+            TType fragData(EbtFloat, EvqFragColor, 4);
             fragData.setArraySize(resources.maxDrawBuffers);
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"),    fragData));
         }
index 091158b..eb5a847 100644 (file)
@@ -132,26 +132,19 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
     node->setRight(right);
     if (! node->promote(infoSink))
         return 0;
-
-    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
-    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
         
-    if (leftTempConstant)
-        leftTempConstant = left->getAsConstantUnion();
-    
-    if (rightTempConstant)
-        rightTempConstant = right->getAsConstantUnion();
-
     //
-    // See if we can fold constants.
+    // If they are both constants, they must be folded.
     //
 
-    TIntermTyped* typedReturnNode = 0;
-    if ( leftTempConstant && rightTempConstant) {
-        typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
-
-        if (typedReturnNode)
-            return typedReturnNode;
+    TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+    if (leftTempConstant && rightTempConstant) {
+        TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
+        if (folded)
+            return folded;
+        else
+            infoSink.info.message(EPrefixInternalError, "Constant folding failed", line);
     }
 
     return node;
@@ -253,9 +246,9 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode,
     }
 
     if (newType != EbtVoid) {
-        child = addConversion(op, TType(newType, EvqTemporary, child->getNominalSize(), 
-                                                               child->isMatrix(), 
-                                                               child->isArray()),
+        child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
+                                                               child->getMatrixCols(),
+                                                               child->getMatrixRows()),
                               child);
         if (child == 0)
             return 0;
@@ -456,7 +449,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
             return 0;
         }
 
-        TType type(promoteTo, EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
+        TType type(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
         newNode = new TIntermUnary(newOp, type);
         newNode->setLine(node->getLine());
         newNode->setOperand(node);
@@ -742,27 +735,7 @@ bool TIntermOperator::modifiesState() const
 //
 bool TIntermOperator::isConstructor() const
 {
-    switch (op) {
-    case EOpConstructVec2:
-    case EOpConstructVec3:
-    case EOpConstructVec4:
-    case EOpConstructMat2:
-    case EOpConstructMat3:
-    case EOpConstructMat4:
-    case EOpConstructFloat:
-    case EOpConstructIVec2:
-    case EOpConstructIVec3:
-    case EOpConstructIVec4:
-    case EOpConstructInt:
-    case EOpConstructBVec2:
-    case EOpConstructBVec3:
-    case EOpConstructBVec4:
-    case EOpConstructBool:
-    case EOpConstructStruct:
-        return true;
-    default:
-        return false;
-    }
+    return op > EOpConstructGuardStart && op < EOpConstructGuardEnd;
 }
 //
 // Make sure the type of a unary operator is appropriate for its 
@@ -814,12 +787,6 @@ bool TIntermUnary::promote(TInfoSink&)
 //
 bool TIntermBinary::promote(TInfoSink& infoSink)
 {
-    int size = left->getNominalSize();
-    if (right->getNominalSize() > size)
-        size = right->getNominalSize();
-
-    TBasicType basicType = left->getBasicType();
-
     //
     // Arrays have to be exact matches.
     //
@@ -870,7 +837,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
     //
     // All scalars.  Code after this test assumes this case is removed!
     //
-    if (size == 1) {
+    if (left->getVectorSize() == 1 && right->getVectorSize() == 1) {
 
         switch (op) {
 
@@ -931,39 +898,44 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
     }
 
     //
-    // Are the sizes compatible?
-    //
-    if ( left->getNominalSize() != size &&  left->getNominalSize() != 1 ||
-        right->getNominalSize() != size && right->getNominalSize() != 1)
-        return false;
-
-    //
     // Can these two operands be combined?
     //
+    TBasicType basicType = left->getBasicType();
     switch (op) {
     case EOpMul:
         if (!left->isMatrix() && right->isMatrix()) {
-            if (left->isVector())
+            if (left->isVector()) {
+                if (left->getVectorSize() != right->getMatrixRows())
+                    return false;
                 op = EOpVectorTimesMatrix;
-            else {
+                setType(TType(basicType, EvqTemporary, right->getMatrixCols()));
+            } else {
                 op = EOpMatrixTimesScalar;
-                setType(TType(basicType, EvqTemporary, size, true));
+                setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows()));
             }
         } else if (left->isMatrix() && !right->isMatrix()) {
             if (right->isVector()) {
+                if (left->getMatrixCols() != right->getVectorSize())
+                    return false;
                 op = EOpMatrixTimesVector;
-                setType(TType(basicType, EvqTemporary, size, false));
+                setType(TType(basicType, EvqTemporary, left->getMatrixRows()));
             } else {
                 op = EOpMatrixTimesScalar;
             }
         } else if (left->isMatrix() && right->isMatrix()) {
+            if (left->getMatrixCols() != right->getMatrixRows())
+                return false;
             op = EOpMatrixTimesMatrix;
+            setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows()));
         } else if (!left->isMatrix() && !right->isMatrix()) {
             if (left->isVector() && right->isVector()) {
+                if (left->getVectorSize() != right->getVectorSize())
+                    return false;
                 // leave as component product
             } else if (left->isVector() || right->isVector()) {
                 op = EOpVectorTimesScalar;
-                setType(TType(basicType, EvqTemporary, size, false));
+                if (right->getVectorSize() > 1)
+                    setType(TType(basicType, EvqTemporary, right->getVectorSize()));
             }
         } else {
             infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
@@ -972,9 +944,11 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
         break;
     case EOpMulAssign:
         if (!left->isMatrix() && right->isMatrix()) {
-            if (left->isVector())
+            if (left->isVector()) {
+                if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols())
+                    return false;
                 op = EOpVectorTimesMatrixAssign;
-            else {
+            else {
                 return false;
             }
         } else if (left->isMatrix() && !right->isMatrix()) {
@@ -984,6 +958,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
                 op = EOpMatrixTimesScalarAssign;
             }
         } else if (left->isMatrix() && right->isMatrix()) {
+            if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows())
+                return false;
             op = EOpMatrixTimesMatrixAssign;
         } else if (!left->isMatrix() && !right->isMatrix()) {
             if (left->isVector() && right->isVector()) {
@@ -992,7 +968,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
                 if (! left->isVector())
                     return false;
                 op = EOpVectorTimesScalarAssign;
-                setType(TType(basicType, EvqTemporary, size, false));
             }
         } else {
             infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
@@ -1000,7 +975,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
         }
         break;      
     case EOpAssign:
-        if (left->getNominalSize() != right->getNominalSize())
+        if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
             return false;
         // fall through
     case EOpAdd:
@@ -1015,7 +990,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
             left->isVector() && right->isMatrix() ||
             left->getBasicType() != right->getBasicType())
             return false;
-        setType(TType(basicType, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+        if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()))
+            return false;
+        if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
+            return false;
+        if (right->isVector() || right->isMatrix())
+            setType(TType(basicType, EvqTemporary, right->getVectorSize(), right->getMatrixCols(), right->getMatrixRows()));
         break;
         
     case EOpEqual:
@@ -1031,7 +1011,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
         setType(TType(EbtBool));
         break;
 
-default:
+    default:
         return false;
     }
 
@@ -1135,7 +1115,7 @@ bool CompareStructure(const TType& leftNodeType, constUnion* rightUnionArray, co
 {
     if (leftNodeType.isArray()) {
         TType typeWithoutArrayness = leftNodeType;
-        typeWithoutArrayness.clearArrayness();
+        typeWithoutArrayness.dereference();
 
         int arraySize = leftNodeType.getArraySize();
 
@@ -1159,7 +1139,7 @@ bool CompareStructure(const TType& leftNodeType, constUnion* rightUnionArray, co
 
 TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
 {   
-    constUnion *unionArray = getUnionArrayPointer(); 
+    constUnion *unionArray = getUnionArrayPointer();
     int objectSize = getType().getObjectSize();
 
     if (constantNode) {  // binary operations
@@ -1167,17 +1147,22 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
         constUnion *rightUnionArray = node->getUnionArrayPointer();
         TType returnType = getType();
 
-        // for a case like float f = 1.2 + vec4(2,3,4,5);
+        if (getType().getBasicType() != node->getBasicType()) {
+            infoSink.info.message(EPrefixInternalError, "Constant folding basic types don't match", getLine());
+            return 0;
+        }
+
         if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
+            // for a case like float f = vec4(2,3,4,5) + 1.2;
             rightUnionArray = new constUnion[objectSize];
             for (int i = 0; i < objectSize; ++i)
-                rightUnionArray[i] = *node->getUnionArrayPointer(); 
-            returnType = getType();
+                rightUnionArray[i] = *node->getUnionArrayPointer();
         } else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
-            // for a case like float f = vec4(2,3,4,5) + 1.2;
+            // for a case like float f = 1.2 + vec4(2,3,4,5);
+            rightUnionArray = node->getUnionArrayPointer();
             unionArray = new constUnion[constantNode->getType().getObjectSize()];
             for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
-                unionArray[i] = *getUnionArrayPointer(); 
+                unionArray[i] = *getUnionArrayPointer();
             returnType = node->getType();
             objectSize = constantNode->getType().getObjectSize();
         }
@@ -1189,182 +1174,142 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
         switch(op) {
         case EOpAdd: 
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] + rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] + rightUnionArray[i];
             break;
         case EOpSub: 
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] - rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] - rightUnionArray[i];
             break;
 
         case EOpMul:
         case EOpVectorTimesScalar:
         case EOpMatrixTimesScalar: 
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] * rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] * rightUnionArray[i];
             break;
-        case EOpMatrixTimesMatrix:                
-            if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
-                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
-                return 0;
-            }
-            {// support MSVC++6.0
-                int size = getNominalSize();
-                tempConstArray = new constUnion[size*size];
-                for (int row = 0; row < size; row++) {
-                    for (int column = 0; column < size; column++) {
-                        tempConstArray[size * column + row].setFConst(0.0f);
-                        for (int i = 0; i < size; i++) {
-                            tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst())); 
-                        }
-                    }
+        case EOpMatrixTimesMatrix:
+            tempConstArray = new constUnion[getMatrixRows() * node->getMatrixCols()];
+            for (int row = 0; row < getMatrixRows(); row++) {
+                for (int column = 0; column < node->getMatrixCols(); column++) {
+                    float sum = 0.0f;                    
+                    for (int i = 0; i < node->getMatrixRows(); i++)
+                        sum += unionArray[i * getMatrixRows() + row].getFConst() * rightUnionArray[column * node->getMatrixRows() + i].getFConst();
+                    tempConstArray[column * getMatrixRows() + row].setFConst(sum);
                 }
             }
+            returnType = TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols());
             break;
         case EOpDiv: 
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++) {
-                    switch (getType().getBasicType()) {
-                    case EbtFloat: 
-                        if (rightUnionArray[i] == 0.0f) {
-                            infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
-                            tempConstArray[i].setFConst(FLT_MAX);
-                        } else
-                            tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
-                    break;
-
-                    case EbtInt:   
-                        if (rightUnionArray[i] == 0) {
-                            infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
-                            tempConstArray[i].setIConst(INT_MAX);
-                        } else
-                            tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
-                        break;            
-                    default: 
-                        infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
-                        return 0;
-                    }
+            for (int i = 0; i < objectSize; i++) {
+                switch (getType().getBasicType()) {
+                case EbtFloat: 
+                    if (rightUnionArray[i] == 0.0f) {
+                        infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                        tempConstArray[i].setFConst(FLT_MAX);
+                    } else
+                        tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
+                break;
+
+                case EbtInt:   
+                    if (rightUnionArray[i] == 0) {
+                        infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
+                        tempConstArray[i].setIConst(INT_MAX);
+                    } else
+                        tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                    break;            
+                default: 
+                    infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
+                    return 0;
                 }
             }
             break;
 
-        case EOpMatrixTimesVector: 
-            if (node->getBasicType() != EbtFloat) {
-                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", getLine());
-                return 0;
-            }
-            tempConstArray = new constUnion[getNominalSize()];
-            
-            {// support MSVC++6.0                    
-                for (int size = getNominalSize(), i = 0; i < size; i++) {
-                    tempConstArray[i].setFConst(0.0f);
-                    for (int j = 0; j < size; j++) {
-                        tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
-                    }
+        case EOpMatrixTimesVector:
+            tempConstArray = new constUnion[getMatrixRows()];
+            for (int i = 0; i < getMatrixRows(); i++) {
+                float sum = 0.0f;
+                for (int j = 0; j < node->getVectorSize(); j++) {
+                    sum += unionArray[j*getMatrixRows() + i].getFConst() * rightUnionArray[j].getFConst();
                 }
+                tempConstArray[i].setFConst(sum);
             }
-            
-            tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
+
+            tempNode = new TIntermConstantUnion(tempConstArray, TType(getBasicType(), EvqConst, getMatrixRows()));
             tempNode->setLine(getLine());
 
             return tempNode;                
 
         case EOpVectorTimesMatrix:
-            if (getType().getBasicType() != EbtFloat) {
-                infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", getLine());
-                return 0;
-            }  
-
-            tempConstArray = new constUnion[getNominalSize()];
-            {// support MSVC++6.0
-                for (int size = getNominalSize(), i = 0; i < size; i++) {
-                    tempConstArray[i].setFConst(0.0f);
-                    for (int j = 0; j < size; j++) {
-                        tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
-                    }
-                }
+            tempConstArray = new constUnion[node->getMatrixCols()];
+            for (int i = 0; i < node->getMatrixCols(); i++) {
+                float sum = 0.0f;
+                for (int j = 0; j < getVectorSize(); j++)
+                    sum += unionArray[j].getFConst() * rightUnionArray[i*node->getMatrixRows() + j].getFConst();
+                tempConstArray[i].setFConst(sum);
             }
-            break;
+
+            tempNode = new TIntermConstantUnion(tempConstArray, TType(getBasicType(), EvqConst, node->getMatrixCols()));
+            tempNode->setLine(getLine());
+
+            return tempNode;                
 
         case EOpMod:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] % rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] % rightUnionArray[i];
             break;
     
         case EOpRightShift:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] >> rightUnionArray[i];
             break;
 
         case EOpLeftShift:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] << rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] << rightUnionArray[i];
             break;
     
         case EOpAnd:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] & rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] & rightUnionArray[i];
             break;
         case EOpInclusiveOr:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] | rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] | rightUnionArray[i];
             break;
         case EOpExclusiveOr:
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] ^ rightUnionArray[i];
             break;
 
         case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] && rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] && rightUnionArray[i];
             break;
 
         case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    tempConstArray[i] = unionArray[i] || rightUnionArray[i];
-            }
+            for (int i = 0; i < objectSize; i++)
+                tempConstArray[i] = unionArray[i] || rightUnionArray[i];
             break;
 
         case EOpLogicalXor:  
             tempConstArray = new constUnion[objectSize];
-            {// support MSVC++6.0
-                for (int i = 0; i < objectSize; i++)
-                    switch (getType().getBasicType()) {
-                    case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
-                    default: assert(false && "Default missing");
-                    }
+            for (int i = 0; i < objectSize; i++) {
+                switch (getType().getBasicType()) {
+                case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+                default: assert(false && "Default missing");
+                }
             }
             break;
 
@@ -1500,13 +1445,15 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
 
 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) 
 {
+    if (node->getType().isArray())
+        infoSink.info.message(EPrefixInternalError, "Cannot promote array", node->getLine());
+
     constUnion *rightUnionArray = node->getUnionArrayPointer();
     int size = node->getType().getObjectSize();
 
     constUnion *leftUnionArray = new constUnion[size];
 
-    for (int i=0; i < size; i++) {
-        
+    for (int i=0; i < size; i++) {        
         switch (promoteTo) {
         case EbtFloat:
             switch (node->getType().getBasicType()) {
@@ -1560,14 +1507,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
         default:
             infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
             return 0;
-        }
-    
+        }    
     }
     
     const TType& t = node->getType();
     
-    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getNominalSize(), t.isMatrix(), 
-                            t.isArray()), node->getLine());
+    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), 
+                            node->getLine());
 }
 
 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
index 5c74801..ccc7d28 100644 (file)
@@ -150,55 +150,6 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
     return true;
 }
 
-
-//
-// Look at a '.' field selector string and change it into offsets
-// for a matrix.
-//
-bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
-{
-    fields.wholeRow = false;
-    fields.wholeCol = false;
-    fields.row = -1;
-    fields.col = -1;
-
-    if (compString.size() != 2) {
-        error(line, "illegal length of matrix field selection", compString.c_str(), "");
-        return false;
-    }
-
-    if (compString[0] == '_') {
-        if (compString[1] < '0' || compString[1] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str(), "");
-            return false;
-        }
-        fields.wholeCol = true;
-        fields.col = compString[1] - '0';
-    } else if (compString[1] == '_') {
-        if (compString[0] < '0' || compString[0] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str(), "");
-            return false;
-        }
-        fields.wholeRow = true;
-        fields.row = compString[0] - '0';
-    } else {
-        if (compString[0] < '0' || compString[0] > '3' ||
-            compString[1] < '0' || compString[1] > '3') {
-            error(line, "illegal matrix field selection", compString.c_str(), "");
-            return false;
-        }
-        fields.row = compString[0] - '0';
-        fields.col = compString[1] - '0';
-    }
-
-    if (fields.row >= matSize || fields.col >= matSize) {
-        error(line, "matrix field selection out of range", compString.c_str(), "");
-        return false;
-    }
-
-    return true;
-}
-
 ///////////////////////////////////////////////////////////////////////
 //
 // Errors
@@ -261,7 +212,7 @@ void TParseContext::unaryOpError(int line, char* op, TString operand)
 //
 void TParseContext::binaryOpError(int line, char* op, TString left, TString right)
 {
-    error(line, " wrong operand types ", op, 
+    error(line, " wrong operand types:", op,
             "no operation '%s' exists that takes a left-hand operand of type '%s' and "
             "a right operand of type '%s' (or there is no acceptable conversion)", 
             op, left.c_str(), right.c_str());
@@ -425,7 +376,7 @@ bool TParseContext::constErrorCheck(TIntermTyped* node)
 //
 bool TParseContext::integerErrorCheck(TIntermTyped* node, char* token)
 {
-    if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
+    if (node->getBasicType() == EbtInt && node->getVectorSize() == 1)
         return false;
 
     error(node->getLine(), "integer expression required", token, "");
@@ -487,9 +438,24 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
 
     bool constructingMatrix = false;
     switch(op) {
-    case EOpConstructMat2:
-    case EOpConstructMat3:
-    case EOpConstructMat4:
+    case EOpConstructMat2x2:
+    case EOpConstructMat2x3:
+    case EOpConstructMat2x4:
+    case EOpConstructMat3x2:
+    case EOpConstructMat3x3:
+    case EOpConstructMat3x4:
+    case EOpConstructMat4x2:
+    case EOpConstructMat4x3:
+    case EOpConstructMat4x4:
+    case EOpConstructDMat2x2:
+    case EOpConstructDMat2x3:
+    case EOpConstructDMat2x4:
+    case EOpConstructDMat3x2:
+    case EOpConstructDMat3x3:
+    case EOpConstructDMat3x4:
+    case EOpConstructDMat4x2:
+    case EOpConstructDMat4x3:
+    case EOpConstructDMat4x4:
         constructingMatrix = true;
         break;
     default: 
@@ -608,7 +574,7 @@ bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
 //
 bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
 {
-    if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
+    if (pType.type != EbtBool || pType.array || pType.matrixCols > 1 || (pType.vectorSize > 1)) {
         error(line, "boolean expression expected", "", "");
         return true;
     } 
@@ -1138,7 +1104,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
     
     TType elementType = *type;
     if (type->isArray())
-        elementType.clearArrayness();
+        elementType.dereference();
 
     bool singleArg;
     if (aggrNode) {
@@ -1246,13 +1212,35 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, T
     case EOpConstructVec2:
     case EOpConstructVec3:
     case EOpConstructVec4:
-    case EOpConstructMat2:
-    case EOpConstructMat3:
-    case EOpConstructMat4:
+    case EOpConstructMat2x2:
+    case EOpConstructMat2x3:
+    case EOpConstructMat2x4:
+    case EOpConstructMat3x2:
+    case EOpConstructMat3x3:
+    case EOpConstructMat3x4:
+    case EOpConstructMat4x2:
+    case EOpConstructMat4x3:
+    case EOpConstructMat4x4:
     case EOpConstructFloat:
         basicOp = EOpConstructFloat;
         break;
 
+    case EOpConstructDVec2:
+    case EOpConstructDVec3:
+    case EOpConstructDVec4:
+    case EOpConstructDMat2x2:
+    case EOpConstructDMat2x3:
+    case EOpConstructDMat2x4:
+    case EOpConstructDMat3x2:
+    case EOpConstructDMat3x3:
+    case EOpConstructDMat3x4:
+    case EOpConstructDMat4x2:
+    case EOpConstructDMat4x3:
+    case EOpConstructDMat4x4:
+    case EOpConstructDouble:
+        basicOp = EOpConstructDouble;
+        break;
+
     case EOpConstructIVec2:
     case EOpConstructIVec3:
     case EOpConstructIVec4:
@@ -1345,7 +1333,7 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
 
     for (int i = 0; i < fields.num; i++) {
         if (fields.offsets[i] >= node->getType().getObjectSize()) {
-            error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]);
+            error(line, "", "[", "vector index out of range '%d'", fields.offsets[i]);
             recover();
             fields.offsets[i] = 0;
         }
@@ -1368,7 +1356,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
     TIntermTyped* typedNode;
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
 
-    if (index >= node->getType().getNominalSize()) {
+    if (index >= node->getType().getMatrixCols()) {
         error(line, "", "[", "matrix field selection out of range '%d'", index);
         recover();
         index = 0;
@@ -1376,7 +1364,8 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
 
     if (tempConstantNode) {
          constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
-         int size = tempConstantNode->getType().getNominalSize();
+         int size = tempConstantNode->getType().getMatrixRows();
+         // Note: the type is corrected (dereferenced) by the caller
          typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
     } else {
         error(line, "Cannot offset into the matrix", "Error", "");
@@ -1401,10 +1390,10 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
     TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
     int arraySize = node->getType().getArraySize();
     TType arrayElementType = node->getType();
-    arrayElementType.clearArrayness();
+    arrayElementType.dereference();
 
     if (index >= node->getType().getArraySize()) {
-        error(line, "", "[", "array field selection out of range '%d'", index);
+        error(line, "", "[", "array index out of range '%d'", index);
         recover();
         index = 0;
     }
index 2c28cce..4465b5e 100644 (file)
@@ -100,7 +100,6 @@ struct TParseContext {
     void recover();
 
     bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
-    bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
     void assignError(int line, const char* op, TString left, TString right);
     void unaryOpError(int line, char* op, TString operand);
     void binaryOpError(int line, char* op, TString left, TString right);
index afbd651..65d91f9 100644 (file)
@@ -175,7 +175,6 @@ TPoolAllocator::~TPoolAllocator()
     }
 }
 
-// Support MSVC++ 6.0
 const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
 const unsigned char TAllocation::guardBlockEndVal   = 0xfe;
 const unsigned char TAllocation::userDataFill       = 0xcd;
index 57b1362..dc899f5 100644 (file)
@@ -399,21 +399,19 @@ int ShLinkExt(
 
     THandleList cObjects;
 
-    {// support MSVC++6.0
-        for (int i = 0; i < numHandles; ++i) {
-            if (compHandles[i] == 0)
-                return 0;
-            TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
-            if (base->getAsLinker()) {
-                cObjects.push_back(base->getAsLinker());
-            }
-            if (base->getAsCompiler())
-                cObjects.push_back(base->getAsCompiler());
+    for (int i = 0; i < numHandles; ++i) {
+        if (compHandles[i] == 0)
+            return 0;
+        TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
+        if (base->getAsLinker()) {
+            cObjects.push_back(base->getAsLinker());
+        }
+        if (base->getAsCompiler())
+            cObjects.push_back(base->getAsCompiler());
     
     
-            if (cObjects[i] == 0)
-                return 0;
-        }
+        if (cObjects[i] == 0)
+            return 0;
     }
 
     TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
@@ -424,13 +422,11 @@ int ShLinkExt(
 
     linker->infoSink.info.erase();
 
-    {// support MSVC++6.0
-        for (int i = 0; i < numHandles; ++i) {
-            if (cObjects[i]->getAsCompiler()) {
-                if (! cObjects[i]->getAsCompiler()->linkable()) {
-                    linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");                
-                    return 0;
-                }
+    for (int i = 0; i < numHandles; ++i) {
+        if (cObjects[i]->getAsCompiler()) {
+            if (! cObjects[i]->getAsCompiler()->linkable()) {
+                linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");                
+                return 0;
             }
         }
     }
index 2983cde..b017f3c 100644 (file)
@@ -70,17 +70,21 @@ void TType::buildMangledName(TString& mangledName)
         mangledName += "struct-";
         if (typeName)
                mangledName += *typeName;
-        {// support MSVC++6.0
-            for (unsigned int i = 0; i < structure->size(); ++i) {
-                mangledName += '-';
-                (*structure)[i].type->buildMangledName(mangledName);
-            }
+        for (unsigned int i = 0; i < structure->size(); ++i) {
+            mangledName += '-';
+            (*structure)[i].type->buildMangledName(mangledName);
         }
     default: 
         break;
     }
 
-    mangledName += static_cast<char>('0' + getNominalSize());
+    if (getVectorSize() > 0)
+        mangledName += static_cast<char>('0' + getVectorSize());
+    else {
+        mangledName += static_cast<char>('0' + getMatrixCols());
+        mangledName += static_cast<char>('0' + getMatrixRows());
+    }
+
     if (isArray()) {
                const int maxSize = 10;
         char buf[maxSize];
index 2d362ea..8be6fbd 100644 (file)
@@ -306,8 +306,10 @@ postfix_expression
             }\r
         } else {\r
             if ($3->getQualifier().storage == EvqConst) {\r
-                if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {\r
-                    parseContext.error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
+                int index = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst();\r
+                if (! $1->isArray() && ($1->isVector() && $1->getType().getVectorSize() <= index ||\r
+                                        $1->isMatrix() && $1->getType().getMatrixCols() <= index)) {\r
+                    parseContext.error($2.line, "", "[", "index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());\r
                     parseContext.recover();\r
                 } else {\r
                     if ($1->isArray()) {\r
@@ -339,24 +341,13 @@ postfix_expression
             constUnion *unionArray = new constUnion[1];\r
             unionArray->setFConst(0.0f);\r
             $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.line);\r
-        } else if ($1->isArray()) {\r
-            if ($1->getType().getStruct())\r
-                $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));\r
-            else\r
-                $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));\r
-\r
-            if ($1->getType().getQualifier().storage == EvqConst)\r
-                $$->getTypePointer()->getQualifier().storage = EvqConst;\r
-        } else if ($1->isMatrix() && $1->getType().getQualifier().storage == EvqConst)\r
-            $$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize()));\r
-        else if ($1->isMatrix())\r
-            $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));\r
-        else if ($1->isVector() && $1->getType().getQualifier().storage == EvqConst)\r
-            $$->setType(TType($1->getBasicType(), EvqConst));\r
-        else if ($1->isVector())\r
-            $$->setType(TType($1->getBasicType(), EvqTemporary));\r
-        else\r
-            $$->setType($1->getType());\r
+        } else {\r
+            TType newType = $1->getType();\r
+            newType.dereference();\r
+            $$->setType(newType);\r
+            //?? why didn't the code above get the type right?\r
+            //?? write a deference test\r
+        }\r
     }\r
     | function_call {\r
         $$ = $1;\r
@@ -381,7 +372,7 @@ postfix_expression
             }\r
         } else if ($1->isVector()) {\r
             TVectorFields fields;\r
-            if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {\r
+            if (! parseContext.parseVectorFields(*$3.string, $1->getVectorSize(), fields, $3.line)) {\r
                 fields.num = 1;\r
                 fields.offsets[0] = 0;\r
                 parseContext.recover();\r
@@ -410,30 +401,8 @@ postfix_expression
                 }\r
             }\r
         } else if ($1->isMatrix()) {\r
-            TMatrixFields fields;\r
-            if (! parseContext.parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {\r
-                fields.wholeRow = false;\r
-                fields.wholeCol = false;\r
-                fields.row = 0;\r
-                fields.col = 0;\r
-                parseContext.recover();\r
-            }\r
-\r
-            if (fields.wholeRow || fields.wholeCol) {\r
-                parseContext.error($2.line, " non-scalar fields not implemented yet", ".", "");\r
-                parseContext.recover();\r
-                constUnion *unionArray = new constUnion[1];\r
-                unionArray->setIConst(0);\r
-                TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);\r
-                $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);\r
-                $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));\r
-            } else {\r
-                constUnion *unionArray = new constUnion[1];\r
-                unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);\r
-                TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);\r
-                $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);\r
-                $$->setType(TType($1->getBasicType()));\r
-            }\r
+            parseContext.error($2.line, "field selection not allowed on matrix", ".", "");\r
+            parseContext.recover();\r
         } else if ($1->getBasicType() == EbtStruct) {\r
             bool fieldFound = false;\r
             TTypeList* fields = $1->getType().getStruct();\r
@@ -455,8 +424,7 @@ postfix_expression
                         if ($$ == 0) {\r
                             parseContext.recover();\r
                             $$ = $1;\r
-                        }\r
-                        else {\r
+                        } else {\r
                             $$->setType(*(*fields)[i].type);\r
                             // change the qualifier of the return type, not of the structure field\r
                             // as the structure definition is shared between various structures.\r
@@ -476,6 +444,7 @@ postfix_expression
                 }\r
             }\r
         } else {\r
+            //?? fix message\r
             parseContext.error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");\r
             parseContext.recover();\r
             $$ = $1;\r
@@ -692,14 +661,32 @@ function_identifier
             TOperator op = EOpNull;\r
             switch ($1.type) {\r
             case EbtFloat:\r
-                if ($1.matrix) {\r
-                    switch($1.size) {\r
-                    case 2: op = EOpConstructMat2;  break;\r
-                    case 3: op = EOpConstructMat3;  break;\r
-                    case 4: op = EOpConstructMat4;  break;\r
+                if ($1.matrixCols) {\r
+                    switch ($1.matrixCols) {\r
+                    case 2:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructMat2x2; break;\r
+                        case 3: op = EOpConstructMat2x3; break;\r
+                        case 4: op = EOpConstructMat2x4; break;\r
+                        }\r
+                        break;\r
+                    case 3:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructMat3x2; break;\r
+                        case 3: op = EOpConstructMat3x3; break;\r
+                        case 4: op = EOpConstructMat3x4; break;\r
+                        }\r
+                        break;\r
+                    case 4:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructMat4x2; break;\r
+                        case 3: op = EOpConstructMat4x3; break;\r
+                        case 4: op = EOpConstructMat4x4; break;\r
+                        }\r
+                        break;\r
                     }\r
                 } else {\r
-                    switch($1.size) {\r
+                    switch($1.vectorSize) {\r
                     case 1: op = EOpConstructFloat; break;\r
                     case 2: op = EOpConstructVec2;  break;\r
                     case 3: op = EOpConstructVec3;  break;\r
@@ -707,8 +694,42 @@ function_identifier
                     }\r
                 }\r
                 break;\r
+            case EbtDouble:\r
+                if ($1.matrixCols) {\r
+                    switch ($1.matrixCols) {\r
+                    case 2:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructDMat2x2; break;\r
+                        case 3: op = EOpConstructDMat2x3; break;\r
+                        case 4: op = EOpConstructDMat2x4; break;\r
+                        }\r
+                        break;\r
+                    case 3:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructDMat3x2; break;\r
+                        case 3: op = EOpConstructDMat3x3; break;\r
+                        case 4: op = EOpConstructDMat3x4; break;\r
+                        }\r
+                        break;\r
+                    case 4:\r
+                        switch ($1.matrixRows) {\r
+                        case 2: op = EOpConstructDMat4x2; break;\r
+                        case 3: op = EOpConstructDMat4x3; break;\r
+                        case 4: op = EOpConstructDMat4x4; break;\r
+                        }\r
+                        break;\r
+                    }\r
+                } else {\r
+                    switch($1.vectorSize) {\r
+                    case 1: op = EOpConstructDouble; break;\r
+                    case 2: op = EOpConstructDVec2;  break;\r
+                    case 3: op = EOpConstructDVec3;  break;\r
+                    case 4: op = EOpConstructDVec4;  break;\r
+                    }\r
+                }\r
+                break;\r
             case EbtInt:\r
-                switch($1.size) {\r
+                switch($1.vectorSize) {\r
                 case 1: op = EOpConstructInt;   break;\r
                 case 2: op = EOpConstructIVec2; break;\r
                 case 3: op = EOpConstructIVec3; break;\r
@@ -716,7 +737,7 @@ function_identifier
                 }\r
                 break;\r
             case EbtBool:\r
-                switch($1.size) {\r
+                switch($1.vectorSize) {\r
                 case 1:  op = EOpConstructBool;  break;\r
                 case 2:  op = EOpConstructBVec2; break;\r
                 case 3:  op = EOpConstructBVec3; break;\r
@@ -1874,209 +1895,197 @@ type_specifier_nonarray
     | VEC2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(2);\r
+        $$.setVector(2);\r
     }\r
     | VEC3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(3);\r
+        $$.setVector(3);\r
     }\r
     | VEC4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4);\r
+        $$.setVector(4);\r
     }\r
     | DVEC2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(2);\r
+        $$.setVector(2);\r
     }\r
     | DVEC3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(3);\r
+        $$.setVector(3);\r
     }\r
     | DVEC4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4);\r
+        $$.setVector(4);\r
     }\r
     | BVEC2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtBool;\r
-        $$.setAggregate(2);\r
+        $$.setVector(2);\r
     }\r
     | BVEC3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtBool;\r
-        $$.setAggregate(3);\r
+        $$.setVector(3);\r
     }\r
     | BVEC4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtBool;\r
-        $$.setAggregate(4);\r
+        $$.setVector(4);\r
     }\r
     | IVEC2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(2);\r
+        $$.setVector(2);\r
     }\r
     | IVEC3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(3);\r
+        $$.setVector(3);\r
     }\r
     | IVEC4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(4);\r
+        $$.setVector(4);\r
     }\r
     | UVEC2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(2);\r
+        $$.setVector(2);\r
     }\r
     | UVEC3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(3);\r
+        $$.setVector(3);\r
     }\r
     | UVEC4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtInt;\r
-        $$.setAggregate(4);\r
+        $$.setVector(4);\r
     }\r
     | MAT2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(2, true);\r
+        $$.setMatrix(2, 2);\r
     }\r
     | MAT3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 3);\r
     }\r
     | MAT4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 4);\r
     }\r
     | MAT2X2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(2, true);\r
+        $$.setMatrix(2, 2);\r
     }\r
     | MAT2X3 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(2, 3);\r
     }\r
     | MAT2X4 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(2, 4);\r
     }\r
     | MAT3X2 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 2);\r
     }\r
     | MAT3X3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 3);\r
     }\r
     | MAT3X4 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(3, 4);\r
     }\r
     | MAT4X2 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 2);\r
     }\r
     | MAT4X3 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 3);\r
     }\r
     | MAT4X4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtFloat;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 4);\r
     }\r
     | DMAT2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(2, true);\r
+        $$.setMatrix(2, 2);\r
     }\r
     | DMAT3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 3);\r
     }\r
     | DMAT4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 4);\r
     }\r
     | DMAT2X2 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(2, true);\r
+        $$.setMatrix(2, 2);\r
     }\r
     | DMAT2X3 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(2, 3);\r
     }\r
     | DMAT2X4 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(2, 4);\r
     }\r
     | DMAT3X2 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 2);\r
     }\r
     | DMAT3X3 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(3, true);\r
+        $$.setMatrix(3, 3);\r
     }\r
     | DMAT3X4 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(3, 4);\r
     }\r
     | DMAT4X2 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 2);\r
     }\r
     | DMAT4X3 {\r
-        // TODO: implement this type\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 3);\r
     }\r
     | DMAT4X4 {\r
         $$.init($1.line, parseContext.symbolTable.atGlobalLevel());\r
         $$.type = EbtDouble;\r
-        $$.setAggregate(4, true);\r
+        $$.setMatrix(4, 4);\r
     }\r
     | ATOMIC_UINT {\r
         // TODO: add type\r
@@ -2511,7 +2520,7 @@ struct_declaration
             //\r
             // Careful not to replace already know aspects of type, like array-ness\r
             //\r
-            (*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);\r
+            (*$$)[i].type->setElementType($1.type, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);\r
 \r
             if ($1.array)\r
                 (*$$)[i].type->setArraySize($1.arraySize);\r
@@ -2529,7 +2538,7 @@ struct_declaration
             //\r
             // Careful not to replace already know aspects of type, like array-ness\r
             //\r
-            (*$$)[i].type->setType($2.type, $2.size, $2.matrix, $2.userDef);\r
+            (*$$)[i].type->setElementType($2.type, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);\r
 \r
             if ($2.array)\r
                 (*$$)[i].type->setArraySize($2.arraySize);\r
@@ -2924,7 +2933,6 @@ function_definition
         parseContext.loopNestingLevel = 0;\r
     }\r
     compound_statement_no_new_scope {\r
-        //?? Check that all paths return a value if return type != void ?\r
         //   May be best done as post process phase on intermediate code\r
         if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) {\r
             parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());\r
index df07121..78ac441 100644 (file)
@@ -66,10 +66,10 @@ TString TType::getCompleteString() const
         p += sprintf_s(p, end - p, "array of ");
     if (qualifier.precision != EpqNone)
         p += sprintf_s(p, end - p, "%s ", getPrecisionQualifierString());
-    if (matrix)
-        p += sprintf_s(p, end - p, "%dX%d matrix of ", size, size);
-    else if (size > 1)
-        p += sprintf_s(p, end - p, "%d-component vector of ", size);
+    if (matrixCols > 0)
+        p += sprintf_s(p, end - p, "%dX%d matrix of ", matrixCols, matrixRows);
+    else if (vectorSize > 1)
+        p += sprintf_s(p, end - p, "%d-component vector of ", vectorSize);
 
     sprintf_s(p, end - p, "%s", getBasicString());
 
@@ -276,9 +276,24 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
     case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
     case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
     case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
-    case EOpConstructMat2:  out.debug << "Construct mat2";  break;
-    case EOpConstructMat3:  out.debug << "Construct mat3";  break;
-    case EOpConstructMat4:  out.debug << "Construct mat4";  break;
+    case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
+    case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
+    case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
+    case EOpConstructMat3x2:  out.debug << "Construct mat3x2";  break;
+    case EOpConstructMat3x3:  out.debug << "Construct mat3";    break;
+    case EOpConstructMat3x4:  out.debug << "Construct mat3x4";  break;
+    case EOpConstructMat4x2:  out.debug << "Construct mat4x2";  break;
+    case EOpConstructMat4x3:  out.debug << "Construct mat4x3";  break;
+    case EOpConstructMat4x4:  out.debug << "Construct mat4";    break;
+    case EOpConstructDMat2x2: out.debug << "Construct dmat2";   break;
+    case EOpConstructDMat2x3: out.debug << "Construct dmat2x3"; break;
+    case EOpConstructDMat2x4: out.debug << "Construct dmat2x4"; break;
+    case EOpConstructDMat3x2: out.debug << "Construct dmat3x2"; break;
+    case EOpConstructDMat3x3: out.debug << "Construct dmat3";   break;
+    case EOpConstructDMat3x4: out.debug << "Construct dmat3x4"; break;
+    case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
+    case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
+    case EOpConstructDMat4x4: out.debug << "Construct dmat4";  break;
     case EOpConstructStruct:  out.debug << "Construct structure";  break;
         
     case EOpLessThan:         out.debug << "Compare Less Than";             break;
@@ -398,8 +413,8 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
                 sprintf_s(buf, maxSize, "%d (%s)", node->getUnionArrayPointer()[i].getIConst(), "const int");
 
                 out.debug << buf << "\n";
-                break;
             }
+            break;
         default: 
             out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
             break;
index 25e721f..2509c71 100644 (file)
@@ -41,7 +41,8 @@
 class TConstTraverser : public TIntermTraverser {
 public:
     TConstTraverser(constUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
-        constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0) {  index = 0; tOp = EOpNull;}
+        constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), 
+        matrixCols(0), matrixRows(0) {  index = 0; tOp = EOpNull;}
     int index ;
     constUnion *unionArray;
     TOperator tOp;
@@ -53,7 +54,8 @@ public:
     bool error;
     int size; // size of the constructor ( 4 for vec4)
     bool isMatrix;
-    int matrixSize; // dimension of the matrix (nominal size and not the instance size)
+    int matrixCols;
+    int matrixRows;
 };
 
 //
@@ -128,15 +130,15 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
     }
 
     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
-    if (flag) 
-    {
+    if (flag) {
         oit->singleConstantParam = true; 
         oit->constructorType = node->getOp();
         oit->size = node->getType().getObjectSize();
 
         if (node->getType().isMatrix()) {
             oit->isMatrix = true;
-            oit->matrixSize = node->getType().getNominalSize();
+            oit->matrixCols = node->getType().getMatrixCols();
+            oit->matrixRows = node->getType().getMatrixRows();
         }
     }       
 
@@ -154,7 +156,8 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse
         oit->constructorType = EOpNull;
         oit->size = 0;
         oit->isMatrix = false;
-        oit->matrixSize = 0;
+        oit->matrixCols = 0;
+        oit->matrixRows = 0;
     }
 
     return false;
@@ -189,12 +192,13 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
             (oit->index)++;
         }
     } else {
-        int size, totalSize, matrixSize;
+        int size, totalSize, matrixCols, matrixRows;
         bool isMatrix = false;
         size = oit->size;
-        matrixSize = oit->matrixSize;
+        matrixCols = oit->matrixCols;
+        matrixRows = oit->matrixRows;
         isMatrix = oit->isMatrix;
-        totalSize = oit->index + size ;
+        totalSize = oit->index + size;
         constUnion *rightUnionArray = node->getUnionArrayPointer();
         if (!isMatrix) {
             int count = 0;
@@ -215,7 +219,7 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
             for (int i = index; i < totalSize; i++) {
                 if (i >= instanceSize)
                     return;
-                if (index - i == 0 || (i - index) % (matrixSize + 1) == 0 )
+                if (index - i == 0 || (i - index) % (matrixRows + 1) == 0 )
                     leftUnionArray[i] = rightUnionArray[count];
                 else 
                     leftUnionArray[i].setFConst(0.0f);