/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Program interface query test case
 *//*--------------------------------------------------------------------*/

#include "es31fProgramInterfaceQueryTestCase.hpp"
#include "es31fProgramInterfaceDefinitionUtil.hpp"
#include "tcuTestLog.hpp"
#include "gluVarTypeUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluShaderProgram.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deString.h"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using ProgramInterfaceDefinition::VariablePathComponent;
using ProgramInterfaceDefinition::VariableSearchFilter;

static glw::GLenum getProgramDefaultBlockInterfaceFromStorage (glu::Storage storage)
{
	switch (storage)
	{
		case glu::STORAGE_IN:
		case glu::STORAGE_PATCH_IN:
			return GL_PROGRAM_INPUT;

		case glu::STORAGE_OUT:
		case glu::STORAGE_PATCH_OUT:
			return GL_PROGRAM_OUTPUT;

		case glu::STORAGE_UNIFORM:
			return GL_UNIFORM;

		default:
			DE_ASSERT(false);
			return 0;
	}
}

static bool isBufferBackedInterfaceBlockStorage (glu::Storage storage)
{
	return storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM;
}

const char* getRequiredExtensionForStage (glu::ShaderType stage)
{
	switch (stage)
	{
		case glu::SHADERTYPE_COMPUTE:
		case glu::SHADERTYPE_VERTEX:
		case glu::SHADERTYPE_FRAGMENT:
			return DE_NULL;

		case glu::SHADERTYPE_GEOMETRY:
			return "GL_EXT_geometry_shader";

		case glu::SHADERTYPE_TESSELLATION_CONTROL:
		case glu::SHADERTYPE_TESSELLATION_EVALUATION:
			return "GL_EXT_tessellation_shader";

		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static int getTypeSize (glu::DataType type)
{
	if (type == glu::TYPE_FLOAT)
		return 4;
	else if (type == glu::TYPE_INT || type == glu::TYPE_UINT)
		return 4;
	else if (type == glu::TYPE_BOOL)
		return 4; // uint

	DE_ASSERT(false);
	return 0;
}

static int getVarTypeSize (const glu::VarType& type)
{
	if (type.isBasicType())
	{
		// return in basic machine units
		return glu::getDataTypeScalarSize(type.getBasicType()) * getTypeSize(glu::getDataTypeScalarType(type.getBasicType()));
	}
	else if (type.isStructType())
	{
		int size = 0;
		for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
			size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType());
		return size;
	}
	else if (type.isArrayType())
	{
		// unsized arrays are handled as if they had only one element
		if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY)
			return getVarTypeSize(type.getElementType());
		else
			return type.getArraySize() * getVarTypeSize(type.getElementType());
	}
	else
	{
		DE_ASSERT(false);
		return 0;
	}
}

static glu::MatrixOrder getMatrixOrderFromPath (const std::vector<VariablePathComponent>& path)
{
	glu::MatrixOrder order = glu::MATRIXORDER_LAST;

	// inherit majority
	for (int pathNdx = 0; pathNdx < (int)path.size(); ++pathNdx)
	{
		glu::MatrixOrder matOrder;

		if (path[pathNdx].isInterfaceBlock())
			matOrder = path[pathNdx].getInterfaceBlock()->layout.matrixOrder;
		else if (path[pathNdx].isDeclaration())
			matOrder = path[pathNdx].getDeclaration()->layout.matrixOrder;
		else if (path[pathNdx].isVariableType())
			matOrder = glu::MATRIXORDER_LAST;
		else
		{
			DE_ASSERT(false);
			return glu::MATRIXORDER_LAST;
		}

		if (matOrder != glu::MATRIXORDER_LAST)
			order = matOrder;
	}

	return order;
}

class PropValidator
{
public:
									PropValidator					(Context& context, ProgramResourcePropFlags validationProp, const char* requiredExtension);

	virtual std::string				getHumanReadablePropertyString	(glw::GLint propVal) const;
	virtual void					validate						(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const = 0;

	bool							isSupported						(void) const;
	bool							isSelected						(deUint32 caseFlags) const;

protected:
	void							setError						(const std::string& err) const;

	tcu::TestContext&				m_testCtx;
	const glu::RenderContext&		m_renderContext;

private:
	const glu::ContextInfo&			m_contextInfo;
	const char*						m_extension;
	const ProgramResourcePropFlags	m_validationProp;
};

PropValidator::PropValidator (Context& context, ProgramResourcePropFlags validationProp, const char* requiredExtension)
	: m_testCtx			(context.getTestContext())
	, m_renderContext	(context.getRenderContext())
	, m_contextInfo		(context.getContextInfo())
	, m_extension		(requiredExtension)
	, m_validationProp	(validationProp)
{
}

std::string PropValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(propVal);
}

bool PropValidator::isSupported (void) const
{
	if(glu::contextSupports(m_renderContext.getType(), glu::ApiType::es(3, 2)) ||
	   glu::contextSupports(m_renderContext.getType(), glu::ApiType::core(4, 5)))
		return true;
	return m_extension == DE_NULL || m_contextInfo.isExtensionSupported(m_extension);
}

bool PropValidator::isSelected (deUint32 caseFlags) const
{
	return (caseFlags & (deUint32)m_validationProp) != 0;
}

void PropValidator::setError (const std::string& err) const
{
	// don't overwrite earlier errors
	if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, err.c_str());
}

class SingleVariableValidator : public PropValidator
{
public:
					SingleVariableValidator	(Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension);

	void			validate				(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	virtual void	validateSingleVariable	(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const = 0;
	virtual void	validateBuiltinVariable	(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;

protected:
	const VariableSearchFilter	m_filter;
	const glw::GLuint			m_programID;
};

SingleVariableValidator::SingleVariableValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension)
	: PropValidator	(context, validationProp, requiredExtension)
	, m_filter		(filter)
	, m_programID	(programID)
{
}

void SingleVariableValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	std::vector<VariablePathComponent> path;

	if (findProgramVariablePathByPathName(path, program, resource, m_filter))
	{
		const glu::VarType* variable = (path.back().isVariableType()) ? (path.back().getVariableType()) : (DE_NULL);

		if (!variable || !variable->isBasicType())
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource name \"" << resource << "\" refers to a non-basic type." << tcu::TestLog::EndMessage;
			setError("resource not basic type");
		}
		else
			validateSingleVariable(path, resource, propValue, implementationName);

		// finding matching variable in any shader is sufficient
		return;
	}
	else if (deStringBeginsWith(resource.c_str(), "gl_"))
	{
		// special case for builtins
		validateBuiltinVariable(resource, propValue, implementationName);
		return;
	}

	// we are only supplied good names, generated by ourselves
	DE_ASSERT(false);
	throw tcu::InternalError("Resource name consistency error");
}

void SingleVariableValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(propValue);
	DE_UNREF(implementationName);
	DE_ASSERT(false);
}

class SingleBlockValidator : public PropValidator
{
public:
								SingleBlockValidator	(Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension);

	void						validate				(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	virtual void				validateSingleBlock		(const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const = 0;

protected:
	const VariableSearchFilter	m_filter;
	const glw::GLuint			m_programID;
};

SingleBlockValidator::SingleBlockValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension)
	: PropValidator	(context, validationProp, requiredExtension)
	, m_filter		(filter)
	, m_programID	(programID)
{
}

void SingleBlockValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	glu::VarTokenizer	tokenizer		(resource.c_str());
	const std::string	blockName		= tokenizer.getIdentifier();
	std::vector<int>	instanceIndex;

	tokenizer.advance();

	// array index
	while (tokenizer.getToken() == glu::VarTokenizer::TOKEN_LEFT_BRACKET)
	{
		tokenizer.advance();
		DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_NUMBER);

		instanceIndex.push_back(tokenizer.getNumber());

		tokenizer.advance();
		DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_RIGHT_BRACKET);

		tokenizer.advance();
	}

	// no trailing garbage
	DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_END);

	for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
	{
		const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx];
		if (!m_filter.matchesFilter(shader))
			continue;

		for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
		{
			const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx];

			if (m_filter.matchesFilter(block) && block.interfaceName == blockName)
			{
				// dimensions match
				DE_ASSERT(instanceIndex.size() == block.dimensions.size());

				validateSingleBlock(block, instanceIndex, resource, propValue, implementationName);
				return;
			}
		}
	}

	// we are only supplied good names, generated by ourselves
	DE_ASSERT(false);
	throw tcu::InternalError("Resource name consistency error");
}

class TypeValidator : public SingleVariableValidator
{
public:
				TypeValidator					(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	std::string	getHumanReadablePropertyString	(glw::GLint propVal) const;
	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateBuiltinVariable			(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

TypeValidator::TypeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_TYPE, programID, filter, DE_NULL)
{
}

std::string TypeValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(glu::getShaderVarTypeStr(propVal));
}

void TypeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const glu::VarType* variable = path.back().getVariableType();

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(variable->getBasicType()) << tcu::TestLog::EndMessage;

	if (variable->getBasicType() != glu::getDataTypeFromGLType(propValue))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
		setError("resource type invalid");
	}
}

void TypeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	static const struct
	{
		const char*		name;
		glu::DataType	type;
	} builtins[] =
	{
		{ "gl_Position",				glu::TYPE_FLOAT_VEC4	},
		{ "gl_FragCoord",				glu::TYPE_FLOAT_VEC4	},
		{ "gl_PerVertex.gl_Position",	glu::TYPE_FLOAT_VEC4	},
		{ "gl_VertexID",				glu::TYPE_INT			},
		{ "gl_InvocationID",			glu::TYPE_INT			},
		{ "gl_NumWorkGroups",			glu::TYPE_UINT_VEC3		},
		{ "gl_FragDepth",				glu::TYPE_FLOAT			},
		{ "gl_TessLevelOuter[0]",		glu::TYPE_FLOAT			},
		{ "gl_TessLevelInner[0]",		glu::TYPE_FLOAT			},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
	{
		if (resource == builtins[ndx].name)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(builtins[ndx].type) << tcu::TestLog::EndMessage;

			if (glu::getDataTypeFromGLType(propValue) != builtins[ndx].type)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
				setError("resource type invalid");
			}
			return;
		}
	}

	DE_ASSERT(false);
}

class ArraySizeValidator : public SingleVariableValidator
{
public:
				ArraySizeValidator				(Context& context, glw::GLuint programID, int unsizedArraySize, const VariableSearchFilter& filter);

	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateBuiltinVariable			(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;

private:
	const int	m_unsizedArraySize;
};

ArraySizeValidator::ArraySizeValidator (Context& context, glw::GLuint programID, int unsizedArraySize, const VariableSearchFilter& filter)
	: SingleVariableValidator	(context, PROGRAMRESOURCEPROP_ARRAY_SIZE, programID, filter, DE_NULL)
	, m_unsizedArraySize		(unsizedArraySize)
{
}

void ArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const VariablePathComponent		nullComponent;
	const VariablePathComponent&	enclosingcomponent	= (path.size() > 1) ? (path[path.size()-2]) : (nullComponent);

