/*------------------------------------------------------------------------
 * 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 indexing (arrays, vector, matrices) tests.
 *//*--------------------------------------------------------------------*/

#include "vktShaderRenderIndexingTests.hpp"
#include "vktShaderRender.hpp"
#include "gluShaderUtil.hpp"
#include "tcuStringTemplate.hpp"

#include <map>

using namespace std;
using namespace tcu;
using namespace glu;

namespace vkt
{
namespace sr
{

namespace
{

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

	/* Must be next to last, since most loop iterations won't include
	 * _CONST
	 */
	INDEXACCESS_CONST,
	INDEXACCESS_LAST
};

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

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

static const char* getIntUniformName (int number)
{
	switch (number)
	{
		case 0:		return "ui_zero";
		case 1:		return "ui_one";
		case 2:		return "ui_two";
		case 3:		return "ui_three";
		case 4:		return "ui_four";
		case 5:		return "ui_five";
		case 6:		return "ui_six";
		case 7:		return "ui_seven";
		case 8:		return "ui_eight";
		case 101:	return "ui_oneHundredOne";
		default:
			DE_ASSERT(false);
			return "";
	}
}

class IndexingTestUniformSetup : public UniformSetup
{
public:
							IndexingTestUniformSetup	(const DataType varType, bool usesArray)
								: m_varType(varType)
								, m_usesArray(usesArray)
							{}
	virtual					~IndexingTestUniformSetup	(void)
							{}

