/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 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 indexing (arrays, vector, matrices) tests.
 *//*--------------------------------------------------------------------*/

#include "es3fShaderIndexingTests.hpp"
#include "glsShaderRenderCase.hpp"
#include "gluShaderUtil.hpp"
#include "tcuStringTemplate.hpp"

#include "deInt32.h"
#include "deMemory.h"

#include <map>

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

using namespace std;
using namespace tcu;
using namespace glu;
using namespace deqp::gls;

namespace deqp
{
namespace gles3
{
namespace Functional
{

enum IndexAccessType
{
	INDEXACCESS_STATIC = 0,
	INDEXACCESS_DYNAMIC,
	INDEXACCESS_STATIC_LOOP,
	INDEXACCESS_DYNAMIC_LOOP,

	INDEXACCESS_LAST
};

static const char* getIndexAccessTypeName (IndexAccessType accessType)
{
	static const char* s_names[INDEXACCESS_LAST] =
	{
		"static",
		"dynamic",
		"static_loop",
		"dynamic_loop"
	};

	DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST));
	return s_names[(int)accessType];
}

enum VectorAccessType
{
	DIRECT = 0,
	COMPONENT,
	SUBSCRIPT_STATIC,
	SUBSCRIPT_DYNAMIC,
	SUBSCRIPT_STATIC_LOOP,
	SUBSCRIPT_DYNAMIC_LOOP,

	VECTORACCESS_LAST
};

static const char* getVectorAccessTypeName (VectorAccessType accessType)
{
	static const char* s_names[VECTORACCESS_LAST] =
	{
		"direct",
		"component",
		"static_subscript",
		"dynamic_subscript",
		"static_loop_subscript",
		"dynamic_loop_subscript"
	};

	DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST));
	return s_names[(int)accessType];
}

void evalArrayCoordsFloat		(ShaderEvalContext& c) { c.color.x()	= 1.875f * c.coords.x(); }
void evalArrayCoordsVec2		(ShaderEvalContext& c) { c.color.xy()	= 1.875f * c.coords.swizzle(0,1); }
void evalArrayCoordsVec3		(ShaderEvalContext& c) { c.color.xyz()	= 1.875f * c.coords.swizzle(0,1,2); }
void evalArrayCoordsVec4		(ShaderEvalContext& c) { c.color		= 1.875f * c.coords; }

static ShaderEvalFunc getArrayCoordsEvalFunc (DataType dataType)
{
	if (dataType == TYPE_FLOAT)				return evalArrayCoordsFloat;
	else if (dataType == TYPE_FLOAT_VEC2)	return evalArrayCoordsVec2;
	else if (dataType == TYPE_FLOAT_VEC3)	return evalArrayCoordsVec3;
	else if (dataType == TYPE_FLOAT_VEC4)	return evalArrayCoordsVec4;

	DE_FATAL("Invalid data type.");
	return NULL;
}

void evalArrayUniformFloat		(ShaderEvalContext& c) { c.color.x()	= 1.875f * c.constCoords.x(); }
void evalArrayUniformVec2		(ShaderEvalContext& c) { c.color.xy()	= 1.875f * c.constCoords.swizzle(0,1); }
void evalArrayUniformVec3		(ShaderEvalContext& c) { c.color.xyz()	= 1.875f * c.constCoords.swizzle(0,1,2); }
void evalArrayUniformVec4		(ShaderEvalContext& c) { c.color		= 1.875f * c.constCoords; }

static ShaderEvalFunc getArrayUniformEvalFunc (DataType dataType)
{
	if (dataType == TYPE_FLOAT)				return evalArrayUniformFloat;
	else if (dataType == TYPE_FLOAT_VEC2)	return evalArrayUniformVec2;
	else if (dataType == TYPE_FLOAT_VEC3)	return evalArrayUniformVec3;
	else if (dataType == TYPE_FLOAT_VEC4)	return evalArrayUniformVec4;

	DE_FATAL("Invalid data type.");
	return NULL;
}

// ShaderIndexingCase

