/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 * Copyright (c) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Shader matrix arithmetic tests.
 *
 * Variables:
 *  + operation
 *    - mat OP mat
 *    - mat OP vec
 *    - vec OP mat
 *    - mat OP scalar
 *    - OP ( mat )
 *    - vec OP vec
 *    - OP mat
 *  + matrix source
 *    - constant (ctor)
 *    - uniform
 *    - vertex input
 *    - fragment input
 *//*--------------------------------------------------------------------*/

#include "vktShaderRenderMatrixTests.hpp"

#include "vktShaderRender.hpp"
#include "tcuVector.hpp"
#include "tcuMatrix.hpp"
#include "tcuMatrixUtil.hpp"
#include "deStringUtil.hpp"

namespace vkt
{
namespace sr
{
namespace
{

using std::string;
using std::vector;
using namespace glu;

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::Mat2;
using tcu::Mat2x3;
using tcu::Mat2x4;
using tcu::Mat3x2;
using tcu::Mat3;
using tcu::Mat3x4;
using tcu::Mat4x2;
using tcu::Mat4x3;
using tcu::Mat4;

// Uniform / constant values for tests.
// \note Input1 should not contain 0 components as it is used as divisor in div cases.
static const float	s_constInFloat[2]	= { 0.5f, -0.2f };
static const Vec2	s_constInVec2[2]	= { Vec2(1.2f, 0.5f), Vec2(0.5f, 1.0f) };
static const Vec3	s_constInVec3[2]	= { Vec3(1.1f, 0.1f, 0.5f), Vec3(-0.2f, 0.5f, 0.8f) };
static const Vec4	s_constInVec4[2]	= { Vec4(1.4f, 0.2f, -0.5f, 0.7f), Vec4(0.2f, -1.0f, 0.5f, 0.8f) };

static const float s_constInMat2x2[2][4] =
{
	{
		-0.1f,  1.0f,
		-0.2f,  0.0f,
	},
	{
		 0.8f,  0.1f,
		 0.5f, -0.9f,
	},
};
static const float s_constInMat3x2[2][6] =
{
	{
		 0.8f, -0.3f,  0.3f,
		 1.0f,  1.2f, -1.2f,
	},
	{
		 1.2f, -1.0f,  0.5f,
		-0.8f,  1.1f,  0.3f,
	},
};
static const float s_constInMat4x2[2][8] =
{
	{
		-0.2f,  0.5f, 0.0f, -1.0f,
		 1.2f, -0.5f, 0.3f, -0.9f,
	},
	{
		1.0f,  0.1f, -1.1f,  0.6f,
		0.8f, -1.2f, -1.1f,  0.7f,
	},
};
static const float s_constInMat2x3[2][6] =
{
	{
		-0.6f, -0.1f,
		-0.7f, -1.2f,
		-0.2f,  0.0f,
	},
	{
		 1.1f,  0.6f,
		 0.8f,  1.0f,
		 0.7f,  0.1f,
	},
};
static const float s_constInMat3x3[2][9] =
{
	{
		-0.2f,  1.1f, 1.2f,
		-1.0f,  1.2f, 0.5f,
		 0.7f, -0.2f, 1.0f,
	},
	{
		-0.1f, -0.1f,  0.1f,
		-0.1f, -0.2f,  1.0f,
		-0.5f,  0.1f, -0.4f,
	},
};
static const float s_constInMat4x3[2][12] =
{
	{
		-0.9f,  0.0f,  0.6f,  0.2f,
		 0.9f, -0.1f, -0.3f, -0.7f,
		-0.1f,  0.1f,  1.0f,  0.0f,
	},
	{
		 0.5f,  0.7f,  0.7f,  1.2f,
		 1.1f,  0.1f,  1.0f, -1.0f,
		-0.2f, -0.2f, -0.3f, -0.5f,
	},
};
static const float s_constInMat2x4[2][8] =
{
	{
		-0.6f, -1.1f,
		-0.6f, -0.6f,
		-0.2f, -0.6f,
		-0.1f, -0.1f,
	},
	{
		-1.2f, -1.0f,
		 0.7f, -1.0f,
		 0.7f,  0.7f,
		-0.4f, -0.3f,
	},
};
static const float s_constInMat3x4[2][12] =
{
	{
		 0.6f, -0.4f,  1.2f,
		 0.9f,  0.8f,  0.4f,
		 1.1f,  0.3f,  0.5f,
		-0.2f,  0.0f,  1.1f,
	},
	{
		-0.8f,  1.2f, -0.2f,
		-1.1f, -0.9f, -0.5f,
		-1.2f,  1.0f,  1.2f,
		 0.1f, -0.7f, -0.5f,
	},
};
static const float s_constInMat4x4[2][16] =
{
	{
		 0.3f,  0.9f, -0.2f,  1.0f,
		-0.4f, -0.6f,  0.6f, -1.0f,
		-0.9f, -0.1f,  0.3f, -0.2f,
		-0.3f, -0.9f,  1.0f,  0.1f,
	},
	{
		 0.4f, -0.7f, -0.8f,  0.7f,
		-0.4f, -0.8f,  0.6f, -0.3f,
		 0.7f, -1.0f,  0.1f, -0.3f,
		 0.2f,  0.6f,  0.4f, -1.0f,
	},
};

namespace MatrixCaseUtils
{

enum InputType
{
	INPUTTYPE_CONST = 0,
	INPUTTYPE_UNIFORM,
	INPUTTYPE_DYNAMIC,

	INPUTTYPE_LAST
};

struct ShaderInput
{
	ShaderInput (InputType inputType_, DataType dataType_, Precision precision_)
		: inputType	(inputType_)
		, dataType	(dataType_)
		, precision	(precision_)
	{
	}

	InputType		inputType;
	DataType		dataType;
	Precision		precision;
};

enum MatrixOp
{
	OP_ADD = 0,
	OP_SUB,
	OP_MUL,
	OP_DIV,
	OP_COMP_MUL,
	OP_OUTER_PRODUCT,
	OP_TRANSPOSE,
	OP_INVERSE,
	OP_DETERMINANT,
	OP_UNARY_PLUS,
	OP_NEGATION,
	OP_PRE_INCREMENT,
	OP_PRE_DECREMENT,
	OP_POST_INCREMENT,
	OP_POST_DECREMENT,
	OP_ADD_INTO,
	OP_SUBTRACT_FROM,
	OP_MULTIPLY_INTO,
	OP_DIVIDE_INTO,
	OP_LAST
};

// Type traits.

template <int DataT>
struct TypeTraits;

#define DECLARE_TYPE_TRAIT(DATATYPE, TYPE)	\
template<>									\
struct TypeTraits<DATATYPE> {				\
	typedef TYPE Type;						\
}

DECLARE_TYPE_TRAIT(TYPE_FLOAT,			float);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC2,		tcu::Vec2);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC3,		tcu::Vec3);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_VEC4,		tcu::Vec4);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2,		tcu::Mat2);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X3,	tcu::Mat2x3);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT2X4,	tcu::Mat2x4);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X2,	tcu::Mat3x2);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3,		tcu::Mat3);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT3X4,	tcu::Mat3x4);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X2,	tcu::Mat4x2);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4X3,	tcu::Mat4x3);
DECLARE_TYPE_TRAIT(TYPE_FLOAT_MAT4,		tcu::Mat4);

// Operation info

enum OperationType
{
	OPERATIONTYPE_BINARY_OPERATOR = 0,
	OPERATIONTYPE_BINARY_FUNCTION,
	OPERATIONTYPE_UNARY_PREFIX_OPERATOR,
	OPERATIONTYPE_UNARY_POSTFIX_OPERATOR,
	OPERATIONTYPE_UNARY_FUNCTION,
	OPERATIONTYPE_ASSIGNMENT,

	OPERATIONTYPE_LAST
};

static const char* getOperationName (MatrixOp op)
{
	switch (op)
	{
		case OP_ADD:			return "+";
		case OP_SUB:			return "-";
		case OP_MUL:			return "*";
		case OP_DIV:			return "/";
		case OP_COMP_MUL:		return "matrixCompMult";
		case OP_OUTER_PRODUCT:	return "outerProduct";
		case OP_TRANSPOSE:		return "transpose";
		case OP_INVERSE:		return "inverse";
		case OP_DETERMINANT:	return "determinant";
		case OP_UNARY_PLUS:		return "+";
		case OP_NEGATION:		return "-";
		case OP_PRE_INCREMENT:	return "++";
		case OP_PRE_DECREMENT:	return "--";
		case OP_POST_INCREMENT:	return "++";
		case OP_POST_DECREMENT:	return "--";
		case OP_ADD_INTO:		return "+=";
		case OP_SUBTRACT_FROM:	return "-=";
		case OP_MULTIPLY_INTO:	return "*=";
		case OP_DIVIDE_INTO:	return "/=";

		default:
			DE_ASSERT(DE_FALSE);
			return "";
	}
}