	const bool						isArray				= enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();
	const bool						inUnsizedArray		= isArray && (enclosingcomponent.getVariableType()->getArraySize() == glu::VarType::UNSIZED_ARRAY);
	const int						arraySize			= (!isArray) ? (1) : (inUnsizedArray) ? (m_unsizedArraySize) : (enclosingcomponent.getVariableType()->getArraySize());

	DE_ASSERT(arraySize >= 0);
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage;

	if (arraySize != propValue)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource array size invalid");
	}
}

void ArraySizeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	static const struct
	{
		const char*		name;
		int				arraySize;
	} builtins[] =
	{
		{ "gl_Position",				1	},
		{ "gl_VertexID",				1	},
		{ "gl_FragCoord",				1	},
		{ "gl_PerVertex.gl_Position",	1	},
		{ "gl_InvocationID",			1	},
		{ "gl_NumWorkGroups",			1	},
		{ "gl_FragDepth",				1	},
		{ "gl_TessLevelOuter[0]",		4	},
		{ "gl_TessLevelInner[0]",		2	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
	{
		if (resource == builtins[ndx].name)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << builtins[ndx].arraySize << tcu::TestLog::EndMessage;

			if (propValue != builtins[ndx].arraySize)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
				setError("resource array size invalid");
			}
			return;
		}
	}

	DE_ASSERT(false);
}

class ArrayStrideValidator : public SingleVariableValidator
{
public:
				ArrayStrideValidator			(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

ArrayStrideValidator::ArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_ARRAY_STRIDE, programID, filter, DE_NULL)
{
}

void ArrayStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const VariablePathComponent		nullComponent;
	const VariablePathComponent&	component			= path.back();
	const VariablePathComponent&	enclosingcomponent	= (path.size() > 1) ? (path[path.size()-2]) : (nullComponent);
	const VariablePathComponent&	firstComponent		= path.front();

	const bool						isBufferBlock		= firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
	const bool						isArray				= enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();
	const bool						isAtomicCounter		= glu::isDataTypeAtomicCounter(component.getVariableType()->getBasicType()); // atomic counters are buffer backed with a stride of 4 basic machine units

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	// Layout tests will verify layouts of buffer backed arrays properly. Here we just check values are greater or equal to the element size
	if (isBufferBlock && isArray)
	{
		const int elementSize = glu::getDataTypeScalarSize(component.getVariableType()->getBasicType()) * getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType()));
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting greater or equal to " << elementSize << tcu::TestLog::EndMessage;

		if (propValue < elementSize)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource array stride invalid");
		}
	}
	else
	{
		// Atomics are buffer backed with stride of 4 even though they are not in an interface block
		const int arrayStride = (isAtomicCounter && isArray) ? (4) : (!isBufferBlock && !isAtomicCounter) ? (-1) : (0);

		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting " << arrayStride << tcu::TestLog::EndMessage;

		if (arrayStride != propValue)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource array stride invalid");
		}
	}
}

class BlockIndexValidator : public SingleVariableValidator
{
public:
				BlockIndexValidator				(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

BlockIndexValidator::BlockIndexValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_BLOCK_INDEX, programID, filter, DE_NULL)
{
}

void BlockIndexValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const VariablePathComponent& firstComponent = path.front();

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (!firstComponent.isInterfaceBlock())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting -1" << tcu::TestLog::EndMessage;

		if (propValue != -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource block index invalid");
		}
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting a valid block index" << tcu::TestLog::EndMessage;

		if (propValue == -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource block index invalid");
		}
		else
		{
			const glw::Functions&	gl			= m_renderContext.getFunctions();
			const glw::GLenum		interface	= (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM_BLOCK) :
												  (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_BUFFER) ? (GL_SHADER_STORAGE_BLOCK) :
												  (0);
			glw::GLint				written		= 0;
			std::vector<char>		nameBuffer	(firstComponent.getInterfaceBlock()->interfaceName.size() + 3 * firstComponent.getInterfaceBlock()->dimensions.size() + 2, '\0'); // +3 for appended "[N]", +1 for '\0' and +1 just for safety

			gl.getProgramResourceName(m_programID, interface, propValue, (int)nameBuffer.size() - 1, &written, &nameBuffer[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query block name");
			TCU_CHECK(written < (int)nameBuffer.size());
			TCU_CHECK(nameBuffer.back() == '\0');

			{
				const std::string	blockName		(&nameBuffer[0], written);
				std::ostringstream	expectedName;

				expectedName << firstComponent.getInterfaceBlock()->interfaceName;
				for (int dimensionNdx = 0; dimensionNdx < (int)firstComponent.getInterfaceBlock()->dimensions.size(); ++dimensionNdx)
					expectedName << "[0]";

				m_testCtx.getLog() << tcu::TestLog::Message << "Block name with index " << propValue << " is \"" << blockName << "\"" << tcu::TestLog::EndMessage;
				if (blockName != expectedName.str())
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "\tError, expected " << expectedName.str() << tcu::TestLog::EndMessage;
					setError("resource block index invalid");
				}
			}
		}
	}
}

class IsRowMajorValidator : public SingleVariableValidator
{
public:
				IsRowMajorValidator				(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	std::string getHumanReadablePropertyString	(glw::GLint propVal) const;
	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

IsRowMajorValidator::IsRowMajorValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, programID, filter, DE_NULL)
{
}

std::string IsRowMajorValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(glu::getBooleanStr(propVal));
}

void IsRowMajorValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const VariablePathComponent&	component			= path.back();
	const VariablePathComponent&	firstComponent		= path.front();

	const bool						isBufferBlock		= firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
	const bool						isMatrix			= glu::isDataTypeMatrix(component.getVariableType()->getBasicType());
	const int						expected			= (isBufferBlock && isMatrix && getMatrixOrderFromPath(path) == glu::MATRIXORDER_ROW_MAJOR) ? (1) : (0);

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix order, expecting IS_ROW_MAJOR = " << expected << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource matrix order invalid");
	}
}

class MatrixStrideValidator : public SingleVariableValidator
{
public:
				MatrixStrideValidator			(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

MatrixStrideValidator::MatrixStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_STRIDE, programID, filter, DE_NULL)
{
}

void MatrixStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const VariablePathComponent&	component			= path.back();
	const VariablePathComponent&	firstComponent		= path.front();

	const bool						isBufferBlock		= firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage);
	const bool						isMatrix			= glu::isDataTypeMatrix(component.getVariableType()->getBasicType());

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	// Layout tests will verify layouts of buffer backed arrays properly. Here we just check the stride is is greater or equal to the row/column size
	if (isBufferBlock && isMatrix)
	{
		const bool	columnMajor			= getMatrixOrderFromPath(path) != glu::MATRIXORDER_ROW_MAJOR;
		const int	numMajorElements	= (columnMajor) ? (glu::getDataTypeMatrixNumRows(component.getVariableType()->getBasicType())) : (glu::getDataTypeMatrixNumColumns(component.getVariableType()->getBasicType()));
		const int	majorSize			= numMajorElements * getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType()));

		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting greater or equal to " << majorSize << tcu::TestLog::EndMessage;

		if (propValue < majorSize)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource matrix stride invalid");
		}
	}
	else
	{
		const int matrixStride = (!isBufferBlock && !glu::isDataTypeAtomicCounter(component.getVariableType()->getBasicType())) ? (-1) : (0);

		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting " << matrixStride << tcu::TestLog::EndMessage;

		if (matrixStride != propValue)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource matrix stride invalid");
		}
	}
}

class AtomicCounterBufferIndexVerifier : public SingleVariableValidator
{
public:
				AtomicCounterBufferIndexVerifier	(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable				(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

AtomicCounterBufferIndexVerifier::AtomicCounterBufferIndexVerifier (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX, programID, filter, DE_NULL)
{
}

void AtomicCounterBufferIndexVerifier::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (!glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType()))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting -1" << tcu::TestLog::EndMessage;

		if (propValue != -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource atomic counter buffer index invalid");
		}
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting a valid index" << tcu::TestLog::EndMessage;

		if (propValue == -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource atomic counter buffer index invalid");
		}
		else
		{
			const glw::Functions&	gl					= m_renderContext.getFunctions();
			glw::GLint				numActiveResources	= 0;

			gl.getProgramInterfaceiv(m_programID, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
			GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramInterfaceiv(..., GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, ...)");

			if (propValue >= numActiveResources)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << ", GL_ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;
				setError("resource atomic counter buffer index invalid");
			}
		}
	}
}

class LocationValidator : public SingleVariableValidator
{
public:
				LocationValidator		(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable	(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateBuiltinVariable	(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

LocationValidator::LocationValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_LOCATION, programID, filter, DE_NULL)
{
}

static int getVariableLocationLength (const glu::VarType& type)
{
	if (type.isBasicType())
	{
		if (glu::isDataTypeMatrix(type.getBasicType()))
			return glu::getDataTypeMatrixNumColumns(type.getBasicType());
		else
			return 1;
	}
	else if (type.isStructType())
	{
		int size = 0;
		for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx)
			size += getVariableLocationLength(type.getStructPtr()->getMember(ndx).getType());
		return size;
	}
	else if (type.isArrayType())
		return type.getArraySize() * getVariableLocationLength(type.getElementType());
	else
	{
		DE_ASSERT(false);
		return 0;
	}
}

static int getIOSubVariableLocation (const std::vector<VariablePathComponent>& path, int startNdx, int currentLocation)
{
	if (currentLocation == -1)
		return -1;

	if (path[startNdx].getVariableType()->isBasicType())
		return currentLocation;
	else if (path[startNdx].getVariableType()->isArrayType())
		return getIOSubVariableLocation(path, startNdx+1, currentLocation);
	else if (path[startNdx].getVariableType()->isStructType())
	{
		for (int ndx = 0; ndx < path[startNdx].getVariableType()->getStructPtr()->getNumMembers(); ++ndx)
		{
			if (&path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType() == path[startNdx + 1].getVariableType())
				return getIOSubVariableLocation(path, startNdx + 1, currentLocation);

			if (currentLocation != -1)
				currentLocation += getVariableLocationLength(path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType());
		}

		// could not find member, never happens
		DE_ASSERT(false);
		return -1;
	}
	else
	{
		DE_ASSERT(false);
		return -1;
	}
}

static int getIOBlockVariableLocation (const std::vector<VariablePathComponent>& path)
{
	const glu::InterfaceBlock*	block			= path.front().getInterfaceBlock();
	int							currentLocation	= block->layout.location;

	// Find the block member
	for (int memberNdx = 0; memberNdx < (int)block->variables.size(); ++memberNdx)
	{
		if (block->variables[memberNdx].layout.location != -1)
			currentLocation = block->variables[memberNdx].layout.location;

		if (&block->variables[memberNdx] == path[1].getDeclaration())
			break;

		// unspecified + unspecified = unspecified
		if (currentLocation != -1)
			currentLocation += getVariableLocationLength(block->variables[memberNdx].varType);
	}

	// Find subtype location in the complex type
	return getIOSubVariableLocation(path, 2, currentLocation);
}

static int getExplicitLocationFromPath (const std::vector<VariablePathComponent>& path)
{
	const glu::VariableDeclaration* varDecl = (path[0].isInterfaceBlock()) ? (path[1].getDeclaration()) : (path[0].getDeclaration());

	if (path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM)
	{
		// inside uniform block
		return -1;
	}
	else if (path.front().isInterfaceBlock() && (path.front().getInterfaceBlock()->storage == glu::STORAGE_IN		||
												 path.front().getInterfaceBlock()->storage == glu::STORAGE_OUT		||
												 path.front().getInterfaceBlock()->storage == glu::STORAGE_PATCH_IN	||
												 path.front().getInterfaceBlock()->storage == glu::STORAGE_PATCH_OUT))
	{
		// inside ioblock
		return getIOBlockVariableLocation(path);
	}
	else if (varDecl->storage == glu::STORAGE_UNIFORM)
	{
		// default block uniform
		return varDecl->layout.location;
	}
	else if (varDecl->storage == glu::STORAGE_IN		||
			 varDecl->storage == glu::STORAGE_OUT		||
			 varDecl->storage == glu::STORAGE_PATCH_IN	||
			 varDecl->storage == glu::STORAGE_PATCH_OUT)
	{
		// default block input/output
		return getIOSubVariableLocation(path, 1, varDecl->layout.location);
	}
	else
	{
		DE_ASSERT(false);
		return -1;
	}
}

void LocationValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const bool			isAtomicCounterUniform	= glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType());
	const bool			isUniformBlockVariable	= path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM;
	const bool			isVertexShader			= m_filter.getShaderTypeBits() == (1u << glu::SHADERTYPE_VERTEX);
	const bool			isFragmentShader		= m_filter.getShaderTypeBits() == (1u << glu::SHADERTYPE_FRAGMENT);
	const glu::Storage	storage					= (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage) : (path.front().getDeclaration()->storage);
	const bool			isInputVariable			= (storage == glu::STORAGE_IN || storage == glu::STORAGE_PATCH_IN);
	const bool			isOutputVariable		= (storage == glu::STORAGE_OUT || storage == glu::STORAGE_PATCH_OUT);
	const int			explicitLayoutLocation	= getExplicitLocationFromPath(path);