class ShaderIndexingCase : public ShaderRenderCase
{
public:
								ShaderIndexingCase		(Context& context, const char* name, const char* description, bool isVertexCase, DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
	virtual						~ShaderIndexingCase		(void);

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

	virtual void				setup					(int programID);
	virtual void				setupUniforms			(int programID, const Vec4& constCoords);

	DataType					m_varType;
};

ShaderIndexingCase::ShaderIndexingCase (Context& context, const char* name, const char* description, bool isVertexCase, DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource)
	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
{
	m_varType			= varType;
	m_vertShaderSource	= vertShaderSource;
	m_fragShaderSource	= fragShaderSource;
}

ShaderIndexingCase::~ShaderIndexingCase (void)
{
}

void ShaderIndexingCase::setup (int programID)
{
	DE_UNREF(programID);
}

void ShaderIndexingCase::setupUniforms (int programID, const Vec4& constCoords)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	DE_UNREF(constCoords);

	int arrLoc = gl.getUniformLocation(programID, "u_arr");
	if (arrLoc != -1)
	{
		//int scalarSize = getDataTypeScalarSize(m_varType);
		if (m_varType == TYPE_FLOAT)
		{
			float arr[4];
			arr[0] = constCoords.x();
			arr[1] = constCoords.x() * 0.5f;
			arr[2] = constCoords.x() * 0.25f;
			arr[3] = constCoords.x() * 0.125f;
			gl.uniform1fv(arrLoc, 4, &arr[0]);
		}
		else if (m_varType == TYPE_FLOAT_VEC2)
		{
			Vec2 arr[4];
			arr[0] = constCoords.swizzle(0,1);
			arr[1] = constCoords.swizzle(0,1) * 0.5f;
			arr[2] = constCoords.swizzle(0,1) * 0.25f;
			arr[3] = constCoords.swizzle(0,1) * 0.125f;
			gl.uniform2fv(arrLoc, 4, arr[0].getPtr());
		}
		else if (m_varType == TYPE_FLOAT_VEC3)
		{
			Vec3 arr[4];
			arr[0] = constCoords.swizzle(0,1,2);
			arr[1] = constCoords.swizzle(0,1,2) * 0.5f;
			arr[2] = constCoords.swizzle(0,1,2) * 0.25f;
			arr[3] = constCoords.swizzle(0,1,2) * 0.125f;
			gl.uniform3fv(arrLoc, 4, arr[0].getPtr());
		}
		else if (m_varType == TYPE_FLOAT_VEC4)
		{
			Vec4 arr[4];
			arr[0] = constCoords.swizzle(0,1,2,3);
			arr[1] = constCoords.swizzle(0,1,2,3) * 0.5f;
			arr[2] = constCoords.swizzle(0,1,2,3) * 0.25f;
			arr[3] = constCoords.swizzle(0,1,2,3) * 0.125f;
			gl.uniform4fv(arrLoc, 4, arr[0].getPtr());
		}
		else
			throw tcu::TestError("u_arr should not have location assigned in this test case");
	}
}

// Helpers.