static OperationType getOperationType (MatrixOp op)
{
	switch (op)
	{
		case OP_ADD:			return OPERATIONTYPE_BINARY_OPERATOR;
		case OP_SUB:			return OPERATIONTYPE_BINARY_OPERATOR;
		case OP_MUL:			return OPERATIONTYPE_BINARY_OPERATOR;
		case OP_DIV:			return OPERATIONTYPE_BINARY_OPERATOR;
		case OP_COMP_MUL:		return OPERATIONTYPE_BINARY_FUNCTION;
		case OP_OUTER_PRODUCT:	return OPERATIONTYPE_BINARY_FUNCTION;
		case OP_TRANSPOSE:		return OPERATIONTYPE_UNARY_FUNCTION;
		case OP_INVERSE:		return OPERATIONTYPE_UNARY_FUNCTION;
		case OP_DETERMINANT:	return OPERATIONTYPE_UNARY_FUNCTION;
		case OP_UNARY_PLUS:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
		case OP_NEGATION:		return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
		case OP_PRE_INCREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
		case OP_PRE_DECREMENT:	return OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
		case OP_POST_INCREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
		case OP_POST_DECREMENT:	return OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
		case OP_ADD_INTO:		return OPERATIONTYPE_ASSIGNMENT;
		case OP_SUBTRACT_FROM:	return OPERATIONTYPE_ASSIGNMENT;
		case OP_MULTIPLY_INTO:	return OPERATIONTYPE_ASSIGNMENT;
		case OP_DIVIDE_INTO:	return OPERATIONTYPE_ASSIGNMENT;
		default:
			DE_ASSERT(DE_FALSE);
			return OPERATIONTYPE_LAST;
	}
}

enum TestMatrixType
{
	TESTMATRIXTYPE_DEFAULT = 0,
	TESTMATRIXTYPE_NEGATED,
	TESTMATRIXTYPE_INCREMENTED,
	TESTMATRIXTYPE_DECREMENTED,
	TESTMATRIXTYPE_NEGATED_INCREMENTED,
	TESTMATRIXTYPE_INCREMENTED_LESS,

	TESTMATRIXTYPE_LAST
};

static TestMatrixType getOperationTestMatrixType (MatrixOp op)
{
	switch(op)
	{
		case OP_ADD:			return TESTMATRIXTYPE_DEFAULT;
		case OP_SUB:			return TESTMATRIXTYPE_DEFAULT;
		case OP_MUL:			return TESTMATRIXTYPE_DEFAULT;
		case OP_DIV:			return TESTMATRIXTYPE_DEFAULT;
		case OP_COMP_MUL:		return TESTMATRIXTYPE_DEFAULT;
		case OP_OUTER_PRODUCT:	return TESTMATRIXTYPE_DEFAULT;
		case OP_TRANSPOSE:		return TESTMATRIXTYPE_DEFAULT;
		case OP_INVERSE:		return TESTMATRIXTYPE_DEFAULT;
		case OP_DETERMINANT:	return TESTMATRIXTYPE_DEFAULT;
		case OP_UNARY_PLUS:		return TESTMATRIXTYPE_DECREMENTED;
		case OP_NEGATION:		return TESTMATRIXTYPE_NEGATED_INCREMENTED;
		case OP_PRE_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
		case OP_PRE_DECREMENT:	return TESTMATRIXTYPE_INCREMENTED;
		case OP_POST_INCREMENT:	return TESTMATRIXTYPE_NEGATED;
		case OP_POST_DECREMENT:	return TESTMATRIXTYPE_DEFAULT;
		case OP_ADD_INTO:		return TESTMATRIXTYPE_DEFAULT;
		case OP_SUBTRACT_FROM:	return TESTMATRIXTYPE_INCREMENTED_LESS;
		case OP_MULTIPLY_INTO:	return TESTMATRIXTYPE_NEGATED;
		case OP_DIVIDE_INTO:	return TESTMATRIXTYPE_DECREMENTED;

		default:
			DE_ASSERT(DE_FALSE);
			return TESTMATRIXTYPE_LAST;
	}
}

static bool isOperationBinary (MatrixOp op)
{
	return getOperationType(op) == OPERATIONTYPE_BINARY_OPERATOR ||
	       getOperationType(op) == OPERATIONTYPE_BINARY_FUNCTION ||
	       getOperationType(op) == OPERATIONTYPE_ASSIGNMENT;
}

static bool isOperationMatrixScalar (MatrixOp op)
{
	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV;
}

static bool isOperationMatrixVector (MatrixOp op)
{
	return op == OP_MUL;
}

static bool isOperationArithmeticMatrixMatrix (MatrixOp op)
{
	return op == OP_MUL;
}

static bool isOperationComponentwiseMatrixMatrix (MatrixOp op)
{
	return op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV || op == OP_COMP_MUL;
}

static bool isOperationVectorVector (MatrixOp op)
{
	return op == OP_OUTER_PRODUCT;
}

static bool isOperationUnaryAnyMatrix (MatrixOp op)
{
	return  op == OP_TRANSPOSE			 ||
			op == OP_UNARY_PLUS			 ||
			op == OP_NEGATION			 ||
			op == OP_PRE_INCREMENT		 ||
			op == OP_PRE_DECREMENT		 ||
			op == OP_POST_INCREMENT		 ||
			op == OP_POST_DECREMENT;
}

static bool isOperationUnarySymmetricMatrix (MatrixOp op)
{
	return op == OP_INVERSE || op == OP_DETERMINANT;
}

static bool isOperationValueModifying (MatrixOp op)
{
	return  op == OP_PRE_INCREMENT		 ||
			op == OP_PRE_DECREMENT		 ||
			op == OP_POST_INCREMENT		 ||
			op == OP_POST_DECREMENT;
}

static bool isOperationAssignment (MatrixOp op)
{
	return  op == OP_ADD_INTO		 ||
			op == OP_SUBTRACT_FROM	 ||
			op == OP_MULTIPLY_INTO	 ||
			op == OP_DIVIDE_INTO;
}

static bool isOperationAssignmentAnyMatrix (MatrixOp op)
{
	return  op == OP_ADD_INTO		 ||
			op == OP_SUBTRACT_FROM	 ||
			op == OP_DIVIDE_INTO;
}

static bool isOperationAssignmentSymmetricMatrix (MatrixOp op)
{
	return op == OP_MULTIPLY_INTO;
}

// Operation nature

enum OperationNature
{
	OPERATIONNATURE_PURE = 0,
	OPERATIONNATURE_MUTATING,
	OPERATIONNATURE_ASSIGNMENT,

	OPERATIONNATURE_LAST
};

static OperationNature getOperationNature (MatrixOp op)
{
	if (isOperationAssignment(op))
		return OPERATIONNATURE_ASSIGNMENT;

	if (isOperationValueModifying(op))
		return OPERATIONNATURE_MUTATING;

	return OPERATIONNATURE_PURE;
}

// Input value loader.

template <int InputT, int DataT>
typename TypeTraits<DataT>::Type getInputValue (const ShaderEvalContext& evalCtx, int inputNdx);

template <> inline float		getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInFloat[inputNdx];	}
template <> inline tcu::Vec2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec2[inputNdx];	}
template <> inline tcu::Vec3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec3[inputNdx];	}
template <> inline tcu::Vec4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_VEC4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return s_constInVec4[inputNdx];	}

template <> inline tcu::Mat2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2(s_constInMat2x2[inputNdx]);		}
template <> inline tcu::Mat2x3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2X3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x3(s_constInMat2x3[inputNdx]);	}
template <> inline tcu::Mat2x4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT2X4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat2x4(s_constInMat2x4[inputNdx]);	}
template <> inline tcu::Mat3x2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3X2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x2(s_constInMat3x2[inputNdx]);	}
template <> inline tcu::Mat3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3(s_constInMat3x3[inputNdx]);		}
template <> inline tcu::Mat3x4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT3X4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat3x4(s_constInMat3x4[inputNdx]);	}
template <> inline tcu::Mat4x2	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4X2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x2(s_constInMat4x2[inputNdx]);	}
template <> inline tcu::Mat4x3	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4X3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4x3(s_constInMat4x3[inputNdx]);	}
template <> inline tcu::Mat4	getInputValue<INPUTTYPE_CONST,		TYPE_FLOAT_MAT4>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(evalCtx); return tcu::Mat4(s_constInMat4x4[inputNdx]);		}

template <> inline float		getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT>			(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.x();					}
template <> inline tcu::Vec2	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC2>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1);			}
template <> inline tcu::Vec3	getInputValue<INPUTTYPE_DYNAMIC,	TYPE_FLOAT_VEC3>	(const ShaderEvalContext& evalCtx, int inputNdx) { DE_UNREF(inputNdx); return evalCtx.coords.swizzle(0, 1, 2);		}
template <> 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);	}

template <> inline tcu::Mat2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat2 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
	return m;
}

template <> inline tcu::Mat2x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X3> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat2x3 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
	return m;
}

template <> inline tcu::Mat2x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT2X4> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat2x4 m;
	m.setColumn(0, evalCtx.in[0]);
	m.setColumn(1, evalCtx.in[1]);
	return m;
}

template <> inline tcu::Mat3x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X2> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat3x2 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
	m.setColumn(2, evalCtx.in[2].swizzle(0,1));
	return m;
}

template <> inline tcu::Mat3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat3 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
	m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
	return m;
}

template <> inline tcu::Mat3x4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT3X4> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat3x4 m;
	m.setColumn(0, evalCtx.in[0]);
	m.setColumn(1, evalCtx.in[1]);
	m.setColumn(2, evalCtx.in[2]);
	return m;
}