	virtual void			setup						(ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const;

private:
	const DataType			m_varType;
	const bool				m_usesArray;
};

void IndexingTestUniformSetup::setup (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) const
{
	instance.useUniform(0u, UI_ZERO);
	instance.useUniform(1u, UI_ONE);
	instance.useUniform(2u, UI_TWO);
	instance.useUniform(3u, UI_THREE);
	instance.useUniform(4u, UI_FOUR);

	if (m_usesArray)
	{
		Vec4 arr[4];
		if (m_varType == TYPE_FLOAT)
		{
			arr[0] = Vec4(constCoords.x());
			arr[1] = Vec4(constCoords.x() * 0.5f);
			arr[2] = Vec4(constCoords.x() * 0.25f);
			arr[3] = Vec4(constCoords.x() * 0.125f);
		}
		else if (m_varType == TYPE_FLOAT_VEC2)
		{
			arr[0] = constCoords.swizzle(0, 1).toWidth<4>();
			arr[1] = (constCoords.swizzle(0, 1) * 0.5f).toWidth<4>();
			arr[2] = (constCoords.swizzle(0, 1) * 0.25f).toWidth<4>();
			arr[3] = (constCoords.swizzle(0, 1) * 0.125f).toWidth<4>();
		}
		else if (m_varType == TYPE_FLOAT_VEC3)
		{
			arr[0] = constCoords.swizzle(0, 1, 2).toWidth<4>();
			arr[1] = (constCoords.swizzle(0, 1, 2) * 0.5f).toWidth<4>();
			arr[2] = (constCoords.swizzle(0, 1, 2) * 0.25f).toWidth<4>();
			arr[3] = (constCoords.swizzle(0, 1, 2) * 0.125f).toWidth<4>();
		}
		else if (m_varType == TYPE_FLOAT_VEC4)
		{
			arr[0] = constCoords;
			arr[1] = constCoords * 0.5f;
			arr[2] = constCoords * 0.25f;
			arr[3] = constCoords * 0.125f;
		}
		else
			throw tcu::TestError("invalid data type for u_arr");

		instance.addUniform(5u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(Vec4) * 4, arr[0].getPtr());
	}
}

// ShaderIndexingCase

class ShaderIndexingCase : public ShaderRenderCase
{
public:
								ShaderIndexingCase		(tcu::TestContext&			testCtx,
														const std::string&			name,
														const std::string&			description,
														bool						isVertexCase,
														const ShaderEvalFunc		evalFunc,
														const std::string&			vertShaderSource,
														const std::string&			fragShaderSource,
														const DataType				varType,
														const bool					usesArray);
	virtual						~ShaderIndexingCase		(void);

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

ShaderIndexingCase::ShaderIndexingCase (tcu::TestContext&			testCtx,
										const std::string&			name,
										const std::string&			description,
										const bool					isVertexCase,
										const ShaderEvalFunc		evalFunc,
										const std::string&			vertShaderSource,
										const std::string&			fragShaderSource,
										const DataType				varType,
										const bool					usesArray)
	: ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, new IndexingTestUniformSetup(varType, usesArray), DE_NULL)
{
	m_vertShaderSource	= vertShaderSource;
	m_fragShaderSource	= fragShaderSource;
}

ShaderIndexingCase::~ShaderIndexingCase (void)
{
}

// Test case builders.

static de::MovePtr<ShaderIndexingCase> createVaryingArrayCase (tcu::TestContext&	context,
															const std::string&		caseName,
															const std::string&		description,
															DataType				varType,
															IndexAccessType			vertAccess,
															IndexAccessType			fragAccess)
{
	std::ostringstream vtx;
	vtx << "#version 310 es\n";
	vtx << "layout(location = 0) in highp vec4 a_position;\n";
	vtx << "layout(location = 1) in highp vec4 a_coords;\n";
	if (vertAccess == INDEXACCESS_DYNAMIC)
	{
		vtx << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		vtx << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		vtx << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		vtx << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}
	else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
		vtx << "layout(std140, binding = 4) uniform something { mediump int ui_four; };\n";
	vtx << "layout(location = 0) 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 310 es\n";
	frag << "precision mediump int;\n";
	frag << "layout(location = 0) out mediump vec4 o_color;\n";
	if (fragAccess == INDEXACCESS_DYNAMIC)
	{
		frag << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		frag << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		frag << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		frag << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}
	else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
		frag << "layout(std140, binding = 4) uniform something4 { mediump int ui_four; };\n";
	frag << "layout(location = 0) 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());
	StringTemplate fragTemplate(frag.str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
	return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, true, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
}

static de::MovePtr<ShaderIndexingCase> createUniformArrayCase (tcu::TestContext&	context,
															const std::string&		caseName,
															const std::string&		description,
															bool					isVertexCase,
															DataType				varType,
															IndexAccessType			readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

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

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

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

	if (readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}
	else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "layout(std140, binding = 4) uniform something4 { mediump int ui_four; };\n";

	op << "layout(std140, binding = 5) uniform something5 { ${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());
	StringTemplate fragTemplate(frag.str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
	return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, true));
}

static de::MovePtr<ShaderIndexingCase> createTmpArrayCase (tcu::TestContext&	context,
														const std::string&		caseName,
														const std::string&		description,
														bool					isVertexCase,
														DataType				varType,
														IndexAccessType			writeAccess,
														IndexAccessType			readAccess)
{
	std::ostringstream vtx;
	std::ostringstream frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

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

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

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

	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}

	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "layout(std140, binding = 4) uniform something4 { 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 if (writeAccess != INDEXACCESS_CONST)
		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_CONST)
	{
		// Not using a loop inside the shader because we want it
		// unrolled to encourage the shader compiler to store it as
		// constant data.
		static const char *constructors[] = {
			"0.125",
			"0.125, 0.25",
			"0.125, 0.25, 0.5",
			"0.125, 0.25, 0.5, 1.0"
		};
		const char *constructor_args =
			constructors[getDataTypeNumComponents(varType) - 1];

		op << "	arr[0] = ${VAR_TYPE}(" << constructor_args << ");\n";
		op << "	arr[1] = ${VAR_TYPE}(" << constructor_args << ") * 0.5;\n";
		op << "	arr[2] = ${VAR_TYPE}(" << constructor_args << ") * 0.25;\n";
		op << "	arr[3] = ${VAR_TYPE}(" << constructor_args << ") * 0.125;\n";

		/* Stuff unused values in the rest of the array. */
		op << "	int i = 4;\n";
		for (int i = 4; i < 40; i++)
			op << "	arr[i++] = ${VAR_TYPE}(" << i << ".0);\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
	{
		if (writeAccess != INDEXACCESS_CONST)
			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)));
	// For const indexing, size the array such that the compiler is
	// more likely to optimize the temporary to constants.  40 was
	// enough to trigger a compiler failure in Mesa's turnip driver
	// without the optimization in place.
	if (writeAccess == INDEXACCESS_CONST)
		params.insert(pair<string, string>("ARRAY_LEN", "40"));
	else
		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());
	StringTemplate fragTemplate(frag.str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc;
	if (writeAccess == INDEXACCESS_CONST)
		evalFunc = getArrayUniformEvalFunc(varType);
	else
		evalFunc = getArrayCoordsEvalFunc(varType);

	return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
}

// 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 de::MovePtr<ShaderIndexingCase> createVectorSubscriptCase (tcu::TestContext&		context,
																const std::string&		caseName,
																const std::string&		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 310 es\n";
	frag << "#version 310 es\n";

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

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

	if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
	{
		op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		if (vecLen >= 2) op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		if (vecLen >= 3) op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		if (vecLen >= 4) op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}

	if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
		op << "layout(std140, binding = " << vecLen << ") uniform something" << vecLen << " { 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());
	StringTemplate fragTemplate(frag.str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
	return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
}