static ShaderIndexingCase* createVaryingArrayCase (Context& context, const char* caseName, const char* description, DataType varType, IndexAccessType vertAccess, IndexAccessType fragAccess)
{
	std::ostringstream vtx;
	vtx << "#version 300 es\n";
	vtx << "in highp vec4 a_position;\n";
	vtx << "in highp vec4 a_coords;\n";
	if (vertAccess == INDEXACCESS_DYNAMIC)
		vtx << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
	else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
		vtx << "uniform mediump int ui_four;\n";
	vtx << "out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
	vtx << "\n";
	vtx << "void main()\n";
	vtx << "{\n";
	vtx << "	gl_Position = a_position;\n";
	if (vertAccess == INDEXACCESS_STATIC)
	{
		vtx << "	var[0] = ${VAR_TYPE}(a_coords);\n";
		vtx << "	var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n";
		vtx << "	var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n";
		vtx << "	var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n";
	}
	else if (vertAccess == INDEXACCESS_DYNAMIC)
	{
		vtx << "	var[ui_zero]  = ${VAR_TYPE}(a_coords);\n";
		vtx << "	var[ui_one]   = ${VAR_TYPE}(a_coords) * 0.5;\n";
		vtx << "	var[ui_two]   = ${VAR_TYPE}(a_coords) * 0.25;\n";
		vtx << "	var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n";
	}
	else if (vertAccess == INDEXACCESS_STATIC_LOOP)
	{
		vtx << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
		vtx << "	for (int i = 0; i < 4; i++)\n";
		vtx << "	{\n";
		vtx << "		var[i] = ${VAR_TYPE}(coords);\n";
		vtx << "		coords = coords * 0.5;\n";
		vtx << "	}\n";
	}
	else
	{
		DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP);
		vtx << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
		vtx << "	for (int i = 0; i < ui_four; i++)\n";
		vtx << "	{\n";
		vtx << "		var[i] = ${VAR_TYPE}(coords);\n";
		vtx << "		coords = coords * 0.5;\n";
		vtx << "	}\n";
	}
	vtx << "}\n";

	std::ostringstream frag;
	frag << "#version 300 es\n";
	frag << "precision mediump int;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";
	if (fragAccess == INDEXACCESS_DYNAMIC)
		frag << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
	else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
		frag << "uniform int ui_four;\n";
	frag << "in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";
	frag << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
	if (fragAccess == INDEXACCESS_STATIC)
	{
		frag << "	res += var[0];\n";
		frag << "	res += var[1];\n";
		frag << "	res += var[2];\n";
		frag << "	res += var[3];\n";
	}
	else if (fragAccess == INDEXACCESS_DYNAMIC)
	{
		frag << "	res += var[ui_zero];\n";
		frag << "	res += var[ui_one];\n";
		frag << "	res += var[ui_two];\n";
		frag << "	res += var[ui_three];\n";
	}
	else if (fragAccess == INDEXACCESS_STATIC_LOOP)
	{
		frag << "	for (int i = 0; i < 4; i++)\n";
		frag << "		res += var[i];\n";
	}
	else
	{
		DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP);
		frag << "	for (int i = 0; i < ui_four; i++)\n";
		frag << "		res += var[i];\n";
	}
	frag << "	o_color = vec4(res${PADDING});\n";
	frag << "}\n";

	// Fill in shader templates.
	map<string, string> params;
	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
	params.insert(pair<string, string>("ARRAY_LEN", "4"));
	params.insert(pair<string, string>("PRECISION", "mediump"));

	if (varType == TYPE_FLOAT)
		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC2)
		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC3)
		params.insert(pair<string, string>("PADDING", ", 1.0"));
	else
		params.insert(pair<string, string>("PADDING", ""));

	StringTemplate vertTemplate(vtx.str().c_str());
	StringTemplate fragTemplate(frag.str().c_str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
	return new ShaderIndexingCase(context, caseName, description, true, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}

static ShaderIndexingCase* createUniformArrayCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	vtx << "#version 300 es\n";
	frag << "#version 300 es\n";

	vtx << "in highp vec4 a_position;\n";
	vtx << "in highp vec4 a_coords;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";

	if (isVertexCase)
	{
		vtx << "out mediump vec4 v_color;\n";
		frag << "in mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "out mediump vec4 v_coords;\n";
		frag << "in mediump vec4 v_coords;\n";
	}

	if (readAccess == INDEXACCESS_DYNAMIC)
		op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
	else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "uniform mediump int ui_four;\n";

	op << "uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n";

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

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	// Read array.
	op << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
	if (readAccess == INDEXACCESS_STATIC)
	{
		op << "	res += u_arr[0];\n";
		op << "	res += u_arr[1];\n";
		op << "	res += u_arr[2];\n";
		op << "	res += u_arr[3];\n";
	}
	else if (readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "	res += u_arr[ui_zero];\n";
		op << "	res += u_arr[ui_one];\n";
		op << "	res += u_arr[ui_two];\n";
		op << "	res += u_arr[ui_three];\n";
	}
	else if (readAccess == INDEXACCESS_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < 4; i++)\n";
		op << "		res += u_arr[i];\n";
	}
	else
	{
		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < ui_four; i++)\n";
		op << "		res += u_arr[i];\n";
	}

	if (isVertexCase)
	{
		vtx << "	v_color = vec4(res${PADDING});\n";
		frag << "	o_color = v_color;\n";
	}
	else
	{
		vtx << "	v_coords = a_coords;\n";
		frag << "	o_color = vec4(res${PADDING});\n";
	}

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

	// Fill in shader templates.
	map<string, string> params;
	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
	params.insert(pair<string, string>("ARRAY_LEN", "4"));
	params.insert(pair<string, string>("PRECISION", "mediump"));

	if (varType == TYPE_FLOAT)
		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC2)
		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC3)
		params.insert(pair<string, string>("PADDING", ", 1.0"));
	else
		params.insert(pair<string, string>("PADDING", ""));

	StringTemplate vertTemplate(vtx.str().c_str());
	StringTemplate fragTemplate(frag.str().c_str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}