	bool				expectLocation;
	std::string			reasonStr;

	DE_UNREF(resource);

	if (isAtomicCounterUniform)
	{
		expectLocation = false;
		reasonStr = "Atomic counter uniforms have effective location of -1";
	}
	else if (isUniformBlockVariable)
	{
		expectLocation = false;
		reasonStr = "Uniform block variables have effective location of -1";
	}
	else if (isInputVariable && !isVertexShader && explicitLayoutLocation == -1)
	{
		expectLocation = false;
		reasonStr = "Inputs (except for vertex shader inputs) not declared with a location layout qualifier have effective location of -1";
	}
	else if (isOutputVariable && !isFragmentShader && explicitLayoutLocation == -1)
	{
		expectLocation = false;
		reasonStr = "Outputs (except for fragment shader outputs) not declared with a location layout qualifier have effective location of -1";
	}
	else
	{
		expectLocation = true;
	}

	if (!expectLocation)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform location, expecting -1. (" << reasonStr << ")" << tcu::TestLog::EndMessage;

		if (propValue != -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource location invalid");
		}
	}
	else
	{
		bool locationOk;

		if (explicitLayoutLocation == -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting a valid location" << tcu::TestLog::EndMessage;
			locationOk = (propValue != -1);
		}
		else
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting " << explicitLayoutLocation << tcu::TestLog::EndMessage;
			locationOk = (propValue == explicitLayoutLocation);
		}

		if (!locationOk)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
			setError("resource location invalid");
		}
		else
		{
			const VariablePathComponent		nullComponent;
			const VariablePathComponent&	enclosingcomponent	= (path.size() > 1) ? (path[path.size()-2]) : (nullComponent);
			const bool						isArray				= enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType();

			const glw::Functions&			gl					= m_renderContext.getFunctions();
			const glw::GLenum				interface			= getProgramDefaultBlockInterfaceFromStorage(storage);

			m_testCtx.getLog() << tcu::TestLog::Message << "Comparing location to the values returned by GetProgramResourceLocation" << tcu::TestLog::EndMessage;

			// Test all bottom-level array elements
			if (isArray)
			{
				const std::string arrayResourceName = (implementationName.size() > 3) ? (implementationName.substr(0, implementationName.size() - 3)) : (""); // chop "[0]"

				for (int arrayElementNdx = 0; arrayElementNdx < enclosingcomponent.getVariableType()->getArraySize(); ++arrayElementNdx)
				{
					const std::string	elementResourceName	= arrayResourceName + "[" + de::toString(arrayElementNdx) + "]";
					const glw::GLint	location			= gl.getProgramResourceLocation(m_programID, interface, elementResourceName.c_str());

					if (location != propValue+arrayElementNdx)
					{
						m_testCtx.getLog()
							<< tcu::TestLog::Message
							<< "\tError, getProgramResourceLocation (resource=\"" << elementResourceName << "\") returned location " << location
							<< ", expected " << (propValue+arrayElementNdx)
							<< tcu::TestLog::EndMessage;
						setError("resource location invalid");
					}
					else
						m_testCtx.getLog() << tcu::TestLog::Message << "\tLocation of \"" << elementResourceName << "\":\t" << location << tcu::TestLog::EndMessage;
				}
			}
			else
			{
				const glw::GLint location = gl.getProgramResourceLocation(m_programID, interface, implementationName.c_str());

				if (location != propValue)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "\tError, getProgramResourceLocation returned location " << location << ", expected " << propValue << tcu::TestLog::EndMessage;
					setError("resource location invalid");
				}
			}

		}
	}
}

void LocationValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	// built-ins have no location

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting -1" << tcu::TestLog::EndMessage;

	if (propValue != -1)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource location invalid");
	}
}

class VariableNameLengthValidator : public SingleVariableValidator
{
public:
				VariableNameLengthValidator	(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable		(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateBuiltinVariable		(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateNameLength			(const std::string& implementationName, glw::GLint propValue) const;
};

VariableNameLengthValidator::VariableNameLengthValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter, DE_NULL)
{
}

void VariableNameLengthValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(path);
	DE_UNREF(resource);
	validateNameLength(implementationName, propValue);
}

void VariableNameLengthValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	validateNameLength(implementationName, propValue);
}

void VariableNameLengthValidator::validateNameLength (const std::string& implementationName, glw::GLint propValue) const
{
	const int expected = (int)implementationName.length() + 1; // includes null byte
	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)implementationName.length() << " for \"" << implementationName << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage;
		setError("name length invalid");
	}
}

class OffsetValidator : public SingleVariableValidator
{
public:
				OffsetValidator			(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable	(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

OffsetValidator::OffsetValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_OFFSET, programID, filter, DE_NULL)
{
}

void OffsetValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const bool isAtomicCounterUniform		= glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType());
	const bool isBufferBackedBlockStorage	= path.front().isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(path.front().getInterfaceBlock()->storage);

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (!isAtomicCounterUniform && !isBufferBackedBlockStorage)
	{
		// Not buffer backed
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting -1" << tcu::TestLog::EndMessage;

		if (propValue != -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue << tcu::TestLog::EndMessage;
			setError("offset invalid");
		}
	}
	else
	{
		// Expect a valid offset
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting a valid offset" << tcu::TestLog::EndMessage;

		if (propValue < 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue << tcu::TestLog::EndMessage;
			setError("offset invalid");
		}
	}
}

class VariableReferencedByShaderValidator : public PropValidator
{
public:
								VariableReferencedByShaderValidator	(Context& context, glu::ShaderType shaderType, const VariableSearchFilter& searchFilter);

	std::string					getHumanReadablePropertyString		(glw::GLint propVal) const;
	void						validate							(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;

private:
	const VariableSearchFilter	m_filter;
	const glu::ShaderType		m_shaderType;
};

VariableReferencedByShaderValidator::VariableReferencedByShaderValidator (Context& context, glu::ShaderType shaderType, const VariableSearchFilter& searchFilter)
	: PropValidator	(context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER, getRequiredExtensionForStage(shaderType))
	, m_filter		(VariableSearchFilter::logicalAnd(VariableSearchFilter::createShaderTypeFilter(shaderType), searchFilter))
	, m_shaderType	(shaderType)
{
	DE_ASSERT(m_shaderType < glu::SHADERTYPE_LAST);
}

std::string VariableReferencedByShaderValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(glu::getBooleanStr(propVal));
}

void VariableReferencedByShaderValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	std::vector<VariablePathComponent>	unusedPath;
	const bool							referencedByShader = findProgramVariablePathByPathName(unusedPath, program, resource, m_filter);

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying referenced by " << glu::getShaderTypeName(m_shaderType) << " shader, expecting "
		<< ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE"))
		<< tcu::TestLog::EndMessage;

	if (propValue != ((referencedByShader) ? (1) : (0)))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_" << glu::getShaderTypeName(m_shaderType) << ", got " << propValue << tcu::TestLog::EndMessage;
		setError("referenced_by_" + std::string(glu::getShaderTypeName(m_shaderType)) + " invalid");
	}
}

class BlockNameLengthValidator : public SingleBlockValidator
{
public:
			BlockNameLengthValidator	(Context& context, const glw::GLuint programID, const VariableSearchFilter& filter);

	void	validateSingleBlock			(const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

BlockNameLengthValidator::BlockNameLengthValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleBlockValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter, DE_NULL)
{
}

void BlockNameLengthValidator::validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(instanceIndex);
	DE_UNREF(block);
	DE_UNREF(resource);

	const int expected = (int)implementationName.length() + 1; // includes null byte
	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)implementationName.length() << " for \"" << implementationName << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage;
		setError("name length invalid");
	}
}

class BufferBindingValidator : public SingleBlockValidator
{
public:
			BufferBindingValidator	(Context& context, const glw::GLuint programID, const VariableSearchFilter& filter);

	void	validateSingleBlock		(const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

BufferBindingValidator::BufferBindingValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleBlockValidator(context, PROGRAMRESOURCEPROP_BUFFER_BINDING, programID, filter, DE_NULL)
{
}

void BufferBindingValidator::validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (block.layout.binding != -1)
	{
		int flatIndex		= 0;
		int dimensionSize	= 1;

		for (int dimensionNdx = (int)(block.dimensions.size()) - 1; dimensionNdx >= 0; --dimensionNdx)
		{
			flatIndex += dimensionSize * instanceIndex[dimensionNdx];
			dimensionSize *= block.dimensions[dimensionNdx];
		}

		const int expected = (block.dimensions.empty()) ? (block.layout.binding) : (block.layout.binding + flatIndex);
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block binding, expecting " << expected << tcu::TestLog::EndMessage;

		if (propValue != expected)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue << tcu::TestLog::EndMessage;
			setError("buffer binding invalid");
		}
	}
	else
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying buffer binding, expecting a valid binding" << tcu::TestLog::EndMessage;

