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;