13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader matrix arithmetic tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Variables:
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + operation
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - mat OP mat
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - mat OP vec
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - vec OP mat
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - mat OP scalar
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - OP ( mat )
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - vec OP vec
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - OP mat
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + matrix source
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - constant (ctor)
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - uniform
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - vertex input
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - fragment input
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + other operand: always dynamic data?
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + how to reduce to vec3?
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderMatrixTests.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrixUtil.hpp"
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat2;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat2x3;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat2x4;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3x2;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3x4;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat4x2;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat4x3;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat4;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Uniform / constant values for tests.
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Input1 should not contain 0 components as it is used as divisor in div cases.
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-02-14 pyry] Make these dynamic.
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float	s_constInFloat[2]	= { 0.5f, -0.2f };
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec2	s_constInVec2[2]	= { Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f) };
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec3	s_constInVec3[2]	= { Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f) };
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec4	s_constInVec4[2]	= { Vec4(1.4f, 0.2f, -0.5f, 0.7f), Vec4(0.2f, -1.0f, 0.5f, 0.8f) };
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat2x2[2][4] =
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.1f,  1.0f,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f,  0.0f,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.8f,  0.1f,
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.5f, -0.9f,
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat3x2[2][6] =
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.8f, -0.3f,  0.3f,
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.0f,  1.2f, -1.2f,
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.2f, -1.0f,  0.5f,
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.8f,  1.1f,  0.3f,
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat4x2[2][8] =
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f,  0.5f, 0.0f, -1.0f,
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.2f, -0.5f, 0.3f, -0.9f,
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f,  0.1f, -1.1f,  0.6f,
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.8f, -1.2f, -1.1f,  0.7f,
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat2x3[2][6] =
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.6f, -0.1f,
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.7f, -1.2f,
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f,  0.0f,
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.1f,  0.6f,
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.8f,  1.0f,
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.7f,  0.1f,
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat3x3[2][9] =
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f,  1.1f, 1.2f,
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.0f,  1.2f, 0.5f,
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.7f, -0.2f, 1.0f,
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.1f, -0.1f,  0.1f,
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.1f, -0.2f,  1.0f,
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.5f,  0.1f, -0.4f,
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat4x3[2][12] =
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.9f,  0.0f,  0.6f,  0.2f,
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.9f, -0.1f, -0.3f, -0.7f,
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.1f,  0.1f,  1.0f,  0.0f,
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.5f,  0.7f,  0.7f,  1.2f,
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.1f,  0.1f,  1.0f, -1.0f,
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f, -0.2f, -0.3f, -0.5f,
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat2x4[2][8] =
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.6f, -1.1f,
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.6f, -0.6f,
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f, -0.6f,
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.1f, -0.1f,
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.2f, -1.0f,
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.7f, -1.0f,
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.7f,  0.7f,
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.4f, -0.3f,
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat3x4[2][12] =
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.6f, -0.4f,  1.2f,
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.9f,  0.8f,  0.4f,
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 1.1f,  0.3f,  0.5f,
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.2f,  0.0f,  1.1f,
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.8f,  1.2f, -0.2f,
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.1f, -0.9f, -0.5f,
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-1.2f,  1.0f,  1.2f,
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.1f, -0.7f, -0.5f,
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat4x4[2][16] =
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.3f,  0.9f, -0.2f,  1.0f,
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.4f, -0.6f,  0.6f, -1.0f,
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.9f, -0.1f,  0.3f, -0.2f,
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.3f, -0.9f,  1.0f,  0.1f,
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.4f, -0.7f, -0.8f,  0.7f,
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		-0.4f, -0.8f,  0.6f, -0.3f,
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.7f, -1.0f,  0.1f, -0.3f,
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 0.2f,  0.6f,  0.4f, -1.0f,
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	},
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace MatrixCaseUtils
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum InputType
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_CONST = 0,
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_UNIFORM,
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_DYNAMIC,
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_LAST
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ShaderInput
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput (InputType inputType_, DataType dataType_, Precision precision_)
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: inputType	(inputType_)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, dataType	(dataType_)
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, precision	(precision_)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType		inputType;
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType		dataType;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Precision		precision;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum MatrixOp
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_ADD = 0,
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_SUB,
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_MUL,
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_DIV,
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_COMP_MUL,
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_OUTER_PRODUCT,
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_TRANSPOSE,
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_INVERSE,
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_DETERMINANT,
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_UNARY_PLUS,
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_NEGATION,
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_PRE_INCREMENT,
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_PRE_DECREMENT,
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_POST_INCREMENT,
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_POST_DECREMENT,
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_ADD_INTO,
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_SUBTRACT_FROM,
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_MULTIPLY_INTO,
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_DIVIDE_INTO,
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_LAST
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Type traits.
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int DataT>
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TypeTraits;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DECLARE_TYPE_TRAIT(DATATYPE, TYPE)	\
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>									\
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TypeTraits<DATATYPE> {				\
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef TYPE Type;						\
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT,			float);
2653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2,		tcu::Vec2);
2663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3,		tcu::Vec3);
2673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4,		tcu::Vec4);
2683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2,		tcu::Mat2);
2693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X3,	tcu::Mat2x3);
2703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X4,	tcu::Mat2x4);
2713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X2,	tcu::Mat3x2);
2723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3,		tcu::Mat3);
2733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X4,	tcu::Mat3x4);
2743c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X2,	tcu::Mat4x2);
2753c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X3,	tcu::Mat4x3);
2763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4,		tcu::Mat4);
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Operation info
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum OperationType
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_BINARY_OPERATOR = 0,
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_BINARY_FUNCTION,
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_UNARY_FUNCTION,
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_ASSIGNMENT,
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_LAST
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getOperationName (MatrixOp op)
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return "+";
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return "-";
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return "*";
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return "/";
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return "matrixCompMult";
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_OUTER_PRODUCT:	return "outerProduct";
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_TRANSPOSE:		return "transpose";
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_INVERSE:		return "inverse";
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DETERMINANT:	return "determinant";
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return "+";
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return "-";
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return "++";
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return "--";
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return "++";
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return "--";
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return "+=";
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return "-=";
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return "*=";
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return "/=";
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic OperationType getOperationType (MatrixOp op)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return OPERATIONTYPE_BINARY_OPERATOR;
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return OPERATIONTYPE_BINARY_OPERATOR;
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return OPERATIONTYPE_BINARY_OPERATOR;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return OPERATIONTYPE_BINARY_OPERATOR;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return OPERATIONTYPE_BINARY_FUNCTION;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_OUTER_PRODUCT:	return OPERATIONTYPE_BINARY_FUNCTION;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_TRANSPOSE:		return OPERATIONTYPE_UNARY_FUNCTION;
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_INVERSE:		return OPERATIONTYPE_UNARY_FUNCTION;
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DETERMINANT:	return OPERATIONTYPE_UNARY_FUNCTION;
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return OPERATIONTYPE_ASSIGNMENT;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return OPERATIONTYPE_ASSIGNMENT;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return OPERATIONTYPE_ASSIGNMENT;
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return OPERATIONTYPE_ASSIGNMENT;
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return OPERATIONTYPE_LAST;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum TestMatrixType
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_DEFAULT = 0,
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_NEGATED,
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_INCREMENTED,
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_DECREMENTED,
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_NEGATED_INCREMENTED,
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_INCREMENTED_LESS,
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_LAST
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic TestMatrixType getOperationTestMatrixType (MatrixOp op)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch(op)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return TESTMATRIXTYPE_DEFAULT;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return TESTMATRIXTYPE_DEFAULT;
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return TESTMATRIXTYPE_DEFAULT;
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return TESTMATRIXTYPE_DEFAULT;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return TESTMATRIXTYPE_DEFAULT;
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_OUTER_PRODUCT:	return TESTMATRIXTYPE_DEFAULT;
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_TRANSPOSE:		return TESTMATRIXTYPE_DEFAULT;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_INVERSE:		return TESTMATRIXTYPE_DEFAULT;
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DETERMINANT:	return TESTMATRIXTYPE_DEFAULT;
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return TESTMATRIXTYPE_DECREMENTED;
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return TESTMATRIXTYPE_NEGATED_INCREMENTED;
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return TESTMATRIXTYPE_INCREMENTED;
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return TESTMATRIXTYPE_DEFAULT;
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return TESTMATRIXTYPE_DEFAULT;
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return TESTMATRIXTYPE_INCREMENTED_LESS;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return TESTMATRIXTYPE_NEGATED;
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return TESTMATRIXTYPE_DECREMENTED;
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return TESTMATRIXTYPE_LAST;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationBinary (MatrixOp op)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	       getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION ||
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	       getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationMatrixScalar (MatrixOp op)
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationMatrixVector (MatrixOp op)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_MUL;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationArithmeticMatrixMatrix (MatrixOp op)
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_MUL;
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationComponentwiseMatrixMatrix (MatrixOp op)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationVectorVector (MatrixOp op)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_OUTER_PRODUCT;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationUnaryAnyMatrix (MatrixOp op)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_TRANSPOSE			 ||
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_UNARY_PLUS			 ||
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_NEGATION			 ||
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_INCREMENT		 ||
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_DECREMENT		 ||
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_INCREMENT		 ||
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_DECREMENT;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationUnarySymmetricMatrix (MatrixOp op)
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_INVERSE || op == OP_DETERMINANT;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationValueModifying (MatrixOp op)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_PRE_INCREMENT		 ||
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_DECREMENT		 ||
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_INCREMENT		 ||
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_DECREMENT;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationAssignment (MatrixOp op)
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_ADD_INTO		 ||
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_SUBTRACT_FROM	 ||
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_MULTIPLY_INTO	 ||
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_DIVIDE_INTO;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationAssignmentAnyMatrix (MatrixOp op)
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_ADD_INTO		 ||
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_SUBTRACT_FROM	 ||
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_DIVIDE_INTO;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationAssignmentSymmetricMatrix (MatrixOp op)
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_MULTIPLY_INTO;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Operation nature
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum OperationNature
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_PURE = 0,
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_MUTATING,
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_ASSIGNMENT,
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_LAST
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic OperationNature getOperationNature (MatrixOp op)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOperationAssignment(op))
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return OPERATIONNATURE_ASSIGNMENT;
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOperationValueModifying(op))
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return OPERATIONNATURE_MUTATING;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return OPERATIONNATURE_PURE;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Input value loader.
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int InputT, int DataT>
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename TypeTraits<DataT>::Type getInputValue (const ShaderEvalContext& evalCtx, int inputNdx);
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline float		getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInFloat[inputNdx];	}
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec2[inputNdx];	}
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec3[inputNdx];	}
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec4[inputNdx];	}
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2(s_constInMat2x2[inputNdx]);		}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2x3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2X3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x3(s_constInMat2x3[inputNdx]);	}
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2x4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2X4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x4(s_constInMat2x4[inputNdx]);	}
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3x2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3X2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x2(s_constInMat3x2[inputNdx]);	}
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3(s_constInMat3x3[inputNdx]);		}
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3x4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3X4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x4(s_constInMat3x4[inputNdx]);	}
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4x2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4X2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x2(s_constInMat4x2[inputNdx]);	}
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4x3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4X3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x3(s_constInMat4x3[inputNdx]);	}
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4(s_constInMat4x4[inputNdx]);		}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline float		getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.x();					}
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec2	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1);			}
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec3	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1, 2);		}
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec4	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1, 2, 3);	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2> (const ShaderEvalContext& evalCtx, int inputNdx)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2 m;
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X3> (const ShaderEvalContext& evalCtx, int inputNdx)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2x3 m;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X4> (const ShaderEvalContext& evalCtx, int inputNdx)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2x4 m;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0]);
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1]);
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X2> (const ShaderEvalContext& evalCtx, int inputNdx)
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3x2 m;
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2].swizzle(0,1));
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3> (const ShaderEvalContext& evalCtx, int inputNdx)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3 m;
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X4> (const ShaderEvalContext& evalCtx, int inputNdx)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3x4 m;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0]);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1]);
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2]);
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X2> (const ShaderEvalContext& evalCtx, int inputNdx)
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat4x2 m;
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2].swizzle(0,1));
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(3, evalCtx.in[3].swizzle(0,1));
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X3> (const ShaderEvalContext& evalCtx, int inputNdx)
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat4x3 m;
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(3, evalCtx.in[3].swizzle(0,1,2));
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4> (const ShaderEvalContext& evalCtx, int inputNdx)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat4 m;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0]);
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1]);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2]);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(3, evalCtx.in[3]);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Reduction from expression result to vec3.
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec2& value)		{ return value.swizzle(0,1,0); }
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec3& value)		{ return value; }
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec4& value)		{ return tcu::Vec3(value.x(), value.y(), value.z()+value.w()); }
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat2& value)		{ return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0)+value(1, 1)); }
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat2x3& value)	{ return value.getColumn(0) + value.getColumn(1); }
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat2x4& value)	{ return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3); }
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat3x2& value)	{ return tcu::Vec3(value(0,0)+value(1,0), value(0,1)+value(1,1), value(0,2)+value(1,2)); }
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat3& value)		{ return value.getColumn(0) + value.getColumn(1) + value.getColumn(2); }
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat3x4& value)	{ return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3) + value.getColumn(2).swizzle(2,3,0); }
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat4x2& value)	{ return tcu::Vec3(value(0,0)+value(1,0)+value(0,3), value(0,1)+value(1,1)+value(1,3), value(0,2)+value(1,2)); }
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat4x3& value)	{ return value.getColumn(0) + value.getColumn(1) + value.getColumn(2) + value.getColumn(3); }
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat4& value)		{ return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3) + value.getColumn(2).swizzle(2,3,0) + value.getColumn(3).swizzle(3,0,1); }
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// matrixCompMult
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> matrixCompMult (const tcu::Matrix<T, Rows, Cols>& a, const tcu::Matrix<T, Rows, Cols>& b)
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = a(r,c) * b(r, c);
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// transpose
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Cols, Rows> transpose (const tcu::Matrix<T, Rows, Cols>& mat)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Cols, Rows> retVal;
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(c, r) = mat(r, c);
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// outerProduct
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Cols, Rows> outerProduct (const tcu::Vector<T, Cols>& a, const tcu::Vector<T, Rows>& b)
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = a[c] * b[r];
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return transpose(retVal); // to gl-form (column-major)
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Determinant
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat determinant (const tcu::Matrix<float, Size, Size>& mat);
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat determinant<2> (const tcu::Matrix<float, 2, 2>& mat)
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat determinant<3> (const tcu::Matrix<float, 3, 3>& mat)
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	+ mat(0,0) * mat(1,1) * mat(2,2)
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,1) * mat(1,2) * mat(2,0)
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,2) * mat(1,0) * mat(2,1)
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,0) * mat(1,2) * mat(2,1)
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,1) * mat(1,0) * mat(2,2)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,2) * mat(1,1) * mat(2,0);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat determinant<4> (const tcu::Matrix<float, 4, 4>& mat)
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float minorMatrices[4][3*3] =
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,3),	mat(2,3),	mat(3,3),
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		},
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,0),	mat(2,0),	mat(3,0),
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,1),	mat(2,1),	mat(3,1),
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			mat(1,2),	mat(2,2),	mat(3,2),
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	+ mat(0,0) * determinant(tcu::Mat3(minorMatrices[0]))
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,1) * determinant(tcu::Mat3(minorMatrices[1]))
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			+ mat(0,2) * determinant(tcu::Mat3(minorMatrices[2]))
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			- mat(0,3) * determinant(tcu::Mat3(minorMatrices[3]));
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Inverse
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<float, Size, Size> inverse (const tcu::Matrix<float, Size, Size>& mat);
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<float, 2, 2> inverse<2> (const tcu::Matrix<float, 2, 2>& mat)
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float					det		= determinant(mat);
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<float, 2, 2>	retVal;
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(det != 0.0f);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(0, 0) =  mat(1, 1) / det;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(0, 1) = -mat(0, 1) / det;
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(1, 0) = -mat(1, 0) / det;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	retVal(1, 1) =  mat(0, 0) / det;
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<float, 3, 3> inverse<3> (const tcu::Matrix<float, 3, 3>& mat)
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Blockwise inversion
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(determinant(mat) != 0.0f);
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaA[2*2] =
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,0),	mat(0,1),
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,0),	mat(1,1)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaB[2] =
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,2),
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,2),
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaC[2] =
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,0),	mat(2,1),
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaD[1] =
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,2)
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float nullField[4] = { 0.0f };
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2>	invA = inverse(tcu::Matrix<float, 2, 2>(areaA));
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 1>	matB =         tcu::Matrix<float, 2, 1>(areaB);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 1, 2>	matC =         tcu::Matrix<float, 1, 2>(areaC);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 1, 1>	matD =         tcu::Matrix<float, 1, 1>(areaD);
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						schurComplement = 1.0f / (matD - matC*invA*matB)(0,0);
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2>	zeroMat         = Mat2(nullField);
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2>	blockA = invA + invA*matB*schurComplement*matC*invA;
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 1>	blockB = (zeroMat-invA)*matB*schurComplement;
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 1, 2>	blockC = matC*invA*(-schurComplement);
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float						blockD = schurComplement;
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float result[3*3] =
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(0,0),	blockA(0,1),	blockB(0,0),
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(1,0),	blockA(1,1),	blockB(1,0),
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(0,0),	blockC(0,1),	blockD,
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Mat3(result);
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<float, 4, 4> inverse<4> (const tcu::Matrix<float, 4, 4>& mat)
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Blockwise inversion
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(determinant(mat) != 0.0f);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaA[2*2] =
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,0),	mat(0,1),
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,0),	mat(1,1)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaB[2*2] =
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(0,2),	mat(0,3),
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(1,2),	mat(1,3)
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaC[2*2] =
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,0),	mat(2,1),
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(3,0),	mat(3,1)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float areaD[2*2] =
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(2,2),	mat(2,3),
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		mat(3,2),	mat(3,3)
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float nullField[4] = { 0.0f };
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> invA = inverse(Mat2(areaA));
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> matB =         Mat2(areaB);
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> matC =         Mat2(areaC);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> matD =         Mat2(areaD);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> zeroMat         = Mat2(nullField);
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Matrix<float, 2, 2> blockD = schurComplement;
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float result[4*4] =
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(0,0),	blockA(0,1),	blockB(0,0),	blockB(0,1),
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockA(1,0),	blockA(1,1),	blockB(1,0),	blockB(1,1),
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(0,0),	blockC(0,1),	blockD(0,0),	blockD(0,1),
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		blockC(1,0),	blockC(1,1),	blockD(1,0),	blockD(1,1),
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Mat4(result);
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// negate
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> negate (const tcu::Matrix<T, Rows, Cols>& mat)
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = -mat(r, c);
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// increment/decrement
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> increment (const tcu::Matrix<T, Rows, Cols>& mat)
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = mat(r, c) + 1.0f;
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> decrement (const tcu::Matrix<T, Rows, Cols>& mat)
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = mat(r, c) - 1.0f;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Evaluator template.
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef void (*MatrixShaderEvalFunc) (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type);
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Op, int In0DataType, int In1DataType>
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator;
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_ADD, In0DataType, In1DataType>
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 + in1);
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_SUB, In0DataType, In1DataType>
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 - in1);
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_MUL, In0DataType, In1DataType>
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 * in1);
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_DIV, In0DataType, In1DataType>
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 / in1);
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_COMP_MUL, In0DataType, In1DataType>
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(matrixCompMult(in0, in1));
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
953