		if (propValue < 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue << tcu::TestLog::EndMessage;
			setError("buffer binding invalid");
		}
	}
}

class BlockReferencedByShaderValidator : public PropValidator
{
public:
								BlockReferencedByShaderValidator	(Context& context, glu::ShaderType shaderType, const VariableSearchFilter& searchFilter);

	std::string					getHumanReadablePropertyString		(glw::GLint propVal) const;
	void						validate							(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;

private:
	const VariableSearchFilter	m_filter;
	const glu::ShaderType		m_shaderType;
};

BlockReferencedByShaderValidator::BlockReferencedByShaderValidator (Context& context, glu::ShaderType shaderType, const VariableSearchFilter& searchFilter)
	: PropValidator	(context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER, getRequiredExtensionForStage(shaderType))
	, m_filter		(VariableSearchFilter::logicalAnd(VariableSearchFilter::createShaderTypeFilter(shaderType), searchFilter))
	, m_shaderType	(shaderType)
{
	DE_ASSERT(m_shaderType < glu::SHADERTYPE_LAST);
}

std::string BlockReferencedByShaderValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(glu::getBooleanStr(propVal));
}

void BlockReferencedByShaderValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const std::string	blockName			= glu::parseVariableName(resource.c_str());
	bool				referencedByShader	= false;

	DE_UNREF(implementationName);

	for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
	{
		const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx];
		if (!m_filter.matchesFilter(shader))
			continue;

		for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
		{
			const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx];

			if (m_filter.matchesFilter(block) && block.interfaceName == blockName)
				referencedByShader = true;
		}
	}

	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< "Verifying referenced by " << glu::getShaderTypeName(m_shaderType) << " shader, expecting "
		<< ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE"))
		<< tcu::TestLog::EndMessage;

	if (propValue != ((referencedByShader) ? (1) : (0)))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_" << glu::getShaderTypeName(m_shaderType) << ", got " << propValue << tcu::TestLog::EndMessage;
		setError("referenced_by_" + std::string(glu::getShaderTypeName(m_shaderType)) + " invalid");
	}
}

class TopLevelArraySizeValidator : public SingleVariableValidator
{
public:
				TopLevelArraySizeValidator	(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable		(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

TopLevelArraySizeValidator::TopLevelArraySizeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE, programID, filter, DE_NULL)
{
}

void TopLevelArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	int			expected;
	std::string	reason;

	DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER);
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (!path[1].getDeclaration()->varType.isArrayType())
	{
		expected = 1;
		reason = "Top-level block member is not an array";
	}
	else if (path[1].getDeclaration()->varType.getElementType().isBasicType())
	{
		expected = 1;
		reason = "Top-level block member is not an array of an aggregate type";
	}
	else if (path[1].getDeclaration()->varType.getArraySize() == glu::VarType::UNSIZED_ARRAY)
	{
		expected = 0;
		reason = "Top-level block member is an unsized top-level array";
	}
	else
	{
		expected = path[1].getDeclaration()->varType.getArraySize();
		reason = "Top-level block member is a sized top-level array";
	}

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array size, expecting " << expected << ". (" << reason << ")." << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array size, got " << propValue << tcu::TestLog::EndMessage;
		setError("top level array size invalid");
	}
}

class TopLevelArrayStrideValidator : public SingleVariableValidator
{
public:
				TopLevelArrayStrideValidator	(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

TopLevelArrayStrideValidator::TopLevelArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE, programID, filter, DE_NULL)
{
}

void TopLevelArrayStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER);
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	if (!path[1].getDeclaration()->varType.isArrayType())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting 0. (Top-level block member is not an array)." << tcu::TestLog::EndMessage;

		if (propValue != 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue << tcu::TestLog::EndMessage;
			setError("top level array stride invalid");
		}
	}
	else if (path[1].getDeclaration()->varType.getElementType().isBasicType())
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting 0. (Top-level block member is not an array of an aggregate type)." << tcu::TestLog::EndMessage;

		if (propValue != 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue << tcu::TestLog::EndMessage;
			setError("top level array stride invalid");
		}
	}
	else
	{
		const int minimumStride = getVarTypeSize(path[1].getDeclaration()->varType.getElementType());

		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting greater or equal to " << minimumStride << "." << tcu::TestLog::EndMessage;

		if (propValue < minimumStride)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array stride, got " << propValue << tcu::TestLog::EndMessage;
			setError("top level array stride invalid");
		}
	}
}

class TransformFeedbackResourceValidator : public PropValidator
{
public:
					TransformFeedbackResourceValidator	(Context& context, ProgramResourcePropFlags validationProp);

	void			validate							(const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;

private:
	virtual void	validateBuiltinVariable				(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const = 0;
	virtual void	validateSingleVariable				(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const = 0;
};


TransformFeedbackResourceValidator::TransformFeedbackResourceValidator (Context& context, ProgramResourcePropFlags validationProp)
	: PropValidator(context, validationProp, DE_NULL)
{
}

void TransformFeedbackResourceValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	if (deStringBeginsWith(resource.c_str(), "gl_"))
	{
		validateBuiltinVariable(resource, propValue, implementationName);
	}
	else
	{
		// Check resource name is a xfb output. (sanity check)
#if defined(DE_DEBUG)
		bool generatorFound = false;

		// Check the resource name is a valid transform feedback resource and find the name generating resource
		for (int varyingNdx = 0; varyingNdx < (int)program->getTransformFeedbackVaryings().size(); ++varyingNdx)
		{
			const std::string					varyingName = program->getTransformFeedbackVaryings()[varyingNdx];
			std::vector<VariablePathComponent>	path;
			std::vector<std::string>			resources;

			if (!findProgramVariablePathByPathName(path, program, varyingName, VariableSearchFilter::createShaderTypeStorageFilter(getProgramTransformFeedbackStage(program), glu::STORAGE_OUT)))
			{
				// program does not contain feedback varying, not valid program
				DE_ASSERT(false);
				return;
			}

			generateVariableTypeResourceNames(resources, varyingName, *path.back().getVariableType(), RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE);

			if (de::contains(resources.begin(), resources.end(), resource))
			{
				generatorFound = true;
				break;
			}
		}

		// resource name was not found, should never happen
		DE_ASSERT(generatorFound);
		DE_UNREF(generatorFound);
#endif

		// verify resource
		{
			std::vector<VariablePathComponent> path;

			if (!findProgramVariablePathByPathName(path, program, resource, VariableSearchFilter::createShaderTypeStorageFilter(getProgramTransformFeedbackStage(program), glu::STORAGE_OUT)))
				DE_ASSERT(false);

			validateSingleVariable(path, resource, propValue, implementationName);
		}
	}
}

class TransformFeedbackArraySizeValidator : public TransformFeedbackResourceValidator
{
public:
				TransformFeedbackArraySizeValidator	(Context& context);

	void		validateBuiltinVariable				(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateSingleVariable				(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

TransformFeedbackArraySizeValidator::TransformFeedbackArraySizeValidator (Context& context)
	: TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_ARRAY_SIZE)
{
}

void TransformFeedbackArraySizeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	int arraySize = 0;

	if (resource == "gl_Position")
		arraySize = 1;
	else
		DE_ASSERT(false);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage;
	if (arraySize != propValue)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource array size invalid");
	}
}

void TransformFeedbackArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	const int arraySize = (path.back().getVariableType()->isArrayType()) ? (path.back().getVariableType()->getArraySize()) : (1);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage;
	if (arraySize != propValue)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource array size invalid");
	}
}

class TransformFeedbackNameLengthValidator : public TransformFeedbackResourceValidator
{
public:
				TransformFeedbackNameLengthValidator	(Context& context);

private:
	void		validateBuiltinVariable					(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateSingleVariable					(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateVariable						(const std::string& implementationName, glw::GLint propValue) const;
};

TransformFeedbackNameLengthValidator::TransformFeedbackNameLengthValidator (Context& context)
	: TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH)
{
}

void TransformFeedbackNameLengthValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	validateVariable(implementationName, propValue);
}

void TransformFeedbackNameLengthValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(path);
	DE_UNREF(resource);
	validateVariable(implementationName, propValue);
}

void TransformFeedbackNameLengthValidator::validateVariable (const std::string& implementationName, glw::GLint propValue) const
{
	const int expected = (int)implementationName.length() + 1; // includes null byte
	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)implementationName.length() << " for \"" << implementationName << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage;
		setError("name length invalid");
	}
}

class TransformFeedbackTypeValidator : public TransformFeedbackResourceValidator
{
public:
				TransformFeedbackTypeValidator		(Context& context);

	void		validateBuiltinVariable				(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateSingleVariable				(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

TransformFeedbackTypeValidator::TransformFeedbackTypeValidator (Context& context)
	: TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_TYPE)
{
}

void TransformFeedbackTypeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	glu::DataType varType = glu::TYPE_INVALID;

	if (resource == "gl_Position")
		varType = glu::TYPE_FLOAT_VEC4;
	else
		DE_ASSERT(false);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(varType) << tcu::TestLog::EndMessage;
	if (glu::getDataTypeFromGLType(propValue) != varType)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
		setError("resource type invalid");
	}
	return;
}

void TransformFeedbackTypeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(resource);
	DE_UNREF(implementationName);

	// Unlike other interfaces, xfb program interface uses just variable name to refer to arrays of basic types. (Others use "variable[0]")
	// Thus we might end up querying a type for an array. In this case, return the type of an array element.
	const glu::VarType& variable    = *path.back().getVariableType();
	const glu::VarType& elementType = (variable.isArrayType()) ? (variable.getElementType()) : (variable);

	DE_ASSERT(elementType.isBasicType());

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(elementType.getBasicType()) << tcu::TestLog::EndMessage;
	if (elementType.getBasicType() != glu::getDataTypeFromGLType(propValue))
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage;
		setError("resource type invalid");
	}
}

class PerPatchValidator : public SingleVariableValidator
{
public:
				PerPatchValidator				(Context& context, glw::GLuint programID, const VariableSearchFilter& filter);

	std::string getHumanReadablePropertyString	(glw::GLint propVal) const;
	void		validateSingleVariable			(const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
	void		validateBuiltinVariable			(const std::string& resource, glw::GLint propValue, const std::string& implementationName) const;
};

PerPatchValidator::PerPatchValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter)
	: SingleVariableValidator(context, PROGRAMRESOURCEPROP_IS_PER_PATCH, programID, filter, "GL_EXT_tessellation_shader")
{
}

std::string PerPatchValidator::getHumanReadablePropertyString (glw::GLint propVal) const
{
	return de::toString(glu::getBooleanStr(propVal));
}

void PerPatchValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	const glu::Storage	storage		= (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage) : (path.front().getDeclaration()->storage);
	const int			expected	= (storage == glu::STORAGE_PATCH_IN || storage == glu::STORAGE_PATCH_OUT) ? (1) : (0);

	DE_UNREF(resource);
	DE_UNREF(implementationName);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying if is per patch, expecting IS_PER_PATCH = " << expected << tcu::TestLog::EndMessage;

	if (propValue != expected)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
		setError("resource is per patch invalid");
	}
}

void PerPatchValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue, const std::string& implementationName) const
{
	DE_UNREF(implementationName);

	static const struct
	{
		const char*		name;
		int				isPerPatch;
	} builtins[] =
	{
		{ "gl_Position",				0	},
		{ "gl_PerVertex.gl_Position",	0	},
		{ "gl_InvocationID",			0	},
		{ "gl_TessLevelOuter[0]",		1	},
		{ "gl_TessLevelInner[0]",		1	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx)
	{
		if (resource == builtins[ndx].name)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying if is per patch, expecting IS_PER_PATCH = " << builtins[ndx].isPerPatch << tcu::TestLog::EndMessage;

			if (propValue != builtins[ndx].isPerPatch)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage;
				setError("resource is per patch invalid");
			}
			return;
		}
	}

	DE_ASSERT(false);
}

} // anonymous

ProgramResourceQueryTestTarget::ProgramResourceQueryTestTarget (ProgramInterface interface_, deUint32 propFlags_)
	: interface(interface_)
	, propFlags(propFlags_)
{
	switch (interface)
	{
		case PROGRAMINTERFACE_UNIFORM:						DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK)			== propFlags);	break;
		case PROGRAMINTERFACE_UNIFORM_BLOCK:				DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_BLOCK_INTERFACE_MASK)	== propFlags);	break;
		case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:			DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_SHADER_STORAGE_BLOCK_MASK)		== propFlags);	break;
		case PROGRAMINTERFACE_PROGRAM_INPUT:				DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_INPUT_MASK)				== propFlags);	break;
		case PROGRAMINTERFACE_PROGRAM_OUTPUT:				DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_OUTPUT_MASK)				== propFlags);	break;
		case PROGRAMINTERFACE_BUFFER_VARIABLE:				DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK)			== propFlags);	break;
		case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:	DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_TRANSFORM_FEEDBACK_VARYING_MASK)	== propFlags);	break;

		default:
			DE_ASSERT(false);
	}
}

ProgramInterfaceQueryTestCase::ProgramInterfaceQueryTestCase (Context& context, const char* name, const char* description, ProgramResourceQueryTestTarget queryTarget)
	: TestCase		(context, name, description)
	, m_queryTarget	(queryTarget)
{
}

ProgramInterfaceQueryTestCase::~ProgramInterfaceQueryTestCase (void)
{
}

ProgramInterface ProgramInterfaceQueryTestCase::getTargetInterface (void) const
{
	return m_queryTarget.interface;
}

static glw::GLenum getGLInterfaceEnumValue (ProgramInterface interface)
{
	switch (interface)
	{
		case PROGRAMINTERFACE_UNIFORM:						return GL_UNIFORM;
		case PROGRAMINTERFACE_UNIFORM_BLOCK:				return GL_UNIFORM_BLOCK;
		case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:		return GL_ATOMIC_COUNTER_BUFFER;
		case PROGRAMINTERFACE_PROGRAM_INPUT:				return GL_PROGRAM_INPUT;
		case PROGRAMINTERFACE_PROGRAM_OUTPUT:				return GL_PROGRAM_OUTPUT;
		case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:	return GL_TRANSFORM_FEEDBACK_VARYING;
		case PROGRAMINTERFACE_BUFFER_VARIABLE:				return GL_BUFFER_VARIABLE;
		case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:			return GL_SHADER_STORAGE_BLOCK;
		default:
			DE_ASSERT(false);
			return 0;
	}
}

static bool isInterfaceBlockInterfaceName (const ProgramInterfaceDefinition::Program* program, ProgramInterface interface, const std::string& blockInterfaceName)
{
	deUint32 validStorageBits;
	deUint32 searchStageBits;

	DE_STATIC_ASSERT(glu::STORAGE_LAST < 32);
	DE_STATIC_ASSERT(glu::SHADERTYPE_LAST < 32);

	switch (interface)
	{
		case PROGRAMINTERFACE_UNIFORM_BLOCK:
		case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
		case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:
			return false;

		case PROGRAMINTERFACE_PROGRAM_INPUT:
			validStorageBits = (1u << glu::STORAGE_IN) | (1u << glu::STORAGE_PATCH_IN);
			searchStageBits = (1u << program->getFirstStage());
			break;

		case PROGRAMINTERFACE_PROGRAM_OUTPUT:
			validStorageBits = (1u << glu::STORAGE_OUT) | (1u << glu::STORAGE_PATCH_OUT);
			searchStageBits = (1u << program->getLastStage());
			break;

		case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
			validStorageBits = (1u << glu::STORAGE_OUT);
			searchStageBits = (1u << getProgramTransformFeedbackStage(program));
			break;

		case PROGRAMINTERFACE_UNIFORM:
			validStorageBits = (1u << glu::STORAGE_UNIFORM);
			searchStageBits = 0xFFFFFFFFu;
			break;

		case PROGRAMINTERFACE_BUFFER_VARIABLE:
			validStorageBits = (1u << glu::STORAGE_BUFFER);
			searchStageBits = 0xFFFFFFFFu;
			break;

		default:
			DE_ASSERT(false);
			return false;
	}

	for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
	{
		const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx];
		if (((1u << shader->getType()) & searchStageBits) == 0)
			continue;

		for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
		{
			const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx];

			if (((1u << block.storage) & validStorageBits) == 0)
				continue;

			if (block.interfaceName == blockInterfaceName)
				return true;
		}
	}
	return false;
}

static std::string getInterfaceBlockInteraceNameByMember (const ProgramInterfaceDefinition::Program* program, ProgramInterface interface, const std::string& memberName)
{
	deUint32 validStorageBits;
	deUint32 searchStageBits;

	DE_STATIC_ASSERT(glu::STORAGE_LAST < 32);
	DE_STATIC_ASSERT(glu::SHADERTYPE_LAST < 32);

	switch (interface)
	{
		case PROGRAMINTERFACE_UNIFORM_BLOCK:
		case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
		case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER:
			return "";

		case PROGRAMINTERFACE_PROGRAM_INPUT:
			validStorageBits = (1u << glu::STORAGE_IN) | (1u << glu::STORAGE_PATCH_IN);
			searchStageBits = (1u << program->getFirstStage());
			break;

		case PROGRAMINTERFACE_PROGRAM_OUTPUT:
			validStorageBits = (1u << glu::STORAGE_OUT) | (1u << glu::STORAGE_PATCH_OUT);
			searchStageBits = (1u << program->getLastStage());
			break;

		case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
			validStorageBits = (1u << glu::STORAGE_OUT);
			searchStageBits = (1u << getProgramTransformFeedbackStage(program));
			break;

		case PROGRAMINTERFACE_UNIFORM:
			validStorageBits = (1u << glu::STORAGE_UNIFORM);
			searchStageBits = 0xFFFFFFFFu;
			break;

		case PROGRAMINTERFACE_BUFFER_VARIABLE:
			validStorageBits = (1u << glu::STORAGE_BUFFER);
			searchStageBits = 0xFFFFFFFFu;
			break;

		default:
			DE_ASSERT(false);
			return "";
	}

	for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
	{
		const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx];
		if (((1u << shader->getType()) & searchStageBits) == 0)
			continue;

		for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx)
		{
			const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx];

			if (((1u << block.storage) & validStorageBits) == 0)
				continue;

			for (int varNdx = 0; varNdx < (int)block.variables.size(); ++varNdx)
			{
				if (block.variables[varNdx].name == memberName)
					return block.interfaceName;
			}
		}
	}
	return "";
}