static ShaderIndexingCase* createTmpArrayCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType writeAccess, IndexAccessType readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	vtx << "#version 300 es\n";
	frag << "#version 300 es\n";

	vtx << "in highp vec4 a_position;\n";
	vtx << "in highp vec4 a_coords;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";

	if (isVertexCase)
	{
		vtx << "out mediump vec4 v_color;\n";
		frag << "in mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "out mediump vec4 v_coords;\n";
		frag << "in mediump vec4 v_coords;\n";
	}

	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
		op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";

	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "uniform mediump int ui_four;\n";

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

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	// Write array.
	if (isVertexCase)
		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
	else
		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";

	op << "	${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n";
	if (writeAccess == INDEXACCESS_STATIC)
	{
		op << "	arr[0] = ${VAR_TYPE}(coords);\n";
		op << "	arr[1] = ${VAR_TYPE}(coords) * 0.5;\n";
		op << "	arr[2] = ${VAR_TYPE}(coords) * 0.25;\n";
		op << "	arr[3] = ${VAR_TYPE}(coords) * 0.125;\n";
	}
	else if (writeAccess == INDEXACCESS_DYNAMIC)
	{
		op << "	arr[ui_zero]  = ${VAR_TYPE}(coords);\n";
		op << "	arr[ui_one]   = ${VAR_TYPE}(coords) * 0.5;\n";
		op << "	arr[ui_two]   = ${VAR_TYPE}(coords) * 0.25;\n";
		op << "	arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n";
	}
	else if (writeAccess == INDEXACCESS_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < 4; i++)\n";
		op << "	{\n";
		op << "		arr[i] = ${VAR_TYPE}(coords);\n";
		op << "		coords = coords * 0.5;\n";
		op << "	}\n";
	}
	else
	{
		DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < ui_four; i++)\n";
		op << "	{\n";
		op << "		arr[i] = ${VAR_TYPE}(coords);\n";
		op << "		coords = coords * 0.5;\n";
		op << "	}\n";
	}

	// Read array.
	op << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
	if (readAccess == INDEXACCESS_STATIC)
	{
		op << "	res += arr[0];\n";
		op << "	res += arr[1];\n";
		op << "	res += arr[2];\n";
		op << "	res += arr[3];\n";
	}
	else if (readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "	res += arr[ui_zero];\n";
		op << "	res += arr[ui_one];\n";
		op << "	res += arr[ui_two];\n";
		op << "	res += arr[ui_three];\n";
	}
	else if (readAccess == INDEXACCESS_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < 4; i++)\n";
		op << "		res += arr[i];\n";
	}
	else
	{
		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < ui_four; i++)\n";
		op << "		res += arr[i];\n";
	}

	if (isVertexCase)
	{
		vtx << "	v_color = vec4(res${PADDING});\n";
		frag << "	o_color = v_color;\n";
	}
	else
	{
		vtx << "	v_coords = a_coords;\n";
		frag << "	o_color = vec4(res${PADDING});\n";
	}

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

	// Fill in shader templates.
	map<string, string> params;
	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
	params.insert(pair<string, string>("ARRAY_LEN", "4"));
	params.insert(pair<string, string>("PRECISION", "mediump"));

	if (varType == TYPE_FLOAT)
		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC2)
		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
	else if (varType == TYPE_FLOAT_VEC3)
		params.insert(pair<string, string>("PADDING", ", 1.0"));
	else
		params.insert(pair<string, string>("PADDING", ""));

	StringTemplate vertTemplate(vtx.str().c_str());
	StringTemplate fragTemplate(frag.str().c_str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}

// VECTOR SUBSCRIPT.

void evalSubscriptVec2 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y()); }
void evalSubscriptVec3 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y() + 0.25f*c.coords.z()); }
void evalSubscriptVec4 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y() + 0.25f*c.coords.z() + 0.125f*c.coords.w()); }

