/*-------------------------------------------------------------------------
 * 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
{
	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>	dummyPath;
	const bool							referencedByShader = findProgramVariablePathByPathName(dummyPath, 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());

	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