static void queryAndValidateProps (tcu::TestContext&							testCtx,
								   const glw::Functions&						gl,
								   glw::GLuint									programID,
								   ProgramInterface								interface,
								   const char*									targetResourceName,
								   const ProgramInterfaceDefinition::Program*	programDefinition,
								   const std::vector<glw::GLenum>&				props,
								   const std::vector<const PropValidator*>&		validators)
{
	const glw::GLenum			glInterface					= getGLInterfaceEnumValue(interface);
	std::string					implementationResourceName	= targetResourceName;
	glw::GLuint					resourceNdx;
	glw::GLint					written						= -1;

	// prefill result buffer with an invalid value. -1 might be valid sometimes, avoid it. Make buffer one larger
	// to allow detection of too many return values
	std::vector<glw::GLint>		propValues		(props.size() + 1, -2);

	DE_ASSERT(props.size() == validators.size());

	// query

	resourceNdx = gl.getProgramResourceIndex(programID, glInterface, targetResourceName);
	GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index");

	if (resourceNdx == GL_INVALID_INDEX)
	{
		static const struct
		{
			bool removeTrailingArray;	// convert from "target[0]" -> "target"
			bool removeTrailingMember;	// convert from "target.member" -> "target"
			bool removeIOBlock;			// convert from "InterfaceName.target" -> "target"
			bool addIOBlock;			// convert from "target" -> "InterfaceName.target"
			bool addIOBlockArray;		// convert from "target" -> "InterfaceName[0].target"
		} recoveryStrategies[] =
		{
			// try one patch
			{ true,		false,	false,	false,	false	},
			{ false,	true,	false,	false,	false	},
			{ false,	false,	true,	false,	false	},
			{ false,	false,	false,	true,	false	},
			{ false,	false,	false,	false,	true	},
			// patch both ends
			{ true,		false,	true,	false,	false	},
			{ true,		false,	false,	true,	false	},
			{ true,		false,	false,	false,	true	},
			{ false,	true,	true,	false,	false	},
			{ false,	true,	false,	true,	false	},
			{ false,	true,	false,	false,	true	},
		};

		// The resource name generation in the GL implementations is very commonly broken. Try to
		// keep the tests producing useful data even in these cases by attempting to recover from
		// common naming bugs. Set test result to failure even if recovery succeeded to signal
		// incorrect name generation.

		testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceIndex returned GL_INVALID_INDEX for \"" << targetResourceName << "\"" << tcu::TestLog::EndMessage;
		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");

		for (int strategyNdx = 0; strategyNdx < DE_LENGTH_OF_ARRAY(recoveryStrategies); ++strategyNdx)
		{
			const std::string	resourceName			= std::string(targetResourceName);
			const size_t		rootNameEnd				= resourceName.find_first_of(".[");
			const std::string	rootName				= resourceName.substr(0, rootNameEnd);
			std::string			simplifiedResourceName;

			if (recoveryStrategies[strategyNdx].removeTrailingArray)
			{
				if (de::endsWith(resourceName, "[0]"))
					simplifiedResourceName = resourceName.substr(0, resourceName.length() - 3);
				else
					continue;
			}

			if (recoveryStrategies[strategyNdx].removeTrailingMember)
			{
				const size_t lastMember = resourceName.find_last_of('.');
				if (lastMember != std::string::npos)
					simplifiedResourceName = resourceName.substr(0, lastMember);
				else
					continue;
			}

			if (recoveryStrategies[strategyNdx].removeIOBlock)
			{
				if (deStringBeginsWith(resourceName.c_str(), "gl_PerVertex."))
				{
					// builtin interface bock, remove block name
					simplifiedResourceName = resourceName.substr(13);
				}
				else if (isInterfaceBlockInterfaceName(programDefinition, interface, rootName))
				{
					// user-defined inteface block, remove name
					const size_t accessorEnd = resourceName.find('.'); // includes potential array accessor

					if (accessorEnd != std::string::npos)
						simplifiedResourceName = resourceName.substr(0, accessorEnd+1);
					else
						continue;
				}
				else
				{
					// recovery not applicable
					continue;
				}
			}

			if (recoveryStrategies[strategyNdx].addIOBlock || recoveryStrategies[strategyNdx].addIOBlockArray)
			{
				const std::string arrayAccessor = (recoveryStrategies[strategyNdx].addIOBlockArray) ? ("[0]") : ("");

				if (deStringBeginsWith(resourceName.c_str(), "gl_") && resourceName.find('.') == std::string::npos)
				{
					// free builtin variable, add block name
					simplifiedResourceName = "gl_PerVertex" + arrayAccessor + "." + resourceName;
				}
				else
				{
					const std::string interafaceName = getInterfaceBlockInteraceNameByMember(programDefinition, interface, rootName);

					if (!interafaceName.empty())
					{
						// free user variable, add block name
						simplifiedResourceName = interafaceName + arrayAccessor + "." + resourceName;
					}
					else
					{
						// recovery not applicable
						continue;
					}
				}
			}

			if (simplifiedResourceName.empty())
				continue;

			resourceNdx = gl.getProgramResourceIndex(programID, glInterface, simplifiedResourceName.c_str());
			GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index");

			// recovery succeeded
			if (resourceNdx != GL_INVALID_INDEX)
			{
				implementationResourceName = simplifiedResourceName;
				testCtx.getLog() << tcu::TestLog::Message << "\tResource not found, continuing anyway using index obtained for resource \"" << simplifiedResourceName << "\"" << tcu::TestLog::EndMessage;
				break;
			}
		}

		if (resourceNdx == GL_INVALID_INDEX)
			return;
	}

	gl.getProgramResourceiv(programID, glInterface, resourceNdx, (int)props.size(), &props[0], (int)propValues.size(), &written, &propValues[0]);
	GLU_EXPECT_NO_ERROR(gl.getError(), "get props");

	if (written != (int)props.size())
	{
		testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceiv returned unexpected number of values, expected " << (int)props.size() << ", got " << written << tcu::TestLog::EndMessage;
		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values");
		return;
	}

	if (propValues.back() != -2)
	{
		testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceiv post write buffer guard value was modified, too many return values" << tcu::TestLog::EndMessage;
		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values");
		return;
	}
	propValues.pop_back();
	DE_ASSERT(validators.size() == propValues.size());

	// log

	{
		tcu::MessageBuilder message(&testCtx.getLog());
		message << "For resource index " << resourceNdx << " (\"" << targetResourceName << "\") got following properties:\n";

		for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx)
			message << "\t" << glu::getProgramResourcePropertyName(props[propNdx]) << ":\t" << validators[propNdx]->getHumanReadablePropertyString(propValues[propNdx]) << "\n";

		message << tcu::TestLog::EndMessage;
	}

	// validate

	for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx)
		validators[propNdx]->validate(programDefinition, targetResourceName, propValues[propNdx], implementationResourceName);
}

const ProgramInterfaceDefinition::Program* ProgramInterfaceQueryTestCase::getAndCheckProgramDefinition (void)
{
	const ProgramInterfaceDefinition::Program* programDefinition = getProgramDefinition();
	DE_ASSERT(programDefinition->isValid());

	auto type = m_context.getRenderContext().getType();
	if (glu::contextSupports(type, glu::ApiType::es(3, 2)) ||
		glu::contextSupports(type, glu::ApiType::core(4, 5)))
	{
		return programDefinition;
	}

	if (programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) ||
		programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
			throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	}

	// Testing IS_PER_PATCH as a part of a larger set is ok, since the extension is checked
	// before query. However, we don't want IS_PER_PATCH-specific tests to become noop and pass.
	if (m_queryTarget.propFlags == PROGRAMRESOURCEPROP_IS_PER_PATCH)
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
			throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	}

	if (programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY))
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
			throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
	}

	if (programContainsIOBlocks(programDefinition))
	{
		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
			throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
	}

	return programDefinition;
}

int ProgramInterfaceQueryTestCase::getMaxPatchVertices (void)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	glw::GLint				maxPatchVertices	= 0;

	gl.getIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv(GL_MAX_PATCH_VERTICES)");
	return maxPatchVertices;
}

