/*------------------------------------------------------------------------
 * 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;
}

// 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, IMAGE_BACKING_MODE_REGULAR, isVertex && op == OP_INVERSE ? 64 : GRID_SIZE_DEFAULTS)
	, 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
