SPV: Add unary-matrix operations, operating at vector level.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 9d42e3c..c174375 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -110,6 +110,7 @@
     spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
     spv::Id createBinaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right);
     spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
+    spv::Id createUnaryMatrixOperation(spv::Op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
     spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
     spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
     spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
@@ -2601,9 +2602,11 @@
 
     switch (op) {
     case glslang::EOpNegative:
-        if (isFloat)
+        if (isFloat) {
             unaryOp = spv::OpFNegate;
-        else
+            if (builder.isMatrixType(typeId))
+                return createUnaryMatrixOperation(unaryOp, precision, typeId, operand, typeProxy);
+        } else
             unaryOp = spv::OpSNegate;
         break;
 
@@ -2862,6 +2865,39 @@
     return id;
 }
 
+// Create a unary operation on a matrix
+spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Id typeId, spv::Id operand, glslang::TBasicType /* typeProxy */)
+{
+    // Handle unary operations vector by vector.
+    // The result type is the same type as the original type.
+    // The algorithm is to:
+    //   - break the matrix into vectors
+    //   - apply the operation to each vector
+    //   - make a matrix out the vector results
+
+    // get the types sorted out
+    int numCols = builder.getNumColumns(operand);
+    int numRows = builder.getNumRows(operand);
+    spv::Id scalarType = builder.getScalarTypeId(typeId);
+    spv::Id vecType = builder.makeVectorType(scalarType, numRows);
+    std::vector<spv::Id> results;
+
+    // do each vector op
+    for (int c = 0; c < numCols; ++c) {
+        std::vector<unsigned int> indexes;
+        indexes.push_back(c);
+        spv::Id vec =  builder.createCompositeExtract(operand, vecType, indexes);
+        results.push_back(builder.createUnaryOp(op, vecType, vec));
+        builder.setPrecision(results.back(), precision);
+    }
+
+    // put the pieces together
+    spv::Id id = builder.createCompositeConstruct(typeId, results);
+    builder.setPrecision(id, precision);
+
+    return id;
+}
+
 spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destType, spv::Id operand)
 {
     spv::Op convOp = spv::OpNop;
diff --git a/Test/baseResults/spv.branch-return.vert.out b/Test/baseResults/spv.branch-return.vert.out
index 75ebefe..8588d74 100644
--- a/Test/baseResults/spv.branch-return.vert.out
+++ b/Test/baseResults/spv.branch-return.vert.out
@@ -60,4 +60,4 @@
               33:     29(ptr) AccessChain 19(gl_Position) 28
                               Store 33 32
                               Return
-                                FunctionEnd
+                              FunctionEnd
diff --git a/Test/baseResults/spv.matrix2.frag.out b/Test/baseResults/spv.matrix2.frag.out
index 5deb539..b1cd71b 100644
--- a/Test/baseResults/spv.matrix2.frag.out
+++ b/Test/baseResults/spv.matrix2.frag.out
@@ -5,12 +5,12 @@
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 213
+// Id's are bound by 221
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 12 16 37 38 65 87 139 150 173 210 211 212
+                              EntryPoint Fragment 4  "main" 12 16 37 38 65 87 147 158 181 218 219 220
                               ExecutionMode 4 OriginLowerLeft
                               Source GLSL 150
                               Name 4  "main"
@@ -22,15 +22,15 @@
                               Name 63  "m44"
                               Name 65  "un34"
                               Name 87  "um43"
-                              Name 139  "um4"
-                              Name 148  "inv"
-                              Name 150  "um2"
-                              Name 171  "inv3"
-                              Name 173  "um3"
-                              Name 182  "inv4"
-                              Name 210  "colorTransform"
-                              Name 211  "m"
-                              Name 212  "n"
+                              Name 147  "um4"
+                              Name 156  "inv"
+                              Name 158  "um2"
+                              Name 179  "inv3"
+                              Name 181  "um3"
+                              Name 190  "inv4"
+                              Name 218  "colorTransform"
+                              Name 219  "m"
+                              Name 220  "n"
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -62,35 +62,35 @@
               85:             TypeMatrix 14(fvec3) 4
               86:             TypePointer Input 85
         87(um43):     86(ptr) Variable Input
-             138:             TypePointer Input 61
-        139(um4):    138(ptr) Variable Input
-             145:             TypeVector 6(float) 2
-             146:             TypeMatrix 145(fvec2) 2
-             147:             TypePointer Function 146
-             149:             TypePointer Input 146
-        150(um2):    149(ptr) Variable Input
-             153:             TypeInt 32 1
-             154:    153(int) Constant 0
-             155:             TypePointer Function 6(float)
-             158:    153(int) Constant 1
-             161:     54(int) Constant 1
-             169:             TypeMatrix 14(fvec3) 3
-             170:             TypePointer Function 169
-             172:             TypePointer Input 169
-        173(um3):    172(ptr) Variable Input
-             176:    153(int) Constant 2
-             202:     54(int) Constant 3
-             203:             TypePointer Output 6(float)
-210(colorTransform):    172(ptr) Variable Input
-          211(m):    138(ptr) Variable Input
-          212(n):    138(ptr) Variable Input
+             146:             TypePointer Input 61
+        147(um4):    146(ptr) Variable Input
+             153:             TypeVector 6(float) 2
+             154:             TypeMatrix 153(fvec2) 2
+             155:             TypePointer Function 154
+             157:             TypePointer Input 154
+        158(um2):    157(ptr) Variable Input
+             161:             TypeInt 32 1
+             162:    161(int) Constant 0
+             163:             TypePointer Function 6(float)
+             166:    161(int) Constant 1
+             169:     54(int) Constant 1
+             177:             TypeMatrix 14(fvec3) 3
+             178:             TypePointer Function 177
+             180:             TypePointer Input 177
+        181(um3):    180(ptr) Variable Input
+             184:    161(int) Constant 2
+             210:     54(int) Constant 3
+             211:             TypePointer Output 6(float)
+218(colorTransform):    180(ptr) Variable Input
+          219(m):    146(ptr) Variable Input
+          220(n):    146(ptr) Variable Input
          4(main):           2 Function None 3
                5:             Label
          10(m34):      9(ptr) Variable Function
          63(m44):     62(ptr) Variable Function
-        148(inv):    147(ptr) Variable Function
-       171(inv3):    170(ptr) Variable Function
-       182(inv4):     62(ptr) Variable Function
+        156(inv):    155(ptr) Variable Function
+       179(inv3):    178(ptr) Variable Function
+       190(inv4):     62(ptr) Variable Function
               13:    7(fvec4) Load 12(v)
               17:   14(fvec3) Load 16(u)
               18:           8 OuterProduct 13 17
@@ -166,100 +166,108 @@
              103:          61 CompositeConstruct 93 96 99 102
                               Store 63(m44) 103
              104:          61 Load 63(m44)
-             105:          61 FNegate 104
-             106:    7(fvec4) Load 12(v)
-             107:    7(fvec4) MatrixTimesVector 105 106
-             108:    7(fvec4) Load 37(FragColor)
-             109:    7(fvec4) FAdd 108 107
-                              Store 37(FragColor) 109
-             110:          61 Load 63(m44)
-             111:          61 Load 63(m44)
-             112:    7(fvec4) CompositeExtract 110 0
-             113:    7(fvec4) CompositeExtract 111 0
-             114:    7(fvec4) FMul 112 113
-             115:    7(fvec4) CompositeExtract 110 1
-             116:    7(fvec4) CompositeExtract 111 1
-             117:    7(fvec4) FMul 115 116
-             118:    7(fvec4) CompositeExtract 110 2
-             119:    7(fvec4) CompositeExtract 111 2
-             120:    7(fvec4) FMul 118 119
-             121:    7(fvec4) CompositeExtract 110 3
-             122:    7(fvec4) CompositeExtract 111 3
-             123:    7(fvec4) FMul 121 122
-             124:          61 CompositeConstruct 114 117 120 123
-             125:    7(fvec4) Load 37(FragColor)
-             126:    7(fvec4) VectorTimesMatrix 125 124
-                              Store 37(FragColor) 126
-             127:          85 Load 87(um43)
-             128:           8 Transpose 127
-                              Store 10(m34) 128
-             129:    7(fvec4) Load 37(FragColor)
-             130:           8 Load 10(m34)
-             131:   14(fvec3) VectorTimesMatrix 129 130
-             132:    6(float) CompositeExtract 131 0
-             133:    6(float) CompositeExtract 131 1
-             134:    6(float) CompositeExtract 131 2
-             135:    7(fvec4) CompositeConstruct 132 133 134 40
-             136:    7(fvec4) Load 37(FragColor)
-             137:    7(fvec4) FMul 136 135
-                              Store 37(FragColor) 137
-             140:          61 Load 139(um4)
-             141:    6(float) ExtInst 1(GLSL.std.450) 33(Determinant) 140
-             142:    7(fvec4) CompositeConstruct 141 141 141 141
-             143:    7(fvec4) Load 37(FragColor)
-             144:    7(fvec4) FMul 143 142
-                              Store 37(FragColor) 144
-             151:         146 Load 150(um2)
-             152:         146 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 151
-                              Store 148(inv) 152
-             156:    155(ptr) AccessChain 148(inv) 154 55
-             157:    6(float) Load 156
-             159:    155(ptr) AccessChain 148(inv) 158 55
-             160:    6(float) Load 159
-             162:    155(ptr) AccessChain 148(inv) 154 161
-             163:    6(float) Load 162
-             164:    155(ptr) AccessChain 148(inv) 158 161
+             105:    7(fvec4) CompositeExtract 104 0
+             106:    7(fvec4) FNegate 105
+             107:    7(fvec4) CompositeExtract 104 1
+             108:    7(fvec4) FNegate 107
+             109:    7(fvec4) CompositeExtract 104 2
+             110:    7(fvec4) FNegate 109
+             111:    7(fvec4) CompositeExtract 104 3
+             112:    7(fvec4) FNegate 111
+             113:          61 CompositeConstruct 106 108 110 112
+             114:    7(fvec4) Load 12(v)
+             115:    7(fvec4) MatrixTimesVector 113 114
+             116:    7(fvec4) Load 37(FragColor)
+             117:    7(fvec4) FAdd 116 115
+                              Store 37(FragColor) 117
+             118:          61 Load 63(m44)
+             119:          61 Load 63(m44)
+             120:    7(fvec4) CompositeExtract 118 0
+             121:    7(fvec4) CompositeExtract 119 0
+             122:    7(fvec4) FMul 120 121
+             123:    7(fvec4) CompositeExtract 118 1
+             124:    7(fvec4) CompositeExtract 119 1
+             125:    7(fvec4) FMul 123 124
+             126:    7(fvec4) CompositeExtract 118 2
+             127:    7(fvec4) CompositeExtract 119 2
+             128:    7(fvec4) FMul 126 127
+             129:    7(fvec4) CompositeExtract 118 3
+             130:    7(fvec4) CompositeExtract 119 3
+             131:    7(fvec4) FMul 129 130
+             132:          61 CompositeConstruct 122 125 128 131
+             133:    7(fvec4) Load 37(FragColor)
+             134:    7(fvec4) VectorTimesMatrix 133 132
+                              Store 37(FragColor) 134
+             135:          85 Load 87(um43)
+             136:           8 Transpose 135
+                              Store 10(m34) 136
+             137:    7(fvec4) Load 37(FragColor)
+             138:           8 Load 10(m34)
+             139:   14(fvec3) VectorTimesMatrix 137 138
+             140:    6(float) CompositeExtract 139 0
+             141:    6(float) CompositeExtract 139 1
+             142:    6(float) CompositeExtract 139 2
+             143:    7(fvec4) CompositeConstruct 140 141 142 40
+             144:    7(fvec4) Load 37(FragColor)
+             145:    7(fvec4) FMul 144 143
+                              Store 37(FragColor) 145
+             148:          61 Load 147(um4)
+             149:    6(float) ExtInst 1(GLSL.std.450) 33(Determinant) 148
+             150:    7(fvec4) CompositeConstruct 149 149 149 149
+             151:    7(fvec4) Load 37(FragColor)
+             152:    7(fvec4) FMul 151 150
+                              Store 37(FragColor) 152
+             159:         154 Load 158(um2)
+             160:         154 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 159
+                              Store 156(inv) 160
+             164:    163(ptr) AccessChain 156(inv) 162 55
              165:    6(float) Load 164
-             166:    7(fvec4) CompositeConstruct 157 160 163 165
-             167:    7(fvec4) Load 37(FragColor)
-             168:    7(fvec4) FMul 167 166
-                              Store 37(FragColor) 168
-             174:         169 Load 173(um3)
-             175:         169 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 174
-                              Store 171(inv3) 175
-             177:    155(ptr) AccessChain 171(inv3) 176 161
-             178:    6(float) Load 177
-             179:    7(fvec4) CompositeConstruct 178 178 178 178
-             180:    7(fvec4) Load 37(FragColor)
-             181:    7(fvec4) FMul 180 179
-                              Store 37(FragColor) 181
-             183:          61 Load 139(um4)
-             184:          61 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 183
-                              Store 182(inv4) 184
-             185:          61 Load 182(inv4)
-             186:    7(fvec4) Load 37(FragColor)
-             187:    7(fvec4) VectorTimesMatrix 186 185
-                              Store 37(FragColor) 187
+             167:    163(ptr) AccessChain 156(inv) 166 55
+             168:    6(float) Load 167
+             170:    163(ptr) AccessChain 156(inv) 162 169
+             171:    6(float) Load 170
+             172:    163(ptr) AccessChain 156(inv) 166 169
+             173:    6(float) Load 172
+             174:    7(fvec4) CompositeConstruct 165 168 171 173
+             175:    7(fvec4) Load 37(FragColor)
+             176:    7(fvec4) FMul 175 174
+                              Store 37(FragColor) 176
+             182:         177 Load 181(um3)
+             183:         177 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 182
+                              Store 179(inv3) 183
+             185:    163(ptr) AccessChain 179(inv3) 184 169
+             186:    6(float) Load 185
+             187:    7(fvec4) CompositeConstruct 186 186 186 186
              188:    7(fvec4) Load 37(FragColor)
-             189:           8 Load 65(un34)
-             190:           8 Load 65(un34)
-             191:    7(fvec4) CompositeExtract 189 0
-             192:    7(fvec4) CompositeExtract 190 0
-             193:    7(fvec4) FMul 191 192
-             194:    7(fvec4) CompositeExtract 189 1
-             195:    7(fvec4) CompositeExtract 190 1
-             196:    7(fvec4) FMul 194 195
-             197:    7(fvec4) CompositeExtract 189 2
-             198:    7(fvec4) CompositeExtract 190 2
-             199:    7(fvec4) FMul 197 198
-             200:           8 CompositeConstruct 193 196 199
-             201:   14(fvec3) VectorTimesMatrix 188 200
-             204:    203(ptr) AccessChain 37(FragColor) 202
-             205:    6(float) Load 204
-             206:    6(float) CompositeExtract 201 0
-             207:    6(float) CompositeExtract 201 1
-             208:    6(float) CompositeExtract 201 2
-             209:    7(fvec4) CompositeConstruct 206 207 208 205
-                              Store 37(FragColor) 209
+             189:    7(fvec4) FMul 188 187
+                              Store 37(FragColor) 189
+             191:          61 Load 147(um4)
+             192:          61 ExtInst 1(GLSL.std.450) 34(MatrixInverse) 191
+                              Store 190(inv4) 192
+             193:          61 Load 190(inv4)
+             194:    7(fvec4) Load 37(FragColor)
+             195:    7(fvec4) VectorTimesMatrix 194 193
+                              Store 37(FragColor) 195
+             196:    7(fvec4) Load 37(FragColor)
+             197:           8 Load 65(un34)
+             198:           8 Load 65(un34)
+             199:    7(fvec4) CompositeExtract 197 0
+             200:    7(fvec4) CompositeExtract 198 0
+             201:    7(fvec4) FMul 199 200
+             202:    7(fvec4) CompositeExtract 197 1
+             203:    7(fvec4) CompositeExtract 198 1
+             204:    7(fvec4) FMul 202 203
+             205:    7(fvec4) CompositeExtract 197 2
+             206:    7(fvec4) CompositeExtract 198 2
+             207:    7(fvec4) FMul 205 206
+             208:           8 CompositeConstruct 201 204 207
+             209:   14(fvec3) VectorTimesMatrix 196 208
+             212:    211(ptr) AccessChain 37(FragColor) 210
+             213:    6(float) Load 212
+             214:    6(float) CompositeExtract 209 0
+             215:    6(float) CompositeExtract 209 1
+             216:    6(float) CompositeExtract 209 2
+             217:    7(fvec4) CompositeConstruct 214 215 216 213
+                              Store 37(FragColor) 217
                               Return
                               FunctionEnd