template <> inline tcu::Mat4x2 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X2> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat4x2 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1));
	m.setColumn(2, evalCtx.in[2].swizzle(0,1));
	m.setColumn(3, evalCtx.in[3].swizzle(0,1));
	return m;
}

template <> inline tcu::Mat4x3 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4X3> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat4x3 m;
	m.setColumn(0, evalCtx.in[0].swizzle(0,1,2));
	m.setColumn(1, evalCtx.in[1].swizzle(0,1,2));
	m.setColumn(2, evalCtx.in[2].swizzle(0,1,2));
	m.setColumn(3, evalCtx.in[3].swizzle(0,1,2));
	return m;
}

template <> inline tcu::Mat4 getInputValue<INPUTTYPE_DYNAMIC, TYPE_FLOAT_MAT4> (const ShaderEvalContext& evalCtx, int inputNdx)
{
	DE_UNREF(inputNdx); // Not used.
	tcu::Mat4 m;
	m.setColumn(0, evalCtx.in[0]);
	m.setColumn(1, evalCtx.in[1]);
	m.setColumn(2, evalCtx.in[2]);
	m.setColumn(3, evalCtx.in[3]);
	return m;
}

// Reduction from expression result to vec3.

inline tcu::Vec3 reduceToVec3 (const tcu::Vec2& value)		{ return value.swizzle(0,1,0); }
inline tcu::Vec3 reduceToVec3 (const tcu::Vec3& value)		{ return value; }
inline tcu::Vec3 reduceToVec3 (const tcu::Vec4& value)		{ return tcu::Vec3(value.x(), value.y(), value.z()+value.w()); }
inline tcu::Vec3 reduceToVec3 (const tcu::Mat2& value)		{ return tcu::Vec3(value(0, 0), value(0, 1), value(1, 0)+value(1, 1)); }
inline tcu::Vec3 reduceToVec3 (const tcu::Mat2x3& value)	{ return value.getColumn(0) + value.getColumn(1); }
inline tcu::Vec3 reduceToVec3 (const tcu::Mat2x4& value)	{ return value.getColumn(0).swizzle(0,1,2) + value.getColumn(1).swizzle(1,2,3); }
inline 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)); }
inline tcu::Vec3 reduceToVec3 (const tcu::Mat3& value)		{ return value.getColumn(0) + value.getColumn(1) + value.getColumn(2); }
inline 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); }
inline 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)); }
inline tcu::Vec3 reduceToVec3 (const tcu::Mat4x3& value)	{ return value.getColumn(0) + value.getColumn(1) + value.getColumn(2) + value.getColumn(3); }
inline 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); }

// matrixCompMult

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Rows, Cols> matrixCompMult (const tcu::Matrix<T, Rows, Cols>& a, const tcu::Matrix<T, Rows, Cols>& b)
{
	tcu::Matrix<T, Rows, Cols> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(r,c) = a(r,c) * b(r, c);

	return retVal;
}

// transpose

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Cols, Rows> transpose (const tcu::Matrix<T, Rows, Cols>& mat)
{
	tcu::Matrix<T, Cols, Rows> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(c, r) = mat(r, c);

	return retVal;
}

// outerProduct

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Cols, Rows> outerProduct (const tcu::Vector<T, Cols>& a, const tcu::Vector<T, Rows>& b)
{
	tcu::Matrix<T, Rows, Cols> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(r,c) = a[c] * b[r];

	return transpose(retVal); // to gl-form (column-major)
}

// Determinant

template <int Size>
float determinant (const tcu::Matrix<float, Size, Size>& mat);

template <>
float determinant<2> (const tcu::Matrix<float, 2, 2>& mat)
{
	return mat(0,0) * mat(1,1) - mat(1,0) * mat(0,1);
}

template <>
float determinant<3> (const tcu::Matrix<float, 3, 3>& mat)
{
	return	+ mat(0,0) * mat(1,1) * mat(2,2)
			+ mat(0,1) * mat(1,2) * mat(2,0)
			+ mat(0,2) * mat(1,0) * mat(2,1)
			- mat(0,0) * mat(1,2) * mat(2,1)
			- mat(0,1) * mat(1,0) * mat(2,2)
			- mat(0,2) * mat(1,1) * mat(2,0);
}

template <>
float determinant<4> (const tcu::Matrix<float, 4, 4>& mat)
{
	const float minorMatrices[4][3*3] =
	{
		{
			mat(1,1),	mat(2,1),	mat(3,1),
			mat(1,2),	mat(2,2),	mat(3,2),
			mat(1,3),	mat(2,3),	mat(3,3),
		},
		{
			mat(1,0),	mat(2,0),	mat(3,0),
			mat(1,2),	mat(2,2),	mat(3,2),
			mat(1,3),	mat(2,3),	mat(3,3),
		},
		{
			mat(1,0),	mat(2,0),	mat(3,0),
			mat(1,1),	mat(2,1),	mat(3,1),
			mat(1,3),	mat(2,3),	mat(3,3),
		},
		{
			mat(1,0),	mat(2,0),	mat(3,0),
			mat(1,1),	mat(2,1),	mat(3,1),
			mat(1,2),	mat(2,2),	mat(3,2),
		}
	};

	return	+ mat(0,0) * determinant(tcu::Mat3(minorMatrices[0]))
			- mat(0,1) * determinant(tcu::Mat3(minorMatrices[1]))
			+ mat(0,2) * determinant(tcu::Mat3(minorMatrices[2]))
			- mat(0,3) * determinant(tcu::Mat3(minorMatrices[3]));
}

// Inverse

template <int Size>
tcu::Matrix<float, Size, Size> inverse (const tcu::Matrix<float, Size, Size>& mat);

template <>
tcu::Matrix<float, 2, 2> inverse<2> (const tcu::Matrix<float, 2, 2>& mat)
{
	const float					det		= determinant(mat);
	tcu::Matrix<float, 2, 2>	retVal;

	DE_ASSERT(det != 0.0f);

	retVal(0, 0) =  mat(1, 1) / det;
	retVal(0, 1) = -mat(0, 1) / det;
	retVal(1, 0) = -mat(1, 0) / det;
	retVal(1, 1) =  mat(0, 0) / det;

	return retVal;
}

template <>
tcu::Matrix<float, 3, 3> inverse<3> (const tcu::Matrix<float, 3, 3>& mat)
{
	// Blockwise inversion

	DE_ASSERT(determinant(mat) != 0.0f);

	const float areaA[2*2] =
	{
		mat(0,0),	mat(0,1),
		mat(1,0),	mat(1,1)
	};
	const float areaB[2] =
	{
		mat(0,2),
		mat(1,2),
	};
	const float areaC[2] =
	{
		mat(2,0),	mat(2,1),
	};
	const float areaD[1] =
	{
		mat(2,2)
	};
	const float nullField[4] = { 0.0f };

	const tcu::Matrix<float, 2, 2>	invA = inverse(tcu::Matrix<float, 2, 2>(areaA));
	const tcu::Matrix<float, 2, 1>	matB =         tcu::Matrix<float, 2, 1>(areaB);
	const tcu::Matrix<float, 1, 2>	matC =         tcu::Matrix<float, 1, 2>(areaC);
	const tcu::Matrix<float, 1, 1>	matD =         tcu::Matrix<float, 1, 1>(areaD);

	const float						schurComplement = 1.0f / (matD - matC*invA*matB)(0,0);
	const tcu::Matrix<float, 2, 2>	zeroMat         = Mat2(nullField);

	const tcu::Matrix<float, 2, 2>	blockA = invA + invA*matB*schurComplement*matC*invA;
	const tcu::Matrix<float, 2, 1>	blockB = (zeroMat-invA)*matB*schurComplement;
	const tcu::Matrix<float, 1, 2>	blockC = matC*invA*(-schurComplement);
	const float						blockD = schurComplement;

	const float result[3*3] =
	{
		blockA(0,0),	blockA(0,1),	blockB(0,0),
		blockA(1,0),	blockA(1,1),	blockB(1,0),
		blockC(0,0),	blockC(0,1),	blockD,
	};

	return Mat3(result);
}

template <>
tcu::Matrix<float, 4, 4> inverse<4> (const tcu::Matrix<float, 4, 4>& mat)
{
	// Blockwise inversion

	DE_ASSERT(determinant(mat) != 0.0f);

	const float areaA[2*2] =
	{
		mat(0,0),	mat(0,1),
		mat(1,0),	mat(1,1)
	};
	const float areaB[2*2] =
	{
		mat(0,2),	mat(0,3),
		mat(1,2),	mat(1,3)
	};
	const float areaC[2*2] =
	{
		mat(2,0),	mat(2,1),
		mat(3,0),	mat(3,1)
	};
	const float areaD[2*2] =
	{
		mat(2,2),	mat(2,3),
		mat(3,2),	mat(3,3)
	};
	const float nullField[4] = { 0.0f };

	const tcu::Matrix<float, 2, 2> invA = inverse(Mat2(areaA));
	const tcu::Matrix<float, 2, 2> matB =         Mat2(areaB);
	const tcu::Matrix<float, 2, 2> matC =         Mat2(areaC);
	const tcu::Matrix<float, 2, 2> matD =         Mat2(areaD);

	const tcu::Matrix<float, 2, 2> schurComplement = inverse(matD - matC*invA*matB);
	const tcu::Matrix<float, 2, 2> zeroMat         = Mat2(nullField);

	const tcu::Matrix<float, 2, 2> blockA = invA + invA*matB*schurComplement*matC*invA;
	const tcu::Matrix<float, 2, 2> blockB = (zeroMat-invA)*matB*schurComplement;
	const tcu::Matrix<float, 2, 2> blockC = (zeroMat-schurComplement)*matC*invA;
	const tcu::Matrix<float, 2, 2> blockD = schurComplement;

	const float result[4*4] =
	{
		blockA(0,0),	blockA(0,1),	blockB(0,0),	blockB(0,1),
		blockA(1,0),	blockA(1,1),	blockB(1,0),	blockB(1,1),
		blockC(0,0),	blockC(0,1),	blockD(0,0),	blockD(0,1),
		blockC(1,0),	blockC(1,1),	blockD(1,0),	blockD(1,1),
	};

	return Mat4(result);
}