static ShaderEvalFunc getVectorSubscriptEvalFunc (DataType dataType)
{
	if (dataType == TYPE_FLOAT_VEC2)		return evalSubscriptVec2;
	else if (dataType == TYPE_FLOAT_VEC3)	return evalSubscriptVec3;
	else if (dataType == TYPE_FLOAT_VEC4)	return evalSubscriptVec4;

	DE_FATAL("Invalid data type.");
	return NULL;
}

static ShaderIndexingCase* createVectorSubscriptCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, VectorAccessType writeAccess, VectorAccessType readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	int			vecLen		= getDataTypeScalarSize(varType);
	const char*	vecLenName	= getIntUniformName(vecLen);

	vtx << "#version 300 es\n";
	frag << "#version 300 es\n";

	vtx << "in highp vec4 a_position;\n";
	vtx << "in highp vec4 a_coords;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";

	if (isVertexCase)
	{
		vtx << "out mediump vec3 v_color;\n";
		frag << "in mediump vec3 v_color;\n";
	}
	else
	{
		vtx << "out mediump vec4 v_coords;\n";
		frag << "in mediump vec4 v_coords;\n";
	}

	if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
	{
		op << "uniform mediump int ui_zero";
		if (vecLen >= 2) op << ", ui_one";
		if (vecLen >= 3) op << ", ui_two";
		if (vecLen >= 4) op << ", ui_three";
		op << ";\n";
	}

	if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
		op << "uniform mediump int " << vecLenName << ";\n";

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

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	// Write vector.
	if (isVertexCase)
		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
	else
		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";

	op << "	${PRECISION} ${VAR_TYPE} tmp;\n";
	if (writeAccess == DIRECT)
		op << "	tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n";
	else if (writeAccess == COMPONENT)
	{
		op << "	tmp.x = coords.x;\n";
		if (vecLen >= 2) op << "	tmp.y = coords.y * 0.5;\n";
		if (vecLen >= 3) op << "	tmp.z = coords.z * 0.25;\n";
		if (vecLen >= 4) op << "	tmp.w = coords.w * 0.125;\n";
	}
	else if (writeAccess == SUBSCRIPT_STATIC)
	{
		op << "	tmp[0] = coords.x;\n";
		if (vecLen >= 2) op << "	tmp[1] = coords.y * 0.5;\n";
		if (vecLen >= 3) op << "	tmp[2] = coords.z * 0.25;\n";
		if (vecLen >= 4) op << "	tmp[3] = coords.w * 0.125;\n";
	}
	else if (writeAccess == SUBSCRIPT_DYNAMIC)
	{
		op << "	tmp[ui_zero]  = coords.x;\n";
		if (vecLen >= 2) op << "	tmp[ui_one]   = coords.y * 0.5;\n";
		if (vecLen >= 3) op << "	tmp[ui_two]   = coords.z * 0.25;\n";
		if (vecLen >= 4) op << "	tmp[ui_three] = coords.w * 0.125;\n";
	}
	else if (writeAccess == SUBSCRIPT_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < " << vecLen << "; i++)\n";
		op << "	{\n";
		op << "		tmp[i] = coords.x;\n";
		op << "		coords = coords.${ROT_SWIZZLE} * 0.5;\n";
		op << "	}\n";
	}
	else
	{
		DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < " << vecLenName << "; i++)\n";
		op << "	{\n";
		op << "		tmp[i] = coords.x;\n";
		op << "		coords = coords.${ROT_SWIZZLE} * 0.5;\n";
		op << "	}\n";
	}

	// Read vector.
	op << "	${PRECISION} float res = 0.0;\n";
	if (readAccess == DIRECT)
		op << "	res = dot(tmp, ${VAR_TYPE}(1.0));\n";
	else if (readAccess == COMPONENT)
	{
		op << "	res += tmp.x;\n";
		if (vecLen >= 2) op << "	res += tmp.y;\n";
		if (vecLen >= 3) op << "	res += tmp.z;\n";
		if (vecLen >= 4) op << "	res += tmp.w;\n";
	}
	else if (readAccess == SUBSCRIPT_STATIC)
	{
		op << "	res += tmp[0];\n";
		if (vecLen >= 2) op << "	res += tmp[1];\n";
		if (vecLen >= 3) op << "	res += tmp[2];\n";
		if (vecLen >= 4) op << "	res += tmp[3];\n";
	}
	else if (readAccess == SUBSCRIPT_DYNAMIC)
	{
		op << "	res += tmp[ui_zero];\n";
		if (vecLen >= 2) op << "	res += tmp[ui_one];\n";
		if (vecLen >= 3) op << "	res += tmp[ui_two];\n";
		if (vecLen >= 4) op << "	res += tmp[ui_three];\n";
	}
	else if (readAccess == SUBSCRIPT_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < " << vecLen << "; i++)\n";
		op << "		res += tmp[i];\n";
	}
	else
	{
		DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < " << vecLenName << "; i++)\n";
		op << "		res += tmp[i];\n";
	}

	if (isVertexCase)
	{
		vtx << "	v_color = vec3(res);\n";
		frag << "	o_color = vec4(v_color.rgb, 1.0);\n";
	}
	else
	{
		vtx << "	v_coords = a_coords;\n";
		frag << "	o_color = vec4(vec3(res), 1.0);\n";
	}

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

	// Fill in shader templates.
	static const char* s_swizzles[5]	= { "", "x", "xy", "xyz", "xyzw" };
	static const char* s_rotSwizzles[5]	= { "", "x", "yx", "yzx", "yzwx" };

	map<string, string> params;
	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
	params.insert(pair<string, string>("PRECISION", "mediump"));
	params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen]));
	params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen]));

	StringTemplate vertTemplate(vtx.str().c_str());
	StringTemplate fragTemplate(frag.str().c_str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}