ProgramInterfaceQueryTestCase::IterateResult ProgramInterfaceQueryTestCase::iterate (void)
{
	struct TestProperty
	{
		glw::GLenum				prop;
		const PropValidator*	validator;
	};

	const ProgramInterfaceDefinition::Program*	programDefinition	= getAndCheckProgramDefinition();
	const std::vector<std::string>				targetResources		= getQueryTargetResources();
	glu::ShaderProgram							program				(m_context.getRenderContext(), generateProgramInterfaceProgramSources(programDefinition));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	// Log program
	{
		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program");

		// Feedback varyings
		if (!programDefinition->getTransformFeedbackVaryings().empty())
		{
			tcu::MessageBuilder builder(&m_testCtx.getLog());
			builder << "Transform feedback varyings: {";
			for (int ndx = 0; ndx < (int)programDefinition->getTransformFeedbackVaryings().size(); ++ndx)
			{
				if (ndx)
					builder << ", ";
				builder << "\"" << programDefinition->getTransformFeedbackVaryings()[ndx] << "\"";
			}
			builder << "}" << tcu::TestLog::EndMessage;
		}

		m_testCtx.getLog() << program;
		if (!program.isOk())
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
			checkProgramResourceUsage(programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

			// within limits
			throw tcu::TestError("could not build program");
		}
	}

	// Check interface props

	switch (m_queryTarget.interface)
	{
		case PROGRAMINTERFACE_UNIFORM:
		{
			const VariableSearchFilter					uniformFilter						= VariableSearchFilter::createStorageFilter(glu::STORAGE_UNIFORM);

			const TypeValidator							typeValidator						(m_context, program.getProgram(),						uniformFilter);
			const ArraySizeValidator					arraySizeValidator					(m_context, program.getProgram(),						-1,					uniformFilter);
			const ArrayStrideValidator					arrayStrideValidator				(m_context, program.getProgram(),						uniformFilter);
			const BlockIndexValidator					blockIndexValidator					(m_context, program.getProgram(),						uniformFilter);
			const IsRowMajorValidator					isRowMajorValidator					(m_context, program.getProgram(),						uniformFilter);
			const MatrixStrideValidator					matrixStrideValidator				(m_context, program.getProgram(),						uniformFilter);
			const AtomicCounterBufferIndexVerifier		atomicCounterBufferIndexVerifier	(m_context, program.getProgram(),						uniformFilter);
			const LocationValidator						locationValidator					(m_context, program.getProgram(),						uniformFilter);
			const VariableNameLengthValidator			nameLengthValidator					(m_context, program.getProgram(),						uniformFilter);
			const OffsetValidator						offsetVerifier						(m_context, program.getProgram(),						uniformFilter);
			const VariableReferencedByShaderValidator	referencedByVertexVerifier			(m_context, glu::SHADERTYPE_VERTEX,						uniformFilter);
			const VariableReferencedByShaderValidator	referencedByFragmentVerifier		(m_context, glu::SHADERTYPE_FRAGMENT,					uniformFilter);
			const VariableReferencedByShaderValidator	referencedByComputeVerifier			(m_context, glu::SHADERTYPE_COMPUTE,					uniformFilter);
			const VariableReferencedByShaderValidator	referencedByGeometryVerifier		(m_context, glu::SHADERTYPE_GEOMETRY,					uniformFilter);
			const VariableReferencedByShaderValidator	referencedByTessControlVerifier		(m_context, glu::SHADERTYPE_TESSELLATION_CONTROL,		uniformFilter);
			const VariableReferencedByShaderValidator	referencedByTessEvaluationVerifier	(m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION,	uniformFilter);

			const TestProperty allProperties[] =
			{
				{ GL_ARRAY_SIZE,							&arraySizeValidator					},
				{ GL_ARRAY_STRIDE,							&arrayStrideValidator				},
				{ GL_ATOMIC_COUNTER_BUFFER_INDEX,			&atomicCounterBufferIndexVerifier	},
				{ GL_BLOCK_INDEX,							&blockIndexValidator				},
				{ GL_IS_ROW_MAJOR,							&isRowMajorValidator				},
				{ GL_LOCATION,								&locationValidator					},
				{ GL_MATRIX_STRIDE,							&matrixStrideValidator				},
				{ GL_NAME_LENGTH,							&nameLengthValidator				},
				{ GL_OFFSET,								&offsetVerifier						},
				{ GL_REFERENCED_BY_VERTEX_SHADER,			&referencedByVertexVerifier			},
				{ GL_REFERENCED_BY_FRAGMENT_SHADER,			&referencedByFragmentVerifier		},
				{ GL_REFERENCED_BY_COMPUTE_SHADER,			&referencedByComputeVerifier		},
				{ GL_REFERENCED_BY_GEOMETRY_SHADER,			&referencedByGeometryVerifier		},
				{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		&referencedByTessControlVerifier	},
				{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	&referencedByTessEvaluationVerifier	},
				{ GL_TYPE,									&typeValidator						},
			};

			for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
			{
				const tcu::ScopedLogSection			section			(m_testCtx.getLog(), "UniformResource", "Uniform resource \"" +  targetResources[targetResourceNdx] + "\"");
				const glw::Functions&				gl				= m_context.getRenderContext().getFunctions();
				std::vector<glw::GLenum>			props;
				std::vector<const PropValidator*>	validators;

				for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
				{
					if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
						allProperties[propNdx].validator->isSupported())
					{
						props.push_back(allProperties[propNdx].prop);
						validators.push_back(allProperties[propNdx].validator);
					}
				}

				DE_ASSERT(!props.empty());

				queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
			}

			break;
		}

		case PROGRAMINTERFACE_UNIFORM_BLOCK:
		case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK:
		{
			const glu::Storage						storage								= (m_queryTarget.interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER);
			const VariableSearchFilter				blockFilter							= VariableSearchFilter::createStorageFilter(storage);

			const BlockNameLengthValidator			nameLengthValidator					(m_context, program.getProgram(),						blockFilter);
			const BlockReferencedByShaderValidator	referencedByVertexVerifier			(m_context, glu::SHADERTYPE_VERTEX,						blockFilter);
			const BlockReferencedByShaderValidator	referencedByFragmentVerifier		(m_context, glu::SHADERTYPE_FRAGMENT,					blockFilter);
			const BlockReferencedByShaderValidator	referencedByComputeVerifier			(m_context, glu::SHADERTYPE_COMPUTE,					blockFilter);
			const BlockReferencedByShaderValidator	referencedByGeometryVerifier		(m_context, glu::SHADERTYPE_GEOMETRY,					blockFilter);
			const BlockReferencedByShaderValidator	referencedByTessControlVerifier		(m_context, glu::SHADERTYPE_TESSELLATION_CONTROL,		blockFilter);
			const BlockReferencedByShaderValidator	referencedByTessEvaluationVerifier	(m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION,	blockFilter);
			const BufferBindingValidator			bufferBindingValidator				(m_context, program.getProgram(),						blockFilter);

			const TestProperty allProperties[] =
			{
				{ GL_NAME_LENGTH,							&nameLengthValidator				},
				{ GL_REFERENCED_BY_VERTEX_SHADER,			&referencedByVertexVerifier			},
				{ GL_REFERENCED_BY_FRAGMENT_SHADER,			&referencedByFragmentVerifier		},
				{ GL_REFERENCED_BY_COMPUTE_SHADER,			&referencedByComputeVerifier		},
				{ GL_REFERENCED_BY_GEOMETRY_SHADER,			&referencedByGeometryVerifier		},
				{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		&referencedByTessControlVerifier	},
				{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	&referencedByTessEvaluationVerifier	},
				{ GL_BUFFER_BINDING,						&bufferBindingValidator				},
			};

			for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
			{
				const tcu::ScopedLogSection			section			(m_testCtx.getLog(), "BlockResource", "Interface block \"" +  targetResources[targetResourceNdx] + "\"");
				const glw::Functions&				gl				= m_context.getRenderContext().getFunctions();
				std::vector<glw::GLenum>			props;
				std::vector<const PropValidator*>	validators;

				for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
				{
					if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
						allProperties[propNdx].validator->isSupported())
					{
						props.push_back(allProperties[propNdx].prop);
						validators.push_back(allProperties[propNdx].validator);
					}
				}

				DE_ASSERT(!props.empty());

				queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
			}

			break;
		}

		case PROGRAMINTERFACE_PROGRAM_INPUT:
		case PROGRAMINTERFACE_PROGRAM_OUTPUT:
		{
			const bool									isInputCase							= (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT);
			const glu::Storage							varyingStorage						= (isInputCase) ? (glu::STORAGE_IN) : (glu::STORAGE_OUT);
			const glu::Storage							patchStorage						= (isInputCase) ? (glu::STORAGE_PATCH_IN) : (glu::STORAGE_PATCH_OUT);
			const glu::ShaderType						shaderType							= (isInputCase) ? (programDefinition->getFirstStage()) : (programDefinition->getLastStage());
			const int									unsizedArraySize					= (isInputCase && shaderType == glu::SHADERTYPE_GEOMETRY)					? (1)															// input points
																							: (isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)		? (getMaxPatchVertices())										// input batch size
																							: (!isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)		? (programDefinition->getTessellationNumOutputPatchVertices())	// output batch size
																							: (isInputCase && shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION)	? (getMaxPatchVertices())										// input batch size
																							: (-1);
			const VariableSearchFilter					variableFilter						= VariableSearchFilter::logicalAnd(VariableSearchFilter::createShaderTypeFilter(shaderType),
																															   VariableSearchFilter::logicalOr(VariableSearchFilter::createStorageFilter(varyingStorage),
																																							   VariableSearchFilter::createStorageFilter(patchStorage)));

			const TypeValidator							typeValidator						(m_context, program.getProgram(),						variableFilter);
			const ArraySizeValidator					arraySizeValidator					(m_context, program.getProgram(),						unsizedArraySize,		variableFilter);
			const LocationValidator						locationValidator					(m_context, program.getProgram(),						variableFilter);
			const VariableNameLengthValidator			nameLengthValidator					(m_context, program.getProgram(),						variableFilter);
			const VariableReferencedByShaderValidator	referencedByVertexVerifier			(m_context, glu::SHADERTYPE_VERTEX,						variableFilter);
			const VariableReferencedByShaderValidator	referencedByFragmentVerifier		(m_context, glu::SHADERTYPE_FRAGMENT,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByComputeVerifier			(m_context, glu::SHADERTYPE_COMPUTE,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByGeometryVerifier		(m_context, glu::SHADERTYPE_GEOMETRY,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByTessControlVerifier		(m_context, glu::SHADERTYPE_TESSELLATION_CONTROL,		variableFilter);
			const VariableReferencedByShaderValidator	referencedByTessEvaluationVerifier	(m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION,	variableFilter);
			const PerPatchValidator						perPatchValidator					(m_context, program.getProgram(),						variableFilter);

			const TestProperty allProperties[] =
			{
				{ GL_ARRAY_SIZE,							&arraySizeValidator					},
				{ GL_LOCATION,								&locationValidator					},
				{ GL_NAME_LENGTH,							&nameLengthValidator				},
				{ GL_REFERENCED_BY_VERTEX_SHADER,			&referencedByVertexVerifier			},
				{ GL_REFERENCED_BY_FRAGMENT_SHADER,			&referencedByFragmentVerifier		},
				{ GL_REFERENCED_BY_COMPUTE_SHADER,			&referencedByComputeVerifier		},
				{ GL_REFERENCED_BY_GEOMETRY_SHADER,			&referencedByGeometryVerifier		},
				{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		&referencedByTessControlVerifier	},
				{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	&referencedByTessEvaluationVerifier	},
				{ GL_TYPE,									&typeValidator						},
				{ GL_IS_PER_PATCH,							&perPatchValidator					},
			};

			for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
			{
				const std::string					resourceInterfaceName	= (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? ("Input") : ("Output");
				const tcu::ScopedLogSection			section					(m_testCtx.getLog(), "BlockResource", resourceInterfaceName + " resource \"" +  targetResources[targetResourceNdx] + "\"");
				const glw::Functions&				gl						= m_context.getRenderContext().getFunctions();
				std::vector<glw::GLenum>			props;
				std::vector<const PropValidator*>	validators;

				for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
				{
					if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
						allProperties[propNdx].validator->isSupported())
					{
						props.push_back(allProperties[propNdx].prop);
						validators.push_back(allProperties[propNdx].validator);
					}
				}

				DE_ASSERT(!props.empty());

				queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
			}

			break;
		}

		case PROGRAMINTERFACE_BUFFER_VARIABLE:
		{
			const VariableSearchFilter					variableFilter						= VariableSearchFilter::createStorageFilter(glu::STORAGE_BUFFER);

			const TypeValidator							typeValidator						(m_context, program.getProgram(),						variableFilter);
			const ArraySizeValidator					arraySizeValidator					(m_context, program.getProgram(),						0,					variableFilter);
			const ArrayStrideValidator					arrayStrideValidator				(m_context, program.getProgram(),						variableFilter);
			const BlockIndexValidator					blockIndexValidator					(m_context, program.getProgram(),						variableFilter);
			const IsRowMajorValidator					isRowMajorValidator					(m_context, program.getProgram(),						variableFilter);
			const MatrixStrideValidator					matrixStrideValidator				(m_context, program.getProgram(),						variableFilter);
			const OffsetValidator						offsetValidator						(m_context, program.getProgram(),						variableFilter);
			const VariableNameLengthValidator			nameLengthValidator					(m_context, program.getProgram(),						variableFilter);
			const VariableReferencedByShaderValidator	referencedByVertexVerifier			(m_context, glu::SHADERTYPE_VERTEX,						variableFilter);
			const VariableReferencedByShaderValidator	referencedByFragmentVerifier		(m_context, glu::SHADERTYPE_FRAGMENT,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByComputeVerifier			(m_context, glu::SHADERTYPE_COMPUTE,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByGeometryVerifier		(m_context, glu::SHADERTYPE_GEOMETRY,					variableFilter);
			const VariableReferencedByShaderValidator	referencedByTessControlVerifier		(m_context, glu::SHADERTYPE_TESSELLATION_CONTROL,		variableFilter);
			const VariableReferencedByShaderValidator	referencedByTessEvaluationVerifier	(m_context, glu::SHADERTYPE_TESSELLATION_EVALUATION,	variableFilter);
			const TopLevelArraySizeValidator			topLevelArraySizeValidator			(m_context, program.getProgram(),						variableFilter);
			const TopLevelArrayStrideValidator			topLevelArrayStrideValidator		(m_context, program.getProgram(),						variableFilter);

			const TestProperty allProperties[] =
			{
				{ GL_ARRAY_SIZE,							&arraySizeValidator					},
				{ GL_ARRAY_STRIDE,							&arrayStrideValidator				},
				{ GL_BLOCK_INDEX,							&blockIndexValidator				},
				{ GL_IS_ROW_MAJOR,							&isRowMajorValidator				},
				{ GL_MATRIX_STRIDE,							&matrixStrideValidator				},
				{ GL_NAME_LENGTH,							&nameLengthValidator				},
				{ GL_OFFSET,								&offsetValidator					},
				{ GL_REFERENCED_BY_VERTEX_SHADER,			&referencedByVertexVerifier			},
				{ GL_REFERENCED_BY_FRAGMENT_SHADER,			&referencedByFragmentVerifier		},
				{ GL_REFERENCED_BY_COMPUTE_SHADER,			&referencedByComputeVerifier		},
				{ GL_REFERENCED_BY_GEOMETRY_SHADER,			&referencedByGeometryVerifier		},
				{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		&referencedByTessControlVerifier	},
				{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	&referencedByTessEvaluationVerifier	},
				{ GL_TOP_LEVEL_ARRAY_SIZE,					&topLevelArraySizeValidator			},
				{ GL_TOP_LEVEL_ARRAY_STRIDE,				&topLevelArrayStrideValidator		},
				{ GL_TYPE,									&typeValidator						},
			};

			for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
			{
				const tcu::ScopedLogSection			section			(m_testCtx.getLog(), "BufferVariableResource", "Buffer variable \"" +  targetResources[targetResourceNdx] + "\"");
				const glw::Functions&				gl				= m_context.getRenderContext().getFunctions();
				std::vector<glw::GLenum>			props;
				std::vector<const PropValidator*>	validators;

				for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
				{
					if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
						allProperties[propNdx].validator->isSupported())
					{
						props.push_back(allProperties[propNdx].prop);
						validators.push_back(allProperties[propNdx].validator);
					}
				}

				DE_ASSERT(!props.empty());

				queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
			}

			break;
		}

		case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING:
		{
			const TransformFeedbackTypeValidator		typeValidator			(m_context);
			const TransformFeedbackArraySizeValidator	arraySizeValidator		(m_context);
			const TransformFeedbackNameLengthValidator	nameLengthValidator		(m_context);

			const TestProperty allProperties[] =
			{
				{ GL_ARRAY_SIZE,					&arraySizeValidator				},
				{ GL_NAME_LENGTH,					&nameLengthValidator			},
				{ GL_TYPE,							&typeValidator					},
			};

			for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx)
			{
				const tcu::ScopedLogSection			section			(m_testCtx.getLog(), "XFBVariableResource", "Transform feedback varying \"" +  targetResources[targetResourceNdx] + "\"");
				const glw::Functions&				gl				= m_context.getRenderContext().getFunctions();
				std::vector<glw::GLenum>			props;
				std::vector<const PropValidator*>	validators;

				for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx)
				{
					if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) &&
						allProperties[propNdx].validator->isSupported())
					{
						props.push_back(allProperties[propNdx].prop);
						validators.push_back(allProperties[propNdx].validator);
					}
				}

				DE_ASSERT(!props.empty());

				queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators);
			}

			break;
		}

		default:
			DE_ASSERT(false);
	}

	return STOP;
}