// negate

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Rows, Cols> negate (const tcu::Matrix<T, Rows, Cols>& mat)
{
	tcu::Matrix<T, Rows, Cols> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(r,c) = -mat(r, c);

	return retVal;
}

// increment/decrement

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Rows, Cols> increment (const tcu::Matrix<T, Rows, Cols>& mat)
{
	tcu::Matrix<T, Rows, Cols> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(r,c) = mat(r, c) + 1.0f;

	return retVal;
}

template <typename T, int Rows, int Cols>
tcu::Matrix<T, Rows, Cols> decrement (const tcu::Matrix<T, Rows, Cols>& mat)
{
	tcu::Matrix<T, Rows, Cols> retVal;

	for (int r = 0; r < Rows; ++r)
		for (int c = 0; c < Cols; ++c)
			retVal(r,c) = mat(r, c) - 1.0f;

	return retVal;
}

// Evaluator template.

typedef void (*MatrixShaderEvalFunc) (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type);

template <int Op, int In0DataType, int In1DataType>
struct Evaluator;

template <int In0DataType, int In1DataType>
struct Evaluator<OP_ADD, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 + in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_SUB, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 - in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_MUL, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 * in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_DIV, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 / in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_COMP_MUL, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(matrixCompMult(in0, in1));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_OUTER_PRODUCT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(outerProduct(in0, in1));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_TRANSPOSE, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		evalCtx.color.xyz() = reduceToVec3(transpose(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_INVERSE, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		evalCtx.color.xyz() = reduceToVec3(inverse(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_DETERMINANT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		evalCtx.color.xyz() = Vec3(determinant(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_UNARY_PLUS, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		evalCtx.color.xyz() = reduceToVec3(in0);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_NEGATION, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		evalCtx.color.xyz() = reduceToVec3(negate(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_PRE_INCREMENT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);

		// modifying reduction: sum modified value too
		evalCtx.color.xyz() = reduceToVec3(increment(in0)) + reduceToVec3(increment(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_PRE_DECREMENT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);

		// modifying reduction: sum modified value too
		evalCtx.color.xyz() = reduceToVec3(decrement(in0)) + reduceToVec3(decrement(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_POST_INCREMENT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);

		// modifying reduction: sum modified value too
		evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(increment(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_POST_DECREMENT, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		DE_UNREF(in1Type);
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);

		// modifying reduction: sum modified value too
		evalCtx.color.xyz() = reduceToVec3(in0) + reduceToVec3(decrement(in0));
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_ADD_INTO, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 + in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_SUBTRACT_FROM, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 - in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_MULTIPLY_INTO, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 * in1);
	}
};

template <int In0DataType, int In1DataType>
struct Evaluator<OP_DIVIDE_INTO, In0DataType, In1DataType>
{
	static void evaluate (ShaderEvalContext& evalCtx, InputType in0Type, InputType in1Type)
	{
		typename TypeTraits<In0DataType>::Type	in0	= (in0Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In0DataType>(evalCtx, 0)
																				     : getInputValue<INPUTTYPE_CONST,	In0DataType>(evalCtx, 0);
		typename TypeTraits<In1DataType>::Type	in1	= (in1Type == INPUTTYPE_DYNAMIC) ? getInputValue<INPUTTYPE_DYNAMIC, In1DataType>(evalCtx, 1)
																				     : getInputValue<INPUTTYPE_CONST,	In1DataType>(evalCtx, 1);
		evalCtx.color.xyz() = reduceToVec3(in0 / in1);
	}
};

MatrixShaderEvalFunc getEvalFunc (const ShaderInput& in0, const ShaderInput& in1, MatrixOp op)
{
	// Evaluator is selected based on op and input data types.
	// For efficient lookup the types and op enums are packed together to form a 19-bit key:
	// [18..14 OP] [13..7 TYPE0] [6..0 TYPE1]

	DE_STATIC_ASSERT(TYPE_LAST	<= (1<<7));
	DE_STATIC_ASSERT(OP_LAST	<= (1<<5));

#define PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE)	(((OP) << 14) | ((IN0DATATYPE) << 7) | (IN1DATATYPE))

#define MAKE_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE)	\
	case PACK_EVAL_CASE(OP, IN0DATATYPE, IN1DATATYPE):	\
		return Evaluator<OP, IN0DATATYPE, IN1DATATYPE>::evaluate

#define MAKE_SCALAR_OPS(IN0DATATYPE, IN1DATATYPE)		\
	MAKE_EVAL_CASE(OP_ADD, IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_SUB, IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_DIV, IN0DATATYPE, IN1DATATYPE)

#define MAKE_CWISE_OPS(IN0DATATYPE, IN1DATATYPE)			\
	MAKE_EVAL_CASE(OP_ADD,		IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_SUB,		IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_DIV,		IN0DATATYPE, IN1DATATYPE);	\
	MAKE_EVAL_CASE(OP_COMP_MUL,	IN0DATATYPE, IN1DATATYPE)

#define MAKE_MUL_OP(IN0DATATYPE, IN1DATATYPE)			\
	MAKE_EVAL_CASE(OP_MUL, IN0DATATYPE, IN1DATATYPE)

#define MAKE_VECVEC_OP(IN0DATATYPE, IN1DATATYPE)			\
	MAKE_EVAL_CASE(OP_OUTER_PRODUCT, IN0DATATYPE, IN1DATATYPE)

#define MAKE_UNARY_OP(IN0DATATYPE)								\
	MAKE_EVAL_CASE(OP_TRANSPOSE,		IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_UNARY_PLUS,		IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_NEGATION,			IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_PRE_INCREMENT,	IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_PRE_DECREMENT,	IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_POST_INCREMENT,	IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_POST_DECREMENT,	IN0DATATYPE, TYPE_LAST)

#define MAKE_UNARY_SYMMETRIC_OP(IN0DATATYPE)					\
	MAKE_UNARY_OP(IN0DATATYPE);									\
	MAKE_EVAL_CASE(OP_DETERMINANT,	IN0DATATYPE, TYPE_LAST);	\
	MAKE_EVAL_CASE(OP_INVERSE,		IN0DATATYPE, TYPE_LAST)

#define MAKE_ASSIGNMENT_OP(IN0DATATYPE)								\
	MAKE_EVAL_CASE(OP_ADD_INTO,			IN0DATATYPE, IN0DATATYPE);	\
	MAKE_EVAL_CASE(OP_SUBTRACT_FROM,	IN0DATATYPE, IN0DATATYPE);	\
	MAKE_EVAL_CASE(OP_DIVIDE_INTO,		IN0DATATYPE, IN0DATATYPE)

#define MAKE_ASSIGNMENT_SYMMETRIC_OP(IN0DATATYPE)					\
	MAKE_ASSIGNMENT_OP(IN0DATATYPE);								\
	MAKE_EVAL_CASE(OP_MULTIPLY_INTO,	IN0DATATYPE, IN0DATATYPE)

	switch (PACK_EVAL_CASE(op, in0.dataType, in1.dataType))
	{
		// Matrix-scalar.
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT);
		MAKE_SCALAR_OPS(TYPE_FLOAT_MAT4,	TYPE_FLOAT);

		// Matrix-vector.
		MAKE_MUL_OP(TYPE_FLOAT_MAT2,	TYPE_FLOAT_VEC2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT_VEC2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT_VEC2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT_VEC3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3,	TYPE_FLOAT_VEC3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT_VEC3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT_VEC4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT_VEC4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4,	TYPE_FLOAT_VEC4);

		// Vector-matrix.
		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT2);
		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT2X3);
		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT2X4);
		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT3X2);
		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT3);
		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT3X4);
		MAKE_MUL_OP(TYPE_FLOAT_VEC2, TYPE_FLOAT_MAT4X2);
		MAKE_MUL_OP(TYPE_FLOAT_VEC3, TYPE_FLOAT_MAT4X3);
		MAKE_MUL_OP(TYPE_FLOAT_VEC4, TYPE_FLOAT_MAT4);

		// Matrix-matrix.
		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT3X2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2,		TYPE_FLOAT_MAT4X2);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X3,	TYPE_FLOAT_MAT2X3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT3X2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X3,		TYPE_FLOAT_MAT4X2);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT2X4,	TYPE_FLOAT_MAT2X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT3X2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT2X4,		TYPE_FLOAT_MAT4X2);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X2,	TYPE_FLOAT_MAT3X2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT2X3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X2,		TYPE_FLOAT_MAT4X3);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT2X3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3,		TYPE_FLOAT_MAT4X3);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT3X4,	TYPE_FLOAT_MAT3X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT2X3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT3X4,		TYPE_FLOAT_MAT4X3);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X2,	TYPE_FLOAT_MAT4X2);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT2X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT3X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X2,		TYPE_FLOAT_MAT4);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4X3,	TYPE_FLOAT_MAT4X3);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT2X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT3X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4X3,		TYPE_FLOAT_MAT4);

		MAKE_CWISE_OPS(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT2X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT3X4);
		MAKE_MUL_OP(TYPE_FLOAT_MAT4,		TYPE_FLOAT_MAT4);

		// Vector-vector.
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC2);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC3);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC2,		TYPE_FLOAT_VEC4);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC2);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC3);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC3,		TYPE_FLOAT_VEC4);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC2);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC3);
		MAKE_VECVEC_OP(TYPE_FLOAT_VEC4,		TYPE_FLOAT_VEC4);

		// Unary Matrix.
		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT2X3);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT2X4);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT3X2);
		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT3X4);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT4X2);
		MAKE_UNARY_OP(TYPE_FLOAT_MAT4X3);
		MAKE_UNARY_SYMMETRIC_OP(TYPE_FLOAT_MAT4);

		// Assignments
		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT2);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X3);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT2X4);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X2);
		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT3);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT3X4);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X2);
		MAKE_ASSIGNMENT_OP(TYPE_FLOAT_MAT4X3);
		MAKE_ASSIGNMENT_SYMMETRIC_OP(TYPE_FLOAT_MAT4);

		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}

