/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 Google Inc.
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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 "glcShaderIndexingTests.hpp"
#include "glcShaderRenderCase.hpp"
#include "gluShaderUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuStringTemplate.hpp"

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

#include <map>

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

namespace deqp
{

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_ASSERT(DE_FALSE && "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_ASSERT(DE_FALSE && "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(deUint32 programID);
	virtual void setupUniforms(deUint32 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(deUint32 programID)
{
	DE_UNREF(programID);
}

void ShaderIndexingCase::setupUniforms(deUint32 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
			DE_TEST_ASSERT(false);
	}
}

// Helpers.

static ShaderIndexingCase* createVaryingArrayCase(Context& context, const char* caseName, const char* description,
												  glu::GLSLVersion glslVersion, DataType varType,
												  IndexAccessType vertAccess, IndexAccessType fragAccess)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  glslVersion >= glu::GLSL_VERSION_330);

	std::ostringstream vtx;
	vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\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 << glu::getGLSLVersionDeclaration(glslVersion) << "\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,
												  glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
												  IndexAccessType readAccess)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  glslVersion >= glu::GLSL_VERSION_330);

	std::ostringstream  vtx;
	std::ostringstream  frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	frag << glu::getGLSLVersionDeclaration(glslVersion) << "\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,
											  glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
											  IndexAccessType writeAccess, IndexAccessType readAccess)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  glslVersion >= glu::GLSL_VERSION_330);

	std::ostringstream  vtx;
	std::ostringstream  frag;
	std::ostringstream& op = isVertexCase ? vtx : frag;

	vtx << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	frag << glu::getGLSLVersionDeclaration(glslVersion) << "\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());
}

void evalGreenColor (ShaderEvalContext& c)
{
    c.color = Vec4(0.0f, 1.0f, 0.0f, 1.0f);
}

static ShaderIndexingCase* createTmpArrayVertexIdCase (Context& context, const char* caseName, const char* description,
													   glu::GLSLVersion glslVersion)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  glslVersion >= glu::GLSL_VERSION_330);

	std::string vtx = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n"
		"precision highp float;\n"
		"in vec4 a_position;\n"
		"out float color[4];\n"
		"void main()\n"
		"{\n"
		"    for(int i = 0; i < 4; i++)\n"
		"    {\n"
		"        int j = (gl_VertexID + i) % 4;\n"
		"        color[j] = (j % 2 == 0) ? 0.0 : 1.0;\n"
		"    }\n"
		"    gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
		"}\n");

	std::string frag = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n"
		"precision highp float;\n"
		"in float color[4];\n"
		"layout(location = 0) out vec4 o_color;\n"
		"void main()\n"
		"{\n"
		"    float temp[4];\n"
		"    for(int i = 0; i < 4; i++)\n"
		"    {\n"
		"        temp[i] = color[i];\n"
		"        o_color = vec4(temp[0], temp[1], temp[2], temp[3]);\n"
		"    }\n"
		"}\n");

	return new ShaderIndexingCase(context, caseName, description, false, TYPE_FLOAT, evalGreenColor,
								  vtx.c_str(), frag.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_ASSERT(DE_FALSE && "Invalid data type.");
	return NULL;
}

static ShaderIndexingCase* createVectorSubscriptCase(Context& context, const char* caseName, const char* description,
													 glu::GLSLVersion glslVersion, 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 << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	frag << glu::getGLSLVersionDeclaration(glslVersion) << "\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_ASSERT(DE_FALSE && "Invalid data type.");
		return DE_NULL;
	}
}

static ShaderIndexingCase* createMatrixSubscriptCase(Context& context, const char* caseName, const char* description,
													 glu::GLSLVersion glslVersion, bool isVertexCase, DataType varType,
													 IndexAccessType writeAccess, IndexAccessType readAccess)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  glslVersion >= glu::GLSL_VERSION_330);

	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 << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	frag << glu::getGLSLVersionDeclaration(glslVersion) << "\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, glu::GLSLVersion glslVersion)
	: TestCaseGroup(context, "indexing", "Indexing Tests"), m_glslVersion(glslVersion)
{
}

ShaderIndexingTests::~ShaderIndexingTests(void)
{
}

void ShaderIndexingTests::init(void)
{
	static const DataType s_floatAndVecTypes[] = { TYPE_FLOAT, TYPE_FLOAT_VEC2, TYPE_FLOAT_VEC3, TYPE_FLOAT_VEC4 };

	static const ShaderType s_shaderTypes[] = { SHADERTYPE_VERTEX, SHADERTYPE_FRAGMENT };

	// 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++)
				{
					if (vertAccess == INDEXACCESS_STATIC && fragAccess == INDEXACCESS_STATIC)
						continue;

					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(), m_glslVersion,
																  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)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(), m_glslVersion,
																  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 isReadStatic = 0; isReadStatic < 2; isReadStatic++)
			{
				for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++)
				{
					IndexAccessType readAccess  = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access;
					IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC;

					const char* writeAccessName = getIndexAccessTypeName(writeAccess);
					const char* readAccessName  = getIndexAccessTypeName(readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType  shaderType	 = s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName = getShaderTypeName((ShaderType)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(), m_glslVersion,
															  isVertexCase, varType, (IndexAccessType)writeAccess,
															  (IndexAccessType)readAccess));
					}
				}
			}
		}

		tmpGroup->addChild(createTmpArrayVertexIdCase(m_context, "vertexid", "", m_glslVersion));
	}

	// 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 isReadDirect = 0; isReadDirect < 2; isReadDirect++)
			{
				for (int access = SUBSCRIPT_STATIC; access < VECTORACCESS_LAST; access++)
				{
					VectorAccessType readAccess  = isReadDirect ? DIRECT : (VectorAccessType)access;
					VectorAccessType writeAccess = isReadDirect ? (VectorAccessType)access : DIRECT;

					const char* writeAccessName = getVectorAccessTypeName(writeAccess);
					const char* readAccessName  = getVectorAccessTypeName(readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType  shaderType	 = s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName = getShaderTypeName((ShaderType)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(), m_glslVersion, 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 isReadStatic = 0; isReadStatic < 2; isReadStatic++)
			{
				for (int access = INDEXACCESS_STATIC + 1; access < INDEXACCESS_LAST; access++)
				{
					IndexAccessType readAccess  = isReadStatic ? INDEXACCESS_STATIC : (IndexAccessType)access;
					IndexAccessType writeAccess = isReadStatic ? (IndexAccessType)access : INDEXACCESS_STATIC;

					const char* writeAccessName = getIndexAccessTypeName(writeAccess);
					const char* readAccessName  = getIndexAccessTypeName(readAccess);

					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
					{
						ShaderType  shaderType	 = s_shaderTypes[shaderTypeNdx];
						const char* shaderTypeName = getShaderTypeName((ShaderType)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(), m_glslVersion, isVertexCase, varType,
							(IndexAccessType)writeAccess, (IndexAccessType)readAccess));
					}
				}
			}
		}
	}
}

} // deqp
