13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 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 Program interface
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramInterfaceDefinition.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace ProgramInterfaceDefinition
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const glu::ShaderType s_shaderStageOrder[] =
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_COMPUTE,
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_VERTEX,
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_TESSELLATION_CONTROL,
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_TESSELLATION_EVALUATION,
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_GEOMETRY,
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::SHADERTYPE_FRAGMENT
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// s_shaderStageOrder does not contain ShaderType_LAST
553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_shaderStageOrder) == glu::SHADERTYPE_LAST);
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool containsMatchingSubtype (const glu::VarType& varType, bool (*predicate)(glu::DataType))
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType() && predicate(varType.getBasicType()))
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isArrayType())
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return containsMatchingSubtype(varType.getElementType(), predicate);
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isStructType())
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int memberNdx = 0; memberNdx < varType.getStructPtr()->getNumMembers(); ++memberNdx)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsMatchingSubtype(varType.getStructPtr()->getMember(memberNdx).getType(), predicate))
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool containsMatchingSubtype (const std::vector<glu::VariableDeclaration>& decls, bool (*predicate)(glu::DataType))
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int varNdx = 0; varNdx < (int)decls.size(); ++varNdx)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (containsMatchingSubtype(decls[varNdx].varType, predicate))
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isOpaqueType (glu::DataType type)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return	glu::isDataTypeAtomicCounter(type)	||
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::isDataTypeImage(type)			||
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glu::isDataTypeSampler(type);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getShaderStageIndex (glu::ShaderType stage)
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderType* const it = std::find(DE_ARRAY_BEGIN(s_shaderStageOrder), DE_ARRAY_END(s_shaderStageOrder), stage);
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (it == DE_ARRAY_END(s_shaderStageOrder))
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return -1;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int index = (int)(it - DE_ARRAY_BEGIN(s_shaderStageOrder));
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return index;
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShader::Shader (glu::ShaderType type, glu::GLSLVersion version)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_shaderType	(type)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_version		(version)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShader::~Shader (void)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isIllegalVertexInput (const glu::VarType& varType)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// booleans, opaque types, arrays, structs are not allowed as inputs
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!varType.isBasicType())
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isDataTypeBoolOrBVec(varType.getBasicType()))
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return false;
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isIllegalVertexOutput (const glu::VarType& varType, bool insideAStruct = false, bool insideAnArray = false)
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// booleans, opaque types, arrays of arrays, arrays of structs, array in struct, struct struct are not allowed as vertex outputs
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOpaqueType = !glu::isDataTypeScalar(varType.getBasicType()) && !glu::isDataTypeVector(varType.getBasicType()) && !glu::isDataTypeMatrix(varType.getBasicType());
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeBoolOrBVec(varType.getBasicType()))
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isOpaqueType)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (insideAnArray || insideAStruct)
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isIllegalVertexOutput(varType.getElementType(), insideAStruct, true);
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isStructType())
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (insideAnArray || insideAStruct)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx)
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isIllegalVertexOutput(varType.getStructPtr()->getMember(ndx).getType(), true, insideAnArray))
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isIllegalFragmentInput (const glu::VarType& varType)
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return isIllegalVertexOutput(varType);
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isIllegalFragmentOutput (const glu::VarType& varType, bool insideAnArray = false)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// booleans, opaque types, matrices, structs, arrays of arrays are not allowed as outputs
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOpaqueType = !glu::isDataTypeScalar(varType.getBasicType()) && !glu::isDataTypeVector(varType.getBasicType()) && !glu::isDataTypeMatrix(varType.getBasicType());
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (glu::isDataTypeBoolOrBVec(varType.getBasicType()) || isOpaqueType || glu::isDataTypeMatrix(varType.getBasicType()))
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (insideAnArray)
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isIllegalFragmentOutput(varType.getElementType(), true);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isStructType())
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isTypeIntegerOrContainsIntegers (const glu::VarType& varType)
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (varType.isBasicType())
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::isDataTypeIntOrIVec(varType.getBasicType()) || glu::isDataTypeUintOrUVec(varType.getBasicType());
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isArrayType())
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return isTypeIntegerOrContainsIntegers(varType.getElementType());
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (varType.isStructType())
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isTypeIntegerOrContainsIntegers(varType.getStructPtr()->getMember(ndx).getType()))
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return true;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(false);
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Shader::isValid (void) const
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Default block variables
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int varNdx = 0; varNdx < (int)m_defaultBlock.variables.size(); ++varNdx)
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// atomic declaration in the default block without binding
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].layout.binding == -1 &&
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				containsMatchingSubtype(m_defaultBlock.variables[varNdx].varType, glu::isDataTypeAtomicCounter))
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// atomic declaration in a struct
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].varType.isStructType() &&
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				containsMatchingSubtype(m_defaultBlock.variables[varNdx].varType, glu::isDataTypeAtomicCounter))
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Unsupported layout qualifiers
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].layout.matrixOrder != glu::MATRIXORDER_LAST)
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsMatchingSubtype(m_defaultBlock.variables[varNdx].varType, glu::isDataTypeSampler))
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const glu::Layout layoutWithLocationAndBinding(m_defaultBlock.variables[varNdx].layout.location, m_defaultBlock.variables[varNdx].layout.binding);
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (m_defaultBlock.variables[varNdx].layout != layoutWithLocationAndBinding)
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Interface blocks
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int interfaceNdx = 0; interfaceNdx < (int)m_defaultBlock.interfaceBlocks.size(); ++interfaceNdx)
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// ES31 disallows interface block array arrays
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.interfaceBlocks[interfaceNdx].dimensions.size() > 1)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Interface block arrays must have instance name
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!m_defaultBlock.interfaceBlocks[interfaceNdx].dimensions.empty() && m_defaultBlock.interfaceBlocks[interfaceNdx].instanceName.empty())
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Opaque types in interface block
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (containsMatchingSubtype(m_defaultBlock.interfaceBlocks[interfaceNdx].variables, isOpaqueType))
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Shader type specific
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_shaderType == glu::SHADERTYPE_VERTEX)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int varNdx = 0; varNdx < (int)m_defaultBlock.variables.size(); ++varNdx)
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_IN && isIllegalVertexInput(m_defaultBlock.variables[varNdx].varType))
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_OUT && isIllegalVertexOutput(m_defaultBlock.variables[varNdx].varType))
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_OUT && m_defaultBlock.variables[varNdx].interpolation != glu::INTERPOLATION_FLAT && isTypeIntegerOrContainsIntegers(m_defaultBlock.variables[varNdx].varType))
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_shaderType == glu::SHADERTYPE_FRAGMENT)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int varNdx = 0; varNdx < (int)m_defaultBlock.variables.size(); ++varNdx)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_IN && isIllegalFragmentInput(m_defaultBlock.variables[varNdx].varType))
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_IN && m_defaultBlock.variables[varNdx].interpolation != glu::INTERPOLATION_FLAT && isTypeIntegerOrContainsIntegers(m_defaultBlock.variables[varNdx].varType))
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_defaultBlock.variables[varNdx].storage == glu::STORAGE_OUT && isIllegalFragmentOutput(m_defaultBlock.variables[varNdx].varType))
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return false;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgram::Program (void)
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_separable	(false)
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_xfbMode		(0)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void collectStructPtrs (std::set<const glu::StructType*>& dst, const glu::VarType& type)
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type.isArrayType())
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		collectStructPtrs(dst, type.getElementType());
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (type.isStructType())
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.insert(type.getStructPtr());
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int memberNdx = 0; memberNdx < type.getStructPtr()->getNumMembers(); ++memberNdx)
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			collectStructPtrs(dst, type.getStructPtr()->getMember(memberNdx).getType());
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgram::~Program (void)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// delete shader struct types, need to be done by the program since shaders might share struct types
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::set<const glu::StructType*> structTypes;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int shaderNdx = 0; shaderNdx < (int)m_shaders.size(); ++shaderNdx)
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int varNdx = 0; varNdx < (int)m_shaders[shaderNdx]->m_defaultBlock.variables.size(); ++varNdx)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				collectStructPtrs(structTypes, m_shaders[shaderNdx]->m_defaultBlock.variables[varNdx].varType);
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int interfaceNdx = 0; interfaceNdx < (int)m_shaders[shaderNdx]->m_defaultBlock.interfaceBlocks.size(); ++interfaceNdx)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int varNdx = 0; varNdx < (int)m_shaders[shaderNdx]->m_defaultBlock.interfaceBlocks[interfaceNdx].variables.size(); ++varNdx)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					collectStructPtrs(structTypes, m_shaders[shaderNdx]->m_defaultBlock.interfaceBlocks[interfaceNdx].variables[varNdx].varType);
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (std::set<const glu::StructType*>::iterator it = structTypes.begin(); it != structTypes.end(); ++it)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			delete *it;
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderNdx = 0; shaderNdx < (int)m_shaders.size(); ++shaderNdx)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_shaders[shaderNdx];
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders.clear();
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShader* Program::addShader (glu::ShaderType type, glu::GLSLVersion version)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Shader* shader;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// make sure push_back() cannot throw
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders.reserve(m_shaders.size() + 1);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	shader = new Shader(type, version);
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_shaders.push_back(shader);
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return shader;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setSeparable (bool separable)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_separable = separable;
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Program::isSeparable (void) const
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_separable;
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst std::vector<Shader*>& Program::getShaders (void) const
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_shaders;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderType Program::getFirstStage (void) const
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	nullValue	= DE_LENGTH_OF_ARRAY(s_shaderStageOrder);
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			firstStage	= nullValue;
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderNdx = 0; shaderNdx < (int)m_shaders.size(); ++shaderNdx)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int index = getShaderStageIndex(m_shaders[shaderNdx]->getType());
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (index != -1)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			firstStage = de::min(firstStage, index);
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (firstStage == nullValue)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::SHADERTYPE_LAST;
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_shaderStageOrder[firstStage];
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ShaderType Program::getLastStage (void) const
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	nullValue	= -1;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			lastStage	= nullValue;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int shaderNdx = 0; shaderNdx < (int)m_shaders.size(); ++shaderNdx)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int index = getShaderStageIndex(m_shaders[shaderNdx]->getType());
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (index != -1)
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			lastStage = de::max(lastStage, index);
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (lastStage == nullValue)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glu::SHADERTYPE_LAST;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return s_shaderStageOrder[lastStage];
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::addTransformFeedbackVarying (const std::string& varName)
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_xfbVaryings.push_back(varName);
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst std::vector<std::string>& Program::getTransformFeedbackVaryings (void) const
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_xfbVaryings;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Program::setTransformFeedbackMode (deUint32 mode)
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_xfbMode = mode;
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4183c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 Program::getTransformFeedbackMode (void) const
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_xfbMode;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Program::isValid (void) const
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool computePresent = false;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_shaders.empty())
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < (int)m_shaders.size(); ++ndx)
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_shaders[ndx]->isValid())
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// same version
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 1; ndx < (int)m_shaders.size(); ++ndx)
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_shaders[0]->getVersion() != m_shaders[ndx]->getVersion())
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// compute present -> no other stages present
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool nonComputePresent = false;
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)m_shaders.size(); ++ndx)
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_shaders[ndx]->getType() == glu::SHADERTYPE_COMPUTE)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				computePresent = true;
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				nonComputePresent = true;
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (computePresent && nonComputePresent)
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// must contain both vertex and fragment shaders
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!computePresent && !m_separable)
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool vertexPresent = false;
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool fragmentPresent = false;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)m_shaders.size(); ++ndx)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_shaders[ndx]->getType() == glu::SHADERTYPE_VERTEX)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexPresent = true;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_shaders[ndx]->getType() == glu::SHADERTYPE_FRAGMENT)
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				fragmentPresent = true;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!vertexPresent || !fragmentPresent)
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// tess.Eval present <=> tess.Control present
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool tessEvalPresent = false;
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool tessControlPresent = false;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)m_shaders.size(); ++ndx)
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_shaders[ndx]->getType() == glu::SHADERTYPE_TESSELLATION_EVALUATION)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tessEvalPresent = true;
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_shaders[ndx]->getType() == glu::SHADERTYPE_TESSELLATION_CONTROL)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tessControlPresent = true;
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (tessEvalPresent != tessControlPresent)
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // ProgramInterfaceDefinition
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
497