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