/*------------------------------------------------------------------------
 * 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) = 0.2f;								// !< prevent matrix*vec from going into zero (assuming vec.w != 0)
		m_userAttribTransforms[attribNdx](                  1, 3) = 0.1f;								// !<
		m_userAttribTransforms[attribNdx](                  2, 3) = 0.4f + 0.15f * float(attribNdx);	// !<
		m_userAttribTransforms[attribNdx](                  3, 3) = 0.7f;								// !<
		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