#undef PACK_EVAL_CASE
#undef MAKE_EVAL_CASE
#undef MUL_OP
#undef ALL_OPS
#undef MAKE_MAT_SCALAR_VEC_CASES
#undef MAKE_MAT_MAT_CASES
}

// Shader source format utilities.

template <int Size>
void writeVectorConstructor (std::ostream& str, const tcu::Vector<float, Size>& v)
{
	str << "vec" << Size << "(";
	for (int ndx = 0; ndx < Size; ndx++)
	{
		if (ndx != 0)
			str << ", ";
		str << de::floatToString(v[ndx], 1);
	}
	str << ")";
}

template <int Cols, int Rows>
void writeMatrixConstructor (std::ostream& str, const tcu::Matrix<float, Rows, Cols>& m)
{
	if (Rows == Cols)
		str << "mat" << Cols;
	else
		str << "mat" << Cols << "x" << Rows;

	str << "(";
	for (int colNdx = 0; colNdx < Cols; colNdx++)
	{
		for (int rowNdx = 0; rowNdx < Rows; rowNdx++)
		{
			if (rowNdx > 0 || colNdx > 0)
				str << ", ";
			str << de::floatToString(m(rowNdx, colNdx), 1);
		}
	}
	str << ")";
}

} // MatrixCaseUtils

using namespace MatrixCaseUtils;

class MatrixShaderEvaluator : public ShaderEvaluator
{
public:
							MatrixShaderEvaluator	(MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1);

	virtual void			evaluate				(ShaderEvalContext& evalCtx) const;

private:
	MatrixShaderEvalFunc	m_matEvalFunc;
	InputType				m_inType0;
	InputType				m_inType1;
};

MatrixShaderEvaluator::MatrixShaderEvaluator (MatrixShaderEvalFunc evalFunc, InputType inType0, InputType inType1)
	: m_matEvalFunc	(evalFunc)
	, m_inType0		(inType0)
	, m_inType1		(inType1)
{
}

void MatrixShaderEvaluator::evaluate (ShaderEvalContext& evalCtx) const
{
	m_matEvalFunc(evalCtx, m_inType0, m_inType1);
}


BaseAttributeType getAttributeType(const glu::DataType dataType)
{
	switch(dataType)
	{
	case TYPE_FLOAT_MAT2:		return MAT2;
	case TYPE_FLOAT_MAT2X3:		return MAT2x3;
	case TYPE_FLOAT_MAT2X4:		return MAT2x4;
	case TYPE_FLOAT_MAT3X2:		return MAT3x2;
	case TYPE_FLOAT_MAT3:		return MAT3;
	case TYPE_FLOAT_MAT3X4:		return MAT3x4;
	case TYPE_FLOAT_MAT4X2:		return MAT4x2;
	case TYPE_FLOAT_MAT4X3:		return MAT4x3;
	case TYPE_FLOAT_MAT4:		return MAT4;
	default:
		TCU_THROW(InternalError, "Not supported");
		break;
	}
}

// ShaderMatrixInstance

class ShaderMatrixInstance : public ShaderRenderCaseInstance
{
public:
							ShaderMatrixInstance		(Context&				context,
														 bool					isVertex,
														 const ShaderEvaluator&	evaluator,
														 const ShaderInput		in0,
														 const ShaderInput		in1,
														 const MatrixOp			m_op);
	virtual					~ShaderMatrixInstance		(void);

protected:
	virtual void			setupUniforms				(const tcu::Vec4&);

private:
	void					addMatrixUniform			(deUint32 bindingLocation, DataType dataType, const float* dataPtr);

	const ShaderInput		m_in0;
	const ShaderInput		m_in1;
	const MatrixOp			m_op;
};

ShaderMatrixInstance::ShaderMatrixInstance (Context&				context,
											bool					isVertex,
											const ShaderEvaluator&	evaluator,
											const ShaderInput		in0,
											const ShaderInput		in1,
											const MatrixOp			op)
	: ShaderRenderCaseInstance	(context, isVertex, evaluator, DE_NULL, DE_NULL)
	, m_in0						(in0)
	, m_in1						(in1)
	, m_op						(op)
{
	m_userAttribTransforms.resize(4);
	for (int attribNdx = 0; attribNdx < 4; attribNdx++)
	{
		m_userAttribTransforms[attribNdx] = Mat4(0.0f);
		m_userAttribTransforms[attribNdx](                  0, 3) = (op == OP_INVERSE ? -0.5f : 0.2f);	// prevent matrix*vec from going into zero (assuming vec.w != 0).
		m_userAttribTransforms[attribNdx](                  1, 3) = (op == OP_INVERSE ? -1.3f : 0.1f);	// Modified input for OP_INVERSE case, as determinant of final input
		m_userAttribTransforms[attribNdx](                  2, 3) = 0.4f + 0.15f * float(attribNdx);	// matrix is spanning both sides of 0, so 0 (and division by 0) may happen on mediump.
		m_userAttribTransforms[attribNdx](                  3, 3) = (op == OP_INVERSE ? -3.0f : 0.7f);	// Modified OP_INVERSE final input matrix is same signed in whole input range.
		m_userAttribTransforms[attribNdx]((0 + attribNdx) % 4, 0) = 1.0f;
		m_userAttribTransforms[attribNdx]((1 + attribNdx) % 4, 1) = 1.0f;
		m_userAttribTransforms[attribNdx]((2 + attribNdx) % 4, 2) = 1.0f;
		m_userAttribTransforms[attribNdx]((3 + attribNdx) % 4, 3) = 1.0f;
	}

	// prevent bad reference cases such as black result images by fine-tuning used matrices
	if (getOperationTestMatrixType(m_op) != TESTMATRIXTYPE_DEFAULT)
	{
		for (int attribNdx = 0; attribNdx < 4; attribNdx++)
		{
			for (int row = 0; row < 4; row++)
			for (int col = 0; col < 4; col++)
			{
				switch (getOperationTestMatrixType(m_op))
				{
					case TESTMATRIXTYPE_NEGATED:
						m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col);
						break;
					case TESTMATRIXTYPE_INCREMENTED:
						m_userAttribTransforms[attribNdx](row, col) += 0.3f;
						break;
					case TESTMATRIXTYPE_DECREMENTED:
						m_userAttribTransforms[attribNdx](row, col) -= 0.3f;
						break;
					case TESTMATRIXTYPE_NEGATED_INCREMENTED:
						m_userAttribTransforms[attribNdx](row, col) = -m_userAttribTransforms[attribNdx](row, col) + 0.3f;
						break;
					case TESTMATRIXTYPE_INCREMENTED_LESS:
						m_userAttribTransforms[attribNdx](row, col) -= 0.1f;
						break;

					default:
						DE_ASSERT(DE_FALSE);
						break;
				}
			}
		}
	}

	int	numInputs = isOperationBinary(m_op) ? 2 : 1;

	for (int inNdx = 0; inNdx < numInputs; inNdx++)
	{
		const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;

		if (in.inputType == INPUTTYPE_DYNAMIC && isDataTypeMatrix(in.dataType))
		{
			useAttribute(4u + inNdx, getAttributeType(in.dataType));
		}
	}

}

ShaderMatrixInstance::~ShaderMatrixInstance (void)
{
}

