13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader indexing (arrays, vector, matrices) tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderIndexingTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderRenderCase.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace std;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace tcu;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glu;
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace deqp::gls;
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum IndexAccessType
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INDEXACCESS_STATIC = 0,
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INDEXACCESS_DYNAMIC,
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INDEXACCESS_STATIC_LOOP,
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INDEXACCESS_DYNAMIC_LOOP,
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	INDEXACCESS_LAST
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getIndexAccessTypeName (IndexAccessType accessType)
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[INDEXACCESS_LAST] =
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"static",
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic",
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"static_loop",
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic_loop"
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)accessType, 0, INDEXACCESS_LAST));
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)accessType];
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum VectorAccessType
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DIRECT = 0,
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	COMPONENT,
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SUBSCRIPT_STATIC,
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SUBSCRIPT_DYNAMIC,
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SUBSCRIPT_STATIC_LOOP,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SUBSCRIPT_DYNAMIC_LOOP,
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VECTORACCESS_LAST
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getVectorAccessTypeName (VectorAccessType accessType)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_names[VECTORACCESS_LAST] =
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"direct",
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"component",
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"static_subscript",
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic_subscript",
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"static_loop_subscript",
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"dynamic_loop_subscript"
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(deInBounds32((int)accessType, 0, VECTORACCESS_LAST));
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s_names[(int)accessType];
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayCoordsFloat		(ShaderEvalContext& c) { c.color.x()	= 1.875f * c.coords.x(); }
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayCoordsVec2		(ShaderEvalContext& c) { c.color.xy()	= 1.875f * c.coords.swizzle(0,1); }
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayCoordsVec3		(ShaderEvalContext& c) { c.color.xyz()	= 1.875f * c.coords.swizzle(0,1,2); }
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayCoordsVec4		(ShaderEvalContext& c) { c.color		= 1.875f * c.coords; }
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getArrayCoordsEvalFunc (DataType dataType)
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (dataType == TYPE_FLOAT)				return evalArrayCoordsFloat;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC2)	return evalArrayCoordsVec2;
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC3)	return evalArrayCoordsVec3;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC4)	return evalArrayCoordsVec4;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid data type.");
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return NULL;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayUniformFloat		(ShaderEvalContext& c) { c.color.x()	= 1.875f * c.constCoords.x(); }
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayUniformVec2		(ShaderEvalContext& c) { c.color.xy()	= 1.875f * c.constCoords.swizzle(0,1); }
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayUniformVec3		(ShaderEvalContext& c) { c.color.xyz()	= 1.875f * c.constCoords.swizzle(0,1,2); }
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalArrayUniformVec4		(ShaderEvalContext& c) { c.color		= 1.875f * c.constCoords; }
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getArrayUniformEvalFunc (DataType dataType)
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (dataType == TYPE_FLOAT)				return evalArrayUniformFloat;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC2)	return evalArrayUniformVec2;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC3)	return evalArrayUniformVec3;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC4)	return evalArrayUniformVec4;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid data type.");
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return NULL;
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderIndexingCase
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderIndexingCase : public ShaderRenderCase
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderIndexingCase		(Context& context, const char* name, const char* description, bool isVertexCase, DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual						~ShaderIndexingCase		(void);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderIndexingCase		(const ShaderIndexingCase&);	// not allowed!
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderIndexingCase&			operator=				(const ShaderIndexingCase&);	// not allowed!
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setup					(int programID);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void				setupUniforms			(int programID, const Vec4& constCoords);
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType					m_varType;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIndexingCase::ShaderIndexingCase (Context& context, const char* name, const char* description, bool isVertexCase, DataType varType, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_varType			= varType;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertShaderSource	= vertShaderSource;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_fragShaderSource	= fragShaderSource;
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIndexingCase::~ShaderIndexingCase (void)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIndexingCase::setup (int programID)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(programID);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIndexingCase::setupUniforms (int programID, const Vec4& constCoords)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(constCoords);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int arrLoc = gl.getUniformLocation(programID, "u_arr");
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (arrLoc != -1)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//int scalarSize = getDataTypeScalarSize(m_varType);
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_varType == TYPE_FLOAT)
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float arr[4];
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[0] = constCoords.x();
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[1] = constCoords.x() * 0.5f;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[2] = constCoords.x() * 0.25f;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[3] = constCoords.x() * 0.125f;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform1fv(arrLoc, 4, &arr[0]);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_varType == TYPE_FLOAT_VEC2)
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec2 arr[4];
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[0] = constCoords.swizzle(0,1);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[1] = constCoords.swizzle(0,1) * 0.5f;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[2] = constCoords.swizzle(0,1) * 0.25f;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[3] = constCoords.swizzle(0,1) * 0.125f;
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform2fv(arrLoc, 4, arr[0].getPtr());
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_varType == TYPE_FLOAT_VEC3)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec3 arr[4];
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[0] = constCoords.swizzle(0,1,2);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[1] = constCoords.swizzle(0,1,2) * 0.5f;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[2] = constCoords.swizzle(0,1,2) * 0.25f;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[3] = constCoords.swizzle(0,1,2) * 0.125f;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform3fv(arrLoc, 4, arr[0].getPtr());
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_varType == TYPE_FLOAT_VEC4)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4 arr[4];
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[0] = constCoords.swizzle(0,1,2,3);
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[1] = constCoords.swizzle(0,1,2,3) * 0.5f;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[2] = constCoords.swizzle(0,1,2,3) * 0.25f;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			arr[3] = constCoords.swizzle(0,1,2,3) * 0.125f;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.uniform4fv(arrLoc, 4, arr[0].getPtr());
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::TestError("u_arr should not have location assigned in this test case");
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Helpers.
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderIndexingCase* createVaryingArrayCase (Context& context, const char* caseName, const char* description, DataType varType, IndexAccessType vertAccess, IndexAccessType fragAccess)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertAccess == INDEXACCESS_DYNAMIC)
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (vertAccess == INDEXACCESS_DYNAMIC_LOOP)
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "uniform mediump int ui_four;\n";
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertAccess == INDEXACCESS_STATIC)
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[0] = ${VAR_TYPE}(a_coords);\n";
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n";
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n";
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n";
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (vertAccess == INDEXACCESS_DYNAMIC)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[ui_zero]  = ${VAR_TYPE}(a_coords);\n";
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[ui_one]   = ${VAR_TYPE}(a_coords) * 0.5;\n";
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[ui_two]   = ${VAR_TYPE}(a_coords) * 0.25;\n";
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n";
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (vertAccess == INDEXACCESS_STATIC_LOOP)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	for (int i = 0; i < 4; i++)\n";
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	{\n";
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "		var[i] = ${VAR_TYPE}(coords);\n";
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "		coords = coords * 0.5;\n";
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	}\n";
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(vertAccess == INDEXACCESS_DYNAMIC_LOOP);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	for (int i = 0; i < ui_four; i++)\n";
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	{\n";
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "		var[i] = ${VAR_TYPE}(coords);\n";
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "		coords = coords * 0.5;\n";
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	}\n";
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "precision mediump int;\n";
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fragAccess == INDEXACCESS_DYNAMIC)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (fragAccess == INDEXACCESS_DYNAMIC_LOOP)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "uniform int ui_four;\n";
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n";
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (fragAccess == INDEXACCESS_STATIC)
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[0];\n";
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[1];\n";
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[2];\n";
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[3];\n";
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (fragAccess == INDEXACCESS_DYNAMIC)
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[ui_zero];\n";
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[ui_one];\n";
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[ui_two];\n";
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	res += var[ui_three];\n";
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (fragAccess == INDEXACCESS_STATIC_LOOP)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	for (int i = 0; i < 4; i++)\n";
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "		res += var[i];\n";
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(fragAccess == INDEXACCESS_DYNAMIC_LOOP);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	for (int i = 0; i < ui_four; i++)\n";
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "		res += var[i];\n";
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "	o_color = vec4(res${PADDING});\n";
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ARRAY_LEN", "4"));
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType == TYPE_FLOAT)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC2)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC3)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 1.0"));
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ""));
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderIndexingCase(context, caseName, description, true, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderIndexingCase* createUniformArrayCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType readAccess)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_color;\n";
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_color;\n";
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (readAccess == INDEXACCESS_DYNAMIC)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_DYNAMIC_LOOP)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_four;\n";
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n";
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (readAccess == INDEXACCESS_STATIC)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[0];\n";
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[1];\n";
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[2];\n";
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[3];\n";
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_DYNAMIC)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[ui_zero];\n";
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[ui_one];\n";
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[ui_two];\n";
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += u_arr[ui_three];\n";
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_STATIC_LOOP)
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < 4; i++)\n";
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += u_arr[i];\n";
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < ui_four; i++)\n";
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += u_arr[i];\n";
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = vec4(res${PADDING});\n";
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = v_color;\n";
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(res${PADDING});\n";
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ARRAY_LEN", "4"));
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType == TYPE_FLOAT)
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC2)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC3)
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 1.0"));
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ""));
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getArrayUniformEvalFunc(varType);
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderIndexingCase* createTmpArrayCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType writeAccess, IndexAccessType readAccess)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_color;\n";
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_color;\n";
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n";
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_four;\n";
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Write array.
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n";
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_STATIC)
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[0] = ${VAR_TYPE}(coords);\n";
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[1] = ${VAR_TYPE}(coords) * 0.5;\n";
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[2] = ${VAR_TYPE}(coords) * 0.25;\n";
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[3] = ${VAR_TYPE}(coords) * 0.125;\n";
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == INDEXACCESS_DYNAMIC)
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[ui_zero]  = ${VAR_TYPE}(coords);\n";
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[ui_one]   = ${VAR_TYPE}(coords) * 0.5;\n";
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[ui_two]   = ${VAR_TYPE}(coords) * 0.25;\n";
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n";
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == INDEXACCESS_STATIC_LOOP)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < 4; i++)\n";
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		arr[i] = ${VAR_TYPE}(coords);\n";
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords * 0.5;\n";
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < ui_four; i++)\n";
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		arr[i] = ${VAR_TYPE}(coords);\n";
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords * 0.5;\n";
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read array.
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n";
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (readAccess == INDEXACCESS_STATIC)
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[0];\n";
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[1];\n";
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[2];\n";
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[3];\n";
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_DYNAMIC)
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[ui_zero];\n";
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[ui_one];\n";
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[ui_two];\n";
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += arr[ui_three];\n";
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_STATIC_LOOP)
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < 4; i++)\n";
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += arr[i];\n";
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < ui_four; i++)\n";
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += arr[i];\n";
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = vec4(res${PADDING});\n";
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = v_color;\n";
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(res${PADDING});\n";
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ARRAY_LEN", "4"));
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType == TYPE_FLOAT)
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 0.0, 1.0"));
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC2)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType == TYPE_FLOAT_VEC3)
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 1.0"));
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ""));
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getArrayCoordsEvalFunc(varType);
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// VECTOR SUBSCRIPT.
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalSubscriptVec2 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y()); }
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalSubscriptVec3 (ShaderEvalContext& c) { c.color.xyz() = Vec3(c.coords.x() + 0.5f*c.coords.y() + 0.25f*c.coords.z()); }
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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()); }
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getVectorSubscriptEvalFunc (DataType dataType)
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (dataType == TYPE_FLOAT_VEC2)		return evalSubscriptVec2;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC3)	return evalSubscriptVec3;
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (dataType == TYPE_FLOAT_VEC4)	return evalSubscriptVec4;
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!"Invalid data type.");
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return NULL;
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderIndexingCase* createVectorSubscriptCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, VectorAccessType writeAccess, VectorAccessType readAccess)
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			vecLen		= getDataTypeScalarSize(varType);
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*	vecLenName	= getIntUniformName(vecLen);
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec3 v_color;\n";
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec3 v_color;\n";
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == SUBSCRIPT_DYNAMIC || readAccess == SUBSCRIPT_DYNAMIC)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_zero";
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << ", ui_one";
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << ", ui_two";
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << ", ui_three";
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << ";\n";
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == SUBSCRIPT_DYNAMIC_LOOP || readAccess == SUBSCRIPT_DYNAMIC_LOOP)
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int " << vecLenName << ";\n";
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Write vector.
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n";
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n";
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${VAR_TYPE} tmp;\n";
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == DIRECT)
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n";
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == COMPONENT)
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp.x = coords.x;\n";
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	tmp.y = coords.y * 0.5;\n";
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	tmp.z = coords.z * 0.25;\n";
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	tmp.w = coords.w * 0.125;\n";
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == SUBSCRIPT_STATIC)
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp[0] = coords.x;\n";
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	tmp[1] = coords.y * 0.5;\n";
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	tmp[2] = coords.z * 0.25;\n";
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	tmp[3] = coords.w * 0.125;\n";
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == SUBSCRIPT_DYNAMIC)
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp[ui_zero]  = coords.x;\n";
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	tmp[ui_one]   = coords.y * 0.5;\n";
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	tmp[ui_two]   = coords.z * 0.25;\n";
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	tmp[ui_three] = coords.w * 0.125;\n";
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == SUBSCRIPT_STATIC_LOOP)
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << vecLen << "; i++)\n";
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		tmp[i] = coords.x;\n";
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords.${ROT_SWIZZLE} * 0.5;\n";
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(writeAccess == SUBSCRIPT_DYNAMIC_LOOP);
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << vecLenName << "; i++)\n";
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		tmp[i] = coords.x;\n";
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords.${ROT_SWIZZLE} * 0.5;\n";
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read vector.
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} float res = 0.0;\n";
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (readAccess == DIRECT)
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res = dot(tmp, ${VAR_TYPE}(1.0));\n";
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == COMPONENT)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += tmp.x;\n";
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	res += tmp.y;\n";
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	res += tmp.z;\n";
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	res += tmp.w;\n";
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == SUBSCRIPT_STATIC)
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += tmp[0];\n";
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	res += tmp[1];\n";
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	res += tmp[2];\n";
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	res += tmp[3];\n";
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == SUBSCRIPT_DYNAMIC)
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += tmp[ui_zero];\n";
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 2) op << "	res += tmp[ui_one];\n";
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 3) op << "	res += tmp[ui_two];\n";
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vecLen >= 4) op << "	res += tmp[ui_three];\n";
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == SUBSCRIPT_STATIC_LOOP)
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << vecLen << "; i++)\n";
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += tmp[i];\n";
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(readAccess == SUBSCRIPT_DYNAMIC_LOOP);
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << vecLenName << "; i++)\n";
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += tmp[i];\n";
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = vec3(res);\n";
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(v_color.rgb, 1.0);\n";
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(vec3(res), 1.0);\n";
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_swizzles[5]	= { "", "x", "xy", "xyz", "xyzw" };
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const char* s_rotSwizzles[5]	= { "", "x", "yx", "yzx", "yzwx" };
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("VAR_TYPE", getDataTypeName(varType)));
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("SWIZZLE", s_swizzles[vecLen]));
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("ROT_SWIZZLE", s_rotSwizzles[vecLen]));
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getVectorSubscriptEvalFunc(varType);
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// MATRIX SUBSCRIPT.
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalSubscriptMat2		(ShaderEvalContext& c) { c.color.xy()	= c.coords.swizzle(0,1) + 0.5f*c.coords.swizzle(1,2); }
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalSubscriptMat2x3	(ShaderEvalContext& c) { c.color.xyz()	= c.coords.swizzle(0,1,2) + 0.5f*c.coords.swizzle(1,2,3); }
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid evalSubscriptMat2x4	(ShaderEvalContext& c) { c.color		= c.coords.swizzle(0,1,2,3) + 0.5f*c.coords.swizzle(1,2,3,0); }
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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); }
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderEvalFunc getMatrixSubscriptEvalFunc (DataType dataType)
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (dataType)
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2:		return evalSubscriptMat2;
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2X3:		return evalSubscriptMat2x3;
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT2X4:		return evalSubscriptMat2x4;
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3X2:		return evalSubscriptMat3x2;
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3:		return evalSubscriptMat3;
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT3X4:		return evalSubscriptMat3x4;
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4X2:		return evalSubscriptMat4x2;
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4X3:		return evalSubscriptMat4x3;
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case TYPE_FLOAT_MAT4:		return evalSubscriptMat4;
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!"Invalid data type.");
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic ShaderIndexingCase* createMatrixSubscriptCase (Context& context, const char* caseName, const char* description, bool isVertexCase, DataType varType, IndexAccessType writeAccess, IndexAccessType readAccess)
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream vtx;
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream frag;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream& op = isVertexCase ? vtx : frag;
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			numCols		= getDataTypeMatrixNumColumns(varType);
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			numRows		= getDataTypeMatrixNumRows(varType);
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char*	matSizeName	= getIntUniformName(numCols);
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataType	vecType		= getDataTypeFloatVec(numRows);
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "#version 300 es\n";
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "#version 300 es\n";
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_position;\n";
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "in highp vec4 a_coords;\n";
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "layout(location = 0) out mediump vec4 o_color;\n";
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_color;\n";
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_color;\n";
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "out mediump vec4 v_coords;\n";
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "in mediump vec4 v_coords;\n";
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_DYNAMIC || readAccess == INDEXACCESS_DYNAMIC)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int ui_zero";
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 2) op << ", ui_one";
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 3) op << ", ui_two";
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 4) op << ", ui_three";
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << ";\n";
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_DYNAMIC_LOOP || readAccess == INDEXACCESS_DYNAMIC_LOOP)
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "uniform mediump int " << matSizeName << ";\n";
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "\n";
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "void main()\n";
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "{\n";
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "	gl_Position = a_position;\n";
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "\n";
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "void main()\n";
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "{\n";
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Write matrix.
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} vec4 coords = a_coords;\n";
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	${PRECISION} vec4 coords = v_coords;\n";
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${MAT_TYPE} tmp;\n";
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (writeAccess == INDEXACCESS_STATIC)
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp[0] = ${VEC_TYPE}(coords);\n";
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 2) op << "	tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 3) op << "	tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 4) op << "	tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == INDEXACCESS_DYNAMIC)
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	tmp[ui_zero]  = ${VEC_TYPE}(coords);\n";
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 2) op << "	tmp[ui_one]   = ${VEC_TYPE}(coords.yzwx) * 0.5;\n";
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 3) op << "	tmp[ui_two]   = ${VEC_TYPE}(coords.zwxy) * 0.25;\n";
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 4) op << "	tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n";
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (writeAccess == INDEXACCESS_STATIC_LOOP)
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << numCols << "; i++)\n";
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		tmp[i] = ${VEC_TYPE}(coords);\n";
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords.yzwx * 0.5;\n";
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(writeAccess == INDEXACCESS_DYNAMIC_LOOP);
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << matSizeName << "; i++)\n";
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	{\n";
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		tmp[i] = ${VEC_TYPE}(coords);\n";
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		coords = coords.yzwx * 0.5;\n";
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	}\n";
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read matrix.
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	op << "	${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n";
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (readAccess == INDEXACCESS_STATIC)
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += tmp[0];\n";
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 2) op << "	res += tmp[1];\n";
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 3) op << "	res += tmp[2];\n";
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 4) op << "	res += tmp[3];\n";
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_DYNAMIC)
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	res += tmp[ui_zero];\n";
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 2) op << "	res += tmp[ui_one];\n";
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 3) op << "	res += tmp[ui_two];\n";
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (numCols >= 4) op << "	res += tmp[ui_three];\n";
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (readAccess == INDEXACCESS_STATIC_LOOP)
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << numCols << "; i++)\n";
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += tmp[i];\n";
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(readAccess == INDEXACCESS_DYNAMIC_LOOP);
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "	for (int i = 0; i < " << matSizeName << "; i++)\n";
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		op << "		res += tmp[i];\n";
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_color = vec4(res${PADDING});\n";
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = v_color;\n";
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vtx << "	v_coords = a_coords;\n";
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		frag << "	o_color = vec4(res${PADDING});\n";
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vtx << "}\n";
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	frag << "}\n";
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Fill in shader templates.
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	map<string, string> params;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("MAT_TYPE", getDataTypeName(varType)));
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("VEC_TYPE", getDataTypeName(vecType)));
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params.insert(pair<string, string>("PRECISION", "mediump"));
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (numRows == 2)
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 0.0, 1.0"));
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (numRows == 3)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ", 1.0"));
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params.insert(pair<string, string>("PADDING", ""));
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate vertTemplate(vtx.str().c_str());
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	StringTemplate fragTemplate(frag.str().c_str());
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string vertexShaderSource = vertTemplate.specialize(params);
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string fragmentShaderSource = fragTemplate.specialize(params);
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderEvalFunc evalFunc = getMatrixSubscriptEvalFunc(varType);
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return new ShaderIndexingCase(context, caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderIndexingTests.
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIndexingTests::ShaderIndexingTests(Context& context)
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "indexing", "Indexing Tests")
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIndexingTests::~ShaderIndexingTests (void)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIndexingTests::init (void)
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const ShaderType s_shaderTypes[] =
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_VERTEX,
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		SHADERTYPE_FRAGMENT
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const DataType s_floatAndVecTypes[] =
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT,
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC2,
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC3,
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TYPE_FLOAT_VEC4
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Varying array access cases.
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* varyingGroup = new TestCaseGroup(m_context, "varying_array", "Varying array access tests.");
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(varyingGroup);
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType varType = s_floatAndVecTypes[typeNdx];
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int vertAccess = 0; vertAccess < INDEXACCESS_LAST; vertAccess++)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int fragAccess = 0; fragAccess < INDEXACCESS_LAST; fragAccess++)
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* vertAccessName = getIndexAccessTypeName((IndexAccessType)vertAccess);
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* fragAccessName = getIndexAccessTypeName((IndexAccessType)fragAccess);
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string name = string(getDataTypeName(varType)) + "_" + vertAccessName + "_write_" + fragAccessName + "_read";
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string desc = string("Varying array with ") + vertAccessName + " write in vertex shader and " + fragAccessName + " read in fragment shader.";
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					varyingGroup->addChild(createVaryingArrayCase(m_context, name.c_str(), desc.c_str(), varType, (IndexAccessType)vertAccess, (IndexAccessType)fragAccess));
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Uniform array access cases.
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* uniformGroup = new TestCaseGroup(m_context, "uniform_array", "Uniform array access tests.");
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(uniformGroup);
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType varType = s_floatAndVecTypes[typeNdx];
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char*	shaderTypeName	= getShaderTypeName(shaderType);
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string		name			= string(getDataTypeName(varType)) + "_" + readAccessName + "_read_" + shaderTypeName;
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string		desc			= string("Uniform array with ") + readAccessName + " read in " + shaderTypeName + " shader.";
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					bool isVertexCase = ((ShaderType)shaderType == SHADERTYPE_VERTEX);
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniformGroup->addChild(createUniformArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)readAccess));
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Temporary array access cases.
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* tmpGroup = new TestCaseGroup(m_context, "tmp_array", "Temporary array access tests.");
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(tmpGroup);
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_floatAndVecTypes); typeNdx++)
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType varType = s_floatAndVecTypes[typeNdx];
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char* shaderTypeName	= getShaderTypeName(shaderType);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		desc			= string("Temporary array with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						tmpGroup->addChild(createTmpArrayCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Vector indexing with subscripts.
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* vecGroup = new TestCaseGroup(m_context, "vector_subscript", "Vector subscript indexing.");
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(vecGroup);
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const DataType s_vectorTypes[] =
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_VEC2,
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_VEC3,
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_VEC4
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_vectorTypes); typeNdx++)
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType varType = s_vectorTypes[typeNdx];
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int writeAccess = 0; writeAccess < VECTORACCESS_LAST; writeAccess++)
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int readAccess = 0; readAccess < VECTORACCESS_LAST; readAccess++)
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* writeAccessName = getVectorAccessTypeName((VectorAccessType)writeAccess);
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* readAccessName = getVectorAccessTypeName((VectorAccessType)readAccess);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char* shaderTypeName	= getShaderTypeName(shaderType);
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		desc			= string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						vecGroup->addChild(createVectorSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (VectorAccessType)writeAccess, (VectorAccessType)readAccess));
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Matrix indexing with subscripts.
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* matGroup = new TestCaseGroup(m_context, "matrix_subscript", "Matrix subscript indexing.");
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addChild(matGroup);
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const DataType s_matrixTypes[] =
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT2,
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT2X3,
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT2X4,
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT3X2,
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT3,
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT3X4,
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT4X2,
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT4X3,
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT_MAT4
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_matrixTypes); typeNdx++)
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DataType varType = s_matrixTypes[typeNdx];
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int writeAccess = 0; writeAccess < INDEXACCESS_LAST; writeAccess++)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int readAccess = 0; readAccess < INDEXACCESS_LAST; readAccess++)
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* writeAccessName = getIndexAccessTypeName((IndexAccessType)writeAccess);
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const char* readAccessName = getIndexAccessTypeName((IndexAccessType)readAccess);
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(s_shaderTypes); shaderTypeNdx++)
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderType	shaderType		= s_shaderTypes[shaderTypeNdx];
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						const char* shaderTypeName	= getShaderTypeName(shaderType);
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		name			= string(getDataTypeName(varType)) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string		desc			= string("Vector subscript access with ") + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						bool		isVertexCase	= ((ShaderType)shaderType == SHADERTYPE_VERTEX);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						matGroup->addChild(createMatrixSubscriptCase(m_context, name.c_str(), desc.c_str(), isVertexCase, varType, (IndexAccessType)writeAccess, (IndexAccessType)readAccess));
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1139