// MATRIX SUBSCRIPT.

void evalSubscriptMat2		(ShaderEvalContext& c) { c.color.xy()	= c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2); }
void evalSubscriptMat2x3	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3); }
void evalSubscriptMat2x4	(ShaderEvalContext& c) { c.color		= c.coords.swizzle(0,1,2,3) + 0.5f*c.coords.swizzle(1,2,3,0); }

void evalSubscriptMat3x2	(ShaderEvalContext& c) { c.color.xy()	= c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2) + 0.25f*c.coords.swizzle(2,3); }
void evalSubscriptMat3		(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3) + 0.25f*c.coords.swizzle(2,3,0); }
void evalSubscriptMat3x4	(ShaderEvalContext& c) { c.color		= c.coords.swizzle(0,1,2,3) + 0.5f*c.coords.swizzle(1,2,3,0) + 0.25f*c.coords.swizzle(2,3,0,1); }

void evalSubscriptMat4x2	(ShaderEvalContext& c) { c.color.xy()	= c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2) + 0.25f*c.coords.swizzle(2,3) + 0.125f*c.coords.swizzle(3,0); }
void evalSubscriptMat4x3	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3) + 0.25f*c.coords.swizzle(2,3,0) + 0.125f*c.coords.swizzle(3,0,1); }
void evalSubscriptMat4		(ShaderEvalContext& c) { c.color		= c.coords + 0.5f*c.coords.swizzle(1,2,3,0) + 0.25f*c.coords.swizzle(2,3,0,1) + 0.125f*c.coords.swizzle(3,0,1,2); }

static ShaderEvalFunc getMatrixSubscriptEvalFunc (DataType dataType)
{
	switch (dataType)
	{
		case TYPE_FLOAT_MAT2:		return evalSubscriptMat2;
		case TYPE_FLOAT_MAT2X3:		return evalSubscriptMat2x3;
		case TYPE_FLOAT_MAT2X4:		return evalSubscriptMat2x4;
		case TYPE_FLOAT_MAT3X2:		return evalSubscriptMat3x2;
		case TYPE_FLOAT_MAT3:		return evalSubscriptMat3;
		case TYPE_FLOAT_MAT3X4:		return evalSubscriptMat3x4;
		case TYPE_FLOAT_MAT4X2:		return evalSubscriptMat4x2;
		case TYPE_FLOAT_MAT4X3:		return evalSubscriptMat4x3;
		case TYPE_FLOAT_MAT4:		return evalSubscriptMat4;

		default:
			DE_FATAL("Invalid data type.");
			return DE_NULL;
	}
}

