es3fShaderMatrixTests.cpp revision 3c827367444ee418f129b2c238299f49d3264554
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};
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_OUTER_PRODUCT, In0DataType, In1DataType>
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(outerProduct(in0, in1));
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_TRANSPOSE, In0DataType, In1DataType>
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(transpose(in0));
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_INVERSE, In0DataType, In1DataType>
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(inverse(in0));
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_DETERMINANT, In0DataType, In1DataType>
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = Vec3(determinant(in0));
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_UNARY_PLUS, In0DataType, In1DataType>
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_NEGATION, In0DataType, In1DataType>
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(negate(in0));
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_PRE_INCREMENT, In0DataType, In1DataType>
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(increment(in0)) + reduceToVec3(increment(in0));
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_PRE_DECREMENT, In0DataType, In1DataType>
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(decrement(in0)) + reduceToVec3(decrement(in0));
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_POST_INCREMENT, In0DataType, In1DataType>
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(increment(in0));
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_POST_DECREMENT, In0DataType, In1DataType>
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(in1Type);
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(decrement(in0));
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_ADD_INTO, In0DataType, In1DataType>
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 + in1);
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_SUBTRACT_FROM, In0DataType, In1DataType>
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 - in1);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_MULTIPLY_INTO, In0DataType, In1DataType>
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 * in1);
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0DataType, int In1DataType>
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_DIVIDE_INTO, In0DataType, In1DataType>
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(in0 / in1);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrixShaderEvalFunc getEvalFunc (const ShaderInput& in0, const ShaderInput& in1, MatrixOp op)
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Evaluator is selected based on op and input data types.
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// For efficient lookup the types and op enums are packed together to form a 19-bit key:
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// [18..14 OP] [13..7 TYPE0] [6..0 TYPE1]
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(TYPE_LAST	<= (1<<7));
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(OP_LAST	<= (1<<5));
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE)	(((OP) << 14) | ((IN0DATATYPE) << 7) | (IN1DATATYPE))
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE)	\
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	case PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE):	\
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Evaluator<OP, IN0DATATYPE, IN1DATATYPE>::evaluate
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_SCALAR_OPS(IN0DATATYPE, IN1DATATYPE)		\
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE);	\
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE);	\
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE);	\
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_CWISE_OPS(IN0DATATYPE, IN1DATATYPE)			\
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD,		IN0DATATYPE, IN1DATATYPE);	\
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUB,		IN0DATATYPE, IN1DATATYPE);	\
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIV,		IN0DATATYPE, IN1DATATYPE);	\
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_COMP_MUL,	IN0DATATYPE, IN1DATATYPE)
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_MUL_OP(IN0DATATYPE, IN1DATATYPE)			\
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_VECVEC_OP(IN0DATATYPE, IN1DATATYPE)			\
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_OUTER_PRODUCT, IN0DATATYPE, IN1DATATYPE)
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_UNARY_OP(IN0DATATYPE)								\
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_TRANSPOSE,		IN0DATATYPE, TYPE_LAST);	\
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_UNARY_PLUS,		IN0DATATYPE, TYPE_LAST);	\
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_NEGATION,			IN0DATATYPE, TYPE_LAST);	\
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_PRE_INCREMENT,	IN0DATATYPE, TYPE_LAST);	\
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_PRE_DECREMENT,	IN0DATATYPE, TYPE_LAST);	\
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_POST_INCREMENT,	IN0DATATYPE, TYPE_LAST);	\
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_POST_DECREMENT,	IN0DATATYPE, TYPE_LAST)
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_UNARY_SYMMETRIC_OP(IN0DATATYPE)					\
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_UNARY_OP(IN0DATATYPE);									\
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DETERMINANT,	IN0DATATYPE, TYPE_LAST);	\
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_INVERSE,		IN0DATATYPE, TYPE_LAST)
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_ASSIGNMENT_OP(IN0DATATYPE)								\
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD_INTO,			IN0DATATYPE, IN0DATATYPE);	\
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUBTRACT_FROM,	IN0DATATYPE, IN0DATATYPE);	\
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIVIDE_INTO,		IN0DATATYPE, IN0DATATYPE)
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_ASSIGNMENT_SYMMETRIC_OP(IN0DATATYPE)					\
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_ASSIGNMENT_OP(IN0DATATYPE);								\
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MULTIPLY_INTO,	IN0DATATYPE, IN0DATATYPE)
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (PACK_EVAL_CASE(op, in0.dataType, in1.dataType))
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-scalar.
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2,	TYPE_FLOAT);
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT);
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT);
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT);
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3,	TYPE_FLOAT);
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT);
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT);
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT);
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4,	TYPE_FLOAT);
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-vector.
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2,	TYPE_FLOAT_VEC2);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT_VEC2);
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT_VEC2);
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT_VEC3);
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3,	TYPE_FLOAT_VEC3);
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT_VEC3);
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT_VEC4);
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT_VEC4);
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4,	TYPE_FLOAT_VEC4);
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Vector-matrix.
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT2X3);
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT2X4);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT3X2);
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT3X4);
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT4X2);
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT4X3);
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-matrix.
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT2);
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT2);
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT3X2);
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT4X2);
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT_MAT2X3);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT2);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT3X2);
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT4X2);
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT_MAT2X4);
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT2);
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT3X2);
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT4X2);
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT_MAT3X2);
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT2X3);
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT3);
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT4X3);
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT3);
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT2X3);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT3);
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT4X3);
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT_MAT3X4);
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT2X3);
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT3);
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT4X3);
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT_MAT4X2);
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT2X4);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT3X4);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT4);
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT_MAT4X3);
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT2X4);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT3X4);
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT4);
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT4);
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT2X4);
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT3X4);
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT4);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Vector-vector.
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC2);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC3);
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC4);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC2);
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC3);
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC4);
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC2);
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC3);
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC4);
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Unary Matrix.
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT2X3);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT2X4);
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT3X2);
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT3X4);
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT4X2);
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_OP(TYPE_FLOAT_MAT4X3);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Assignments
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X3);
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X4);
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X2);
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X4);
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X2);
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X3);
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT4);
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PACK_EVAL_CASE
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_EVAL_CASE
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MUL_OP
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef ALL_OPS
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_MAT_SCALAR_VEC_CASES
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_MAT_MAT_CASES
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Shader source format utilities.
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid writeVectorConstructor (std::ostream& str, const tcu::Vector<float, Size>& v)
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << "vec" << Size << "(";
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < Size; ndx++)
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ndx != 0)
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << ", ";
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << de::floatToString(v[ndx], 1);
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << ")";
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Cols, int Rows>
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid writeMatrixConstructor (std::ostream& str, const tcu::Matrix<float, Rows, Cols>& m)
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Rows == Cols)
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << "mat" << Cols;
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << "mat" << Cols << "x" << Rows;
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << "(";
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int colNdx = 0; colNdx < Cols; colNdx++)
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (rowNdx > 0 || colNdx > 0)
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				str << ", ";
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << de::floatToString(m(rowNdx, colNdx), 1);
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << ")";
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // MatrixCaseUtils
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace MatrixCaseUtils;
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatrixShaderEvaluator : public ShaderEvaluator
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							MatrixShaderEvaluator	(MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			evaluate				(ShaderEvalContext& evalCtx);
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MatrixShaderEvalFunc	m_matEvalFunc;
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType				m_inType0;
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType				m_inType1;
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrixShaderEvaluator::MatrixShaderEvaluator (MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1)
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_matEvalFunc	(evalFunc)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_inType0		(inType0)
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_inType1		(inType1)
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MatrixShaderEvaluator::evaluate (ShaderEvalContext& evalCtx)
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_matEvalFunc(evalCtx, m_inType0, m_inType1);
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderMatrixCase : public ShaderRenderCase
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ShaderMatrixCase			(Context& context, const char* name, const char* desc, const ShaderInput& in0, const ShaderInput& in1, MatrixOp op, bool isVertexCase);
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~ShaderMatrixCase			(void);
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init						(void);
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string				genGLSLMatToVec3Reduction	(const glu::DataType& matType, const char* varName);
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					setupUniforms				(int programID, const tcu::Vec4& constCoords);
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput				m_in0;
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput				m_in1;
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MatrixOp				m_op;
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MatrixShaderEvaluator	m_matEvaluator;
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixCase::ShaderMatrixCase (Context& context, const char* name, const char* desc, const ShaderInput& in0, const ShaderInput& in1, MatrixOp op, bool isVertexCase)
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, m_matEvaluator)
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_in0				(in0)
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_in1				(in1)
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_op				(op)
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_matEvaluator	(getEvalFunc(in0, in1, op), in0.inputType, in1.inputType)
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixCase::~ShaderMatrixCase (void)
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderMatrixCase::init (void)
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	vtx;
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	frag;
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream&	op				= m_isVertexCase ? vtx : frag;
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				isInDynMat0		= isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				isInDynMat1		= isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				inValue0;
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				inValue1;
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType			resultType		= TYPE_LAST;
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Precision			resultPrec		= m_in0.precision;
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<string>		passVars;
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numInputs		= (isOperationBinary(m_op)) ? (2) : (1);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			operationValue0;
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			operationValue1;
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(isInDynMat0 && isInDynMat1);
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute result type.
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_op == OP_MUL && isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = getDataTypeMatrix(getDataTypeMatrixNumColumns(m_in1.dataType), getDataTypeMatrixNumRows(m_in0.dataType));
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_op == OP_OUTER_PRODUCT)
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = getDataTypeMatrix(getDataTypeScalarSize(m_in1.dataType), getDataTypeScalarSize(m_in0.dataType));
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_op == OP_TRANSPOSE)
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = getDataTypeMatrix(getDataTypeMatrixNumRows(m_in0.dataType), getDataTypeMatrixNumColumns(m_in0.dataType));
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_op == OP_INVERSE)
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = m_in0.dataType;
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_op == OP_DETERMINANT)
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = TYPE_FLOAT;
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = m_in0.dataType;
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_in0.dataType == m_in1.dataType);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = m_in0.dataType;
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (isDataTypeMatrix(m_in0.dataType) || isDataTypeMatrix(m_in1.dataType))
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			matNdx		= isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType	matrixType	= matNdx == 0 ? m_in0.dataType : m_in1.dataType;
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType	otherType	= matNdx == 0 ? m_in1.dataType : m_in0.dataType;
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (otherType == TYPE_FLOAT)
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultType = matrixType;
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(isDataTypeVector(otherType));
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultType = getDataTypeFloatVec(matNdx == 0 ? getDataTypeMatrixNumRows(matrixType) : getDataTypeMatrixNumColumns(matrixType));
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(DE_FALSE);
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_color;\n";
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_color;\n";
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Input declarations.
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int inNdx = 0; inNdx < numInputs; inNdx++)
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ShaderInput&	in			= inNdx > 0 ? m_in1 : m_in0;
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			precName	= getPrecisionName(in.precision);
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			typeName	= getDataTypeName(in.dataType);
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string&				inValue		= inNdx > 0 ? inValue1 : inValue0;
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (in.inputType == INPUTTYPE_DYNAMIC)
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "in " << precName << " " << typeName << " a_";
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDataTypeMatrix(in.dataType))
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// a_matN, v_matN
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << typeName << ";\n";
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!m_isVertexCase)
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vtx << "out " << precName << " " << typeName << " v_" << typeName << ";\n";
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					frag << "in " << precName << " " << typeName << " v_" << typeName << ";\n";
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					passVars.push_back(typeName);
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// a_coords, v_coords
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "coords;\n";
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!m_isVertexCase)
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vtx << "out " << precName << " " << typeName << " v_coords;\n";
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					frag << "in " << precName << " " << typeName << " v_coords;\n";
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					passVars.push_back("coords");
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue = m_isVertexCase ? "a_coords" : "v_coords";
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (in.inputType == INPUTTYPE_UNIFORM)
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform " << precName << " " << typeName << " u_in" << inNdx << ";\n";
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inValue = string("u_in") + de::toString(inNdx);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (in.inputType == INPUTTYPE_CONST)
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "const " << precName << " " << typeName << " in" << inNdx << " = ";
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generate declaration.
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (in.dataType)
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT:		op << de::floatToString(s_constInFloat[inNdx], 1);					break;
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC2:	writeVectorConstructor<2>(op, s_constInVec2[inNdx]);				break;
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC3:	writeVectorConstructor<3>(op, s_constInVec3[inNdx]);				break;
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC4:	writeVectorConstructor<4>(op, s_constInVec4[inNdx]);				break;
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2:	writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2x2[inNdx]));		break;
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2X3:	writeMatrixConstructor<2, 3>(op, Mat2x3(s_constInMat2x3[inNdx]));	break;
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2X4:	writeMatrixConstructor<2, 4>(op, Mat2x4(s_constInMat2x4[inNdx]));	break;
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3X2:	writeMatrixConstructor<3, 2>(op, Mat3x2(s_constInMat3x2[inNdx]));	break;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3:	writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3x3[inNdx]));		break;
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3X4:	writeMatrixConstructor<3, 4>(op, Mat3x4(s_constInMat3x4[inNdx]));	break;
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4X2:	writeMatrixConstructor<4, 2>(op, Mat4x2(s_constInMat4x2[inNdx]));	break;
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4X3:	writeMatrixConstructor<4, 3>(op, Mat4x3(s_constInMat4x3[inNdx]));	break;
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4:	writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4x4[inNdx]));		break;
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(DE_FALSE);
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << ";\n";
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inValue = string("in") + de::toString(inNdx);
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n"
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "void main (void)\n"
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "{\n"
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "	gl_Position = a_position;\n";
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n"
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 << "void main (void)\n"
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 << "{\n";
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	dEQP_FragColor = v_color;\n";
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_" << *copyIter << " = " << "a_" << *copyIter << ";\n";
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Operation.
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (getOperationNature(m_op))
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_PURE:
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = inValue0;
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_MUTATING:
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0 << ";\n";
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = "tmpValue";
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_ASSIGNMENT:
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = inValue0;
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (getOperationType(m_op))
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_BINARY_OPERATOR:
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_BINARY_FUNCTION:
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ", " << operationValue1 << ");\n";
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_UNARY_FUNCTION:
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ");\n";
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_ASSIGNMENT:
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << ";\n";
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	res " << getOperationName(m_op) << " " << operationValue1 << ";\n";
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Reduction to vec3 (rgb). Check the used value too if it was modified
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	" << (m_isVertexCase ? "v_color" : "dEQP_FragColor") << " = ";
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOperationValueModifying(m_op))
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0) + vec4(" << genGLSLMatToVec3Reduction(resultType, "tmpValue") << ", 0.0);\n";
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0);\n";
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertShaderSource	= vtx.str();
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragShaderSource	= frag.str();
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-02-14 pyry] Compute better values for matrix tests.
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_userAttribTransforms.resize(4);
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int attribNdx = 0; attribNdx < 4; attribNdx++)
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx] = Mat4(0.0f);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx](                  0, 3) = 0.2f;						// !< prevent matrix*vec from going into zero (assuming vec.w != 0)
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx](                  1, 3) = 0.1f;						// !<
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx](                  2, 3) = 0.4f + 0.15f * attribNdx;	// !<
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx](                  3, 3) = 0.7f;						// !<
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx]((0 + attribNdx) % 4, 0) = 1.0f;
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx]((1 + attribNdx) % 4, 1) = 1.0f;
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx]((2 + attribNdx) % 4, 2) = 1.0f;
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_userAttribTransforms[attribNdx]((3 + attribNdx) % 4, 3) = 1.0f;
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// prevent bad reference cases such as black result images by fine-tuning used matrices
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getOperationTestMatrixType(m_op) != TESTMATRIXTYPE_DEFAULT)
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int attribNdx = 0; attribNdx < 4; attribNdx++)
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int row = 0; row < 4; row++)
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int col = 0; col < 4; col++)
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				switch (getOperationTestMatrixType(m_op))
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case TESTMATRIXTYPE_NEGATED:
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col);
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case TESTMATRIXTYPE_INCREMENTED:
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_userAttribTransforms[attribNdx](row, col) += 0.3f;
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case TESTMATRIXTYPE_DECREMENTED:
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_userAttribTransforms[attribNdx](row, col) -= 0.3f;
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case TESTMATRIXTYPE_NEGATED_INCREMENTED:
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col) + 0.3f;
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					case TESTMATRIXTYPE_INCREMENTED_LESS:
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						m_userAttribTransforms[attribNdx](row, col) -= 0.1f;
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					default:
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(DE_FALSE);
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						break;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderRenderCase::init();
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string ShaderMatrixCase::genGLSLMatToVec3Reduction (const glu::DataType& matType, const char* varName)
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream op;
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (matType)
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT:		op << varName << ", "			<< varName << ", "			<< varName << "";																																			break;
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_VEC2:	op << varName << ".x, "			<< varName << ".y, "		<< varName << ".x";																																			break;
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_VEC3:	op << varName << "";																																																	break;
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_VEC4:	op << varName << ".x, "			<< varName << ".y, "		<< varName << ".z+"			<< varName << ".w";																												break;
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2:	op << varName << "[0][0], "		<< varName << "[1][0], "	<< varName << "[0][1]+"		<< varName << "[1][1]";																											break;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2X3:	op << varName << "[0] + "		<< varName << "[1]";																																									break;
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2X4:	op << varName << "[0].xyz + "	<< varName << "[1].yzw";																																								break;
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3X2:	op << varName << "[0][0]+"		<< varName << "[0][1], "	<< varName << "[1][0]+"		<< varName << "[1][1], "	<< varName << "[2][0]+" << varName << "[2][1]";														break;
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3:	op << varName << "[0] + "		<< varName << "[1] + "		<< varName << "[2]";																																		break;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3X4:	op << varName << "[0].xyz + "	<< varName << "[1].yzw + "	<< varName << "[2].zwx";																																	break;
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4X2:	op << varName << "[0][0]+"		<< varName << "[0][1]+"		<< varName << "[3][0], "	<< varName << "[1][0]+"		<< varName << "[1][1]+" << varName << "[3][1], " << varName << "[2][0]+" << varName << "[2][1]";	break;
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4X3:	op << varName << "[0] + "		<< varName << "[1] + "		<< varName << "[2] + "		<< varName << "[3]";																											break;
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4:	op << varName << "[0].xyz+"		<< varName << "[1].yzw+"	<< varName << "[2].zwx+"	<< varName << "[3].wxy";																										break;
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op.str();
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderMatrixCase::setupUniforms (int programID, const tcu::Vec4& constCoords)
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(constCoords);
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int inNdx = 0; inNdx < 2; inNdx++)
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (in.inputType == INPUTTYPE_UNIFORM)
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int loc = gl.getUniformLocation(programID, (string("u_in") + de::toString(inNdx)).c_str());
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (loc < 0)
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (in.dataType)
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT:		gl.uniform1f(loc, s_constInFloat[inNdx]);						break;
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC2:	gl.uniform2fv(loc, 1, s_constInVec2[inNdx].getPtr());			break;
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC3:	gl.uniform3fv(loc, 1, s_constInVec3[inNdx].getPtr());			break;
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC4:	gl.uniform4fv(loc, 1, s_constInVec4[inNdx].getPtr());			break;
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note GLES3 supports transpose in matrix upload.
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2:	gl.uniformMatrix2fv	(loc, 1, GL_TRUE, s_constInMat2x2[inNdx]);	break;
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2X3:	gl.uniformMatrix2x3fv(loc, 1, GL_TRUE, s_constInMat2x3[inNdx]);	break;
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2X4:	gl.uniformMatrix2x4fv(loc, 1, GL_TRUE, s_constInMat2x4[inNdx]);	break;
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3X2:	gl.uniformMatrix3x2fv(loc, 1, GL_TRUE, s_constInMat3x2[inNdx]);	break;
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3:	gl.uniformMatrix3fv	(loc, 1, GL_TRUE, s_constInMat3x3[inNdx]);	break;
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3X4:	gl.uniformMatrix3x4fv(loc, 1, GL_TRUE, s_constInMat3x4[inNdx]);	break;
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4X2:	gl.uniformMatrix4x2fv(loc, 1, GL_TRUE, s_constInMat4x2[inNdx]);	break;
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4X3:	gl.uniformMatrix4x3fv(loc, 1, GL_TRUE, s_constInMat4x3[inNdx]);	break;
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4:	gl.uniformMatrix4fv	(loc, 1, GL_TRUE, s_constInMat4x4[inNdx]);	break;
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixTests::ShaderMatrixTests (Context& context)
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "matrix", "Matrix Tests")
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixTests::~ShaderMatrixTests (void)
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderMatrixTests::init (void)
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		desc;
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MatrixOp		op;
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			extendedInputTypeCases; // !< test with const and uniform types too
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool			createInputTypeGroup;	// !< create group for input types
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} ops[] =
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "add",			"Matrix addition tests",						OP_ADD,				true,	true	},
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "sub",			"Matrix subtraction tests",						OP_SUB,				true,	true	},
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mul",			"Matrix multiplication tests",					OP_MUL,				true,	true	},
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "div",			"Matrix division tests",						OP_DIV,				true,	true	},
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "matrixcompmult",	"Matrix component-wise multiplication tests",	OP_COMP_MUL,		false,	true	},
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "outerproduct",	"Matrix outerProduct() tests",					OP_OUTER_PRODUCT,	false,	true	},
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "transpose",		"Matrix transpose() tests",						OP_TRANSPOSE,		false,	true	},
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "determinant",	"Matrix determinant() tests",					OP_DETERMINANT,		false,	true	},
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "inverse",		"Matrix inverse() tests",						OP_INVERSE,			false,	true	},
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "unary_addition",	"Matrix unary addition tests",					OP_UNARY_PLUS,		false,	false	},
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "negation",		"Matrix negation tests",						OP_NEGATION,		false,	false	},
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pre_increment",	"Matrix prefix increment tests",				OP_PRE_INCREMENT,	false,	false	},
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "pre_decrement",	"Matrix prefix decrement tests",				OP_PRE_DECREMENT,	false,	false	},
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "post_increment",	"Matrix postfix increment tests",				OP_POST_INCREMENT,	false,	false	},
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "post_decrement",	"Matrix postfix decrement tests",				OP_POST_DECREMENT,	false,	false	},
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "add_assign",		"Matrix add into tests",						OP_ADD_INTO,		false,	false	},
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "sub_assign",		"Matrix subtract from tests",					OP_SUBTRACT_FROM,	false,	false	},
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mul_assign",		"Matrix multiply into tests",					OP_MULTIPLY_INTO,	false,	false	},
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "div_assign",		"Matrix divide into tests",						OP_DIVIDE_INTO,		false,	false	},
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct InputTypeSpec
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		desc;
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		InputType		type;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const InputTypeSpec extendedInputTypes[] =
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "const",		"Constant matrix input",	INPUTTYPE_CONST		},
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "uniform",	"Uniform matrix input",		INPUTTYPE_UNIFORM	},
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "dynamic",	"Dynamic matrix input",		INPUTTYPE_DYNAMIC	}
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const InputTypeSpec reducedInputTypes[] =
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "dynamic",	"Dynamic matrix input",		INPUTTYPE_DYNAMIC	}
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const DataType matrixTypes[] =
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2,
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2X3,
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT2X4,
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3X2,
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3,
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT3X4,
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4X2,
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4X3,
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_MAT4
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const Precision precisions[] =
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PRECISION_LOWP,
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PRECISION_MEDIUMP,
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PRECISION_HIGHP
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int opNdx = 0; opNdx < DE_LENGTH_OF_ARRAY(ops); opNdx++)
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const InputTypeSpec*	inTypeList		= (ops[opNdx].extendedInputTypeCases) ? (extendedInputTypes) : (reducedInputTypes);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int				inTypeListSize	= (ops[opNdx].extendedInputTypeCases) ? (DE_LENGTH_OF_ARRAY(extendedInputTypes)) : (DE_LENGTH_OF_ARRAY(reducedInputTypes));
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const MatrixOp			op				= ops[opNdx].op;
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TestCaseGroup*		opGroup			= new tcu::TestCaseGroup(m_testCtx, ops[opNdx].name, ops[opNdx].desc);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(opGroup);
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++)
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const InputType		inputType	= inTypeList[inTypeNdx].type;
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TestCaseGroup* inGroup;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ops[opNdx].createInputTypeGroup)
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inGroup = new tcu::TestCaseGroup(m_testCtx, inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				opGroup->addChild(inGroup);
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inGroup = opGroup;
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int matTypeNdx = 0; matTypeNdx < DE_LENGTH_OF_ARRAY(matrixTypes); matTypeNdx++)
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DataType	matType		= matrixTypes[matTypeNdx];
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int			numCols		= getDataTypeMatrixNumColumns(matType);
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int			numRows		= getDataTypeMatrixNumRows(matType);
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*	matTypeName	= getDataTypeName(matType);
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++)
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Precision	precision	= precisions[precNdx];
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*	precName	= getPrecisionName(precision);
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string		baseName	= string(precName) + "_" + matTypeName + "_";
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderInput	matIn		(inputType, matType, precision);
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (isOperationMatrixScalar(op))
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Matrix-scalar \note For div cases we use uniform input.
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput scalarIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, TYPE_FLOAT, precision);
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),		"Matrix-scalar case", matIn, scalarIn, op, true));
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),	"Matrix-scalar case", matIn, scalarIn, op, false));
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (isOperationMatrixVector(op))
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Matrix-vector.
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DataType	colVecType	= getDataTypeFloatVec(numCols);
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput colVecIn	(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, colVecType, precision);
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + getDataTypeName(colVecType) + "_vertex").c_str(),		"Matrix-vector case", matIn, colVecIn, op, true));
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + getDataTypeName(colVecType) + "_fragment").c_str(),	"Matrix-vector case", matIn, colVecIn, op, false));
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Vector-matrix.
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DataType	rowVecType	= getDataTypeFloatVec(numRows);
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput	rowVecIn	(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, rowVecType, precision);
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		vecMatName	= string(precName) + "_" + getDataTypeName(rowVecType) + "_" + matTypeName;
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_vertex").c_str(),		"Vector-matrix case", rowVecIn, matIn, op, true));
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (vecMatName + "_fragment").c_str(),	"Vector-matrix case", rowVecIn, matIn, op, false));
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (isOperationArithmeticMatrixMatrix(op))
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Arithmetic matrix-matrix multiplication.
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int otherCols = 2; otherCols <= 4; otherCols++)
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, getDataTypeMatrix(otherCols, numCols /* rows */), precision);
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + getDataTypeName(otherMatIn.dataType) + "_vertex").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, true));
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + getDataTypeName(otherMatIn.dataType) + "_fragment").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, false));
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					else if (isOperationComponentwiseMatrixMatrix(op))
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Component-wise.
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + matTypeName + "_vertex").c_str(),		"Matrix-matrix case", matIn, otherMatIn, op, true));
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + matTypeName + "_fragment").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, false));
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (isOperationVectorVector(op))
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput vec1In(inputType,																getDataTypeFloatVec(numRows), precision);
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput vec2In((inputType == INPUTTYPE_DYNAMIC) ? (INPUTTYPE_UNIFORM) : (inputType),	getDataTypeFloatVec(numCols), precision);
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),		"Vector-vector case", vec1In, vec2In, op, true));
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),	"Vector-vector case", vec1In, vec2In, op, false));
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if ((isOperationUnaryAnyMatrix(op)) ||
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						(isOperationUnarySymmetricMatrix(op) && numCols == numRows))
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput voidInput(INPUTTYPE_LAST, TYPE_LAST, PRECISION_LAST);
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),		"Matrix case", matIn, voidInput, op, true));
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),	"Matrix case", matIn, voidInput, op, false));
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if ((isOperationAssignmentAnyMatrix(op)) ||
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						(isOperationAssignmentSymmetricMatrix(op) && numCols == numRows))
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_vertex").c_str(),		"Matrix assignment case", matIn, otherMatIn, op, true));
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						inGroup->addChild(new ShaderMatrixCase(m_context, (baseName + "float_fragment").c_str(),	"Matrix assignment case", matIn, otherMatIn, op, false));
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1974