// 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 de::MovePtr<ShaderIndexingCase> createMatrixSubscriptCase (tcu::TestContext&		context,
																const std::string&		caseName,
																const std::string&		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 310 es\n";
	frag << "#version 310 es\n";

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

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

	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
	{
		op << "layout(std140, binding = 0) uniform something0 { mediump int ui_zero; };\n";
		if (numCols >= 2) op << "layout(std140, binding = 1) uniform something1 { mediump int ui_one; };\n";
		if (numCols >= 3) op << "layout(std140, binding = 2) uniform something2 { mediump int ui_two; };\n";
		if (numCols >= 4) op << "layout(std140, binding = 3) uniform something3 { mediump int ui_three; };\n";
	}

	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
		op << "layout(std140, binding = " << numCols << ") uniform something" << numCols << " { 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());
	StringTemplate fragTemplate(frag.str());
	string vertexShaderSource = vertTemplate.specialize(params);
	string fragmentShaderSource = fragTemplate.specialize(params);

	ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
	return de::MovePtr<ShaderIndexingCase>(new ShaderIndexingCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource, varType, false));
}

// ShaderIndexingTests.

class ShaderIndexingTests : public tcu::TestCaseGroup
{
public:
							ShaderIndexingTests		(tcu::TestContext& context);
	virtual					~ShaderIndexingTests	(void);

	virtual void			init					(void);

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

ShaderIndexingTests::ShaderIndexingTests(tcu::TestContext& 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.
	{
		de::MovePtr<TestCaseGroup> varyingGroup(new TestCaseGroup(m_testCtx, "varying_array", "Varying array access tests."));

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
		{
			DataType varType = s_floatAndVecTypes[typeNdx];
			for (int vertAccess = 0; vertAccess < INDEXACCESS_CONST; vertAccess++)
			{
				for (int fragAccess = 0; fragAccess < INDEXACCESS_CONST; 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.";
					de::MovePtr<ShaderIndexingCase> testCase(createVaryingArrayCase(m_testCtx, name, desc, varType, (IndexAccessType)vertAccess, (IndexAccessType)fragAccess));
					varyingGroup->addChild(testCase.release());
				}
			}
		}

		addChild(varyingGroup.release());
	}

	// Uniform array access cases.
	{
		de::MovePtr<TestCaseGroup> uniformGroup(new TestCaseGroup(m_testCtx, "uniform_array", "Uniform array access tests."));

		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
		{
			DataType varType = s_floatAndVecTypes[typeNdx];
			for (int readAccess = 0; readAccess < INDEXACCESS_CONST; 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);
					de::MovePtr<ShaderIndexingCase> testCase(createUniformArrayCase(m_testCtx, name, desc, isVertexCase, varType, (IndexAccessType)readAccess));
					uniformGroup->addChild(testCase.release());
				}
			}
		}

		addChild(uniformGroup.release());
	}

	// Temporary array access cases.
	{
		de::MovePtr<TestCaseGroup> tmpGroup(new TestCaseGroup(m_testCtx, "tmp_array", "Temporary array access tests."));

		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_CONST; 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);
						de::MovePtr<ShaderIndexingCase> testCase(createTmpArrayCase(m_testCtx, name, desc, isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
						tmpGroup->addChild(testCase.release());
					}
				}
			}
		}

		addChild(tmpGroup.release());
	}

	// Vector indexing with subscripts.
	{
		de::MovePtr<TestCaseGroup> vecGroup(new TestCaseGroup(m_testCtx, "vector_subscript", "Vector subscript indexing."));

		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);
						de::MovePtr<ShaderIndexingCase> testCase(createVectorSubscriptCase(m_testCtx, name.c_str(), desc.c_str(), isVertexCase, varType, (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
						vecGroup->addChild(testCase.release());
					}
				}
			}
		}

		addChild(vecGroup.release());
	}

	// Matrix indexing with subscripts.
	{
		de::MovePtr<TestCaseGroup> matGroup(new TestCaseGroup(m_testCtx, "matrix_subscript", "Matrix subscript indexing."));

		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_CONST; writeAccess++)
			{
				for (int readAccess = 0; readAccess < INDEXACCESS_CONST; 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);
						de::MovePtr<ShaderIndexingCase> testCase(createMatrixSubscriptCase(m_testCtx, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
						matGroup->addChild(testCase.release());
					}
				}
			}
		}

		addChild(matGroup.release());
	}
}

} // anonymous

tcu::TestCaseGroup* createIndexingTests (tcu::TestContext& testCtx)
{
	return new ShaderIndexingTests(testCtx);
}

} // sr
} // vkt