static ShaderIndexingCase* createMatrixSubscriptCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType writeAccess, IndexAccessType readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	int			numCols		= getDataTypeMatrixNumColumns(varType);
	int			numRows		= getDataTypeMatrixNumRows(varType);
	const char*	matSizeName	= getIntUniformName(numCols);
	DataType	vecType		= getDataTypeFloatVec(numRows);

	vtx << "#version 300 es\n";
	frag << "#version 300 es\n";

	vtx << "in highp vec4 a_position;\n";
	vtx << "in highp vec4 a_coords;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";

	if (isVertexCase)
	{
		vtx << "out mediump vec4 v_color;\n";
		frag << "in mediump vec4 v_color;\n";
	}
	else
	{
		vtx << "out mediump vec4 v_coords;\n";
		frag << "in mediump vec4 v_coords;\n";
	}

	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "uniform mediump int ui_zero";
		if (numCols >= 2) op << ", ui_one";
		if (numCols >= 3) op << ", ui_two";
		if (numCols >= 4) op << ", ui_three";
		op << ";\n";
	}

	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "uniform mediump int " << matSizeName << ";\n";

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

	frag << "\n";
	frag << "void main()\n";
	frag << "{\n";

	// Write matrix.
	if (isVertexCase)
		op << "	${PRECISION} vec4 coords = a_coords;\n";
	else
		op << "	${PRECISION} vec4 coords = v_coords;\n";

	op << "	${PRECISION} ${MAT_TYPE} tmp;\n";
	if (writeAccess == INDEXACCESS_STATIC)
	{
		op << "	tmp[0] = ${VEC_TYPE}(coords);\n";
		if (numCols >= 2) op << "	tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
		if (numCols >= 3) op << "	tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
		if (numCols >= 4) op << "	tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
	}
	else if (writeAccess == INDEXACCESS_DYNAMIC)
	{
		op << "	tmp[ui_zero]  = ${VEC_TYPE}(coords);\n";
		if (numCols >= 2) op << "	tmp[ui_one]   = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
		if (numCols >= 3) op << "	tmp[ui_two]   = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
		if (numCols >= 4) op << "	tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
	}
	else if (writeAccess == INDEXACCESS_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < " << numCols << "; i++)\n";
		op << "	{\n";
		op << "		tmp[i] = ${VEC_TYPE}(coords);\n";
		op << "		coords = coords.yzwx * 0.5;\n";
		op << "	}\n";
	}
	else
	{
		DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < " << matSizeName << "; i++)\n";
		op << "	{\n";
		op << "		tmp[i] = ${VEC_TYPE}(coords);\n";
		op << "		coords = coords.yzwx * 0.5;\n";
		op << "	}\n";
	}

	// Read matrix.
	op << "	${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n";
	if (readAccess == INDEXACCESS_STATIC)
	{
		op << "	res += tmp[0];\n";
		if (numCols >= 2) op << "	res += tmp[1];\n";
		if (numCols >= 3) op << "	res += tmp[2];\n";
		if (numCols >= 4) op << "	res += tmp[3];\n";
	}
	else if (readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "	res += tmp[ui_zero];\n";
		if (numCols >= 2) op << "	res += tmp[ui_one];\n";
		if (numCols >= 3) op << "	res += tmp[ui_two];\n";
		if (numCols >= 4) op << "	res += tmp[ui_three];\n";
	}
	else if (readAccess == INDEXACCESS_STATIC_LOOP)
	{
		op << "	for (int i = 0; i < " << numCols << "; i++)\n";
		op << "		res += tmp[i];\n";
	}
	else
	{
		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
		op << "	for (int i = 0; i < " << matSizeName << "; i++)\n";
		op << "		res += tmp[i];\n";
	}

	if (isVertexCase)
	{
		vtx << "	v_color = vec4(res${PADDING});\n";
		frag << "	o_color = v_color;\n";
	}
	else
	{
		vtx << "	v_coords = a_coords;\n";
		frag << "	o_color = vec4(res${PADDING});\n";
	}

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

	// Fill in shader templates.
	map<string, string> params;
	params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType)));
	params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType)));
	params.insert(pair<string, string>("PRECISION", "mediump"));

	if (numRows == 2)
		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
	else if (numRows == 3)
		params.insert(pair<string, string>("PADDING", ", 1.0"));
	else
		params.insert(pair<string, string>("PADDING", ""));

	StringTemplate vertTemplate(vtx.str().c_str());
	StringTemplate fragTemplate(frag.str().c_str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
}