static bool checkLimit (glw::GLenum pname, int usage, const glw::Functions& gl, tcu::TestLog& log)
{
	if (usage > 0)
	{
		glw::GLint limit = 0;
		gl.getIntegerv(pname, &limit);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query limits");

		log << tcu::TestLog::Message << "\t" << glu::getGettableStateStr(pname) << " = " << limit << ", test requires " << usage << tcu::TestLog::EndMessage;

		if (limit < usage)
		{
			log << tcu::TestLog::Message << "\t\tLimit exceeded" << tcu::TestLog::EndMessage;
			return false;
		}
	}

	return true;
}

static bool checkShaderResourceUsage (const ProgramInterfaceDefinition::Program* program, const ProgramInterfaceDefinition::Shader* shader, const glw::Functions& gl, tcu::TestLog& log)
{
	const ProgramInterfaceDefinition::ShaderResourceUsage usage = getShaderResourceUsage(program, shader);

	switch (shader->getType())
	{
		case glu::SHADERTYPE_VERTEX:
		{
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_VERTEX_ATTRIBS,						usage.numInputVectors					},
				{ GL_MAX_VERTEX_UNIFORM_COMPONENTS,				usage.numDefaultBlockUniformComponents	},
				{ GL_MAX_VERTEX_UNIFORM_VECTORS,				usage.numUniformVectors					},
				{ GL_MAX_VERTEX_UNIFORM_BLOCKS,					usage.numUniformBlocks					},
				{ GL_MAX_VERTEX_OUTPUT_COMPONENTS,				usage.numOutputComponents				},
				{ GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,			usage.numSamplers						},
				{ GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS,			usage.numAtomicCounterBuffers			},
				{ GL_MAX_VERTEX_ATOMIC_COUNTERS,				usage.numAtomicCounters					},
				{ GL_MAX_VERTEX_IMAGE_UNIFORMS,					usage.numImages							},
				{ GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,	usage.numCombinedUniformComponents		},
				{ GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,			usage.numShaderStorageBlocks			},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Vertex shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		case glu::SHADERTYPE_FRAGMENT:
		{
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,			usage.numDefaultBlockUniformComponents		},
				{ GL_MAX_FRAGMENT_UNIFORM_VECTORS,				usage.numUniformVectors						},
				{ GL_MAX_FRAGMENT_UNIFORM_BLOCKS,				usage.numUniformBlocks						},
				{ GL_MAX_FRAGMENT_INPUT_COMPONENTS,				usage.numInputComponents					},
				{ GL_MAX_TEXTURE_IMAGE_UNITS,					usage.numSamplers							},
				{ GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS,		usage.numAtomicCounterBuffers				},
				{ GL_MAX_FRAGMENT_ATOMIC_COUNTERS,				usage.numAtomicCounters						},
				{ GL_MAX_FRAGMENT_IMAGE_UNIFORMS,				usage.numImages								},
				{ GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,	usage.numCombinedUniformComponents			},
				{ GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,		usage.numShaderStorageBlocks				},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Fragment shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		case glu::SHADERTYPE_COMPUTE:
		{
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_COMPUTE_UNIFORM_BLOCKS,				usage.numUniformBlocks					},
				{ GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS,			usage.numSamplers						},
				{ GL_MAX_COMPUTE_UNIFORM_COMPONENTS,			usage.numDefaultBlockUniformComponents	},
				{ GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS,		usage.numAtomicCounterBuffers			},
				{ GL_MAX_COMPUTE_ATOMIC_COUNTERS,				usage.numAtomicCounters					},
				{ GL_MAX_COMPUTE_IMAGE_UNIFORMS,				usage.numImages							},
				{ GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS,	usage.numCombinedUniformComponents		},
				{ GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS,			usage.numShaderStorageBlocks			},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Compute shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		case glu::SHADERTYPE_GEOMETRY:
		{
			const int totalOutputComponents = program->getGeometryNumOutputVertices() * usage.numOutputComponents;
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_GEOMETRY_UNIFORM_COMPONENTS,				usage.numDefaultBlockUniformComponents			},
				{ GL_MAX_GEOMETRY_UNIFORM_BLOCKS,					usage.numUniformBlocks							},
				{ GL_MAX_GEOMETRY_INPUT_COMPONENTS,					usage.numInputComponents						},
				{ GL_MAX_GEOMETRY_OUTPUT_COMPONENTS,				usage.numOutputComponents						},
				{ GL_MAX_GEOMETRY_OUTPUT_VERTICES,					(int)program->getGeometryNumOutputVertices()	},
				{ GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,			totalOutputComponents							},
				{ GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,				usage.numSamplers								},
				{ GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,			usage.numAtomicCounterBuffers					},
				{ GL_MAX_GEOMETRY_ATOMIC_COUNTERS,					usage.numAtomicCounters							},
				{ GL_MAX_GEOMETRY_IMAGE_UNIFORMS,					usage.numImages									},
				{ GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,			usage.numShaderStorageBlocks					},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Geometry shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		case glu::SHADERTYPE_TESSELLATION_CONTROL:
		{
			const int totalOutputComponents = program->getTessellationNumOutputPatchVertices() * usage.numOutputComponents + usage.numPatchOutputComponents;
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_PATCH_VERTICES,								(int)program->getTessellationNumOutputPatchVertices()	},
				{ GL_MAX_TESS_PATCH_COMPONENTS,							usage.numPatchOutputComponents							},
				{ GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS,				usage.numDefaultBlockUniformComponents					},
				{ GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,					usage.numUniformBlocks									},
				{ GL_MAX_TESS_CONTROL_INPUT_COMPONENTS,					usage.numInputComponents								},
				{ GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS,				usage.numOutputComponents								},
				{ GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,			totalOutputComponents									},
				{ GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,				usage.numSamplers										},
				{ GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,			usage.numAtomicCounterBuffers							},
				{ GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS,					usage.numAtomicCounters									},
				{ GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,					usage.numImages											},
				{ GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,			usage.numShaderStorageBlocks							},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Tessellation control shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		case glu::SHADERTYPE_TESSELLATION_EVALUATION:
		{
			const struct
			{
				glw::GLenum	pname;
				int			usage;
			} restrictions[] =
			{
				{ GL_MAX_PATCH_VERTICES,								(int)program->getTessellationNumOutputPatchVertices()	},
				{ GL_MAX_TESS_PATCH_COMPONENTS,							usage.numPatchInputComponents							},
				{ GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS,			usage.numDefaultBlockUniformComponents					},
				{ GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,				usage.numUniformBlocks									},
				{ GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS,				usage.numInputComponents								},
				{ GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS,				usage.numOutputComponents								},
				{ GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,			usage.numSamplers										},
				{ GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS,		usage.numAtomicCounterBuffers							},
				{ GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS,				usage.numAtomicCounters									},
				{ GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS,				usage.numImages											},
				{ GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,			usage.numShaderStorageBlocks							},
			};

			bool allOk = true;

			log << tcu::TestLog::Message << "Tessellation evaluation shader:" << tcu::TestLog::EndMessage;
			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
				allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

			return allOk;
		}

		default:
			DE_ASSERT(false);
			return false;
	}
}

static bool checkProgramCombinedResourceUsage (const ProgramInterfaceDefinition::Program* program, const glw::Functions& gl, tcu::TestLog& log)
{
	const ProgramInterfaceDefinition::ProgramResourceUsage usage = getCombinedProgramResourceUsage(program);

	const struct
	{
		glw::GLenum	pname;
		int			usage;
	} restrictions[] =
	{
		{ GL_MAX_UNIFORM_BUFFER_BINDINGS,						usage.uniformBufferMaxBinding+1					},
		{ GL_MAX_UNIFORM_BLOCK_SIZE,							usage.uniformBufferMaxSize						},
		{ GL_MAX_COMBINED_UNIFORM_BLOCKS,						usage.numUniformBlocks							},
		{ GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,			usage.numCombinedVertexUniformComponents		},
		{ GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,			usage.numCombinedFragmentUniformComponents		},
		{ GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS,			usage.numCombinedGeometryUniformComponents		},
		{ GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS,		usage.numCombinedTessControlUniformComponents	},
		{ GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS,	usage.numCombinedTessEvalUniformComponents		},
		{ GL_MAX_VARYING_COMPONENTS,							usage.numVaryingComponents						},
		{ GL_MAX_VARYING_VECTORS,								usage.numVaryingVectors							},
		{ GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,					usage.numCombinedSamplers						},
		{ GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES,				usage.numCombinedOutputResources				},
		{ GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,				usage.atomicCounterBufferMaxBinding+1			},
		{ GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE,					usage.atomicCounterBufferMaxSize				},
		{ GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS,				usage.numAtomicCounterBuffers					},
		{ GL_MAX_COMBINED_ATOMIC_COUNTERS,						usage.numAtomicCounters							},
		{ GL_MAX_IMAGE_UNITS,									usage.maxImageBinding+1							},
		{ GL_MAX_COMBINED_IMAGE_UNIFORMS,						usage.numCombinedImages							},
		{ GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,				usage.shaderStorageBufferMaxBinding+1			},
		{ GL_MAX_SHADER_STORAGE_BLOCK_SIZE,						usage.shaderStorageBufferMaxSize				},
		{ GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS,				usage.numShaderStorageBlocks					},
		{ GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,		usage.numXFBInterleavedComponents				},
		{ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,			usage.numXFBSeparateAttribs						},
		{ GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS,		usage.numXFBSeparateComponents					},
		{ GL_MAX_DRAW_BUFFERS,									usage.fragmentOutputMaxBinding+1				},
	};

	bool allOk = true;

	log << tcu::TestLog::Message << "Program combined:" << tcu::TestLog::EndMessage;
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx)
		allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log);

	return allOk;
}

void checkProgramResourceUsage (const ProgramInterfaceDefinition::Program* program, const glw::Functions& gl, tcu::TestLog& log)
{
	bool limitExceeded = false;

	for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx)
		limitExceeded |= !checkShaderResourceUsage(program, program->getShaders()[shaderNdx], gl, log);

	limitExceeded |= !checkProgramCombinedResourceUsage(program, gl, log);

	if (limitExceeded)
	{
		log << tcu::TestLog::Message << "One or more resource limits exceeded" << tcu::TestLog::EndMessage;
		throw tcu::NotSupportedError("one or more resource limits exceeded");
	}
}

} // Functional
} // gles31
} // deqp
