13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.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 *  + matrix source
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - constant (ctor)
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - uniform
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - vertex input
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *    - fragment input
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + other operand: always dynamic data?
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *  + how to reduce to vec3?
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2fShaderMatrixTests.hpp"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrixUtil.hpp"
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat2;
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3;
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat4;
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Uniform / constant values for tests.
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note Input1 should not contain 0 components as it is used as divisor in div cases.
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-02-14 pyry] Make these dynamic.
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float	s_constInFloat[2]	= { 0.5f, -0.2f };
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec2	s_constInVec2[2]	= { Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f) };
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec3	s_constInVec3[2]	= { Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f) };
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Vec4	s_constInVec4[2]	= { Vec4(1.4f, 0.2f, -0.5f, 0.7f), Vec4(0.2f, -1.0f, 0.5f, 0.8f) };
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat20[] = { 0.6f, -1.0f, 0.7f, 0.4f };
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat21[] = { -0.5f, -0.4f, 0.7f, -0.8f };
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat31[] =
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	1.2f,  0.1f, -0.1f,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0.1f,  0.9f,  0.2f,
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	0.2f, -0.1f,  0.7f
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float s_constInMat41[] =
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	 1.2f, -0.2f,  0.4f,  0.1f,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	 0.1f,  0.8f, -0.1f, -0.2f,
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	-0.2f,  0.1f, -1.1f,  0.3f,
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	 0.1f,  0.2f,  0.3f,  0.9f
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Mat2	s_constInMat2[2]	= { tcu::Mat2(s_constInMat20), tcu::Mat2(s_constInMat21) };
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Mat3	s_constInMat3[2]	= { tcu::translationMatrix(tcu::Vec2(0.2f, -0.3f)), tcu::Mat3(s_constInMat31) };
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const Mat4	s_constInMat4[2]	= { tcu::translationMatrix(tcu::Vec3(0.2f, -0.3f, 0.15f)), tcu::Mat4(s_constInMat41) };
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace MatrixCaseUtils
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum InputType
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_CONST = 0,
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_UNIFORM,
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_DYNAMIC,
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INPUTTYPE_LAST
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ShaderInput
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput (InputType inputType_, DataType dataType_, Precision precision_)
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: inputType	(inputType_)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, dataType	(dataType_)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, precision	(precision_)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType		inputType;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType		dataType;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Precision		precision;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum MatrixOp
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_ADD = 0,
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_SUB,
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_MUL,
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_DIV,
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_COMP_MUL,
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_UNARY_PLUS,
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_NEGATION,
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_PRE_INCREMENT,
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_PRE_DECREMENT,
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_POST_INCREMENT,
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_POST_DECREMENT,
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_ADD_INTO,
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_SUBTRACT_FROM,
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_MULTIPLY_INTO,
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_DIVIDE_INTO,
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP_LAST
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Type traits.
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int DataT>
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TypeTraits;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define DECLARE_TYPE_TRAIT(DATATYPE, TYPE)	\
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<>									\
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct TypeTraits<DATATYPE> {				\
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef TYPE Type;						\
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT,		float);
1573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2,	tcu::Vec2);
1583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3,	tcu::Vec3);
1593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4,	tcu::Vec4);
1603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2, tcu::Mat2);
1613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3, tcu::Mat3);
1623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4, tcu::Mat4);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Operation info
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum OperationType
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_BINARY_OPERATOR = 0,
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_BINARY_FUNCTION,
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_ASSIGNMENT,
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONTYPE_LAST
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getOperationName (MatrixOp op)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return "+";
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return "-";
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return "*";
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return "/";
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return "matrixCompMult";
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return "+";
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return "-";
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return "++";
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return "--";
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return "++";
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return "--";
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return "+=";
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return "-=";
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return "*=";
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return "/=";
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "";
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic OperationType getOperationType (MatrixOp op)
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return OPERATIONTYPE_BINARY_OPERATOR;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return OPERATIONTYPE_BINARY_OPERATOR;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return OPERATIONTYPE_BINARY_OPERATOR;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return OPERATIONTYPE_BINARY_OPERATOR;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return OPERATIONTYPE_BINARY_FUNCTION;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return OPERATIONTYPE_ASSIGNMENT;
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return OPERATIONTYPE_ASSIGNMENT;
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return OPERATIONTYPE_ASSIGNMENT;
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return OPERATIONTYPE_ASSIGNMENT;
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return OPERATIONTYPE_LAST;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum TestMatrixType
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_DEFAULT = 0,
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_NEGATED,
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_INCREMENTED,
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_DECREMENTED,
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TESTMATRIXTYPE_LAST
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic TestMatrixType getOperationTestMatrixType (MatrixOp op)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch(op)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD:			return TESTMATRIXTYPE_DEFAULT;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUB:			return TESTMATRIXTYPE_DEFAULT;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MUL:			return TESTMATRIXTYPE_DEFAULT;
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIV:			return TESTMATRIXTYPE_DEFAULT;
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_COMP_MUL:		return TESTMATRIXTYPE_DEFAULT;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_UNARY_PLUS:		return TESTMATRIXTYPE_DEFAULT;
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_NEGATION:		return TESTMATRIXTYPE_NEGATED;
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_PRE_DECREMENT:	return TESTMATRIXTYPE_INCREMENTED;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_POST_DECREMENT:	return TESTMATRIXTYPE_DEFAULT;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_ADD_INTO:		return TESTMATRIXTYPE_DECREMENTED;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_SUBTRACT_FROM:	return TESTMATRIXTYPE_DEFAULT;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_MULTIPLY_INTO:	return TESTMATRIXTYPE_DEFAULT;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OP_DIVIDE_INTO:	return TESTMATRIXTYPE_DEFAULT;
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return TESTMATRIXTYPE_LAST;
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationBinary (MatrixOp op)
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	       getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION ||
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	       getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationMatrixScalar (MatrixOp op)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationMatrixVector (MatrixOp op)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_MUL;
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationMatrixMatrix (MatrixOp op)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationUnary (MatrixOp op)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_UNARY_PLUS			||
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_NEGATION			||
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_INCREMENT		||
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_DECREMENT		||
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_INCREMENT		||
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_DECREMENT;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationValueModifying (MatrixOp op)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_PRE_INCREMENT		||
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_PRE_DECREMENT		||
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_INCREMENT		||
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_POST_DECREMENT;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOperationAssignment (MatrixOp op)
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return  op == OP_ADD_INTO		 ||
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_SUBTRACT_FROM	 ||
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_MULTIPLY_INTO	 ||
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op == OP_DIVIDE_INTO;
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Operation nature
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum OperationNature
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_PURE = 0,
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_MUTATING,
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_ASSIGNMENT,
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OPERATIONNATURE_LAST
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic OperationNature getOperationNature (MatrixOp op)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOperationAssignment(op))
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return OPERATIONNATURE_ASSIGNMENT;
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isOperationValueModifying(op))
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return OPERATIONNATURE_MUTATING;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return OPERATIONNATURE_PURE;
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Input value loader.
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int InputT, int DataT>
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename TypeTraits<DataT>::Type getInputValue (const ShaderEvalContext& evalCtx, int inputNdx);
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline float		getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInFloat[inputNdx];	}
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec2[inputNdx];	}
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec3[inputNdx];	}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec4[inputNdx];	}
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInMat2[inputNdx];	}
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInMat3[inputNdx];	}
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInMat4[inputNdx];	}
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline float		getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.x();					}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Vec2	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1);			}
3483c827367444ee418f129b2c238299f49d3264554Jarkko 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);		}
3493c827367444ee418f129b2c238299f49d3264554Jarkko 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);	}
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2> (const ShaderEvalContext& evalCtx, int inputNdx)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat2 m;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3> (const ShaderEvalContext& evalCtx, int inputNdx)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3 m;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4> (const ShaderEvalContext& evalCtx, int inputNdx)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(inputNdx); // Not used.
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat4 m;
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(0, evalCtx.in[0]);
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(1, evalCtx.in[1]);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(2, evalCtx.in[2]);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m.setColumn(3, evalCtx.in[3]);
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m;
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Reduction from expression result to vec3.
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec2& value) { return value.swizzle(0,1,0); }
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec3& value) { return value; }
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Vec4& value) { return tcu::Vec3(value.x(), value.y(), value.z()+value.w()); }
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat2& value) { return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0)+value(1, 1)); }
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline tcu::Vec3 reduceToVec3 (const tcu::Mat3& value) { return value.getColumn(0) + value.getColumn(1) + value.getColumn(2); }
3883c827367444ee418f129b2c238299f49d3264554Jarkko 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); }
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// matrixCompMult
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> matrixCompMult (const tcu::Matrix<T, Rows, Cols>& a, const tcu::Matrix<T, Rows, Cols>& b)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = a(r,c) * b(r, c);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// negate
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> negate (const tcu::Matrix<T, Rows, Cols>& mat)
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = -mat(r, c);
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// increment/decrement
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> increment (const tcu::Matrix<T, Rows, Cols>& mat)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = mat(r, c) + 1.0f;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int Rows, int Cols>
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Matrix<T, Rows, Cols> decrement (const tcu::Matrix<T, Rows, Cols>& mat)
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Matrix<T, Rows, Cols> retVal;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int r = 0; r < Rows; ++r)
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int c = 0; c < Cols; ++c)
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			retVal(r,c) = mat(r, c) - 1.0f;
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return retVal;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Evaluator template.
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Op, int In0Type, int In0DataType, int In1Type, int In1DataType>
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_ADD, In0Type, In0DataType, In1Type, In1DataType>
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) + getInputValue<In1Type, In1DataType>(evalCtx, 1));
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_SUB, In0Type, In0DataType, In1Type, In1DataType>
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) - getInputValue<In1Type, In1DataType>(evalCtx, 1));
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_MUL, In0Type, In0DataType, In1Type, In1DataType>
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) * getInputValue<In1Type, In1DataType>(evalCtx, 1));
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_DIV, In0Type, In0DataType, In1Type, In1DataType>
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) / getInputValue<In1Type, In1DataType>(evalCtx, 1));
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_COMP_MUL, In0Type, In0DataType, In1Type, In1DataType>
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(matrixCompMult(getInputValue<In0Type, In0DataType>(evalCtx, 0), getInputValue<In1Type, In1DataType>(evalCtx, 1)));
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_UNARY_PLUS, In0Type, In0DataType, In1Type, In1DataType>
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0));
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_NEGATION, In0Type, In0DataType, In1Type, In1DataType>
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(negate(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_PRE_INCREMENT, In0Type, In0DataType, In1Type, In1DataType>
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0))) + reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_PRE_DECREMENT, In0Type, In0DataType, In1Type, In1DataType>
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0))) + reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_POST_INCREMENT, In0Type, In0DataType, In1Type, In1DataType>
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0)) + reduceToVec3(increment(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_POST_DECREMENT, In0Type, In0DataType, In1Type, In1DataType>
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// modifying reduction: sum modified value too
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0)) + reduceToVec3(decrement(getInputValue<In0Type, In0DataType>(evalCtx, 0)));
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_ADD_INTO, In0Type, In0DataType, In1Type, In1DataType>
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) + getInputValue<In1Type, In1DataType>(evalCtx, 1));
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_SUBTRACT_FROM, In0Type, In0DataType, In1Type, In1DataType>
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) - getInputValue<In1Type, In1DataType>(evalCtx, 1));
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_MULTIPLY_INTO, In0Type, In0DataType, In1Type, In1DataType>
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) * getInputValue<In1Type, In1DataType>(evalCtx, 1));
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int In0Type, int In0DataType, int In1Type, int In1DataType>
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Evaluator<OP_DIVIDE_INTO, In0Type, In0DataType, In1Type, In1DataType>
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static void evaluate (ShaderEvalContext& evalCtx)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		evalCtx.color.xyz() = reduceToVec3(getInputValue<In0Type, In0DataType>(evalCtx, 0) / getInputValue<In1Type, In1DataType>(evalCtx, 1));
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderEvalFunc getEvalFunc (const ShaderInput& in0, const ShaderInput& in1, MatrixOp op)
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(TYPE_LAST		<= (1<<7));
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(OP_LAST		<= (1<<4));
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(INPUTTYPE_LAST	<= (1<<2));
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define PACK_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)	(((OP) << 18) | ((IN0TYPE) << 16) | ((IN0DATATYPE) << 9) | ((IN1TYPE) << 7) | (IN1DATATYPE))
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)		\
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	case PACK_EVAL_CASE(OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE):	\
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return Evaluator<OP, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE>::evaluate
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define SCALAR_OPS(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)	\
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUB,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MUL,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIV,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define ALL_OPS(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)	\
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD,			IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUB,			IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MUL,			IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIV,			IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_COMP_MUL,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MUL_OP(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)	\
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MUL, IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_MAT_SCALAR_VEC_CASES(OP, TYPE0, TYPE1)				\
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		TYPE0, INPUTTYPE_CONST,		TYPE1);	\
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	TYPE0, INPUTTYPE_CONST,		TYPE1);	\
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		TYPE0, INPUTTYPE_DYNAMIC,	TYPE1);	\
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	TYPE0, INPUTTYPE_DYNAMIC,	TYPE1)
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_MAT_MAT_CASES(OP, MATTYPE)								\
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		MATTYPE, INPUTTYPE_CONST,	MATTYPE);	\
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	MATTYPE, INPUTTYPE_CONST,	MATTYPE)
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define UNARY_OP(IN0TYPE, IN0DATATYPE)														\
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_UNARY_PLUS,		IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);	\
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_NEGATION,			IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);	\
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_PRE_INCREMENT,	IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);	\
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_PRE_DECREMENT,	IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);	\
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_POST_INCREMENT,	IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST);	\
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_POST_DECREMENT,	IN0TYPE, IN0DATATYPE, INPUTTYPE_CONST, TYPE_LAST)
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_UNARY_CASES(OP, MATTYPE)	\
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		MATTYPE);	\
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	MATTYPE)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define ASSIGN_OP(IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)							\
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_ADD_INTO,			IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_SUBTRACT_FROM,	IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_MULTIPLY_INTO,	IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE);	\
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MAKE_EVAL_CASE(OP_DIVIDE_INTO,		IN0TYPE, IN0DATATYPE, IN1TYPE, IN1DATATYPE)
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAKE_ASSIGNMENT_CASES(OP, MATTYPE)						\
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		MATTYPE, INPUTTYPE_CONST,	MATTYPE);	\
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	MATTYPE, INPUTTYPE_CONST,	MATTYPE);	\
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_CONST,		MATTYPE, INPUTTYPE_DYNAMIC,	MATTYPE);	\
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	OP(INPUTTYPE_DYNAMIC,	MATTYPE, INPUTTYPE_DYNAMIC,	MATTYPE)
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note At the moment there is no difference between uniform and const inputs. This saves binary size.
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType in0Type = in0.inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_DYNAMIC : INPUTTYPE_CONST;
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InputType in1Type = in1.inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_DYNAMIC : INPUTTYPE_CONST;
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (PACK_EVAL_CASE(op, in0Type, in0.dataType, in1Type, in1.dataType))
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-scalar.
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS,	TYPE_FLOAT_MAT2, TYPE_FLOAT);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS,	TYPE_FLOAT_MAT3, TYPE_FLOAT);
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(SCALAR_OPS,	TYPE_FLOAT_MAT4, TYPE_FLOAT);
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-vector.
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_MAT2, TYPE_FLOAT_VEC2);
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_MAT3, TYPE_FLOAT_VEC3);
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_MAT4, TYPE_FLOAT_VEC4);
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Vector-matrix.
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_SCALAR_VEC_CASES(MUL_OP,		TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Matrix-matrix.
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_MAT_CASES(ALL_OPS,	TYPE_FLOAT_MAT2);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_MAT_CASES(ALL_OPS,	TYPE_FLOAT_MAT3);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_MAT_MAT_CASES(ALL_OPS,	TYPE_FLOAT_MAT4);
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Unary matrix
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT2);
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT3);
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_UNARY_CASES(UNARY_OP, TYPE_FLOAT_MAT4);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Assignment matrix
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT2);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT3);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		MAKE_ASSIGNMENT_CASES(ASSIGN_OP, TYPE_FLOAT_MAT4);
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef PACK_EVAL_CASE
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_EVAL_CASE
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MUL_OP
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef ALL_OPS
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_MAT_SCALAR_VEC_CASES
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef MAKE_MAT_MAT_CASES
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Shader source format utilities.
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid writeVectorConstructor (std::ostream& str, const tcu::Vector<float, Size>& v)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << "vec" << Size << "(";
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < Size; ndx++)
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ndx != 0)
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << ", ";
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << de::floatToString(v[ndx], 1);
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << ")";
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Cols, int Rows>
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid writeMatrixConstructor (std::ostream& str, const tcu::Matrix<float, Rows, Cols>& m)
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (Rows == Cols)
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << "mat" << Cols;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		str << "mat" << Cols << "x" << Rows;
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << "(";
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int colNdx = 0; colNdx < Cols; colNdx++)
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (rowNdx > 0 || colNdx > 0)
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				str << ", ";
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			str << de::floatToString(m(rowNdx, colNdx), 1);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	str << ")";
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // MatrixCaseUtils
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace MatrixCaseUtils;
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderMatrixCase : public ShaderRenderCase
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderMatrixCase			(Context& context, const char* name, const char* desc, const ShaderInput& in0, const ShaderInput& in1, MatrixOp op, bool isVertexCase);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					~ShaderMatrixCase			(void);
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init						(void);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string		genGLSLMatToVec3Reduction	(const glu::DataType& matType, const char* varName);
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			setupUniforms				(int programID, const tcu::Vec4& constCoords);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput		m_in0;
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderInput		m_in1;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	MatrixOp		m_op;
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixCase::ShaderMatrixCase (Context& context, const char* name, const char* desc, const ShaderInput& in0, const ShaderInput& in1, MatrixOp op, bool isVertexCase)
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, desc, isVertexCase, getEvalFunc(in0, in1, op))
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_in0				(in0)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_in1				(in1)
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_op				(op)
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderMatrixCase::~ShaderMatrixCase (void)
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderMatrixCase::init (void)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	vtx;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream	frag;
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream&	op				= m_isVertexCase ? vtx : frag;
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				isInDynMat0		= isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				isInDynMat1		= isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				inValue0;
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				inValue1;
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType			resultType		= TYPE_LAST;
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Precision			resultPrec		= m_in0.precision;
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<string>		passVars;
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					numInputs		= (isOperationBinary(m_op)) ? (2) : (1);
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			operationValue0;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string			operationValue1;
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(isInDynMat0 && isInDynMat1);
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute result type.
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_in0.dataType == m_in1.dataType);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = m_in0.dataType;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultType = m_in0.dataType;
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int			matNdx		= isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType	matrixType	= matNdx == 0 ? m_in0.dataType : m_in1.dataType;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataType	otherType	= matNdx == 0 ? m_in1.dataType : m_in0.dataType;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (otherType == TYPE_FLOAT)
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultType = matrixType;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(isDataTypeVector(otherType));
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultType = otherType;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "attribute highp vec4 a_position;\n";
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "varying mediump vec4 v_color;\n";
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "varying mediump vec4 v_color;\n";
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Input declarations.
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int inNdx = 0; inNdx < numInputs; inNdx++)
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const ShaderInput&	in			= inNdx > 0 ? m_in1 : m_in0;
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			precName	= getPrecisionName(in.precision);
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*			typeName	= getDataTypeName(in.dataType);
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string&				inValue		= inNdx > 0 ? inValue1 : inValue0;
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (in.inputType == INPUTTYPE_DYNAMIC)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "attribute " << precName << " " << typeName << " a_";
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDataTypeMatrix(in.dataType))
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// a_matN, v_matN
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << typeName << ";\n";
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!m_isVertexCase)
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vtx << "varying " << precName << " " << typeName << " v_" << typeName << ";\n";
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					frag << "varying " << precName << " " << typeName << " v_" << typeName << ";\n";
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					passVars.push_back(typeName);
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// a_coords, v_coords
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vtx << "coords;\n";
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!m_isVertexCase)
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					vtx << "varying " << precName << " " << typeName << " v_coords;\n";
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					frag << "varying " << precName << " " << typeName << " v_coords;\n";
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					passVars.push_back("coords");
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inValue = m_isVertexCase ? "a_coords" : "v_coords";
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (in.inputType == INPUTTYPE_UNIFORM)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "uniform " << precName << " " << typeName << " u_in" << inNdx << ";\n";
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inValue = string("u_in") + de::toString(inNdx);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (in.inputType == INPUTTYPE_CONST)
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "const " << precName << " " << typeName << " in" << inNdx << " = ";
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Generate declaration.
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (in.dataType)
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT:		op << de::floatToString(s_constInFloat[inNdx], 1);					break;
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC2:	writeVectorConstructor<2>(op, s_constInVec2[inNdx]);				break;
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC3:	writeVectorConstructor<3>(op, s_constInVec3[inNdx]);				break;
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_VEC4:	writeVectorConstructor<4>(op, s_constInVec4[inNdx]);				break;
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT2:	writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2[inNdx]));		break;
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT3:	writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3[inNdx]));		break;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case TYPE_FLOAT_MAT4:	writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4[inNdx]));		break;
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(DE_FALSE);
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << ";\n";
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			inValue = string("in") + de::toString(inNdx);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n"
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "void main (void)\n"
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "{\n"
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< "	gl_Position = a_position;\n";
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n"
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 << "void main (void)\n"
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		 << "{\n";
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	gl_FragColor = v_color;\n";
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vtx << "	v_" << *copyIter << " = " << "a_" << *copyIter << ";\n";
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Operation.
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (getOperationNature(m_op))
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_PURE:
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = inValue0;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_MUTATING:
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0 << ";\n";
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = "tmpValue";
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONNATURE_ASSIGNMENT:
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue0 = inValue0;
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			operationValue1 = inValue1;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (getOperationType(m_op))
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_BINARY_OPERATOR:
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
955