void ShaderMatrixInstance::addMatrixUniform(deUint32 bindingLocation, DataType dataType, const float *dataPtr)
{
	Mat4			result;
	const size_t	matrixSize = sizeof(float) * 4 * 4;

	switch(dataType)
	{
		case TYPE_FLOAT_MAT2:
		{
			Mat2 matrix = Mat2(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT2X3:
		{
			Mat2x3 matrix = Mat2x3(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT2X4:
		{
			Mat2x4 matrix = Mat2x4(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT3X2:
		{
			Mat3x2 matrix = Mat3x2(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT3:
		{
			Mat3 matrix = Mat3(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT3X4:
		{
			Mat3x4 matrix = Mat3x4(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT4X2:
		{
			Mat4x2 matrix = Mat4x2(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			result.setColumn(3, matrix.getColumn(3).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT4X3:
		{
			Mat4x3 matrix = Mat4x3(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			result.setColumn(3, matrix.getColumn(3).toWidth<4>());
			break;
		}
		case TYPE_FLOAT_MAT4:
		{
			Mat4 matrix = Mat4(dataPtr);
			result.setColumn(0, matrix.getColumn(0).toWidth<4>());
			result.setColumn(1, matrix.getColumn(1).toWidth<4>());
			result.setColumn(2, matrix.getColumn(2).toWidth<4>());
			result.setColumn(3, matrix.getColumn(3).toWidth<4>());
			break;
		}
		default:
			DE_ASSERT(false);
			break;
	}

	addUniform(bindingLocation, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, matrixSize, result.getColumnMajorData().getPtr());
}

void ShaderMatrixInstance::setupUniforms (const tcu::Vec4&)
{
	const int	numInputs		= isOperationBinary(m_op) ? 2 : 1;
	deUint32	uniformBinding	= 0;

	for (int inNdx = 0; inNdx < numInputs; inNdx++)
	{
		const ShaderInput& in = inNdx > 0 ? m_in1 : m_in0;

		if (in.inputType == INPUTTYPE_UNIFORM)
		{
			switch (in.dataType)
			{
				case TYPE_FLOAT:		addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(float), &s_constInFloat[inNdx]);					break;
				case TYPE_FLOAT_VEC2:	addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec2[inNdx]);			break;
				case TYPE_FLOAT_VEC3:	addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec3[inNdx]);			break;
				case TYPE_FLOAT_VEC4:	addUniform(uniformBinding, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, s_constInVec4[inNdx]);			break;
				// \note GLES3 supports transpose in matrix upload.
				case TYPE_FLOAT_MAT2:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x2[inNdx]);	break;
				case TYPE_FLOAT_MAT2X3:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x3[inNdx]);	break;
				case TYPE_FLOAT_MAT2X4:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat2x4[inNdx]);	break;
				case TYPE_FLOAT_MAT3X2:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x2[inNdx]);	break;
				case TYPE_FLOAT_MAT3:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x3[inNdx]);	break;
				case TYPE_FLOAT_MAT3X4:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat3x4[inNdx]);	break;
				case TYPE_FLOAT_MAT4X2:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x2[inNdx]);	break;
				case TYPE_FLOAT_MAT4X3:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x3[inNdx]);	break;
				case TYPE_FLOAT_MAT4:	addMatrixUniform(uniformBinding, in.dataType, s_constInMat4x4[inNdx]);	break;
				default:
					DE_ASSERT(false);
			}
			uniformBinding++;
		}
	}
}

// ShaderMatrixCase

class ShaderMatrixCase : public ShaderRenderCase
{
public:
							ShaderMatrixCase			(tcu::TestContext&	testCtx,
														 const std::string&	name,
														 const std::string&	desc,
														 const ShaderInput&	in0,
														 const ShaderInput&	in1,
														 const MatrixOp		op,
														 bool				isVertexCase);
							~ShaderMatrixCase			(void);

	virtual TestInstance*	createInstance				(Context& context) const;

protected:
	void					setupShader					(void);
	std::string				genGLSLMatToVec3Reduction	(const glu::DataType& matType, const char* varName);

private:
	const ShaderInput		m_in0;
	const ShaderInput		m_in1;
	const MatrixOp			m_op;
};

ShaderMatrixCase::ShaderMatrixCase (tcu::TestContext&	testCtx,
									const std::string&	name,
									const std::string&	desc,
									const ShaderInput&	in0,
									const ShaderInput&	in1,
									MatrixOp			op,
									bool				isVertexCase)
	: ShaderRenderCase	(testCtx,
						 name,
						 desc,
						 isVertexCase,
						 new MatrixShaderEvaluator(getEvalFunc(in0, in1, op), in0.inputType, in1.inputType),
						 DE_NULL /* uniform setup */,
						 DE_NULL /* attribute setup */)
	, m_in0				(in0)
	, m_in1				(in1)
	, m_op				(op)
{
	setupShader();
}

ShaderMatrixCase::~ShaderMatrixCase (void)
{
}

TestInstance* ShaderMatrixCase::createInstance (Context& context) const
{
	return new ShaderMatrixInstance(context, m_isVertexCase, *m_evaluator, m_in0, m_in1, m_op);
}

void ShaderMatrixCase::setupShader (void)
{
	std::ostringstream	vtx;
	std::ostringstream	frag;
	std::ostringstream&	op				= m_isVertexCase ? vtx : frag;

	bool				isInDynMat0		= isDataTypeMatrix(m_in0.dataType) && m_in0.inputType == INPUTTYPE_DYNAMIC;
	bool				isInDynMat1		= isDataTypeMatrix(m_in1.dataType) && m_in1.inputType == INPUTTYPE_DYNAMIC;
	string				inValue0;
	string				inValue1;
	DataType			resultType		= TYPE_LAST;
	Precision			resultPrec		= m_in0.precision;
	vector<string>		passVars;
	int					numInputs		= (isOperationBinary(m_op)) ? (2) : (1);

	std::string			operationValue0;
	std::string			operationValue1;

	DE_ASSERT(!isInDynMat0 || !isInDynMat1); // Only single dynamic matrix input is allowed.
	DE_UNREF(isInDynMat0 && isInDynMat1);

	// Compute result type.
	if (m_op == OP_MUL && isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
	{
		resultType = getDataTypeMatrix(getDataTypeMatrixNumColumns(m_in1.dataType), getDataTypeMatrixNumRows(m_in0.dataType));
	}
	else if (m_op == OP_OUTER_PRODUCT)
	{
		resultType = getDataTypeMatrix(getDataTypeScalarSize(m_in1.dataType), getDataTypeScalarSize(m_in0.dataType));
	}
	else if (m_op == OP_TRANSPOSE)
	{
		resultType = getDataTypeMatrix(getDataTypeMatrixNumRows(m_in0.dataType), getDataTypeMatrixNumColumns(m_in0.dataType));
	}
	else if (m_op == OP_INVERSE)
	{
		resultType = m_in0.dataType;
	}
	else if (m_op == OP_DETERMINANT)
	{
		resultType = TYPE_FLOAT;
	}
	else if (getOperationType(m_op) == OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
			 getOperationType(m_op) == OPERATIONTYPE_UNARY_POSTFIX_OPERATOR)
	{
		resultType = m_in0.dataType;
	}
	else if (isDataTypeMatrix(m_in0.dataType) && isDataTypeMatrix(m_in1.dataType))
	{
		DE_ASSERT(m_in0.dataType == m_in1.dataType);
		resultType = m_in0.dataType;
	}
	else if (isDataTypeMatrix(m_in0.dataType) || isDataTypeMatrix(m_in1.dataType))
	{
		int			matNdx		= isDataTypeMatrix(m_in0.dataType) ? 0 : 1;
		DataType	matrixType	= matNdx == 0 ? m_in0.dataType : m_in1.dataType;
		DataType	otherType	= matNdx == 0 ? m_in1.dataType : m_in0.dataType;

		if (otherType == TYPE_FLOAT)
			resultType = matrixType;
		else
		{
			DE_ASSERT(isDataTypeVector(otherType));
			resultType = getDataTypeFloatVec(matNdx == 0 ? getDataTypeMatrixNumRows(matrixType) : getDataTypeMatrixNumColumns(matrixType));
		}
	}
	else
	{
		DE_ASSERT(DE_FALSE);
	}

	static const std::string header =
		"#version 310 es\n";

	vtx << header;
	frag << header;

	vtx << "layout(location = 0) in highp vec4 a_position;\n";
	frag << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
	if (m_isVertexCase)
	{
		vtx << "layout(location = 0) out mediump vec4 v_color;\n";
		frag << "layout(location = 0) in mediump vec4 v_color;\n";
	}

	// Input declarations.
	deUint32 uniformBinding = 0;
	deUint32 padding = 0;
	for (int inNdx = 0; inNdx < numInputs; inNdx++)
	{
		const ShaderInput&	in			= inNdx > 0 ? m_in1 : m_in0;
		const char*			precName	= getPrecisionName(in.precision);
		const char*			typeName	= getDataTypeName(in.dataType);
		string&				inValue		= inNdx > 0 ? inValue1 : inValue0;

		if (in.inputType == INPUTTYPE_DYNAMIC)
		{
			if (isDataTypeMatrix(in.dataType))
			{
				vtx << "layout(location = " << 4 + inNdx + padding << ") in " << precName << " " << typeName << " a_";
				// a_matN, v_matN
				vtx << typeName << ";\n";
				if (!m_isVertexCase)
				{
					vtx << "layout(location = " << 1 + inNdx + padding << ") out " << precName << " " << typeName << " v_" << typeName << ";\n";
					frag << "layout(location = " << 1 + inNdx + padding << ") in " << precName << " " << typeName << " v_" << typeName << ";\n";
					passVars.push_back(typeName);
				}

				inValue = string(m_isVertexCase ? "a_" : "v_") + getDataTypeName(in.dataType);
				padding += getDataTypeMatrixNumColumns(in.dataType);
			}
			else
			{
				// a_coords, v_coords
				vtx << "layout(location = 1) in " << precName << " " << typeName << " a_coords;\n";
				if (!m_isVertexCase)
				{
					vtx << "layout(location = " << 1 + padding << ") out " << precName << " " << typeName << " v_coords;\n";
					frag << "layout(location = " << 1 + padding << ") in " << precName << " " << typeName << " v_coords;\n";
					passVars.push_back("coords");
				}

				inValue = m_isVertexCase ? "a_coords" : "v_coords";
			}
		}
		else if (in.inputType == INPUTTYPE_UNIFORM)
		{
			op << "layout(std140, set = 0, binding = " << uniformBinding++ <<  ") uniform buffer"<< inNdx <<" { " << precName << " " << typeName << " u_in" << inNdx << "; };\n";
			inValue = string("u_in") + de::toString(inNdx);
		}
		else if (in.inputType == INPUTTYPE_CONST)
		{
			op << "const " << precName << " " << typeName << " in" << inNdx << " = ";

			// Generate declaration.
			switch (in.dataType)
			{
				case TYPE_FLOAT:		op << de::floatToString(s_constInFloat[inNdx], 1);					break;
				case TYPE_FLOAT_VEC2:	writeVectorConstructor<2>(op, s_constInVec2[inNdx]);				break;
				case TYPE_FLOAT_VEC3:	writeVectorConstructor<3>(op, s_constInVec3[inNdx]);				break;
				case TYPE_FLOAT_VEC4:	writeVectorConstructor<4>(op, s_constInVec4[inNdx]);				break;
				case TYPE_FLOAT_MAT2:	writeMatrixConstructor<2, 2>(op, Mat2(s_constInMat2x2[inNdx]));		break;
				case TYPE_FLOAT_MAT2X3:	writeMatrixConstructor<2, 3>(op, Mat2x3(s_constInMat2x3[inNdx]));	break;
				case TYPE_FLOAT_MAT2X4:	writeMatrixConstructor<2, 4>(op, Mat2x4(s_constInMat2x4[inNdx]));	break;
				case TYPE_FLOAT_MAT3X2:	writeMatrixConstructor<3, 2>(op, Mat3x2(s_constInMat3x2[inNdx]));	break;
				case TYPE_FLOAT_MAT3:	writeMatrixConstructor<3, 3>(op, Mat3(s_constInMat3x3[inNdx]));		break;
				case TYPE_FLOAT_MAT3X4:	writeMatrixConstructor<3, 4>(op, Mat3x4(s_constInMat3x4[inNdx]));	break;
				case TYPE_FLOAT_MAT4X2:	writeMatrixConstructor<4, 2>(op, Mat4x2(s_constInMat4x2[inNdx]));	break;
				case TYPE_FLOAT_MAT4X3:	writeMatrixConstructor<4, 3>(op, Mat4x3(s_constInMat4x3[inNdx]));	break;
				case TYPE_FLOAT_MAT4:	writeMatrixConstructor<4, 4>(op, Mat4(s_constInMat4x4[inNdx]));		break;

				default:
					DE_ASSERT(DE_FALSE);
			}

			op << ";\n";

			inValue = string("in") + de::toString(inNdx);
		}
	}

	vtx << "\n"
		<< "void main (void)\n"
		<< "{\n"
		<< "	gl_Position = a_position;\n";
	frag << "\n"
		 << "void main (void)\n"
		 << "{\n";

	if (m_isVertexCase)
		frag << "	dEQP_FragColor = v_color;\n";
	else
	{
		for (vector<string>::const_iterator copyIter = passVars.begin(); copyIter != passVars.end(); copyIter++)
			vtx << "	v_" << *copyIter << " = " << "a_" << *copyIter << ";\n";
	}

	// Operation.

	switch (getOperationNature(m_op))
	{
		case OPERATIONNATURE_PURE:
			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);

			operationValue0 = inValue0;
			operationValue1 = inValue1;
			break;

		case OPERATIONNATURE_MUTATING:
			DE_ASSERT(getOperationType(m_op) != OPERATIONTYPE_ASSIGNMENT);

			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " tmpValue = " << inValue0 << ";\n";

			operationValue0 = "tmpValue";
			operationValue1 = inValue1;
			break;

		case OPERATIONNATURE_ASSIGNMENT:
			DE_ASSERT(getOperationType(m_op) == OPERATIONTYPE_ASSIGNMENT);

			operationValue0 = inValue0;
			operationValue1 = inValue1;
			break;

		default:
			DE_ASSERT(DE_FALSE);
	}

	switch (getOperationType(m_op))
	{
		case OPERATIONTYPE_BINARY_OPERATOR:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << " " << getOperationName(m_op) << " " << operationValue1 << ";\n";
			break;

		case OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << operationValue0 << ";\n";
			break;

		case OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << getOperationName(m_op) << ";\n";
			break;

		case OPERATIONTYPE_BINARY_FUNCTION:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ", " << operationValue1 << ");\n";
			break;

		case OPERATIONTYPE_UNARY_FUNCTION:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << getOperationName(m_op) << "(" << operationValue0 << ");\n";
			break;

		case OPERATIONTYPE_ASSIGNMENT:
			op << "	" << getPrecisionName(resultPrec) << " " << getDataTypeName(resultType) << " res = " << operationValue0 << ";\n";
			op << "	res " << getOperationName(m_op) << " " << operationValue1 << ";\n";
			break;

		default:
			DE_ASSERT(DE_FALSE);
	}

	// Reduction to vec3 (rgb). Check the used value too if it was modified
	op << "	" << (m_isVertexCase ? "v_color" : "dEQP_FragColor") << " = ";

	if (isOperationValueModifying(m_op))
		op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0) + vec4(" << genGLSLMatToVec3Reduction(resultType, "tmpValue") << ", 0.0);\n";
	else
		op << "vec4(" << genGLSLMatToVec3Reduction(resultType, "res") << ", 1.0);\n";

	vtx << "}\n";
	frag << "}\n";

	m_vertShaderSource	= vtx.str();
	m_fragShaderSource	= frag.str();
}

std::string ShaderMatrixCase::genGLSLMatToVec3Reduction (const glu::DataType& matType, const char* varName)
{
	std::ostringstream op;

	switch (matType)
	{
		case TYPE_FLOAT:		op << varName << ", "			<< varName << ", "			<< varName << "";																																			break;
		case TYPE_FLOAT_VEC2:	op << varName << ".x, "			<< varName << ".y, "		<< varName << ".x";																																			break;
		case TYPE_FLOAT_VEC3:	op << varName << "";																																																	break;
		case TYPE_FLOAT_VEC4:	op << varName << ".x, "			<< varName << ".y, "		<< varName << ".z+"			<< varName << ".w";																												break;
		case TYPE_FLOAT_MAT2:	op << varName << "[0][0], "		<< varName << "[1][0], "	<< varName << "[0][1]+"		<< varName << "[1][1]";																											break;
		case TYPE_FLOAT_MAT2X3:	op << varName << "[0] + "		<< varName << "[1]";																																									break;
		case TYPE_FLOAT_MAT2X4:	op << varName << "[0].xyz + "	<< varName << "[1].yzw";																																								break;
		case TYPE_FLOAT_MAT3X2:	op << varName << "[0][0]+"		<< varName << "[0][1], "	<< varName << "[1][0]+"		<< varName << "[1][1], "	<< varName << "[2][0]+" << varName << "[2][1]";														break;
		case TYPE_FLOAT_MAT3:	op << varName << "[0] + "		<< varName << "[1] + "		<< varName << "[2]";																																		break;
		case TYPE_FLOAT_MAT3X4:	op << varName << "[0].xyz + "	<< varName << "[1].yzw + "	<< varName << "[2].zwx";																																	break;
		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;
		case TYPE_FLOAT_MAT4X3:	op << varName << "[0] + "		<< varName << "[1] + "		<< varName << "[2] + "		<< varName << "[3]";																											break;
		case TYPE_FLOAT_MAT4:	op << varName << "[0].xyz+"		<< varName << "[1].yzw+"	<< varName << "[2].zwx+"	<< varName << "[3].wxy";																										break;

		default:
			DE_ASSERT(DE_FALSE);
	}

	return op.str();
}

class ShaderMatrixTests : public tcu::TestCaseGroup
{
public:
							ShaderMatrixTests		(tcu::TestContext& testCtx);
	virtual					~ShaderMatrixTests		(void);

	virtual void			init					(void);

private:
							ShaderMatrixTests		(const ShaderMatrixTests&);		// not allowed!
	ShaderMatrixTests&		operator=				(const ShaderMatrixTests&);		// not allowed!
};

ShaderMatrixTests::ShaderMatrixTests (tcu::TestContext& testCtx)
	: TestCaseGroup(testCtx, "matrix", "Matrix Tests")
{
}

ShaderMatrixTests::~ShaderMatrixTests (void)
{
}

void ShaderMatrixTests::init (void)
{
	static const struct
	{
		const char*		name;
		const char*		desc;
		const MatrixOp	op;
		const bool		extendedInputTypeCases; // !< test with const and uniform types too
		const bool		createInputTypeGroup;	// !< create group for input types
	} ops[] =
	{
		{ "add",			"Matrix addition tests",						OP_ADD,				true,	true	},
		{ "sub",			"Matrix subtraction tests",						OP_SUB,				true,	true	},
		{ "mul",			"Matrix multiplication tests",					OP_MUL,				true,	true	},
		{ "div",			"Matrix division tests",						OP_DIV,				true,	true	},
		{ "matrixcompmult",	"Matrix component-wise multiplication tests",	OP_COMP_MUL,		false,	true	},
		{ "outerproduct",	"Matrix outerProduct() tests",					OP_OUTER_PRODUCT,	false,	true	},
		{ "transpose",		"Matrix transpose() tests",						OP_TRANSPOSE,		false,	true	},
		{ "determinant",	"Matrix determinant() tests",					OP_DETERMINANT,		false,	true	},
		{ "inverse",		"Matrix inverse() tests",						OP_INVERSE,			false,	true	},
		{ "unary_addition",	"Matrix unary addition tests",					OP_UNARY_PLUS,		false,	false	},
		{ "negation",		"Matrix negation tests",						OP_NEGATION,		false,	false	},
		{ "pre_increment",	"Matrix prefix increment tests",				OP_PRE_INCREMENT,	false,	false	},
		{ "pre_decrement",	"Matrix prefix decrement tests",				OP_PRE_DECREMENT,	false,	false	},
		{ "post_increment",	"Matrix postfix increment tests",				OP_POST_INCREMENT,	false,	false	},
		{ "post_decrement",	"Matrix postfix decrement tests",				OP_POST_DECREMENT,	false,	false	},
		{ "add_assign",		"Matrix add into tests",						OP_ADD_INTO,		false,	false	},
		{ "sub_assign",		"Matrix subtract from tests",					OP_SUBTRACT_FROM,	false,	false	},
		{ "mul_assign",		"Matrix multiply into tests",					OP_MULTIPLY_INTO,	false,	false	},
		{ "div_assign",		"Matrix divide into tests",						OP_DIVIDE_INTO,		false,	false	},
	};

	struct InputTypeSpec
	{
		const char*		name;
		const char*		desc;
		const InputType	type;
	};
	static const InputTypeSpec extendedInputTypes[] =
	{
		{ "const",		"Constant matrix input",	INPUTTYPE_CONST		},
		{ "uniform",	"Uniform matrix input",		INPUTTYPE_UNIFORM	},
		{ "dynamic",	"Dynamic matrix input",		INPUTTYPE_DYNAMIC	}
	};
	static const InputTypeSpec reducedInputTypes[] =
	{
		{ "dynamic",	"Dynamic matrix input",		INPUTTYPE_DYNAMIC	}
	};

	static const DataType matrixTypes[] =
	{
		TYPE_FLOAT_MAT2,
		TYPE_FLOAT_MAT2X3,
		TYPE_FLOAT_MAT2X4,
		TYPE_FLOAT_MAT3X2,
		TYPE_FLOAT_MAT3,
		TYPE_FLOAT_MAT3X4,
		TYPE_FLOAT_MAT4X2,
		TYPE_FLOAT_MAT4X3,
		TYPE_FLOAT_MAT4
	};

	static const Precision precisions[] =
	{
		PRECISION_MEDIUMP,
		PRECISION_HIGHP
	};

	for (int opNdx = 0; opNdx < DE_LENGTH_OF_ARRAY(ops); opNdx++)
	{
		const InputTypeSpec*	inTypeList		= (ops[opNdx].extendedInputTypeCases) ? (extendedInputTypes) : (reducedInputTypes);
		const int				inTypeListSize	= (ops[opNdx].extendedInputTypeCases) ? (DE_LENGTH_OF_ARRAY(extendedInputTypes)) : (DE_LENGTH_OF_ARRAY(reducedInputTypes));
		const MatrixOp			op				= ops[opNdx].op;
		tcu::TestCaseGroup*		opGroup			= new tcu::TestCaseGroup(m_testCtx, ops[opNdx].name, ops[opNdx].desc);

		addChild(opGroup);

		for (int inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++)
		{
			const InputType		inputType	= inTypeList[inTypeNdx].type;
			tcu::TestCaseGroup* inGroup;

			if (ops[opNdx].createInputTypeGroup)
			{
				inGroup = new tcu::TestCaseGroup(m_testCtx, inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
				opGroup->addChild(inGroup);
			}
			else
				inGroup = opGroup;

			for (int matTypeNdx = 0; matTypeNdx < DE_LENGTH_OF_ARRAY(matrixTypes); matTypeNdx++)
			{
				DataType	matType		= matrixTypes[matTypeNdx];
				int			numCols		= getDataTypeMatrixNumColumns(matType);
				int			numRows		= getDataTypeMatrixNumRows(matType);
				const char*	matTypeName	= getDataTypeName(matType);

				for (int precNdx = 0; precNdx < DE_LENGTH_OF_ARRAY(precisions); precNdx++)
				{
					Precision	precision	= precisions[precNdx];
					const char*	precName	= getPrecisionName(precision);
					string		baseName	= string(precName) + "_" + matTypeName + "_";
					ShaderInput	matIn		(inputType, matType, precision);

					if (isOperationMatrixScalar(op))
					{
						// Matrix-scalar \note For div cases we use uniform input.
						ShaderInput scalarIn(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, TYPE_FLOAT, precision);
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(),		"Matrix-scalar case", matIn, scalarIn, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(),	"Matrix-scalar case", matIn, scalarIn, op, false));
					}

					if (isOperationMatrixVector(op))
					{
						// Matrix-vector.
						DataType	colVecType	= getDataTypeFloatVec(numCols);
						ShaderInput colVecIn	(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, colVecType, precision);

						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(colVecType) + "_vertex").c_str(),		"Matrix-vector case", matIn, colVecIn, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(colVecType) + "_fragment").c_str(),	"Matrix-vector case", matIn, colVecIn, op, false));

						// Vector-matrix.
						DataType	rowVecType	= getDataTypeFloatVec(numRows);
						ShaderInput	rowVecIn	(op == OP_DIV ? INPUTTYPE_UNIFORM : INPUTTYPE_DYNAMIC, rowVecType, precision);
						string		vecMatName	= string(precName) + "_" + getDataTypeName(rowVecType) + "_" + matTypeName;

						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (vecMatName + "_vertex").c_str(),		"Vector-matrix case", rowVecIn, matIn, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (vecMatName + "_fragment").c_str(),	"Vector-matrix case", rowVecIn, matIn, op, false));
					}

					if (isOperationArithmeticMatrixMatrix(op))
					{
						// Arithmetic matrix-matrix multiplication.
						for (int otherCols = 2; otherCols <= 4; otherCols++)
						{
							ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, getDataTypeMatrix(otherCols, numCols /* rows */), precision);
							inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(otherMatIn.dataType) + "_vertex").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, true));
							inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + getDataTypeName(otherMatIn.dataType) + "_fragment").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, false));
						}
					}
					else if (isOperationComponentwiseMatrixMatrix(op))
					{
						// Component-wise.
						ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + matTypeName + "_vertex").c_str(),		"Matrix-matrix case", matIn, otherMatIn, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + matTypeName + "_fragment").c_str(),	"Matrix-matrix case", matIn, otherMatIn, op, false));
					}

					if (isOperationVectorVector(op))
					{
						ShaderInput vec1In(inputType,																getDataTypeFloatVec(numRows), precision);
						ShaderInput vec2In((inputType == INPUTTYPE_DYNAMIC) ? (INPUTTYPE_UNIFORM) : (inputType),	getDataTypeFloatVec(numCols), precision);

						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(),		"Vector-vector case", vec1In, vec2In, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(),	"Vector-vector case", vec1In, vec2In, op, false));
					}

					if ((isOperationUnaryAnyMatrix(op)) ||
						(isOperationUnarySymmetricMatrix(op) && numCols == numRows))
					{
						ShaderInput voidInput(INPUTTYPE_LAST, TYPE_LAST, PRECISION_LAST);
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(),		"Matrix case", matIn, voidInput, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(),	"Matrix case", matIn, voidInput, op, false));
					}

					if ((isOperationAssignmentAnyMatrix(op)) ||
						(isOperationAssignmentSymmetricMatrix(op) && numCols == numRows))
					{
						ShaderInput otherMatIn(inputType == INPUTTYPE_DYNAMIC ? INPUTTYPE_UNIFORM : inputType, matType, precision);
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_vertex").c_str(),		"Matrix assignment case", matIn, otherMatIn, op, true));
						inGroup->addChild(new ShaderMatrixCase(m_testCtx, (baseName + "float_fragment").c_str(),	"Matrix assignment case", matIn, otherMatIn, op, false));
					}
				}
			}
		}
	}
}

} // anonymous

tcu::TestCaseGroup* createMatrixTests (tcu::TestContext& testCtx)
{
	return new ShaderMatrixTests(testCtx);
}

} // sr
} // vkt