// ShaderIndexingTests.

ShaderIndexingTests::ShaderIndexingTests(Context& context)
	: TestCaseGroup(context, "indexing", "Indexing Tests")
{
}

ShaderIndexingTests::~ShaderIndexingTests (void)
{
}

void ShaderIndexingTests::init (void)
{
	static const ShaderType s_shaderTypes[] =
	{
		SHADERTYPE_VERTEX,
		SHADERTYPE_FRAGMENT
	};

	static const DataType s_floatAndVecTypes[] =
	{
		TYPE_FLOAT,
		TYPE_FLOAT_VEC2,
		TYPE_FLOAT_VEC3,
		TYPE_FLOAT_VEC4
	};

	// Varying array access cases.
	{
		TestCaseGroup* varyingGroup = new TestCaseGroup(m_context, "varying_array", "Varying array access tests.");
		addChild(varyingGroup);

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
		{
			DataType varType = s_floatAndVecTypes[typeNdx];
			for (int vertAccess = 0; vertAccess < INDEXACCESS_LAST; vertAccess++)
			{
				for (int fragAccess = 0; fragAccess < INDEXACCESS_LAST; fragAccess++)
				{
					const char* vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess);
					const char* fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess);
					string name = string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read";
					string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " + fragAccessName + " read in fragment shader.";
					varyingGroup->addChild(createVaryingArrayCase(m_context, name.c_str(), desc.c_str(), varType, (IndexAccessType)vertAccess, (IndexAccessType)fragAccess));
				}
			}
		}
	}

	// Uniform array access cases.
	{
		TestCaseGroup* uniformGroup = new TestCaseGroup(m_context, "uniform_array", "Uniform array access tests.");
		addChild(uniformGroup);

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
		{
			DataType varType = s_floatAndVecTypes[typeNdx];
			for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
			{
				const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
				for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
				{
					ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
					const char*	shaderTypeName	= getShaderTypeName(shaderType);
					string		name			= string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName;
					string		desc			= string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader.";
					bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
					uniformGroup->addChild(createUniformArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)readAccess));
				}
			}
		}
	}

	// Temporary array access cases.
	{
		TestCaseGroup* tmpGroup = new TestCaseGroup(m_context, "tmp_array", "Temporary array access tests.");
		addChild(tmpGroup);

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
		{
			DataType varType = s_floatAndVecTypes[typeNdx];
			for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
			{
				for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
				{
					const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
					const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName	= getShaderTypeName(shaderType);
						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
						string		desc			= string("Temporary array with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
						tmpGroup->addChild(createTmpArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
					}
				}
			}
		}
	}

	// Vector indexing with subscripts.
	{
		TestCaseGroup* vecGroup = new TestCaseGroup(m_context, "vector_subscript", "Vector subscript indexing.");
		addChild(vecGroup);

		static const DataType s_vectorTypes[] =
		{
			TYPE_FLOAT_VEC2,
			TYPE_FLOAT_VEC3,
			TYPE_FLOAT_VEC4
		};

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++)
		{
			DataType varType = s_vectorTypes[typeNdx];
			for (int writeAccess = 0; writeAccess < VECTORACCESS_LAST; writeAccess++)
			{
				for (int readAccess = 0; readAccess < VECTORACCESS_LAST; readAccess++)
				{
					const char* writeAccessName = getVectorAccessTypeName((VectorAccessType)writeAccess);
					const char* readAccessName = getVectorAccessTypeName((VectorAccessType)readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName	= getShaderTypeName(shaderType);
						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
						string		desc			= string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
						vecGroup->addChild(createVectorSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
					}
				}
			}
		}
	}

	// Matrix indexing with subscripts.
	{
		TestCaseGroup* matGroup = new TestCaseGroup(m_context, "matrix_subscript", "Matrix subscript indexing.");
		addChild(matGroup);

		static const DataType s_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
		};

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++)
		{
			DataType varType = s_matrixTypes[typeNdx];
			for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
			{
				for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
				{
					const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
					const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName	= getShaderTypeName(shaderType);
						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
						string		desc			= string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
						matGroup->addChild(createMatrixSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
					}
				}
			}
		}
	}
}

} // Functional
} // gles3
} // deqp
