Construct non matrices from matrix in GLSL

GLSL supports constructing vectors from matrices. In the case
of vec3(mat2), vec4(mat2) or vec4(mat3), a second instruction
is required to copy the remaining matrix elements from the
2nd row of the matrix into the rest of the vector.

Fixes 6 webgl conformance tests:
conformance/glsl/constructors/glsl-construct-vec3.html
conformance/glsl/constructors/glsl-construct-vec4.html
conformance/glsl/constructors/glsl-construct-ivec3.html
conformance/glsl/constructors/glsl-construct-ivec4.html
conformance/glsl/constructors/glsl-construct-bvec3.html
conformance/glsl/constructors/glsl-construct-bvec4.html

Change-Id: I85ffd3b60623d0dce2bd7c0027748e1829a27dbc
Reviewed-on: https://swiftshader-review.googlesource.com/16469
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/compiler/OutputASM.cpp b/src/OpenGL/compiler/OutputASM.cpp
index 4ef41be..fc076a7 100644
--- a/src/OpenGL/compiler/OutputASM.cpp
+++ b/src/OpenGL/compiler/OutputASM.cpp
@@ -1520,6 +1520,23 @@
 
 						component += size;
 					}
+					else if(!result->isMatrix()) // Construct a non matrix from a matrix
+					{
+						Instruction *mov = emitCast(result, arrayIndex, argi, 0);
+						mov->dst.mask = (0xF << swizzle) & 0xF;
+						mov->src[0].swizzle = readSwizzle(argi, size) << (swizzle * 2);
+
+						// At most one more instruction when constructing a vec3 from a mat2 or a vec4 from a mat2/mat3
+						if(result->getNominalSize() > size)
+						{
+							Instruction *mov = emitCast(result, arrayIndex, argi, 1);
+							mov->dst.mask = (0xF << (swizzle + size)) & 0xF;
+							// mat2: xxxy (0x40), mat3: xxxx (0x00)
+							mov->src[0].swizzle = ((size == 2) ? 0x40 : 0x00) << (swizzle * 2);
+						}
+
+						component += size;
+					}
 					else   // Matrix
 					{
 						int column = 0;