/*-------------------------------------------------------------------------
 * 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 tests.
 *//*--------------------------------------------------------------------*/

#include "es31fProgramInterfaceQueryTests.hpp"
#include "es31fProgramInterfaceQueryTestCase.hpp"
#include "es31fProgramInterfaceDefinition.hpp"
#include "es31fProgramInterfaceDefinitionUtil.hpp"
#include "tcuTestLog.hpp"
#include "gluShaderProgram.hpp"
#include "gluVarTypeUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deRandom.hpp"
#include "deString.h"
#include "deStringUtil.hpp"
#include "deSharedPtr.hpp"
#include "deUniquePtr.hpp"
#include "deSTLUtil.hpp"
#include "deArrayUtil.hpp"

#include <set>
#include <map>

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

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 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())
	{
		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 std::string convertGLTypeNameToTestName (const char* glName)
{
	// vectors and matrices are fine as is
	{
		if (deStringBeginsWith(glName, "vec")  == DE_TRUE ||
			deStringBeginsWith(glName, "ivec") == DE_TRUE ||
			deStringBeginsWith(glName, "uvec") == DE_TRUE ||
			deStringBeginsWith(glName, "bvec") == DE_TRUE ||
			deStringBeginsWith(glName, "mat")  == DE_TRUE)
			return std::string(glName);
	}

	// convert camel case to use underscore
	{
		std::ostringstream	buf;
		std::istringstream	name					(glName);
		bool				mergeNextToken			= false;
		bool				previousTokenWasDigit	= false;

		while (!name.eof())
		{
			std::ostringstream token;

			while (name.peek() != EOF)
			{
				if ((de::isDigit((char)name.peek()) || de::isUpper((char)name.peek())) && token.tellp())
					break;

				token << de::toLower((char)name.get());
			}

			if (buf.str().empty() || mergeNextToken)
				buf << token.str();
			else
				buf << '_' << token.str();

			// Single char causes next char to be merged (don't split initialisms or acronyms) unless it is 'D' after a number (split to ..._2d_acronym_aa
			mergeNextToken = false;
			if (token.tellp() == (std::streamoff)1)
			{
				if (!previousTokenWasDigit || token.str()[0] != 'd')
					mergeNextToken = true;

				previousTokenWasDigit = de::isDigit(token.str()[0]);
			}
			else
				previousTokenWasDigit = false;
		}

		return buf.str();
	}
}

static glw::GLenum getProgramInterfaceGLEnum (ProgramInterface interface)
{
	static const glw::GLenum s_enums[] =
	{
		GL_UNIFORM,						// PROGRAMINTERFACE_UNIFORM
		GL_UNIFORM_BLOCK,				// PROGRAMINTERFACE_UNIFORM_BLOCK
		GL_ATOMIC_COUNTER_BUFFER,		// PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER
		GL_PROGRAM_INPUT,				// PROGRAMINTERFACE_PROGRAM_INPUT
		GL_PROGRAM_OUTPUT,				// PROGRAMINTERFACE_PROGRAM_OUTPUT
		GL_TRANSFORM_FEEDBACK_VARYING,	// PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING
		GL_BUFFER_VARIABLE,				// PROGRAMINTERFACE_BUFFER_VARIABLE
		GL_SHADER_STORAGE_BLOCK,		// PROGRAMINTERFACE_SHADER_STORAGE_BLOCK
	};

	return de::getSizedArrayElement<PROGRAMINTERFACE_LAST>(s_enums, interface);
}

static glu::ShaderType getShaderMaskFirstStage (deUint32 mask)
{
	if (mask & (1u << glu::SHADERTYPE_COMPUTE))
		return glu::SHADERTYPE_COMPUTE;

	if (mask & (1u << glu::SHADERTYPE_VERTEX))
		return glu::SHADERTYPE_VERTEX;

	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
		return glu::SHADERTYPE_TESSELLATION_CONTROL;

	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
		return glu::SHADERTYPE_TESSELLATION_EVALUATION;

	if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
		return glu::SHADERTYPE_GEOMETRY;

	if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
		return glu::SHADERTYPE_FRAGMENT;

	DE_ASSERT(false);
	return glu::SHADERTYPE_LAST;
}

static glu::ShaderType getShaderMaskLastStage (deUint32 mask)
{
	if (mask & (1u << glu::SHADERTYPE_FRAGMENT))
		return glu::SHADERTYPE_FRAGMENT;

	if (mask & (1u << glu::SHADERTYPE_GEOMETRY))
		return glu::SHADERTYPE_GEOMETRY;

	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_EVALUATION))
		return glu::SHADERTYPE_TESSELLATION_EVALUATION;

	if (mask & (1u << glu::SHADERTYPE_TESSELLATION_CONTROL))
		return glu::SHADERTYPE_TESSELLATION_CONTROL;

	if (mask & (1u << glu::SHADERTYPE_VERTEX))
		return glu::SHADERTYPE_VERTEX;

	if (mask & (1u << glu::SHADERTYPE_COMPUTE))
		return glu::SHADERTYPE_COMPUTE;

	DE_ASSERT(false);
	return glu::SHADERTYPE_LAST;
}

namespace ResourceDefinition
{

class Node
{
public:
	enum NodeType
	{
		TYPE_PROGRAM = 0,
		TYPE_SHADER,
		TYPE_DEFAULT_BLOCK,
		TYPE_VARIABLE,
		TYPE_INTERFACE_BLOCK,
		TYPE_ARRAY_ELEMENT,
		TYPE_STRUCT_MEMBER,
		TYPE_STORAGE_QUALIFIER,
		TYPE_LAYOUT_QUALIFIER,
		TYPE_SHADER_SET,
		TYPE_INTERPOLATION_QUALIFIER,
		TYPE_TRANSFORM_FEEDBACK_TARGET,

		TYPE_LAST
	};

	typedef de::SharedPtr<const Node> SharedPtr;

							Node				(NodeType type, const SharedPtr& enclosingNode) : m_type(type), m_enclosingNode(enclosingNode) { DE_ASSERT(type < TYPE_LAST); }
	virtual					~Node				(void) { }

	inline const Node*		getEnclosingNode	(void) const					{ return m_enclosingNode.get();	}
	inline NodeType			getType				(void) const					{ return m_type;				}

private:
	const NodeType			m_type;
	const SharedPtr			m_enclosingNode;
};

class Program : public Node
{
public:
	Program (bool separable = false)
		: Node			(TYPE_PROGRAM, SharedPtr())
		, m_separable	(separable)
	{
	}

	const bool m_separable;
};

class Shader : public Node
{
public:
	Shader (const SharedPtr& enclosingNode, glu::ShaderType type, glu::GLSLVersion version)
		: Node		(TYPE_SHADER, enclosingNode)
		, m_type	(type)
		, m_version	(version)
	{
		DE_ASSERT(enclosingNode->getType() == TYPE_PROGRAM);
		DE_ASSERT(type < glu::SHADERTYPE_LAST);
	}

	const glu::ShaderType	m_type;
	const glu::GLSLVersion	m_version;
};

class DefaultBlock : public Node
{
public:
	DefaultBlock (const SharedPtr& enclosing)
		: Node(TYPE_DEFAULT_BLOCK, enclosing)
	{
		// enclosed by the shader
		DE_ASSERT(enclosing->getType() == TYPE_SHADER		||
				  enclosing->getType() == TYPE_SHADER_SET);
	}
};

class StorageQualifier : public Node
{
public:
	StorageQualifier (const SharedPtr& enclosing, glu::Storage storage)
		: Node		(TYPE_STORAGE_QUALIFIER, enclosing)
		, m_storage	(storage)
	{
		// not a part of any block
		DE_ASSERT(enclosing->getType() == TYPE_DEFAULT_BLOCK);
	}

	const glu::Storage	m_storage;
};

class Variable : public Node
{
public:
	Variable (const SharedPtr& enclosing, glu::DataType dataType)
		: Node			(TYPE_VARIABLE, enclosing)
		, m_dataType	(dataType)
	{
		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
	}

	const glu::DataType	m_dataType;
};

class InterfaceBlock : public Node
{
public:
	InterfaceBlock (const SharedPtr& enclosing, bool named)
		: Node		(TYPE_INTERFACE_BLOCK, enclosing)
		, m_named	(named)
	{
		// Must be storage qualified
		const Node* storageNode = enclosing.get();
		while (storageNode->getType() == TYPE_ARRAY_ELEMENT ||
			   storageNode->getType() == TYPE_LAYOUT_QUALIFIER)
		{
			storageNode = storageNode->getEnclosingNode();
		}

		DE_ASSERT(storageNode->getType() == TYPE_STORAGE_QUALIFIER);
		DE_UNREF(storageNode);
	}

	const bool	m_named;
};

class ArrayElement : public Node
{
public:
	ArrayElement (const SharedPtr& enclosing, int arraySize = DEFAULT_SIZE)
		: Node			(TYPE_ARRAY_ELEMENT, enclosing)
		, m_arraySize	(arraySize)
	{
		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
	}

	const int m_arraySize;

	enum
	{
		DEFAULT_SIZE	= -1,
		UNSIZED_ARRAY	= -2,
	};
};

class StructMember : public Node
{
public:
	StructMember (const SharedPtr& enclosing)
		: Node(TYPE_STRUCT_MEMBER, enclosing)
	{
		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
				  enclosing->getType() == TYPE_INTERFACE_BLOCK			||
				  enclosing->getType() == TYPE_ARRAY_ELEMENT			||
				  enclosing->getType() == TYPE_STRUCT_MEMBER			||
				  enclosing->getType() == TYPE_TRANSFORM_FEEDBACK_TARGET);
	}
};

class LayoutQualifier : public Node
{
public:
	LayoutQualifier (const SharedPtr& enclosing, const glu::Layout& layout)
		: Node		(TYPE_LAYOUT_QUALIFIER, enclosing)
		, m_layout	(layout)
	{
		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
				  enclosing->getType() == TYPE_DEFAULT_BLOCK			||
				  enclosing->getType() == TYPE_INTERFACE_BLOCK);
	}

	const glu::Layout m_layout;
};

class InterpolationQualifier : public Node
{
public:
	InterpolationQualifier (const SharedPtr& enclosing, const glu::Interpolation& interpolation)
		: Node				(TYPE_INTERPOLATION_QUALIFIER, enclosing)
		, m_interpolation	(interpolation)
	{
		DE_ASSERT(enclosing->getType() == TYPE_STORAGE_QUALIFIER		||
				  enclosing->getType() == TYPE_LAYOUT_QUALIFIER			||
				  enclosing->getType() == TYPE_INTERPOLATION_QUALIFIER	||
				  enclosing->getType() == TYPE_DEFAULT_BLOCK			||
				  enclosing->getType() == TYPE_INTERFACE_BLOCK);
	}

	const glu::Interpolation m_interpolation;
};

class ShaderSet : public Node
{
public:
				ShaderSet			(const SharedPtr& enclosing, glu::GLSLVersion version);
				ShaderSet			(const SharedPtr& enclosing, glu::GLSLVersion version, deUint32 stagesPresentBits, deUint32 stagesReferencingBits);

	void		setStage			(glu::ShaderType type, bool referencing);
	bool		isStagePresent		(glu::ShaderType stage) const;
	bool		isStageReferencing	(glu::ShaderType stage) const;

	deUint32	getReferencingMask	(void) const;

	const glu::GLSLVersion	m_version;
private:
	bool		m_stagePresent[glu::SHADERTYPE_LAST];
	bool		m_stageReferencing[glu::SHADERTYPE_LAST];
};

ShaderSet::ShaderSet (const SharedPtr& enclosing, glu::GLSLVersion version)
	: Node		(TYPE_SHADER_SET, enclosing)
	, m_version	(version)
{
	DE_ASSERT(enclosing->getType() == TYPE_PROGRAM);

	deMemset(m_stagePresent, 0, sizeof(m_stagePresent));
	deMemset(m_stageReferencing, 0, sizeof(m_stageReferencing));
}

ShaderSet::ShaderSet (const SharedPtr&	enclosing,
					  glu::GLSLVersion	version,
					  deUint32			stagesPresentBits,
					  deUint32			stagesReferencingBits)
	: Node		(TYPE_SHADER_SET, enclosing)
	, m_version	(version)
{
	for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
	{
		const deUint32	stageMask			= (1u << stageNdx);
		const bool		stagePresent		= (stagesPresentBits & stageMask) != 0;
		const bool		stageReferencing	= (stagesReferencingBits & stageMask) != 0;

		DE_ASSERT(stagePresent || !stageReferencing);

		m_stagePresent[stageNdx]		= stagePresent;
		m_stageReferencing[stageNdx]	= stageReferencing;
	}
}

void ShaderSet::setStage (glu::ShaderType type, bool referencing)
{
	DE_ASSERT(type < glu::SHADERTYPE_LAST);
	m_stagePresent[type] = true;
	m_stageReferencing[type] = referencing;
}

bool ShaderSet::isStagePresent (glu::ShaderType stage) const
{
	DE_ASSERT(stage < glu::SHADERTYPE_LAST);
	return m_stagePresent[stage];
}

bool ShaderSet::isStageReferencing (glu::ShaderType stage) const
{
	DE_ASSERT(stage < glu::SHADERTYPE_LAST);
	return m_stageReferencing[stage];
}

deUint32 ShaderSet::getReferencingMask (void) const
{
	deUint32 mask = 0;
	for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
	{
		if (m_stageReferencing[stage])
			mask |= (1u << stage);
	}
	return mask;
}

class TransformFeedbackTarget : public Node
{
public:
	TransformFeedbackTarget (const SharedPtr& enclosing, const char* builtinVarName = DE_NULL)
		: Node				(TYPE_TRANSFORM_FEEDBACK_TARGET, enclosing)
		, m_builtinVarName	(builtinVarName)
	{
	}

	const char* const m_builtinVarName;
};

} // ResourceDefinition

static glu::Precision getDataTypeDefaultPrecision (const glu::DataType& type)
{
	if (glu::isDataTypeBoolOrBVec(type))
		return glu::PRECISION_LAST;
	else if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type))
		return glu::PRECISION_HIGHP;
	else if (glu::isDataTypeSampler(type))
		return glu::PRECISION_HIGHP;
	else if (glu::isDataTypeImage(type))
		return glu::PRECISION_HIGHP;
	else if (type == glu::TYPE_UINT_ATOMIC_COUNTER)
		return glu::PRECISION_HIGHP;

	DE_ASSERT(false);
	return glu::PRECISION_LAST;
}

static de::MovePtr<ProgramInterfaceDefinition::Program>	generateProgramDefinitionFromResource (const ResourceDefinition::Node* resource)
{
	de::MovePtr<ProgramInterfaceDefinition::Program>	program	(new ProgramInterfaceDefinition::Program());
	const ResourceDefinition::Node*						head	= resource;

	if (head->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
	{
		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));

		enum BindingType
		{
			BINDING_VARIABLE,
			BINDING_INTERFACE_BLOCK,
			BINDING_DEFAULT_BLOCK
		};

		int											structNdx				= 0;
		int											autoAssignArraySize		= 0;
		const glu::DataType							basicType				= static_cast<const ResourceDefinition::Variable*>(resource)->m_dataType;
		BindingType									boundObject				= BINDING_VARIABLE;
		glu::VariableDeclaration					variable				(glu::VarType(basicType, getDataTypeDefaultPrecision(basicType)), "target");
		glu::InterfaceBlock							interfaceBlock;
		ProgramInterfaceDefinition::DefaultBlock	defaultBlock;
		std::vector<std::string>					feedbackTargetVaryingPath;
		bool										feedbackTargetSet		= false;

		// image specific
		if (glu::isDataTypeImage(basicType))
		{
			variable.memoryAccessQualifierBits |= glu::MEMORYACCESSQUALIFIER_READONLY_BIT;
			variable.layout.binding = 1;

			if (basicType >= glu::TYPE_IMAGE_2D && basicType <= glu::TYPE_IMAGE_3D)
				variable.layout.format = glu::FORMATLAYOUT_RGBA8;
			else if (basicType >= glu::TYPE_INT_IMAGE_2D && basicType <= glu::TYPE_INT_IMAGE_3D)
				variable.layout.format = glu::FORMATLAYOUT_RGBA8I;
			else if (basicType >= glu::TYPE_UINT_IMAGE_2D && basicType <= glu::TYPE_UINT_IMAGE_3D)
				variable.layout.format = glu::FORMATLAYOUT_RGBA8UI;
			else
				DE_ASSERT(false);
		}

		// atomic counter specific
		if (basicType == glu::TYPE_UINT_ATOMIC_COUNTER)
			variable.layout.binding = 1;

		for (head = head->getEnclosingNode(); head; head = head->getEnclosingNode())
		{
			if (head->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
			{
				const ResourceDefinition::StorageQualifier* qualifier = static_cast<const ResourceDefinition::StorageQualifier*>(head);

				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(head));

				if (boundObject == BINDING_VARIABLE)
				{
					DE_ASSERT(variable.storage == glu::STORAGE_LAST);
					variable.storage = qualifier->m_storage;
				}
				else if (boundObject == BINDING_INTERFACE_BLOCK)
				{
					DE_ASSERT(interfaceBlock.storage == glu::STORAGE_LAST);
					interfaceBlock.storage = qualifier->m_storage;
				}
				else
					DE_ASSERT(false);
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_LAYOUT_QUALIFIER)
			{
				const ResourceDefinition::LayoutQualifier*	qualifier		= static_cast<const ResourceDefinition::LayoutQualifier*>(head);
				glu::Layout*								targetLayout	= DE_NULL;

				DE_ASSERT(dynamic_cast<const ResourceDefinition::LayoutQualifier*>(head));

				if (boundObject == BINDING_VARIABLE)
					targetLayout = &variable.layout;
				else if (boundObject == BINDING_INTERFACE_BLOCK)
					targetLayout = &interfaceBlock.layout;
				else
					DE_ASSERT(false);

				if (qualifier->m_layout.location != -1)
					targetLayout->location = qualifier->m_layout.location;

				if (qualifier->m_layout.binding != -1)
					targetLayout->binding = qualifier->m_layout.binding;

				if (qualifier->m_layout.offset != -1)
					targetLayout->offset = qualifier->m_layout.offset;

				if (qualifier->m_layout.format != glu::FORMATLAYOUT_LAST)
					targetLayout->format = qualifier->m_layout.format;

				if (qualifier->m_layout.matrixOrder != glu::MATRIXORDER_LAST)
					targetLayout->matrixOrder = qualifier->m_layout.matrixOrder;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_INTERPOLATION_QUALIFIER)
			{
				const ResourceDefinition::InterpolationQualifier* qualifier = static_cast<const ResourceDefinition::InterpolationQualifier*>(head);

				DE_ASSERT(dynamic_cast<const ResourceDefinition::InterpolationQualifier*>(head));

				if (boundObject == BINDING_VARIABLE)
					variable.interpolation = qualifier->m_interpolation;
				else
					DE_ASSERT(false);
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(head));

				const ResourceDefinition::ArrayElement*	arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(head);
				int										arraySize;

				// Vary array size per level
				if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::DEFAULT_SIZE)
				{
					if (--autoAssignArraySize <= 1)
						autoAssignArraySize = 3;

					arraySize = autoAssignArraySize;
				}
				else if (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY)
					arraySize = glu::VarType::UNSIZED_ARRAY;
				else
					arraySize = arrayElement->m_arraySize;

				if (boundObject == BINDING_VARIABLE)
					variable.varType = glu::VarType(variable.varType, arraySize);
				else if (boundObject == BINDING_INTERFACE_BLOCK)
					interfaceBlock.dimensions.push_back(arraySize);
				else
					DE_ASSERT(false);

				if (feedbackTargetSet)
					feedbackTargetVaryingPath.back().append("[0]");
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::StructMember*>(head));
				DE_ASSERT(boundObject == BINDING_VARIABLE);

				// Struct members cannot contain any qualifiers except precision
				DE_ASSERT(variable.interpolation == glu::INTERPOLATION_LAST);
				DE_ASSERT(variable.layout == glu::Layout());
				DE_ASSERT(variable.memoryAccessQualifierBits == 0);
				DE_ASSERT(variable.storage == glu::STORAGE_LAST);

				{
					glu::StructType* structPtr = new glu::StructType(("StructType" + de::toString(structNdx++)).c_str());
					structPtr->addMember(variable.name.c_str(), variable.varType);

					variable = glu::VariableDeclaration(glu::VarType(structPtr), "target");
				}

				if (feedbackTargetSet)
					feedbackTargetVaryingPath.push_back("target");
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::InterfaceBlock*>(head));
				DE_ASSERT(boundObject == BINDING_VARIABLE);

				const bool named = static_cast<const ResourceDefinition::InterfaceBlock*>(head)->m_named;

				boundObject = BINDING_INTERFACE_BLOCK;

				interfaceBlock.interfaceName = "TargetInterface";
				interfaceBlock.instanceName = (named) ? ("targetInstance") : ("");
				interfaceBlock.variables.push_back(variable);

				if (feedbackTargetSet && !interfaceBlock.instanceName.empty())
					feedbackTargetVaryingPath.push_back(interfaceBlock.interfaceName);
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::DefaultBlock*>(head));
				DE_ASSERT(boundObject == BINDING_VARIABLE || boundObject == BINDING_INTERFACE_BLOCK);

				if (boundObject == BINDING_VARIABLE)
					defaultBlock.variables.push_back(variable);
				else if (boundObject == BINDING_INTERFACE_BLOCK)
					defaultBlock.interfaceBlocks.push_back(interfaceBlock);
				else
					DE_ASSERT(false);

				boundObject = BINDING_DEFAULT_BLOCK;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));

				const ResourceDefinition::Shader*	shaderDef	= static_cast<const ResourceDefinition::Shader*>(head);
				ProgramInterfaceDefinition::Shader* shader		= program->addShader(shaderDef->m_type, shaderDef->m_version);

				shader->getDefaultBlock() = defaultBlock;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));

				const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);

				for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
				{
					if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
					{
						ProgramInterfaceDefinition::Shader* shader = program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);

						if (shaderDef->isStageReferencing((glu::ShaderType)shaderType))
							shader->getDefaultBlock() = defaultBlock;
					}
				}
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));

				const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);

				program->setSeparable(programDef->m_separable);

				DE_ASSERT(feedbackTargetSet == !feedbackTargetVaryingPath.empty());
				if (!feedbackTargetVaryingPath.empty())
				{
					std::ostringstream buf;

					for (std::vector<std::string>::reverse_iterator it = feedbackTargetVaryingPath.rbegin(); it != feedbackTargetVaryingPath.rend(); ++it)
					{
						if (it != feedbackTargetVaryingPath.rbegin())
							buf << ".";
						buf << *it;
					}

					program->addTransformFeedbackVarying(buf.str());
					program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
				}
				break;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));

				const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);

				DE_ASSERT(feedbackTarget->m_builtinVarName == DE_NULL);
				DE_UNREF(feedbackTarget);

				feedbackTargetSet = true;
				feedbackTargetVaryingPath.push_back(variable.name);
			}
			else
			{
				DE_ASSERT(DE_FALSE);
				break;
			}
		}
	}
	else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK ||
			 head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
	{
		const char* feedbackTargetVaryingName = DE_NULL;

		// empty default block

		for (; head; head = head->getEnclosingNode())
		{
			if (head->getType() == ResourceDefinition::Node::TYPE_SHADER)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(head));

				const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(head);

				program->addShader(shaderDef->m_type, shaderDef->m_version);
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_SHADER_SET)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(head));

				const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(head);

				for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
					if (shaderDef->isStagePresent((glu::ShaderType)shaderType))
						program->addShader((glu::ShaderType)shaderType, shaderDef->m_version);
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_PROGRAM)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::Program*>(head));

				const ResourceDefinition::Program* programDef = static_cast<const ResourceDefinition::Program*>(head);

				program->setSeparable(programDef->m_separable);
				if (feedbackTargetVaryingName)
				{
					program->addTransformFeedbackVarying(std::string(feedbackTargetVaryingName));
					program->setTransformFeedbackMode(GL_INTERLEAVED_ATTRIBS);
				}
				break;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(head));

				const ResourceDefinition::TransformFeedbackTarget* feedbackTarget = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(head);

				DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);

				feedbackTargetVaryingName = feedbackTarget->m_builtinVarName;
			}
			else if (head->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
			{
			}
			else
			{
				DE_ASSERT(DE_FALSE);
				break;
			}
		}
	}

	if (program->hasStage(glu::SHADERTYPE_GEOMETRY))
		program->setGeometryNumOutputVertices(1);
	if (program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
		program->setTessellationNumOutputPatchVertices(1);

	return program;
}

static void checkAndLogProgram (const glu::ShaderProgram& program, const ProgramInterfaceDefinition::Program* programDefinition, const glw::Functions& gl, tcu::TestLog& log)
{
	const tcu::ScopedLogSection section(log, "Program", "Program");

	log << program;
	if (!program.isOk())
	{
		log << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage;
		checkProgramResourceUsage(programDefinition, gl, log);

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

// Resource list query case

class ResourceListTestCase : public TestCase
{
public:
												ResourceListTestCase		(Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name = DE_NULL);
												~ResourceListTestCase		(void);

protected:
	void										init						(void);
	void										deinit						(void);
	IterateResult								iterate						(void);

	void										queryResourceList			(std::vector<std::string>& dst, glw::GLuint program);
	bool										verifyResourceList			(const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources);
	bool										verifyResourceIndexQuery	(const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program);
	bool										verifyMaxNameLength			(const std::vector<std::string>& referenceResourceList, glw::GLuint program);

	static std::string							genTestCaseName				(ProgramInterface interface, const ResourceDefinition::Node*);
	static bool									isArrayedInterface			(ProgramInterface interface, deUint32 stageBits);

	const ProgramInterface						m_programInterface;
	ResourceDefinition::Node::SharedPtr			m_targetResource;
	ProgramInterfaceDefinition::Program*		m_programDefinition;
};

ResourceListTestCase::ResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, ProgramInterface interface, const char* name)
	: TestCase				(context, (name == DE_NULL) ? (genTestCaseName(interface, targetResource.get()).c_str()) : (name), "")
	, m_programInterface	(interface)
	, m_targetResource		(targetResource)
	, m_programDefinition	(DE_NULL)
{
	// GL_ATOMIC_COUNTER_BUFFER: no resource names
	DE_ASSERT(m_programInterface != PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER);
}

ResourceListTestCase::~ResourceListTestCase (void)
{
	deinit();
}

void ResourceListTestCase::init (void)
{
	m_programDefinition = generateProgramDefinitionFromResource(m_targetResource.get()).release();

	if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
		!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
	{
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	}
	if (m_programDefinition->hasStage(glu::SHADERTYPE_GEOMETRY) &&
		!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
	{
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
	}
	if (programContainsIOBlocks(m_programDefinition) &&
		!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_io_blocks"))
	{
		throw tcu::NotSupportedError("Test requires GL_EXT_shader_io_blocks extension");
	}
}

void ResourceListTestCase::deinit (void)
{
	m_targetResource.clear();

	delete m_programDefinition;
	m_programDefinition = DE_NULL;
}

ResourceListTestCase::IterateResult ResourceListTestCase::iterate (void)
{
	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// Check resource list
	{
		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "ResourceList", "Resource list");
		std::vector<std::string>	resourceList;
		std::vector<std::string>	expectedResources;

		queryResourceList(resourceList, program.getProgram());
		expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);

		// verify the list and the expected list match

		if (!verifyResourceList(resourceList, expectedResources))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");

		// verify GetProgramResourceIndex() matches the indices of the list

		if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");

		// Verify MAX_NAME_LENGTH
		if (!verifyMaxNameLength(resourceList, program.getProgram()))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
	}

	return STOP;
}

void ResourceListTestCase::queryResourceList (std::vector<std::string>& dst, glw::GLuint program)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glw::GLenum		programInterface	= getProgramInterfaceGLEnum(m_programInterface);
	glw::GLint				numActiveResources	= 0;
	glw::GLint				maxNameLength		= 0;
	std::vector<char>		buffer;

	m_testCtx.getLog() << tcu::TestLog::Message << "Querying " << glu::getProgramInterfaceName(programInterface) << " interface:" << tcu::TestLog::EndMessage;

	gl.getProgramInterfaceiv(program, programInterface, GL_ACTIVE_RESOURCES, &numActiveResources);
	gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
	GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");

	m_testCtx.getLog()	<< tcu::TestLog::Message
						<< "\tGL_ACTIVE_RESOURCES = " << numActiveResources << "\n"
						<< "\tGL_MAX_NAME_LENGTH = " << maxNameLength
						<< tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::Message << "Querying all active resources" << tcu::TestLog::EndMessage;

	buffer.resize(maxNameLength+1, '\0');

	for (int resourceNdx = 0; resourceNdx < numActiveResources; ++resourceNdx)
	{
		glw::GLint written = 0;

		gl.getProgramResourceName(program, programInterface, resourceNdx, maxNameLength, &written, &buffer[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");

		dst.push_back(std::string(&buffer[0], written));
	}
}

bool ResourceListTestCase::verifyResourceList (const std::vector<std::string>& resourceList, const std::vector<std::string>& expectedResources)
{
	bool error = false;

	// Log and compare resource lists

	m_testCtx.getLog() << tcu::TestLog::Message << "GL returned resources:" << tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
		m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << resourceList[ndx] << tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::Message << "Expected list of resources:" << tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
		m_testCtx.getLog() << tcu::TestLog::Message << "\t" << ndx << ": " << expectedResources[ndx] << tcu::TestLog::EndMessage;

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying resource list contents." << tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)expectedResources.size(); ++ndx)
	{
		if (!de::contains(resourceList.begin(), resourceList.end(), expectedResources[ndx]))
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list did not contain active resource " << expectedResources[ndx] << tcu::TestLog::EndMessage;
			error = true;
		}
	}

	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
	{
		if (!de::contains(expectedResources.begin(), expectedResources.end(), resourceList[ndx]))
		{
			// Ignore all builtin variables, mismatch causes errors otherwise
			if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
				error = true;
			}
			else
				m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
		}
	}

	return !error;
}

bool ResourceListTestCase::verifyResourceIndexQuery (const std::vector<std::string>& resourceList, const std::vector<std::string>& referenceResources, glw::GLuint program)
{
	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
	const glw::GLenum		programInterface	= getProgramInterfaceGLEnum(m_programInterface);
	bool					error				= false;

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GetProgramResourceIndex returns correct indices for resource names." << tcu::TestLog::EndMessage;

	for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
	{
		const glw::GLuint index = gl.getProgramResourceIndex(program, programInterface, referenceResources[ndx].c_str());
		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

		if (index == GL_INVALID_INDEX)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
			error = true;
		}
		else if ((int)index >= (int)resourceList.size())
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
			error = true;
		}
		else if (resourceList[index] != referenceResources[ndx])
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, for active resource \"" << referenceResources[ndx] << "\" got index (index = " << index << ") of another resource (" << resourceList[index] << ")." << tcu::TestLog::EndMessage;
			error = true;
		}
	}

	// Query for "name" should match "name[0]" except for XFB

	if (m_programInterface != PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING)
	{
		for (int ndx = 0; ndx < (int)referenceResources.size(); ++ndx)
		{
			if (de::endsWith(referenceResources[ndx], "[0]"))
			{
				const std::string	queryString	= referenceResources[ndx].substr(0, referenceResources[ndx].length()-3);
				const glw::GLuint	index		= gl.getProgramResourceIndex(program, programInterface, queryString.c_str());
				GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

				if (index == GL_INVALID_INDEX)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index GL_INVALID_INDEX." << tcu::TestLog::EndMessage;
					error = true;
				}
				else if ((int)index >= (int)resourceList.size())
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" resulted in index " << index << " (larger or equal to GL_ACTIVE_RESOURCES)." << tcu::TestLog::EndMessage;
					error = true;
				}
				else if (resourceList[index] != queryString + "[0]")
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for \"" << queryString << "\" got index (index = " << index << ") of another resource (\"" << resourceList[index] << "\")." << tcu::TestLog::EndMessage;
					error = true;
				}
			}
		}
	}

	return !error;
}

bool ResourceListTestCase::verifyMaxNameLength (const std::vector<std::string>& resourceList, glw::GLuint program)
{
	const glw::Functions&	gl						= m_context.getRenderContext().getFunctions();
	const glw::GLenum		programInterface		= getProgramInterfaceGLEnum(m_programInterface);
	glw::GLint				maxNameLength			= 0;
	glw::GLint				expectedMaxNameLength	= 0;

	gl.getProgramInterfaceiv(program, programInterface, GL_MAX_NAME_LENGTH, &maxNameLength);
	GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");

	for (int ndx = 0; ndx < (int)resourceList.size(); ++ndx)
		expectedMaxNameLength = de::max(expectedMaxNameLength, (int)resourceList[ndx].size() + 1);

	m_testCtx.getLog() << tcu::TestLog::Message << "Verifying MAX_NAME_LENGTH, expecting " << expectedMaxNameLength << " (i.e. consistent with the queried resource list)" << tcu::TestLog::EndMessage;

	if (expectedMaxNameLength != maxNameLength)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Error, got " << maxNameLength << tcu::TestLog::EndMessage;
		return false;
	}

	return true;
}

std::string ResourceListTestCase::genTestCaseName (ProgramInterface interface, const ResourceDefinition::Node* root)
{
	bool				isImplicitlySizedArray	= false;
	bool				hasVariable				= false;
	bool				accumulateName			= true;
	std::string			buf						= "var";
	std::string			prefix;

	for (const ResourceDefinition::Node* node = root; node; node = node->getEnclosingNode())
	{
		switch (node->getType())
		{
			case ResourceDefinition::Node::TYPE_VARIABLE:
			{
				hasVariable = true;
				break;
			}

			case ResourceDefinition::Node::TYPE_STRUCT_MEMBER:
			{
				if (accumulateName)
					buf += "_struct";
				break;
			}

			case ResourceDefinition::Node::TYPE_ARRAY_ELEMENT:
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::ArrayElement*>(node));
				const ResourceDefinition::ArrayElement* arrayElement = static_cast<const ResourceDefinition::ArrayElement*>(node);

				isImplicitlySizedArray = (arrayElement->m_arraySize == ResourceDefinition::ArrayElement::UNSIZED_ARRAY);

				if (accumulateName)
					buf += "_array";
				break;
			}

			case ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER:
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));
				const ResourceDefinition::StorageQualifier* storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);

				if (storageDef->m_storage == glu::STORAGE_PATCH_IN ||
					storageDef->m_storage == glu::STORAGE_PATCH_OUT)
				{
					if (accumulateName)
						prefix += "patch_";
				}
				break;
			}

			case ResourceDefinition::Node::TYPE_SHADER:
			case ResourceDefinition::Node::TYPE_SHADER_SET:
			{
				bool arrayedInterface;

				if (node->getType() == ResourceDefinition::Node::TYPE_SHADER)
				{
					DE_ASSERT(dynamic_cast<const ResourceDefinition::Shader*>(node));
					const ResourceDefinition::Shader* shaderDef = static_cast<const ResourceDefinition::Shader*>(node);

					arrayedInterface = isArrayedInterface(interface, (1u << shaderDef->m_type));
				}
				else
				{
					DE_ASSERT(node->getType() == ResourceDefinition::Node::TYPE_SHADER_SET);
					DE_ASSERT(dynamic_cast<const ResourceDefinition::ShaderSet*>(node));
					const ResourceDefinition::ShaderSet* shaderDef = static_cast<const ResourceDefinition::ShaderSet*>(node);

					arrayedInterface = isArrayedInterface(interface, shaderDef->getReferencingMask());
				}

				if (arrayedInterface && isImplicitlySizedArray)
				{
					// omit implicit arrayness from name, i.e. remove trailing "_array"
					DE_ASSERT(de::endsWith(buf, "_array"));
					buf = buf.substr(0, buf.length() - 6);
				}

				break;
			}

			case ResourceDefinition::Node::TYPE_INTERFACE_BLOCK:
			{
				accumulateName = false;
				break;
			}

			default:
				break;
		}
	}

	if (!hasVariable)
		return prefix + "empty";
	else
		return prefix + buf;
}

bool ResourceListTestCase::isArrayedInterface (ProgramInterface interface, deUint32 stageBits)
{
	if (interface == PROGRAMINTERFACE_PROGRAM_INPUT)
	{
		const glu::ShaderType firstStage = getShaderMaskFirstStage(stageBits);
		return	firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL		||
				firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
				firstStage == glu::SHADERTYPE_GEOMETRY;
	}
	else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT)
	{
		const glu::ShaderType lastStage = getShaderMaskLastStage(stageBits);
		return	lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL;
	}
	return false;
}

// Resouce property query case

class ResourceTestCase : public ProgramInterfaceQueryTestCase
{
public:
															ResourceTestCase			(Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name = DE_NULL);
															~ResourceTestCase			(void);

private:
	void													init						(void);
	void													deinit						(void);
	const ProgramInterfaceDefinition::Program*				getProgramDefinition		(void) const;
	std::vector<std::string>								getQueryTargetResources		(void) const;

	static std::string										genTestCaseName				(const ResourceDefinition::Node*);
	static std::string										genMultilineDescription		(const ResourceDefinition::Node*);

	ResourceDefinition::Node::SharedPtr						m_targetResource;
	ProgramInterfaceDefinition::Program*					m_program;
	std::vector<std::string>								m_targetResources;
};

ResourceTestCase::ResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, const ProgramResourceQueryTestTarget& queryTarget, const char* name)
	: ProgramInterfaceQueryTestCase	(context, (name == DE_NULL) ? (genTestCaseName(targetResource.get()).c_str()) : (name), "", queryTarget)
	, m_targetResource				(targetResource)
	, m_program						(DE_NULL)
{
}

ResourceTestCase::~ResourceTestCase (void)
{
	deinit();
}

void ResourceTestCase::init (void)
{
	m_testCtx.getLog()
		<< tcu::TestLog::Message
		<< genMultilineDescription(m_targetResource.get())
		<< tcu::TestLog::EndMessage;

	// Program
	{
		// Generate interface with target resource
		m_program = generateProgramDefinitionFromResource(m_targetResource.get()).release();
		m_targetResources = getProgramInterfaceResourceList(m_program, getTargetInterface());
	}
}

void ResourceTestCase::deinit (void)
{
	m_targetResource.clear();

	delete m_program;
	m_program = DE_NULL;

	m_targetResources = std::vector<std::string>();
}

const ProgramInterfaceDefinition::Program* ResourceTestCase::getProgramDefinition (void) const
{
	return m_program;
}

std::vector<std::string> ResourceTestCase::getQueryTargetResources (void) const
{
	return m_targetResources;
}

std::string ResourceTestCase::genTestCaseName (const ResourceDefinition::Node* resource)
{
	if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
	{
		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));

		const ResourceDefinition::Variable* variable = static_cast<const ResourceDefinition::Variable*>(resource);

		return convertGLTypeNameToTestName(glu::getDataTypeName(variable->m_dataType));
	}

	DE_ASSERT(false);
	return "";
}

std::string ResourceTestCase::genMultilineDescription (const ResourceDefinition::Node* resource)
{
	if (resource->getType() == ResourceDefinition::Node::TYPE_VARIABLE)
	{
		DE_ASSERT(dynamic_cast<const ResourceDefinition::Variable*>(resource));

		const ResourceDefinition::Variable*	varDef				= static_cast<const ResourceDefinition::Variable*>(resource);
		std::ostringstream					buf;
		std::ostringstream					structureDescriptor;
		std::string							uniformType;

		for (const ResourceDefinition::Node* node = resource; node; node = node->getEnclosingNode())
		{
			if (node->getType() == ResourceDefinition::Node::TYPE_STORAGE_QUALIFIER)
			{
				DE_ASSERT(dynamic_cast<const ResourceDefinition::StorageQualifier*>(node));

				const ResourceDefinition::StorageQualifier*	storageDef = static_cast<const ResourceDefinition::StorageQualifier*>(node);

				uniformType = std::string(" ") + glu::getStorageName(storageDef->m_storage);
				structureDescriptor << "\n\tdeclared as \"" << glu::getStorageName(storageDef->m_storage) << "\"";
			}

			if (node->getType() == ResourceDefinition::Node::TYPE_ARRAY_ELEMENT)
				structureDescriptor << "\n\tarray";

			if (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER)
				structureDescriptor << "\n\tin a struct";

			if (node->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK)
				structureDescriptor << "\n\tin the default block";

			if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
				structureDescriptor << "\n\tin an interface block";
		}

		buf	<< "Querying properties of " << glu::getDataTypeName(varDef->m_dataType) << uniformType << " variable.\n"
			<< "Variable is:\n"
			<< "\t" << glu::getDataTypeName(varDef->m_dataType)
			<< structureDescriptor.str();

		return buf.str();
	}
	else if (resource->getType() == ResourceDefinition::Node::TYPE_TRANSFORM_FEEDBACK_TARGET)
	{
		DE_ASSERT(dynamic_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource));

		const ResourceDefinition::TransformFeedbackTarget* xfbDef = static_cast<const ResourceDefinition::TransformFeedbackTarget*>(resource);

		DE_ASSERT(xfbDef->m_builtinVarName);

		return std::string("Querying properties of a builtin variable ") + xfbDef->m_builtinVarName;
	}

	DE_ASSERT(false);
	return DE_NULL;
}

class ResourceNameBufferLimitCase : public TestCase
{
public:
					ResourceNameBufferLimitCase		(Context& context, const char* name, const char* description);
					~ResourceNameBufferLimitCase	(void);

private:
	IterateResult	iterate							(void);
};

ResourceNameBufferLimitCase::ResourceNameBufferLimitCase (Context& context, const char* name, const char* description)
	: TestCase(context, name, description)
{
}

ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
{
}

ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
{
	static const char* const computeSource =	"#version 310 es\n"
												"layout(local_size_x = 1) in;\n"
												"uniform highp int u_uniformWithALongName;\n"
												"writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
												"void main ()\n"
												"{\n"
												"	b_output_int = u_uniformWithALongName;\n"
												"}\n";

	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
	glw::GLuint					uniformIndex;

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

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

		m_testCtx.getLog() << program;
		if (!program.isOk())
			throw tcu::TestError("could not build program");
	}

	uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniformWithALongName");
	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

	if (uniformIndex == GL_INVALID_INDEX)
		throw tcu::TestError("Uniform u_uniformWithALongName resource index was GL_INVALID_INDEX");

	// Query with different sized buffers, len("u_uniformWithALongName") == 22

	{
		static const struct
		{
			const char*	description;
			int			querySize;
			bool		returnLength;
		} querySizes[] =
		{
			{ "Query to larger buffer",										24,		true	},
			{ "Query to buffer the same size",								23,		true	},
			{ "Query to one byte too small buffer",							22,		true	},
			{ "Query to one byte buffer",									1,		true	},
			{ "Query to zero sized buffer",									0,		true	},
			{ "Query to one byte too small buffer, null length argument",	22,		false	},
			{ "Query to one byte buffer, null length argument",				1,		false	},
			{ "Query to zero sized buffer, null length argument",			0,		false	},
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
		{
			const tcu::ScopedLogSection			section				(m_testCtx.getLog(), "Query", querySizes[ndx].description);
			const int							uniformNameLen		= 22;
			const int							expectedWriteLen	= (querySizes[ndx].querySize != 0) ? (de::min(uniformNameLen, (querySizes[ndx].querySize - 1))) : (0);
			char								buffer				[26];
			glw::GLsizei						written				= -1;

			// One byte for guard
			DE_ASSERT((int)sizeof(buffer) > querySizes[ndx].querySize);

			deMemset(buffer, 'x', sizeof(buffer));

			if (querySizes[ndx].querySize)
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
					<< ", expecting query to write " << expectedWriteLen << " bytes followed by a null terminator"
					<< tcu::TestLog::EndMessage;
			else
				m_testCtx.getLog()
					<< tcu::TestLog::Message
					<< "Querying uniform name to a buffer of size " << querySizes[ndx].querySize
					<< ", expecting query to write 0 bytes"
					<< tcu::TestLog::EndMessage;

			gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].querySize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query resource name");

			if (querySizes[ndx].returnLength && written != expectedWriteLen)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
			}
			else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen] != 0)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected null terminator at " << expectedWriteLen << ", got dec=" << (int)buffer[expectedWriteLen] << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Missing null terminator");
			}
			else if (querySizes[ndx].querySize != 0 && buffer[expectedWriteLen+1] != 'x')
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen+1) << " was modified, got dec=" << (int)buffer[expectedWriteLen+1] << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
			}
			else if (querySizes[ndx].querySize == 0 && buffer[0] != 'x')
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was 0 but buffer contents were modified. At index 0 got dec=" << (int)buffer[0] << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer contents were modified");
			}
		}
	}

	return STOP;
}

class ResourceQueryBufferLimitCase : public TestCase
{
public:
					ResourceQueryBufferLimitCase	(Context& context, const char* name, const char* description);
					~ResourceQueryBufferLimitCase	(void);

private:
	IterateResult	iterate							(void);
};

ResourceQueryBufferLimitCase::ResourceQueryBufferLimitCase (Context& context, const char* name, const char* description)
	: TestCase(context, name, description)
{
}

ResourceQueryBufferLimitCase::~ResourceQueryBufferLimitCase (void)
{
}

ResourceQueryBufferLimitCase::IterateResult ResourceQueryBufferLimitCase::iterate (void)
{
	static const char* const computeSource =	"#version 310 es\n"
												"layout(local_size_x = 1) in;\n"
												"uniform highp int u_uniform;\n"
												"writeonly buffer OutputBufferBlock { highp int b_output_int; };\n"
												"void main ()\n"
												"{\n"
												"	b_output_int = u_uniform;\n"
												"}\n";

	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program			(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(computeSource));
	glw::GLuint					uniformIndex;

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

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

		m_testCtx.getLog() << program;
		if (!program.isOk())
			throw tcu::TestError("could not build program");
	}

	uniformIndex = gl.getProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_uniform");
	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

	if (uniformIndex == GL_INVALID_INDEX)
		throw tcu::TestError("Uniform u_uniform resource index was GL_INVALID_INDEX");

	// Query uniform properties

	{
		static const struct
		{
			const char*	description;
			int			numProps;
			int			bufferSize;
			bool		returnLength;
		} querySizes[] =
		{
			{ "Query to a larger buffer",							2, 3, true	},
			{ "Query to too small a buffer",						3, 2, true	},
			{ "Query to zero sized buffer",							3, 0, true	},
			{ "Query to a larger buffer, null length argument",		2, 3, false	},
			{ "Query to too small a buffer, null length argument",	3, 2, false	},
			{ "Query to zero sized buffer, null length argument",	3, 0, false	},
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(querySizes); ++ndx)
		{
			const tcu::ScopedLogSection		section				(m_testCtx.getLog(), "QueryToLarger", querySizes[ndx].description);
			const glw::GLenum				props[]				= { GL_LOCATION, GL_LOCATION, GL_LOCATION };
			const int						expectedWriteLen	= de::min(querySizes[ndx].bufferSize, querySizes[ndx].numProps);
			int								params[]			= { 255, 255, 255, 255 };
			glw::GLsizei					written				= -1;

			DE_ASSERT(querySizes[ndx].numProps <= DE_LENGTH_OF_ARRAY(props));
			DE_ASSERT(querySizes[ndx].bufferSize < DE_LENGTH_OF_ARRAY(params)); // leave at least one element for overflow detection

			m_testCtx.getLog()
				<< tcu::TestLog::Message
				<< "Querying " << querySizes[ndx].numProps << " uniform prop(s) to a buffer with size " << querySizes[ndx].bufferSize << ". Expecting query to return " << expectedWriteLen << " prop(s)"
				<< tcu::TestLog::EndMessage;

			gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, uniformIndex, querySizes[ndx].numProps, props, querySizes[ndx].bufferSize, (querySizes[ndx].returnLength) ? (&written) : (DE_NULL), params);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query program resources");

			if (querySizes[ndx].returnLength && written != expectedWriteLen)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, expected write length of " << expectedWriteLen << ", got " << written << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected write lenght");
			}
			else if (params[expectedWriteLen] != 255)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, guard at index " << (expectedWriteLen) << " was modified. Was 255 before call, got dec=" << params[expectedWriteLen] << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrote over buffer size");
			}
		}
	}

	return STOP;
}

class InterfaceBlockBaseCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_NAMED_BLOCK = 0,
		CASE_UNNAMED_BLOCK,
		CASE_BLOCK_ARRAY,

		CASE_LAST
	};

											InterfaceBlockBaseCase		(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);
											~InterfaceBlockBaseCase		(void);

private:
	void									init						(void);
	void									deinit						(void);

protected:
	const glu::Storage						m_storage;
	const CaseType							m_caseType;
	ProgramInterfaceDefinition::Program*	m_program;
};

InterfaceBlockBaseCase::InterfaceBlockBaseCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
	: TestCase		(context, name, description)
	, m_storage		(storage)
	, m_caseType	(caseType)
	, m_program		(DE_NULL)
{
	DE_ASSERT(storage == glu::STORAGE_UNIFORM || storage == glu::STORAGE_BUFFER);
}

InterfaceBlockBaseCase::~InterfaceBlockBaseCase (void)
{
	deinit();
}

void InterfaceBlockBaseCase::init (void)
{
	ProgramInterfaceDefinition::Shader* shader;

	m_program = new ProgramInterfaceDefinition::Program();
	shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);

	// PrecedingInterface
	{
		glu::InterfaceBlock precedingInterfaceBlock;

		precedingInterfaceBlock.interfaceName	= "PrecedingInterface";
		precedingInterfaceBlock.layout.binding	= 0;
		precedingInterfaceBlock.storage			= m_storage;
		precedingInterfaceBlock.instanceName	= "precedingInstance";

		precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "precedingMember"));

		// Unsized array type
		if (m_storage == glu::STORAGE_BUFFER)
			precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "precedingMemberUnsizedArray"));
		else
			precedingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2), "precedingMemberArray"));

		shader->getDefaultBlock().interfaceBlocks.push_back(precedingInterfaceBlock);
	}

	// TargetInterface
	{
		glu::InterfaceBlock targetInterfaceBlock;

		targetInterfaceBlock.interfaceName	= "TargetInterface";
		targetInterfaceBlock.layout.binding	= 1;
		targetInterfaceBlock.storage		= m_storage;

		if (m_caseType == CASE_UNNAMED_BLOCK)
			targetInterfaceBlock.instanceName = "";
		else
			targetInterfaceBlock.instanceName = "targetInstance";

		if (m_caseType == CASE_BLOCK_ARRAY)
			targetInterfaceBlock.dimensions.push_back(2);

		// Basic type
		{
			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "blockMemberBasic"));
		}

		// Array type
		{
			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 3), "blockMemberArray"));
		}

		// Struct type
		{
			glu::StructType* structPtr = new glu::StructType("StructType");
			structPtr->addMember("structMemberBasic", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP));
			structPtr->addMember("structMemberArray", glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), 2));

			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(structPtr), 2), "blockMemberStruct"));
		}

		// Unsized array type
		if (m_storage == glu::STORAGE_BUFFER)
			targetInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY), "blockMemberUnsizedArray"));

		shader->getDefaultBlock().interfaceBlocks.push_back(targetInterfaceBlock);
	}

	// TrailingInterface
	{
		glu::InterfaceBlock trailingInterfaceBlock;

		trailingInterfaceBlock.interfaceName	= "TrailingInterface";
		trailingInterfaceBlock.layout.binding	= 3;
		trailingInterfaceBlock.storage			= m_storage;
		trailingInterfaceBlock.instanceName		= "trailingInstance";
		trailingInterfaceBlock.variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), "trailingMember"));

		shader->getDefaultBlock().interfaceBlocks.push_back(trailingInterfaceBlock);
	}

	DE_ASSERT(m_program->isValid());
}

void InterfaceBlockBaseCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

class InterfaceBlockActiveVariablesTestCase : public InterfaceBlockBaseCase
{
public:
											InterfaceBlockActiveVariablesTestCase	(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);

private:
	IterateResult							iterate									(void);
};

InterfaceBlockActiveVariablesTestCase::InterfaceBlockActiveVariablesTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
	: InterfaceBlockBaseCase(context, name, description, storage, caseType)
{
}

InterfaceBlockActiveVariablesTestCase::IterateResult InterfaceBlockActiveVariablesTestCase::iterate (void)
{
	const ProgramInterface			programInterface				= (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
																	  (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
																	  (PROGRAMINTERFACE_LAST);
	const glw::GLenum				programGLInterfaceValue			= getProgramInterfaceGLEnum(programInterface);
	const glw::GLenum				programMemberInterfaceValue		= (m_storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM) :
																	  (m_storage == glu::STORAGE_BUFFER) ? (GL_BUFFER_VARIABLE) :
																	  (0);
	const std::vector<std::string>	blockNames						= getProgramInterfaceResourceList(m_program, programInterface);
	glu::ShaderProgram				program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
	int								expectedMaxNumActiveVariables	= 0;

	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// Verify all blocks

	for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
	{
		const tcu::ScopedLogSection section				(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
		const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
		const glw::GLuint			resourceNdx			= gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
		glw::GLint					numActiveResources;
		std::vector<std::string>	activeResourceNames;

		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

		if (resourceNdx == GL_INVALID_INDEX)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
			continue;
		}

		// query block information

		{
			const glw::GLenum	props[]			= { GL_NUM_ACTIVE_VARIABLES };
			glw::GLint			retBuffer[2]	= { -1, -1 };
			glw::GLint			written			= -1;

			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, 1, &written, retBuffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NUM_ACTIVE_VARIABLES");

			numActiveResources = retBuffer[0];
			expectedMaxNumActiveVariables = de::max(expectedMaxNumActiveVariables, numActiveResources);
			m_testCtx.getLog() << tcu::TestLog::Message << "NUM_ACTIVE_VARIABLES = " << numActiveResources << tcu::TestLog::EndMessage;

			if (written == -1 || retBuffer[0] == -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES did not return a value" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES failed");
				continue;
			}
			else if (retBuffer[1] != -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for NUM_ACTIVE_VARIABLES returned too many values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for NUM_ACTIVE_VARIABLES returned too many values");
				continue;
			}
			else if (retBuffer[0] < 0)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, NUM_ACTIVE_VARIABLES < 0" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES < 0");
				continue;
			}
		}

		// query block variable information

		{
			const glw::GLenum			props[]					= { GL_ACTIVE_VARIABLES };
			std::vector<glw::GLint>		activeVariableIndices	(numActiveResources + 1, -1);	// Allocate one extra trailing to detect wrong write lengths
			glw::GLint					written					= -1;

			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, DE_LENGTH_OF_ARRAY(props), props, (glw::GLsizei)activeVariableIndices.size(), &written, &activeVariableIndices[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_VARIABLES");

			if (written == -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return any values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES failed");
				continue;
			}
			else if (written != numActiveResources)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, Query for GL_ACTIVE_VARIABLES did not return NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned invalid number of values");
				continue;
			}
			else if (activeVariableIndices.back() != -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_ACTIVE_VARIABLES query return buffer trailing guard value was modified, getProgramResourceiv returned more than NUM_ACTIVE_VARIABLES values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Query for GL_ACTIVE_VARIABLES returned too many values");
				continue;
			}

			// log indices
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder << "Active variable indices: {";
				for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
				{
					if (varNdx)
						builder << ", ";
					builder << activeVariableIndices[varNdx];
				}
				builder << "}" << tcu::TestLog::EndMessage;
			}

			// collect names

			activeResourceNames.resize(numActiveResources);

			for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
			{
				const glw::GLenum	nameProp	= GL_NAME_LENGTH;
				glw::GLint			nameLength	= -1;
				std::vector<char>	nameBuffer;

				written = -1;
				gl.getProgramResourceiv(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], 1, &nameProp, 1, &written, &nameLength);
				GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_NAME_LENGTH");

				if (nameLength <= 0 || written <= 0)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_NAME_LENGTH query failed" << tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
					continue;
				}

				nameBuffer.resize(nameLength + 2, 'X'); // allocate more than required
				written = -1;
				gl.getProgramResourceName(program.getProgram(), programMemberInterfaceValue, activeVariableIndices[varNdx], nameLength+1, &written, &nameBuffer[0]);
				GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramResourceName");

				if (written <= 0)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, no data written" << tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
					continue;
				}
				else if (written > nameLength)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, name query failed, query returned too much data" << tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "name query failed");
					continue;
				}

				activeResourceNames[varNdx] = std::string(&nameBuffer[0], written);
			}

			// log collected names
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder << "Active variables:\n";
				for (int varNdx = 0; varNdx < numActiveResources; ++varNdx)
					builder << "\t" << activeResourceNames[varNdx] << "\n";
				builder << tcu::TestLog::EndMessage;
			}
		}

		// verify names
		{
			glu::InterfaceBlock*		block		= DE_NULL;
			const std::string			blockName	= glu::parseVariableName(blockNames[blockNdx].c_str());
			std::vector<std::string>	referenceList;

			for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
			{
				if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName)
				{
					block = &m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx];
					break;
				}
			}

			if (!block)
				throw tcu::InternalError("could not find block referenced in the reference resource list");

			// generate reference list

			referenceList = getProgramInterfaceBlockMemberResourceList(*block);
			{
				tcu::MessageBuilder builder(&m_testCtx.getLog());

				builder << "Expected variable names:\n";
				for (int varNdx = 0; varNdx < (int)referenceList.size(); ++varNdx)
					builder << "\t" << referenceList[varNdx] << "\n";
				builder << tcu::TestLog::EndMessage;
			}

			// compare lists
			{
				bool listsIdentical = true;

				for (int ndx = 0; ndx < (int)referenceList.size(); ++ndx)
				{
					if (!de::contains(activeResourceNames.begin(), activeResourceNames.end(), referenceList[ndx]))
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list did not contain active variable " << referenceList[ndx] << tcu::TestLog::EndMessage;
						listsIdentical = false;
					}
				}

				for (int ndx = 0; ndx < (int)activeResourceNames.size(); ++ndx)
				{
					if (!de::contains(referenceList.begin(), referenceList.end(), activeResourceNames[ndx]))
					{
						m_testCtx.getLog() << tcu::TestLog::Message << "Error, variable name list contains unexpected resource \"" << activeResourceNames[ndx] << "\"" << tcu::TestLog::EndMessage;
						listsIdentical = false;
					}
				}

				if (listsIdentical)
					m_testCtx.getLog() << tcu::TestLog::Message << "Lists identical" << tcu::TestLog::EndMessage;
				else
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, invalid active variable list" << tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid active variable list");
					continue;
				}
			}
		}
	}

	// Max num active variables
	{
		const tcu::ScopedLogSection	section					(m_testCtx.getLog(), "MaxNumActiveVariables", "MAX_NUM_ACTIVE_VARIABLES");
		const glw::Functions&		gl						= m_context.getRenderContext().getFunctions();
		glw::GLint					maxNumActiveVariables	= -1;

		gl.getProgramInterfaceiv(program.getProgram(), programGLInterfaceValue, GL_MAX_NUM_ACTIVE_VARIABLES, &maxNumActiveVariables);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query MAX_NUM_ACTIVE_VARIABLES");

		m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES = " << maxNumActiveVariables << tcu::TestLog::EndMessage;

		if (expectedMaxNumActiveVariables != maxNumActiveVariables)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected MAX_NUM_ACTIVE_VARIABLES" << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected MAX_NUM_ACTIVE_VARIABLES");
		}
		else
			m_testCtx.getLog() << tcu::TestLog::Message << "MAX_NUM_ACTIVE_VARIABLES valid" << tcu::TestLog::EndMessage;
	}

	return STOP;
}

class InterfaceBlockDataSizeTestCase : public InterfaceBlockBaseCase
{
public:
											InterfaceBlockDataSizeTestCase	(Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType);

private:
	IterateResult							iterate							(void);
	int										getBlockMinDataSize				(const std::string& blockName) const;
	int										getBlockMinDataSize				(const glu::InterfaceBlock& block) const;
};

InterfaceBlockDataSizeTestCase::InterfaceBlockDataSizeTestCase (Context& context, const char* name, const char* description, glu::Storage storage, CaseType caseType)
	: InterfaceBlockBaseCase(context, name, description, storage, caseType)
{
}

InterfaceBlockDataSizeTestCase::IterateResult InterfaceBlockDataSizeTestCase::iterate (void)
{
	const ProgramInterface			programInterface		= (m_storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
															  (m_storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
															  (PROGRAMINTERFACE_LAST);
	const glw::GLenum				programGLInterfaceValue	= getProgramInterfaceGLEnum(programInterface);
	const std::vector<std::string>	blockNames				= getProgramInterfaceResourceList(m_program, programInterface);
	glu::ShaderProgram				program					(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));

	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// Verify all blocks
	for (int blockNdx = 0; blockNdx < (int)blockNames.size(); ++blockNdx)
	{
		const tcu::ScopedLogSection section				(m_testCtx.getLog(), "Block", "Block \"" + blockNames[blockNdx] + "\"");
		const glw::Functions&		gl					= m_context.getRenderContext().getFunctions();
		const glw::GLuint			resourceNdx			= gl.getProgramResourceIndex(program.getProgram(), programGLInterfaceValue, blockNames[blockNdx].c_str());
		const int					expectedMinDataSize	= getBlockMinDataSize(blockNames[blockNdx]);
		glw::GLint					queryDataSize		= -1;

		GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

		if (resourceNdx == GL_INVALID_INDEX)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, getProgramResourceIndex returned GL_INVALID_INDEX for \"" << blockNames[blockNdx] << "\"" << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Resource not found");
			continue;
		}

		// query
		{
			const glw::GLenum prop = GL_BUFFER_DATA_SIZE;

			gl.getProgramResourceiv(program.getProgram(), programGLInterfaceValue, resourceNdx, 1, &prop, 1, DE_NULL, &queryDataSize);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query resource BUFFER_DATA_SIZE");
		}

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "BUFFER_DATA_SIZE = " << queryDataSize << "\n"
			<< "Buffer data size with tight packing: " << expectedMinDataSize
			<< tcu::TestLog::EndMessage;

		if (queryDataSize < expectedMinDataSize)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, buffer size was less than minimum buffer data size" << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer data size invalid");
			continue;
		}
		else
			m_testCtx.getLog() << tcu::TestLog::Message << "Buffer size valid" << tcu::TestLog::EndMessage;
	}

	return STOP;
}

int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const std::string& blockFullName) const
{
	const std::string blockName = glu::parseVariableName(blockFullName.c_str());

	for (int interfaceNdx = 0; interfaceNdx < (int)m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx)
	{
		if (m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName &&
			m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx].storage == m_storage)
			return getBlockMinDataSize(m_program->getShaders()[0]->getDefaultBlock().interfaceBlocks[interfaceNdx]);
	}

	DE_ASSERT(false);
	return -1;
}

class AtomicCounterCase : public TestCase
{
public:
											AtomicCounterCase			(Context& context, const char* name, const char* description);
											~AtomicCounterCase			(void);

private:
	void									init						(void);
	void									deinit						(void);

protected:
	int										getNumAtomicCounterBuffers	(void) const;
	int										getMaxNumActiveVariables	(void) const;
	int										getBufferVariableCount		(int binding) const;
	int										getBufferMinimumDataSize	(int binding) const;

	ProgramInterfaceDefinition::Program*	m_program;
};

AtomicCounterCase::AtomicCounterCase (Context& context, const char* name, const char* description)
	: TestCase	(context, name, description)
	, m_program	(DE_NULL)
{
}

AtomicCounterCase::~AtomicCounterCase (void)
{
	deinit();
}

void AtomicCounterCase::init (void)
{
	ProgramInterfaceDefinition::Shader* shader;

	m_program = new ProgramInterfaceDefinition::Program();
	shader = m_program->addShader(glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES);

	{
		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter1", glu::STORAGE_UNIFORM);
		decl.layout.binding = 1;
		shader->getDefaultBlock().variables.push_back(decl);
	}
	{
		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding1_counter2", glu::STORAGE_UNIFORM);
		decl.layout.binding = 1;
		decl.layout.offset = 8;

		shader->getDefaultBlock().variables.push_back(decl);
	}
	{
		glu::VariableDeclaration decl(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "binding2_counter1", glu::STORAGE_UNIFORM);
		decl.layout.binding = 2;
		shader->getDefaultBlock().variables.push_back(decl);
	}

	DE_ASSERT(m_program->isValid());
}

void AtomicCounterCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

int AtomicCounterCase::getNumAtomicCounterBuffers (void) const
{
	std::set<int> buffers;

	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
	{
		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
		{
			buffers.insert(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding);
		}
	}

	return (int)buffers.size();
}

int AtomicCounterCase::getMaxNumActiveVariables (void) const
{
	int					maxVars			= 0;
	std::map<int,int>	numBufferVars;

	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
	{
		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()))
		{
			const int binding = m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding;

			if (numBufferVars.find(binding) == numBufferVars.end())
				numBufferVars[binding] = 1;
			else
				++numBufferVars[binding];
		}
	}

	for (std::map<int,int>::const_iterator it = numBufferVars.begin(); it != numBufferVars.end(); ++it)
		maxVars = de::max(maxVars, it->second);

	return maxVars;
}

int AtomicCounterCase::getBufferVariableCount (int binding) const
{
	int numVars = 0;

	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
	{
		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
			m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
			++numVars;
	}

	return numVars;
}

int AtomicCounterCase::getBufferMinimumDataSize (int binding) const
{
	int minSize			= -1;
	int currentOffset	= 0;

	for (int ndx = 0; ndx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++ndx)
	{
		if (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.isBasicType() &&
			glu::isDataTypeAtomicCounter(m_program->getShaders()[0]->getDefaultBlock().variables[ndx].varType.getBasicType()) &&
			m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.binding == binding)
		{
			const int thisOffset = (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset != -1) ? (m_program->getShaders()[0]->getDefaultBlock().variables[ndx].layout.offset) : (currentOffset);
			currentOffset = thisOffset + 4;

			minSize = de::max(minSize, thisOffset + 4);
		}
	}

	return minSize;
}

class AtomicCounterResourceListCase : public AtomicCounterCase
{
public:
						AtomicCounterResourceListCase	(Context& context, const char* name, const char* description);

private:
	IterateResult		iterate							(void);
};

AtomicCounterResourceListCase::AtomicCounterResourceListCase (Context& context, const char* name, const char* description)
	: AtomicCounterCase(context, name, description)
{
}

AtomicCounterResourceListCase::IterateResult AtomicCounterResourceListCase::iterate (void)
{
	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	{
		const tcu::ScopedLogSection		section						(m_testCtx.getLog(), "ActiveResources", "ACTIVE_RESOURCES");
		const glw::Functions&			gl							= m_context.getRenderContext().getFunctions();
		glw::GLint						numActiveResources			= -1;
		const int						numExpectedActiveResources	= 2; // 2 buffer bindings

		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying ACTIVE_RESOURCES, expecting " << numExpectedActiveResources << tcu::TestLog::EndMessage;

		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query GL_ACTIVE_RESOURCES");

		m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage;

		if (numActiveResources != numExpectedActiveResources)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected ACTIVE_RESOURCES" << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_RESOURCES");
		}
		else
			m_testCtx.getLog() << tcu::TestLog::Message << "ACTIVE_RESOURCES valid" << tcu::TestLog::EndMessage;
	}

	return STOP;
}

class AtomicCounterActiveVariablesCase : public AtomicCounterCase
{
public:
					AtomicCounterActiveVariablesCase	(Context& context, const char* name, const char* description);

private:
	IterateResult	iterate								(void);
};

AtomicCounterActiveVariablesCase::AtomicCounterActiveVariablesCase (Context& context, const char* name, const char* description)
	: AtomicCounterCase(context, name, description)
{
}

AtomicCounterActiveVariablesCase::IterateResult AtomicCounterActiveVariablesCase::iterate (void)
{
	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();
	const int					expectedMaxNumActiveVariables	= getMaxNumActiveVariables();

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// check active variables
	{
		const tcu::ScopedLogSection	section						(m_testCtx.getLog(), "Interface", "ATOMIC_COUNTER_BUFFER interface");
		glw::GLint					queryActiveResources		= -1;
		glw::GLint					queryMaxNumActiveVariables	= -1;

		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &queryActiveResources);
		gl.getProgramInterfaceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &queryMaxNumActiveVariables);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query interface");

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "GL_ACTIVE_RESOURCES = " << queryActiveResources << "\n"
			<< "GL_MAX_NUM_ACTIVE_VARIABLES = " << queryMaxNumActiveVariables << "\n"
			<< tcu::TestLog::EndMessage;

		if (queryActiveResources != numAtomicBuffers)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_ACTIVE_RESOURCES, expected " << numAtomicBuffers << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_ACTIVE_RESOURCES");
		}

		if (queryMaxNumActiveVariables != expectedMaxNumActiveVariables)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected GL_MAX_NUM_ACTIVE_VARIABLES, expected " << expectedMaxNumActiveVariables << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected GL_MAX_NUM_ACTIVE_VARIABLES");
		}
	}

	// Check each buffer
	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
	{
		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
		std::vector<glw::GLint>		activeVariables;
		std::vector<std::string>	memberNames;

		// Find active variables
		{
			const glw::GLenum	numActiveVariablesProp	= GL_NUM_ACTIVE_VARIABLES;
			const glw::GLenum	activeVariablesProp		= GL_ACTIVE_VARIABLES;
			glw::GLint			numActiveVariables		= -2;
			glw::GLint			written					= -1;

			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &numActiveVariablesProp, 1, &written, &numActiveVariables);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query num active variables");

			if (numActiveVariables <= 0)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected NUM_ACTIVE_VARIABLES: " << numActiveVariables  << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected NUM_ACTIVE_VARIABLES");
				continue;
			}

			if (written <= 0)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for NUM_ACTIVE_VARIABLES returned no values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "NUM_ACTIVE_VARIABLES query failed");
				continue;
			}

			m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_ACTIVE_VARIABLES = " << numActiveVariables << tcu::TestLog::EndMessage;

			written = -1;
			activeVariables.resize(numActiveVariables + 1, -2);

			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &activeVariablesProp, numActiveVariables, &written, &activeVariables[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query active variables");

			if (written != numActiveVariables)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, unexpected number of ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES = " << numActiveVariables << ", query returned " << written << " values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected ACTIVE_VARIABLES");
				continue;
			}

			if (activeVariables.back() != -2)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for ACTIVE_VARIABLES wrote over target buffer bounds" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "ACTIVE_VARIABLES query failed");
				continue;
			}

			activeVariables.pop_back();
		}

		// log indices
		{
			tcu::MessageBuilder builder(&m_testCtx.getLog());

			builder << "Active variable indices: {";
			for (int varNdx = 0; varNdx < (int)activeVariables.size(); ++varNdx)
			{
				if (varNdx)
					builder << ", ";
				builder << activeVariables[varNdx];
			}
			builder << "}" << tcu::TestLog::EndMessage;
		}

		// collect member names
		for (int ndx = 0; ndx < (int)activeVariables.size(); ++ndx)
		{
			const glw::GLenum	nameLengthProp	= GL_NAME_LENGTH;
			glw::GLint			nameLength		= -1;
			glw::GLint			written			= -1;
			std::vector<char>	nameBuf;

			gl.getProgramResourceiv(program.getProgram(), GL_UNIFORM, activeVariables[ndx], 1, &nameLengthProp, 1, &written, &nameLength);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name length");

			if (written <= 0 || nameLength == -1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for GL_NAME_LENGTH returned no values" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GL_NAME_LENGTH query failed");
				continue;
			}

			nameBuf.resize(nameLength + 2, 'X'); // +2 to tolerate potential off-by-ones in some implementations, name queries will check these cases better
			written = -1;

			gl.getProgramResourceName(program.getProgram(), GL_UNIFORM, activeVariables[ndx], (int)nameBuf.size(), &written, &nameBuf[0]);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer variable name");

			if (written <= 0)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource name returned no name" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Name query failed");
				continue;
			}

			memberNames.push_back(std::string(&nameBuf[0], written));
		}

		// log names
		{
			tcu::MessageBuilder builder(&m_testCtx.getLog());

			builder << "Active variables:\n";
			for (int varNdx = 0; varNdx < (int)memberNames.size(); ++varNdx)
			{
				builder << "\t" << memberNames[varNdx] << "\n";
			}
			builder << tcu::TestLog::EndMessage;
		}

		// check names are all in the same buffer
		{
			bool bindingsValid = true;

			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying names" << tcu::TestLog::EndMessage;

			for (int nameNdx = 0; nameNdx < (int)memberNames.size(); ++nameNdx)
			{
				int prevBinding = -1;

				for (int varNdx = 0; varNdx < (int)m_program->getShaders()[0]->getDefaultBlock().variables.size(); ++varNdx)
				{
					if (m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].name == memberNames[nameNdx])
					{
						const int varBinding = m_program->getShaders()[0]->getDefaultBlock().variables[varNdx].layout.binding;

						if (prevBinding == -1 || prevBinding == varBinding)
							prevBinding = varBinding;
						else
							bindingsValid = false;
					}
				}

				if (prevBinding == -1)
				{
					m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find variable with name \"" << memberNames[nameNdx] << "\"" << tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable name invalid");
				}
				else if (getBufferVariableCount(prevBinding) != (int)memberNames.size())
				{
					m_testCtx.getLog()
						<< tcu::TestLog::Message
						<< "Error, unexpected variable count for binding " << prevBinding
						<< ". Expected " << getBufferVariableCount(prevBinding) << ", got " << (int)memberNames.size()
						<< tcu::TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Variable names invalid");
				}
			}

			if (!bindingsValid)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, all resource do not share the same buffer" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Active variables invalid");
				continue;
			}
		}
	}

	return STOP;
}

class AtomicCounterBufferBindingCase : public AtomicCounterCase
{
public:
					AtomicCounterBufferBindingCase		(Context& context, const char* name, const char* description);

private:
	IterateResult	iterate								(void);
};

AtomicCounterBufferBindingCase::AtomicCounterBufferBindingCase (Context& context, const char* name, const char* description)
	: AtomicCounterCase(context, name, description)
{
}

AtomicCounterBufferBindingCase::IterateResult AtomicCounterBufferBindingCase::iterate (void)
{
	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// check every buffer
	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
	{
		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
		const glw::GLenum			bufferBindingProp	= GL_BUFFER_BINDING;
		glw::GLint					bufferBinding		= -1;
		glw::GLint					written				= -1;

		gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, 1, &bufferBindingProp, 1, &written, &bufferBinding);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");

		if (written <= 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for BUFFER_BINDING returned no values." << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "BUFFER_BINDING query failed");
		}

		m_testCtx.getLog() << tcu::TestLog::Message << "GL_BUFFER_BINDING = " << bufferBinding << tcu::TestLog::EndMessage;

		// no such buffer binding?
		if (getBufferVariableCount(bufferBinding) == 0)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << bufferBinding << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
		}
	}

	return STOP;
}

class AtomicCounterBufferDataSizeCase : public AtomicCounterCase
{
public:
					AtomicCounterBufferDataSizeCase		(Context& context, const char* name, const char* description);

private:
	IterateResult	iterate								(void);
};

AtomicCounterBufferDataSizeCase::AtomicCounterBufferDataSizeCase (Context& context, const char* name, const char* description)
	: AtomicCounterCase(context, name, description)
{
}

AtomicCounterBufferDataSizeCase::IterateResult AtomicCounterBufferDataSizeCase::iterate (void)
{
	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
	const int					numAtomicBuffers				= getNumAtomicCounterBuffers();

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// check every buffer
	for (int bufferNdx = 0; bufferNdx < numAtomicBuffers; ++bufferNdx)
	{
		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "Resource", "Resource index " + de::toString(bufferNdx));
		const glw::GLenum			props[]				= { GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE };
		glw::GLint					values[]			= { -1, -1 };
		glw::GLint					written				= -1;
		int							bufferMinDataSize;

		gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, bufferNdx, DE_LENGTH_OF_ARRAY(props), props, DE_LENGTH_OF_ARRAY(values), &written, values);
		GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");

		if (written != 2)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for (BUFFER_BINDING, BUFFER_DATA_SIZE) returned " << written << " value(s)." << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
			continue;
		}

		m_testCtx.getLog()
			<< tcu::TestLog::Message
			<< "GL_BUFFER_BINDING = " << values[0] << "\n"
			<< "GL_BUFFER_DATA_SIZE = " << values[1]
			<< tcu::TestLog::EndMessage;

		bufferMinDataSize = getBufferMinimumDataSize(values[0]);
		m_testCtx.getLog() << tcu::TestLog::Message << "Verifying data size, expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;

		// no such buffer binding?
		if (bufferMinDataSize == -1)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_BINDING = " << values[0] << ", but such buffer does not exist." << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
		}
		else if (values[1] < bufferMinDataSize)
		{
			m_testCtx.getLog() << tcu::TestLog::Message << "Error, got buffer with BUFFER_DATA_SIZE = " << values[1] << ", expected greater than or equal to " << bufferMinDataSize << tcu::TestLog::EndMessage;
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected BUFFER_BINDING");
		}
		else
			m_testCtx.getLog() << tcu::TestLog::Message << "Data size valid" << tcu::TestLog::EndMessage;
	}

	return STOP;
}

class AtomicCounterReferencedByCase : public TestCase
{
public:
											AtomicCounterReferencedByCase	(Context&		context,
																			 const char*	name,
																			 const char*	description,
																			 bool			separable,
																			 deUint32		presentStagesMask,
																			 deUint32		activeStagesMask);
											~AtomicCounterReferencedByCase	(void);

private:
	void									init							(void);
	void									deinit							(void);
	IterateResult							iterate							(void);

	const bool								m_separable;
	const deUint32							m_presentStagesMask;
	const deUint32							m_activeStagesMask;
	ProgramInterfaceDefinition::Program*	m_program;
};

AtomicCounterReferencedByCase::AtomicCounterReferencedByCase (Context&		context,
															  const char*	name,
															  const char*	description,
															  bool			separable,
															  deUint32		presentStagesMask,
															  deUint32		activeStagesMask)
	: TestCase				(context, name, description)
	, m_separable			(separable)
	, m_presentStagesMask	(presentStagesMask)
	, m_activeStagesMask	(activeStagesMask)
	, m_program				(DE_NULL)
{
	DE_ASSERT((activeStagesMask & presentStagesMask) == activeStagesMask);
}

AtomicCounterReferencedByCase::~AtomicCounterReferencedByCase (void)
{
	deinit();
}

void AtomicCounterReferencedByCase::init (void)
{
	const deUint32				geometryMask		= (1 << glu::SHADERTYPE_GEOMETRY);
	const deUint32				tessellationMask	= (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
	glu::VariableDeclaration	atomicVar			(glu::VarType(glu::TYPE_UINT_ATOMIC_COUNTER, glu::PRECISION_LAST), "targetCounter", glu::STORAGE_UNIFORM);

	if ((m_presentStagesMask & tessellationMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if ((m_presentStagesMask & geometryMask) != 0 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");

	atomicVar.layout.binding = 1;

	m_program = new ProgramInterfaceDefinition::Program();
	m_program->setSeparable(m_separable);

	for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
	{
		if (m_activeStagesMask & (1 << shaderType))
			m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(atomicVar);
		else if (m_presentStagesMask & (1 << shaderType))
			m_program->addShader((glu::ShaderType)shaderType, glu::GLSL_VERSION_310_ES);
	}

	if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
		m_program->setGeometryNumOutputVertices(1);
	if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
		m_program->setTessellationNumOutputPatchVertices(1);

	DE_ASSERT(m_program->isValid());
}

void AtomicCounterReferencedByCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

AtomicCounterReferencedByCase::IterateResult AtomicCounterReferencedByCase::iterate (void)
{
	static const struct
	{
		glw::GLenum		propName;
		glu::ShaderType	shaderType;
		const char*		extension;
	} targetProps[] =
	{
		{ GL_REFERENCED_BY_VERTEX_SHADER,			glu::SHADERTYPE_VERTEX,						DE_NULL							},
		{ GL_REFERENCED_BY_FRAGMENT_SHADER,			glu::SHADERTYPE_FRAGMENT,					DE_NULL							},
		{ GL_REFERENCED_BY_COMPUTE_SHADER,			glu::SHADERTYPE_COMPUTE,					DE_NULL							},
		{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		glu::SHADERTYPE_TESSELLATION_CONTROL,		"GL_EXT_tessellation_shader"	},
		{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	glu::SHADERTYPE_TESSELLATION_EVALUATION,	"GL_EXT_tessellation_shader"	},
		{ GL_REFERENCED_BY_GEOMETRY_SHADER,			glu::SHADERTYPE_GEOMETRY,					"GL_EXT_geometry_shader"		},
	};

	const glw::Functions&		gl			= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program		(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// check props
	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
	{
		if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
		{
			const glw::GLenum	prop		= targetProps[propNdx].propName;
			const glw::GLint	expected	= ((m_activeStagesMask & (1 << targetProps[propNdx].shaderType)) != 0) ? (GL_TRUE) : (GL_FALSE);
			glw::GLint			value		= -1;
			glw::GLint			written		= -1;

			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << glu::getBooleanName(expected) << tcu::TestLog::EndMessage;

			gl.getProgramResourceiv(program.getProgram(), GL_ATOMIC_COUNTER_BUFFER, 0, 1, &prop, 1, &written, &value);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");

			if (written != 1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
				continue;
			}

			m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;

			if (value != expected)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
				continue;
			}
		}
	}

	return STOP;
}

class ProgramInputOutputReferencedByCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_VERTEX_FRAGMENT = 0,
		CASE_VERTEX_GEO_FRAGMENT,
		CASE_VERTEX_TESS_FRAGMENT,
		CASE_VERTEX_TESS_GEO_FRAGMENT,

		CASE_SEPARABLE_VERTEX,
		CASE_SEPARABLE_FRAGMENT,
		CASE_SEPARABLE_GEOMETRY,
		CASE_SEPARABLE_TESS_CTRL,
		CASE_SEPARABLE_TESS_EVAL,

		CASE_LAST
	};
											ProgramInputOutputReferencedByCase	(Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType);
											~ProgramInputOutputReferencedByCase	(void);

private:
	void									init								(void);
	void									deinit								(void);
	IterateResult							iterate								(void);

	const CaseType							m_caseType;
	const glu::Storage						m_targetStorage;
	ProgramInterfaceDefinition::Program*	m_program;
};

ProgramInputOutputReferencedByCase::ProgramInputOutputReferencedByCase (Context& context, const char* name, const char* description, glu::Storage targetStorage, CaseType caseType)
	: TestCase				(context, name, description)
	, m_caseType			(caseType)
	, m_targetStorage		(targetStorage)
	, m_program				(DE_NULL)
{
	DE_ASSERT(caseType < CASE_LAST);
}

ProgramInputOutputReferencedByCase::~ProgramInputOutputReferencedByCase (void)
{
	deinit();
}

void ProgramInputOutputReferencedByCase::init (void)
{
	const bool hasTessellationShader =	(m_caseType == CASE_VERTEX_TESS_FRAGMENT)		||
										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
										(m_caseType == CASE_SEPARABLE_TESS_CTRL)		||
										(m_caseType == CASE_SEPARABLE_TESS_EVAL);
	const bool hasGeometryShader =		(m_caseType == CASE_VERTEX_GEO_FRAGMENT)		||
										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
										(m_caseType == CASE_SEPARABLE_GEOMETRY);

	if (hasTessellationShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if (hasGeometryShader && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");

	m_program = new ProgramInterfaceDefinition::Program();

	if (m_caseType == CASE_SEPARABLE_VERTEX		||
		m_caseType == CASE_SEPARABLE_FRAGMENT	||
		m_caseType == CASE_SEPARABLE_GEOMETRY	||
		m_caseType == CASE_SEPARABLE_TESS_CTRL	||
		m_caseType == CASE_SEPARABLE_TESS_EVAL)
	{
		const bool						isInputCase			= (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
		const bool						perPatchStorage		= (m_targetStorage == glu::STORAGE_PATCH_IN || m_targetStorage == glu::STORAGE_PATCH_OUT);
		const char*						varName				= (isInputCase) ? ("shaderInput") : ("shaderOutput");
		const glu::VariableDeclaration	targetDecl			(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), varName, m_targetStorage);
		const glu::ShaderType			shaderType			= (m_caseType == CASE_SEPARABLE_VERTEX)		? (glu::SHADERTYPE_VERTEX)
															: (m_caseType == CASE_SEPARABLE_FRAGMENT)	? (glu::SHADERTYPE_FRAGMENT)
															: (m_caseType == CASE_SEPARABLE_GEOMETRY)	? (glu::SHADERTYPE_GEOMETRY)
															: (m_caseType == CASE_SEPARABLE_TESS_CTRL)	? (glu::SHADERTYPE_TESSELLATION_CONTROL)
															: (m_caseType == CASE_SEPARABLE_TESS_EVAL)	? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
															:											  (glu::SHADERTYPE_LAST);
		const bool						arrayedInterface	= (isInputCase) ? ((shaderType == glu::SHADERTYPE_GEOMETRY)					||
																			   (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)		||
																			   (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION))
																			: (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL);

		m_program->setSeparable(true);

		if (arrayedInterface && !perPatchStorage)
		{
			const glu::VariableDeclaration targetDeclArr(glu::VarType(targetDecl.varType, glu::VarType::UNSIZED_ARRAY), varName, m_targetStorage);
			m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDeclArr);
		}
		else
		{
			m_program->addShader(shaderType, glu::GLSL_VERSION_310_ES)->getDefaultBlock().variables.push_back(targetDecl);
		}
	}
	else if (m_caseType == CASE_VERTEX_FRAGMENT			||
			 m_caseType == CASE_VERTEX_GEO_FRAGMENT		||
			 m_caseType == CASE_VERTEX_TESS_FRAGMENT	||
			 m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
	{
		ProgramInterfaceDefinition::Shader*	vertex		= m_program->addShader(glu::SHADERTYPE_VERTEX, glu::GLSL_VERSION_310_ES);
		ProgramInterfaceDefinition::Shader*	fragment	= m_program->addShader(glu::SHADERTYPE_FRAGMENT, glu::GLSL_VERSION_310_ES);

		m_program->setSeparable(false);

		vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																			   "shaderInput",
																			   glu::STORAGE_IN));
		vertex->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																			   "shaderOutput",
																			   glu::STORAGE_OUT,
																			   glu::INTERPOLATION_LAST,
																			   glu::Layout(1)));

		fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																				 "shaderOutput",
																				 glu::STORAGE_OUT,
																				 glu::INTERPOLATION_LAST,
																				 glu::Layout(0)));
		fragment->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																				 "shaderInput",
																				 glu::STORAGE_IN,
																				 glu::INTERPOLATION_LAST,
																				 glu::Layout(1)));

		if (m_caseType == CASE_VERTEX_TESS_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
		{
			ProgramInterfaceDefinition::Shader* tessCtrl = m_program->addShader(glu::SHADERTYPE_TESSELLATION_CONTROL, glu::GLSL_VERSION_310_ES);
			ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glu::GLSL_VERSION_310_ES);

			tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
																					 "shaderInput",
																					 glu::STORAGE_IN,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));
			tessCtrl->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
																					 "shaderOutput",
																					 glu::STORAGE_OUT,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));

			tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
																					 "shaderInput",
																					 glu::STORAGE_IN,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));
			tessEval->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																					 "shaderOutput",
																					 glu::STORAGE_OUT,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));
		}

		if (m_caseType == CASE_VERTEX_GEO_FRAGMENT || m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)
		{
			ProgramInterfaceDefinition::Shader* geometry = m_program->addShader(glu::SHADERTYPE_GEOMETRY, glu::GLSL_VERSION_310_ES);

			geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP), glu::VarType::UNSIZED_ARRAY),
																					 "shaderInput",
																					 glu::STORAGE_IN,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));
			geometry->getDefaultBlock().variables.push_back(glu::VariableDeclaration(glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP),
																					 "shaderOutput",
																					 glu::STORAGE_OUT,
																					 glu::INTERPOLATION_LAST,
																					 glu::Layout(1)));
		}
	}
	else
		DE_ASSERT(false);

	if (m_program->hasStage(glu::SHADERTYPE_GEOMETRY))
		m_program->setGeometryNumOutputVertices(1);
	if (m_program->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_program->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION))
		m_program->setTessellationNumOutputPatchVertices(1);

	DE_ASSERT(m_program->isValid());
}

void ProgramInputOutputReferencedByCase::deinit (void)
{
	delete m_program;
	m_program = DE_NULL;
}

ProgramInputOutputReferencedByCase::IterateResult ProgramInputOutputReferencedByCase::iterate (void)
{
	static const struct
	{
		glw::GLenum		propName;
		glu::ShaderType	shaderType;
		const char*		extension;
	} targetProps[] =
	{
		{ GL_REFERENCED_BY_VERTEX_SHADER,			glu::SHADERTYPE_VERTEX,						DE_NULL							},
		{ GL_REFERENCED_BY_FRAGMENT_SHADER,			glu::SHADERTYPE_FRAGMENT,					DE_NULL							},
		{ GL_REFERENCED_BY_COMPUTE_SHADER,			glu::SHADERTYPE_COMPUTE,					DE_NULL							},
		{ GL_REFERENCED_BY_TESS_CONTROL_SHADER,		glu::SHADERTYPE_TESSELLATION_CONTROL,		"GL_EXT_tessellation_shader"	},
		{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	glu::SHADERTYPE_TESSELLATION_EVALUATION,	"GL_EXT_tessellation_shader"	},
		{ GL_REFERENCED_BY_GEOMETRY_SHADER,			glu::SHADERTYPE_GEOMETRY,					"GL_EXT_geometry_shader"		},
	};

	const bool					isInputCase						= (m_targetStorage == glu::STORAGE_IN || m_targetStorage == glu::STORAGE_PATCH_IN);
	const glw::Functions&		gl								= m_context.getRenderContext().getFunctions();
	const glu::ShaderProgram	program							(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_program));
	const std::string			targetResourceName				= (isInputCase) ? ("shaderInput") : ("shaderOutput");
	const glw::GLenum			programGLInterface				= (isInputCase) ? (GL_PROGRAM_INPUT) : (GL_PROGRAM_OUTPUT);
	glw::GLuint					resourceIndex;

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// find target resource index

	resourceIndex = gl.getProgramResourceIndex(program.getProgram(), programGLInterface, targetResourceName.c_str());
	GLU_EXPECT_NO_ERROR(gl.getError(), "query resource index");

	if (resourceIndex == GL_INVALID_INDEX)
	{
		m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for resource \"" << targetResourceName << "\" index returned invalid index." << tcu::TestLog::EndMessage;
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource");
		return STOP;
	}

	// check props
	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(targetProps); ++propNdx)
	{
		if (targetProps[propNdx].extension == DE_NULL || m_context.getContextInfo().isExtensionSupported(targetProps[propNdx].extension))
		{
			const glw::GLenum	prop			= targetProps[propNdx].propName;
			const bool			expected		= (isInputCase) ? (targetProps[propNdx].shaderType == m_program->getFirstStage()) : (targetProps[propNdx].shaderType == m_program->getLastStage());
			glw::GLint			value			= -1;
			glw::GLint			written			= -1;

			m_testCtx.getLog() << tcu::TestLog::Message << "Verifying " << glu::getProgramResourcePropertyName(prop) << ", expecting " << ((expected) ? ("TRUE") : ("FALSE")) << tcu::TestLog::EndMessage;

			gl.getProgramResourceiv(program.getProgram(), programGLInterface, resourceIndex, 1, &prop, 1, &written, &value);
			GLU_EXPECT_NO_ERROR(gl.getError(), "query buffer binding");

			if (written != 1)
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, query for referenced_by_* returned invalid number of values." << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "property query failed");
				continue;
			}

			m_testCtx.getLog() << tcu::TestLog::Message << glu::getProgramResourcePropertyName(prop) << " = " << glu::getBooleanStr(value) << tcu::TestLog::EndMessage;

			if (value != ((expected) ? (GL_TRUE) : (GL_FALSE)))
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, got unexpected value" << tcu::TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "unexpected property value");
				continue;
			}
		}
	}

	return STOP;
}

class FeedbackResourceListTestCase : public ResourceListTestCase
{
public:
											FeedbackResourceListTestCase	(Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name);
											~FeedbackResourceListTestCase	(void);

private:
	IterateResult							iterate							(void);
};

FeedbackResourceListTestCase::FeedbackResourceListTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& resource, const char* name)
	: ResourceListTestCase(context, resource, PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, name)
{
}

FeedbackResourceListTestCase::~FeedbackResourceListTestCase (void)
{
	deinit();
}

FeedbackResourceListTestCase::IterateResult FeedbackResourceListTestCase::iterate (void)
{
	const glu::ShaderProgram program(m_context.getRenderContext(), generateProgramInterfaceProgramSources(m_programDefinition));

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

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

	checkAndLogProgram(program, m_programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog());

	// Check resource list
	{
		const tcu::ScopedLogSection	section				(m_testCtx.getLog(), "ResourceList", "Resource list");
		std::vector<std::string>	resourceList;
		std::vector<std::string>	expectedResources;

		queryResourceList(resourceList, program.getProgram());
		expectedResources = getProgramInterfaceResourceList(m_programDefinition, m_programInterface);

		// verify the list and the expected list match

		if (!verifyResourceList(resourceList, expectedResources))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid resource list");

		// verify GetProgramResourceIndex() matches the indices of the list

		if (!verifyResourceIndexQuery(resourceList, expectedResources, program.getProgram()))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "GetProgramResourceIndex returned unexpected values");

		// Verify MAX_NAME_LENGTH
		if (!verifyMaxNameLength(resourceList, program.getProgram()))
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "MAX_NAME_LENGTH invalid");
	}

	return STOP;
}

int InterfaceBlockDataSizeTestCase::getBlockMinDataSize (const glu::InterfaceBlock& block) const
{
	int dataSize = 0;

	for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx)
		dataSize += getVarTypeSize(block.variables[ndx].varType);

	return dataSize;
}

static bool isDataTypeLayoutQualified (glu::DataType type)
{
	return glu::isDataTypeImage(type) || glu::isDataTypeAtomicCounter(type);
}

static void generateVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
{
	static const struct
	{
		int				level;
		glu::DataType	dataType;
	} variableTypes[] =
	{
		{ 0,	glu::TYPE_FLOAT			},
		{ 1,	glu::TYPE_INT			},
		{ 1,	glu::TYPE_UINT			},
		{ 1,	glu::TYPE_BOOL			},

		{ 3,	glu::TYPE_FLOAT_VEC2	},
		{ 1,	glu::TYPE_FLOAT_VEC3	},
		{ 1,	glu::TYPE_FLOAT_VEC4	},

		{ 3,	glu::TYPE_INT_VEC2		},
		{ 2,	glu::TYPE_INT_VEC3		},
		{ 3,	glu::TYPE_INT_VEC4		},

		{ 3,	glu::TYPE_UINT_VEC2		},
		{ 2,	glu::TYPE_UINT_VEC3		},
		{ 3,	glu::TYPE_UINT_VEC4		},

		{ 3,	glu::TYPE_BOOL_VEC2		},
		{ 2,	glu::TYPE_BOOL_VEC3		},
		{ 3,	glu::TYPE_BOOL_VEC4		},

		{ 2,	glu::TYPE_FLOAT_MAT2	},
		{ 3,	glu::TYPE_FLOAT_MAT2X3	},
		{ 3,	glu::TYPE_FLOAT_MAT2X4	},
		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
		{ 2,	glu::TYPE_FLOAT_MAT3	},
		{ 3,	glu::TYPE_FLOAT_MAT3X4	},
		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
		{ 3,	glu::TYPE_FLOAT_MAT4X3	},
		{ 2,	glu::TYPE_FLOAT_MAT4	},
	};

	tcu::TestCaseGroup* group;

	if (createTestGroup)
	{
		group = new tcu::TestCaseGroup(context.getTestContext(), "basic_type", "Basic variable");
		targetGroup->addChild(group);
	}
	else
		group = targetGroup;

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		if (variableTypes[ndx].level <= expandLevel)
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
			group->addChild(new ResourceTestCase(context, variable, queryTarget));
		}
	}
}

static void generateOpaqueTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3, bool createTestGroup = true)
{
	static const struct
	{
		int				level;
		glu::DataType	dataType;
	} variableTypes[] =
	{
		{ 0,	glu::TYPE_SAMPLER_2D					},
		{ 2,	glu::TYPE_SAMPLER_CUBE					},
		{ 1,	glu::TYPE_SAMPLER_2D_ARRAY				},
		{ 1,	glu::TYPE_SAMPLER_3D					},
		{ 2,	glu::TYPE_SAMPLER_2D_SHADOW				},
		{ 3,	glu::TYPE_SAMPLER_CUBE_SHADOW			},
		{ 3,	glu::TYPE_SAMPLER_2D_ARRAY_SHADOW		},
		{ 1,	glu::TYPE_INT_SAMPLER_2D				},
		{ 3,	glu::TYPE_INT_SAMPLER_CUBE				},
		{ 3,	glu::TYPE_INT_SAMPLER_2D_ARRAY			},
		{ 3,	glu::TYPE_INT_SAMPLER_3D				},
		{ 2,	glu::TYPE_UINT_SAMPLER_2D				},
		{ 3,	glu::TYPE_UINT_SAMPLER_CUBE				},
		{ 3,	glu::TYPE_UINT_SAMPLER_2D_ARRAY			},
		{ 3,	glu::TYPE_UINT_SAMPLER_3D				},
		{ 2,	glu::TYPE_SAMPLER_2D_MULTISAMPLE		},
		{ 2,	glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE	},
		{ 3,	glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE	},
		{ 1,	glu::TYPE_IMAGE_2D						},
		{ 3,	glu::TYPE_IMAGE_CUBE					},
		{ 3,	glu::TYPE_IMAGE_2D_ARRAY				},
		{ 3,	glu::TYPE_IMAGE_3D						},
		{ 3,	glu::TYPE_INT_IMAGE_2D					},
		{ 3,	glu::TYPE_INT_IMAGE_CUBE				},
		{ 1,	glu::TYPE_INT_IMAGE_2D_ARRAY			},
		{ 3,	glu::TYPE_INT_IMAGE_3D					},
		{ 2,	glu::TYPE_UINT_IMAGE_2D					},
		{ 3,	glu::TYPE_UINT_IMAGE_CUBE				},
		{ 3,	glu::TYPE_UINT_IMAGE_2D_ARRAY			},
		{ 3,	glu::TYPE_UINT_IMAGE_3D					},
		{ 1,	glu::TYPE_UINT_ATOMIC_COUNTER			},
	};

	bool isStructMember = false;

	// Requirements
	for (const ResourceDefinition::Node* node = parentStructure.get(); node; node = node->getEnclosingNode())
	{
		// Don't insert inside a interface block
		if (node->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
			return;

		isStructMember |= (node->getType() == ResourceDefinition::Node::TYPE_STRUCT_MEMBER);
	}

	// Add cases
	{
		tcu::TestCaseGroup* group;

		if (createTestGroup)
		{
			group = new tcu::TestCaseGroup(context.getTestContext(), "opaque_type", "Opaque types");
			targetGroup->addChild(group);
		}
		else
			group = targetGroup;

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
		{
			if (variableTypes[ndx].level > expandLevel)
				continue;

			// Layout qualifiers are not allowed on struct members
			if (isDataTypeLayoutQualified(variableTypes[ndx].dataType) && isStructMember)
				continue;

			{
				const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
				group->addChild(new ResourceTestCase(context, variable, queryTarget));
			}
		}
	}
}

static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3);

static void generateVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel = 3)
{
	if (expandLevel > 0)
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");

		targetGroup->addChild(blockGroup);

		// Arrays of basic variables
		generateVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);

		// Arrays of opaque types
		generateOpaqueTypeCases(context, arrayElement, blockGroup, queryTarget, expandLevel, expandLevel != 1);

		// Arrays of arrays
		generateVariableArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);

		// Arrays of structs
		generateCompoundVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
	}
}

static void generateCompoundVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
{
	if (expandLevel > 0)
	{
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");

		targetGroup->addChild(blockGroup);

		// Struct containing basic variable
		generateVariableCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);

		// Struct containing opaque types
		generateOpaqueTypeCases(context, structMember, blockGroup, queryTarget, expandLevel, expandLevel != 1);

		// Struct containing arrays
		generateVariableArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);

		// Struct containing struct
		generateCompoundVariableCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
	}
}

// Resource list cases

enum BlockFlags
{
	BLOCKFLAG_DEFAULT	= 0x01,
	BLOCKFLAG_NAMED		= 0x02,
	BLOCKFLAG_UNNAMED	= 0x04,
	BLOCKFLAG_ARRAY		= 0x08,

	BLOCKFLAG_ALL		= 0x0F
};

static void generateUniformCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, deUint32 blockFlags, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const))
{
	const ResourceDefinition::Node::SharedPtr defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr uniform		(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));

	// .default_block
	if (blockFlags & BLOCKFLAG_DEFAULT)
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "default_block", "Default block");
		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, uniform, blockGroup);
	}

	// .named_block
	if (blockFlags & BLOCKFLAG_NAMED)
	{
		const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, true));

		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "named_block", "Named uniform block");
		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, block, blockGroup);
	}

	// .unnamed_block
	if (blockFlags & BLOCKFLAG_UNNAMED)
	{
		const ResourceDefinition::Node::SharedPtr block(new ResourceDefinition::InterfaceBlock(uniform, false));

		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "unnamed_block", "Unnamed uniform block");
		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, block, blockGroup);
	}

	// .block_array
	if (blockFlags & BLOCKFLAG_ARRAY)
	{
		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(uniform));
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));

		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "block_array", "Uniform block array");
		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, block, blockGroup);
	}
}

static void generateBufferBackedResourceListBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, int depth)
{
	// variable
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new ResourceListTestCase(context, variable, interface));
	}

	// struct
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
		generateBufferBackedResourceListBlockContentCases(context, structMember, targetGroup, interface, depth - 1);
	}

	// array
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
		generateBufferBackedResourceListBlockContentCases(context, arrayElement, targetGroup, interface, depth - 1);
	}
}

static void generateBufferBackedVariableAggregateTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, ProgramResourcePropFlags targetProp, glu::DataType dataType, const std::string& nameSuffix, int depth)
{
	// variable
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, dataType));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, targetProp), ("var" + nameSuffix).c_str()));
	}

	// struct
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr structMember(new ResourceDefinition::StructMember(parentStructure));
		generateBufferBackedVariableAggregateTypeCases(context, structMember, targetGroup, interface, targetProp, dataType, "_struct" + nameSuffix, depth - 1);
	}

	// array
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure));
		generateBufferBackedVariableAggregateTypeCases(context, arrayElement, targetGroup, interface, targetProp, dataType, "_array" + nameSuffix, depth - 1);
	}
}

static void generateUniformResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, 4);
}

static void generateUniformBlockArraySizeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_SIZE);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	if (!isInterfaceBlock || namedNonArrayBlock)
	{
		// .types
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
			targetGroup->addChild(blockGroup);

			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
		}

		// aggregates
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
			targetGroup->addChild(blockGroup);

			generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 3);
		}
	}
	else
	{
		// aggregates
		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, queryTarget.interface, PROGRAMRESOURCEPROP_ARRAY_SIZE, glu::TYPE_FLOAT, "", 2);
	}
}

static void generateBufferBackedArrayStrideTypeAggregateSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const std::string& namePrefix, ProgramInterface interface, glu::DataType type, int expandLevel)
{
	// case
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
	}

	if (expandLevel > 0)
	{
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));

		// _struct
		generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);

		// _array
		generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
	}
}

static void generateBufferBackedArrayStrideTypeAggregateCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, glu::DataType type, int expandLevel, bool includeBaseCase)
{
	const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
	const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
	const std::string							namePrefix		= glu::getDataTypeName(type);

	if (expandLevel == 0 || includeBaseCase)
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, type));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_ARRAY_STRIDE), namePrefix.c_str()));
	}
	if (expandLevel >= 1)
	{
		// _struct
		if (!glu::isDataTypeAtomicCounter(type))
			generateBufferBackedArrayStrideTypeAggregateSubCases(context, structMember, targetGroup, namePrefix + "_struct", interface, type, expandLevel - 1);

		// _array
		generateBufferBackedArrayStrideTypeAggregateSubCases(context, arrayElement, targetGroup, namePrefix + "_array", interface, type, expandLevel - 1);
	}
}

static void generateUniformBlockArrayStrideContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ARRAY_STRIDE);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	if (!isInterfaceBlock || namedNonArrayBlock)
	{
		// .types
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
			targetGroup->addChild(blockGroup);

			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 2, false);
			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 2, false);
		}

		// .aggregates
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
			targetGroup->addChild(blockGroup);

			// .sampler_2d_*
			if (!isInterfaceBlock)
				generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_SAMPLER_2D, 1, false);

			// .atomic_counter_*
			if (!isInterfaceBlock)
			{
				const ResourceDefinition::Node::SharedPtr layout(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
				generateBufferBackedArrayStrideTypeAggregateCases(context, layout, blockGroup, queryTarget.interface, glu::TYPE_UINT_ATOMIC_COUNTER, 1, false);
			}

			// .float_*
			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT, 2, false);

			// .bool_*
			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL, 1, false);

			// .bvec3_*
			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, 2, false);

			// .vec3_*
			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC3, 2, false);

			// .ivec2_*
			generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, blockGroup, queryTarget.interface, glu::TYPE_INT_VEC3, 2, false);
		}
	}
	else
	{
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
	}
}

static void generateUniformBlockLocationContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_LOCATION);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);

	if (!isInterfaceBlock)
	{
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
		generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);
		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 2);
		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 2);
	}
	else
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
}

static void generateUniformBlockBlockIndexContents (Context& context, tcu::TestCaseGroup* const targetGroup)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	uniform			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(uniform, glu::Layout(-1, 0)));

	// .default_block
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(uniform, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "default_block"));
	}

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
	}
}

static void generateUniformBlockAtomicCounterBufferIndexContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);

	if (!isInterfaceBlock)
	{
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 3);
		generateOpaqueTypeCases(context, parentStructure, targetGroup, queryTarget, 3);

		// .array
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
			const ResourceDefinition::Node::SharedPtr	arrayArrayElement	(new ResourceDefinition::ArrayElement(arrayElement));
			const ResourceDefinition::Node::SharedPtr	variable			(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
			const ResourceDefinition::Node::SharedPtr	elementvariable		(new ResourceDefinition::Variable(arrayArrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));
			tcu::TestCaseGroup* const					blockGroup			= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");

			targetGroup->addChild(blockGroup);

			blockGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "var_array"));
			blockGroup->addChild(new ResourceTestCase(context, elementvariable, queryTarget, "var_array_array"));
		}
	}
	else
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1, false);
}

static void generateUniformBlockNameLengthContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const bool	isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
	const bool	namedNonArrayBlock	= isInterfaceBlock																					&&
									  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
									  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	if (!isInterfaceBlock || namedNonArrayBlock)
		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
	else
		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 1);
}

static void generateUniformBlockTypeContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_TYPE);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	if (!isInterfaceBlock || namedNonArrayBlock)
	{
		// .types
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
			targetGroup->addChild(blockGroup);

			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
		}

		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);

	}
	else
	{
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
	}
}

static void generateUniformBlockOffsetContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_OFFSET);
	const bool								isInterfaceBlock	= (parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);
	const bool								namedNonArrayBlock	= isInterfaceBlock																					&&
																  static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named			&&
																  parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	if (!isInterfaceBlock)
	{
		// .types
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
			targetGroup->addChild(blockGroup);

			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
		}

		// .aggregates
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
			targetGroup->addChild(blockGroup);

			// .atomic_uint_struct
			// .atomic_uint_array
			{
				const ResourceDefinition::Node::SharedPtr offset			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, 4)));
				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::ArrayElement(offset));
				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));

				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "atomic_uint_array"));
			}

			// .float_array
			// .float_struct
			{
				const ResourceDefinition::Node::SharedPtr structMember		(new ResourceDefinition::StructMember(parentStructure));
				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
				const ResourceDefinition::Node::SharedPtr memberVariable	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));

				blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
			}
		}
	}
	else if (namedNonArrayBlock)
	{
		// .types
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
			targetGroup->addChild(blockGroup);

			generateVariableCases(context, parentStructure, blockGroup, queryTarget, 3, false);
			generateOpaqueTypeCases(context, parentStructure, blockGroup, queryTarget, 3, false);
		}

		// .aggregates
		{
			tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
			targetGroup->addChild(blockGroup);

			// .float_array
			// .float_struct
			{
				const ResourceDefinition::Node::SharedPtr structMember		(new ResourceDefinition::StructMember(parentStructure));
				const ResourceDefinition::Node::SharedPtr arrayElement		(new ResourceDefinition::StructMember(parentStructure));
				const ResourceDefinition::Node::SharedPtr memberVariable	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));
				const ResourceDefinition::Node::SharedPtr elementVariable	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));

				blockGroup->addChild(new ResourceTestCase(context, memberVariable, queryTarget, "float_struct"));
				blockGroup->addChild(new ResourceTestCase(context, elementVariable, queryTarget, "float_array"));
			}
		}
	}
	else
	{
		generateVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateVariableArrayCases(context, parentStructure, targetGroup, queryTarget, 1);
		generateCompoundVariableCases(context, parentStructure, targetGroup, queryTarget, 1);
	}
}

static void generateMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool createTestGroup = true, int expandLevel = 2)
{
	static const struct
	{
		int				priority;
		glu::DataType	type;
	} variableTypes[] =
	{
		{ 0,	glu::TYPE_FLOAT_MAT2	},
		{ 1,	glu::TYPE_FLOAT_MAT2X3	},
		{ 2,	glu::TYPE_FLOAT_MAT2X4	},
		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
		{ 1,	glu::TYPE_FLOAT_MAT3	},
		{ 0,	glu::TYPE_FLOAT_MAT3X4	},
		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
		{ 1,	glu::TYPE_FLOAT_MAT4X3	},
		{ 0,	glu::TYPE_FLOAT_MAT4	},
	};

	tcu::TestCaseGroup* group;

	if (createTestGroup)
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "matrix", "Basic matrix type");
		targetGroup->addChild(blockGroup);
		group = blockGroup;
	}
	else
		group = targetGroup;

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		if (variableTypes[ndx].priority < expandLevel)
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
			group->addChild(new ResourceTestCase(context, variable, queryTarget));
		}
	}
}

static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel);

static void generateMatrixArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
{
	if (expandLevel > 0)
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "array", "Arrays");

		targetGroup->addChild(blockGroup);

		// Arrays of basic variables
		generateMatrixVariableCases(context, arrayElement, blockGroup, queryTarget, expandLevel != 1, expandLevel);

		// Arrays of arrays
		generateMatrixArrayCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);

		// Arrays of structs
		generateMatrixStructCases(context, arrayElement, blockGroup, queryTarget, expandLevel-1);
	}
}

static void generateMatrixStructCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, int expandLevel)
{
	if (expandLevel > 0)
	{
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), "struct", "Structs");

		targetGroup->addChild(blockGroup);

		// Struct containing basic variable
		generateMatrixVariableCases(context, structMember, blockGroup, queryTarget, expandLevel != 1, expandLevel);

		// Struct containing arrays
		generateMatrixArrayCases(context, structMember, blockGroup, queryTarget, expandLevel-1);

		// Struct containing struct
		generateMatrixStructCases(context, structMember, blockGroup, queryTarget, expandLevel-1);
	}
}

static void generateUniformMatrixOrderCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
{
	static const struct
	{
		const char*			name;
		glu::MatrixOrder	order;
	} qualifiers[] =
	{
		{ "no_qualifier",	glu::MATRIXORDER_LAST			},
		{ "row_major",		glu::MATRIXORDER_ROW_MAJOR		},
		{ "column_major",	glu::MATRIXORDER_COLUMN_MAJOR	},
	};

	const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR);

	for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
	{
		// Add layout qualifiers only for block members
		if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
		{
			ResourceDefinition::Node::SharedPtr	subStructure	= parentStructure;
			tcu::TestCaseGroup* const			qualifierGroup	= new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");

			targetGroup->addChild(qualifierGroup);

			if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
			{
				glu::Layout layout;
				layout.matrixOrder = qualifiers[qualifierNdx].order;
				subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
			}

			if (extendedBasicTypeCases && qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
			{
				// .types
				{
					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
					qualifierGroup->addChild(blockGroup);

					generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
					generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
					if (opaqueCases)
						generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
				}

				// .aggregates
				{
					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
					qualifierGroup->addChild(blockGroup);

					generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
				}
			}
			else
			{
				generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
			}
		}
	}
}

static void generateUniformMatrixStrideCaseBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, bool extendedBasicTypeCases, bool opaqueCases)
{
	static const struct
	{
		const char*			name;
		glu::MatrixOrder	order;
	} qualifiers[] =
	{
		{ "no_qualifier",	glu::MATRIXORDER_LAST			},
		{ "row_major",		glu::MATRIXORDER_ROW_MAJOR		},
		{ "column_major",	glu::MATRIXORDER_COLUMN_MAJOR	},
	};

	const ProgramResourceQueryTestTarget queryTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_MATRIX_STRIDE);

	for (int qualifierNdx = 0; qualifierNdx < DE_LENGTH_OF_ARRAY(qualifiers); ++qualifierNdx)
	{
		// Add layout qualifiers only for block members
		if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST || parentStructure->getType() == ResourceDefinition::Node::TYPE_INTERFACE_BLOCK)
		{
			ResourceDefinition::Node::SharedPtr	subStructure	= parentStructure;
			tcu::TestCaseGroup* const			qualifierGroup	= new tcu::TestCaseGroup(context.getTestContext(), qualifiers[qualifierNdx].name, "");

			targetGroup->addChild(qualifierGroup);

			if (qualifiers[qualifierNdx].order != glu::MATRIXORDER_LAST)
			{
				glu::Layout layout;
				layout.matrixOrder = qualifiers[qualifierNdx].order;
				subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
			}

			if (extendedBasicTypeCases)
			{
				// .types
				// .matrix
				if (qualifiers[qualifierNdx].order == glu::MATRIXORDER_LAST)
				{
					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "");
					qualifierGroup->addChild(blockGroup);

					generateVariableCases(context, subStructure, blockGroup, queryTarget, 1, false);
					generateMatrixVariableCases(context, subStructure, blockGroup, queryTarget, false);
					if (opaqueCases)
						generateOpaqueTypeCases(context, subStructure, blockGroup, queryTarget, 2, false);
				}
				else
					generateMatrixVariableCases(context, subStructure, qualifierGroup, queryTarget);

				// .aggregates
				{
					tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "");
					qualifierGroup->addChild(blockGroup);

					generateBufferBackedVariableAggregateTypeCases(context, subStructure, blockGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
				}
			}
			else
				generateBufferBackedVariableAggregateTypeCases(context, subStructure, qualifierGroup, queryTarget.interface, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, glu::TYPE_FLOAT_MAT3X2, "", 1);
		}
	}
}

static void generateUniformMatrixCaseBlocks (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, bool, bool))
{
	static const struct
	{
		const char*			name;
		const char*			description;
		bool				block;
		bool				namedBlock;
		bool				extendedBasicTypeCases;
		glu::MatrixOrder	order;
	} children[] =
	{
		{ "default_block",				"Default block",			false,	true,	true,	glu::MATRIXORDER_LAST			},
		{ "named_block",				"Named uniform block",		true,	true,	true,	glu::MATRIXORDER_LAST			},
		{ "named_block_row_major",		"Named uniform block",		true,	true,	false,	glu::MATRIXORDER_ROW_MAJOR		},
		{ "named_block_col_major",		"Named uniform block",		true,	true,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
		{ "unnamed_block",				"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_LAST			},
		{ "unnamed_block_row_major",	"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_ROW_MAJOR		},
		{ "unnamed_block_col_major",	"Unnamed uniform block",	true,	false,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
	};

	const ResourceDefinition::Node::SharedPtr defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr uniform		(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));

	for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
	{
		ResourceDefinition::Node::SharedPtr	subStructure	= uniform;
		tcu::TestCaseGroup* const			blockGroup		= new tcu::TestCaseGroup(context.getTestContext(), children[childNdx].name, children[childNdx].description);
		const bool							addOpaqueCases	= children[childNdx].extendedBasicTypeCases && !children[childNdx].block;

		targetGroup->addChild(blockGroup);

		if (children[childNdx].order != glu::MATRIXORDER_LAST)
		{
			glu::Layout layout;
			layout.matrixOrder = children[childNdx].order;
			subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(subStructure, layout));
		}

		if (children[childNdx].block)
			subStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(subStructure, children[childNdx].namedBlock));

		blockContentGenerator(context, subStructure, blockGroup, children[childNdx].extendedBasicTypeCases, addOpaqueCases);
	}
}

static void generateBufferReferencedByShaderInterfaceBlockCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, const ProgramResourceQueryTestTarget& queryTarget, bool extendedCases)
{
	const bool isDefaultBlock = (parentStructure->getType() != ResourceDefinition::Node::TYPE_INTERFACE_BLOCK);

	// .float
	// .float_array
	// .float_struct
	{
		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(parentStructure, glu::TYPE_FLOAT));
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));
		const ResourceDefinition::Node::SharedPtr	variableStruct	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));

		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "float"));
		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_array"));
		targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "float_struct"));
	}

	// .sampler
	// .sampler_array
	// .sampler_struct
	if (isDefaultBlock)
	{
		const ResourceDefinition::Node::SharedPtr	layout			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(layout, glu::TYPE_SAMPLER_2D));
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(layout));
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_SAMPLER_2D));
		const ResourceDefinition::Node::SharedPtr	variableStruct	(new ResourceDefinition::Variable(structMember, glu::TYPE_SAMPLER_2D));

		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "sampler"));
		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "sampler_array"));
		targetGroup->addChild(new ResourceTestCase(context, variableStruct, queryTarget, "sampler_struct"));
	}

	// .atomic_uint
	// .atomic_uint_array
	if (isDefaultBlock)
	{
		const ResourceDefinition::Node::SharedPtr	layout			(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, 0)));
		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(layout, glu::TYPE_UINT_ATOMIC_COUNTER));
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(layout));
		const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_UINT_ATOMIC_COUNTER));

		targetGroup->addChild(new ResourceTestCase(context, variable, queryTarget, "atomic_uint"));
		targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "atomic_uint_array"));
	}

	if (extendedCases)
	{
		// .float_array_struct
		{
			const ResourceDefinition::Node::SharedPtr	structMember		(new ResourceDefinition::StructMember(parentStructure));
			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(structMember));
			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));

			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_struct"));
		}

		// .float_struct_array
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
			const ResourceDefinition::Node::SharedPtr	arrayStructMember	(new ResourceDefinition::StructMember(arrayElement));
			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(arrayStructMember, glu::TYPE_FLOAT));

			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_array"));
		}

		// .float_array_array
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement		(new ResourceDefinition::ArrayElement(parentStructure));
			const ResourceDefinition::Node::SharedPtr	subArrayElement		(new ResourceDefinition::ArrayElement(arrayElement));
			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(subArrayElement, glu::TYPE_FLOAT));

			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_array_array"));
		}

		// .float_struct_struct
		{
			const ResourceDefinition::Node::SharedPtr	structMember		(new ResourceDefinition::StructMember(parentStructure));
			const ResourceDefinition::Node::SharedPtr	subStructMember		(new ResourceDefinition::StructMember(structMember));
			const ResourceDefinition::Node::SharedPtr	variableArrayStruct	(new ResourceDefinition::Variable(subStructMember, glu::TYPE_FLOAT));

			targetGroup->addChild(new ResourceTestCase(context, variableArrayStruct, queryTarget, "float_struct_struct"));
		}

		if (queryTarget.interface == PROGRAMINTERFACE_BUFFER_VARIABLE)
		{
			const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));

			// .float_unsized_array
			{
				const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(arrayElement, glu::TYPE_FLOAT));

				targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_array"));
			}

			// .float_unsized_struct_array
			{
				const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(arrayElement));
				const ResourceDefinition::Node::SharedPtr	variableArray	(new ResourceDefinition::Variable(structMember, glu::TYPE_FLOAT));

				targetGroup->addChild(new ResourceTestCase(context, variableArray, queryTarget, "float_unsized_struct_array"));
			}
		}
	}
}

static void generateUniformReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, int expandLevel)
{
	DE_UNREF(expandLevel);

	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	uniform				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
	const ProgramResourceQueryTestTarget		queryTarget			(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
	const bool									singleShaderCase	= parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;

	// .default_block
	{
		TestCaseGroup* const blockGroup = new TestCaseGroup(context, "default_block", "");
		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, uniform, blockGroup, queryTarget, singleShaderCase);
	}

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(uniform, true));
		TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, "uniform_block", "");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, singleShaderCase);
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(uniform, false));
		TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, "unnamed_block", "");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(uniform));
		const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		TestCaseGroup* const						blockGroup		= new TestCaseGroup(context, "block_array", "");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, block, blockGroup, queryTarget, false);
	}
}

static void generateReferencedByShaderCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*generateBlockContent)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, int expandLevel))
{
	static const struct
	{
		const char*		name;
		glu::ShaderType	stage;
		int				expandLevel;
	} singleStageCases[] =
	{
		{ "compute",				glu::SHADERTYPE_COMPUTE,					3	},
		{ "separable_vertex",		glu::SHADERTYPE_VERTEX,						2	},
		{ "separable_fragment",		glu::SHADERTYPE_FRAGMENT,					2	},
		{ "separable_tess_ctrl",	glu::SHADERTYPE_TESSELLATION_CONTROL,		2	},
		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION,	2	},
		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY,					2	},
	};
	static const struct
	{
		const char*	name;
		deUint32	flags;
		int			expandLevel;
		int			subExpandLevel;
	} pipelines[] =
	{
		{
			"vertex_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
			3,
			2,
		},
		{
			"vertex_tess_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
			2,
			2,
		},
		{
			"vertex_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
			2,
			2,
		},
		{
			"vertex_tess_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
			2,
			1,
		},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
	{
		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
		const bool									programSeparable	= (singleStageCases[ndx].stage != glu::SHADERTYPE_COMPUTE);
		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(programSeparable));
		const ResourceDefinition::Node::SharedPtr	stage				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));

		targetGroup->addChild(blockGroup);

		generateBlockContent(context, stage, blockGroup, singleStageCases[ndx].expandLevel);
	}

	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
	{
		// whole pipeline
		{
			TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
			const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
			ResourceDefinition::ShaderSet*				shaderSet			= new ResourceDefinition::ShaderSet(program,
																												glu::GLSL_VERSION_310_ES,
																												pipelines[pipelineNdx].flags,
																												pipelines[pipelineNdx].flags);
			targetGroup->addChild(blockGroup);

			{
				const ResourceDefinition::Node::SharedPtr shaders(shaderSet);
				generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].expandLevel);
			}
		}

		// only one stage
		for (int selectedStageBit = 0; selectedStageBit < glu::SHADERTYPE_LAST; ++selectedStageBit)
		{
			if (pipelines[pipelineNdx].flags & (1 << selectedStageBit))
			{
				const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
				ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program,
																											glu::GLSL_VERSION_310_ES,
																											pipelines[pipelineNdx].flags,
																											(1u << selectedStageBit));
				const char*									stageName	= (selectedStageBit == glu::SHADERTYPE_VERTEX)					? ("vertex")
																		: (selectedStageBit == glu::SHADERTYPE_FRAGMENT)				? ("fragment")
																		: (selectedStageBit == glu::SHADERTYPE_GEOMETRY)				? ("geo")
																		: (selectedStageBit == glu::SHADERTYPE_TESSELLATION_CONTROL)	? ("tess_ctrl")
																		: (selectedStageBit == glu::SHADERTYPE_TESSELLATION_EVALUATION)	? ("tess_eval")
																		: (DE_NULL);
				const std::string							setName		= std::string() + pipelines[pipelineNdx].name + "_only_" + stageName;
				TestCaseGroup* const						blockGroup	= new TestCaseGroup(context, setName.c_str(), "");
				const ResourceDefinition::Node::SharedPtr	shaders		(shaderSet);

				generateBlockContent(context, shaders, blockGroup, pipelines[pipelineNdx].subExpandLevel);
				targetGroup->addChild(blockGroup);
			}
		}
	}
}

static glu::DataType generateRandomDataType (de::Random& rnd, bool excludeOpaqueTypes)
{
	static const glu::DataType s_types[] =
	{
		glu::TYPE_FLOAT,
		glu::TYPE_INT,
		glu::TYPE_UINT,
		glu::TYPE_BOOL,
		glu::TYPE_FLOAT_VEC2,
		glu::TYPE_FLOAT_VEC3,
		glu::TYPE_FLOAT_VEC4,
		glu::TYPE_INT_VEC2,
		glu::TYPE_INT_VEC3,
		glu::TYPE_INT_VEC4,
		glu::TYPE_UINT_VEC2,
		glu::TYPE_UINT_VEC3,
		glu::TYPE_UINT_VEC4,
		glu::TYPE_BOOL_VEC2,
		glu::TYPE_BOOL_VEC3,
		glu::TYPE_BOOL_VEC4,
		glu::TYPE_FLOAT_MAT2,
		glu::TYPE_FLOAT_MAT2X3,
		glu::TYPE_FLOAT_MAT2X4,
		glu::TYPE_FLOAT_MAT3X2,
		glu::TYPE_FLOAT_MAT3,
		glu::TYPE_FLOAT_MAT3X4,
		glu::TYPE_FLOAT_MAT4X2,
		glu::TYPE_FLOAT_MAT4X3,
		glu::TYPE_FLOAT_MAT4,

		glu::TYPE_SAMPLER_2D,
		glu::TYPE_SAMPLER_CUBE,
		glu::TYPE_SAMPLER_2D_ARRAY,
		glu::TYPE_SAMPLER_3D,
		glu::TYPE_SAMPLER_2D_SHADOW,
		glu::TYPE_SAMPLER_CUBE_SHADOW,
		glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
		glu::TYPE_INT_SAMPLER_2D,
		glu::TYPE_INT_SAMPLER_CUBE,
		glu::TYPE_INT_SAMPLER_2D_ARRAY,
		glu::TYPE_INT_SAMPLER_3D,
		glu::TYPE_UINT_SAMPLER_2D,
		glu::TYPE_UINT_SAMPLER_CUBE,
		glu::TYPE_UINT_SAMPLER_2D_ARRAY,
		glu::TYPE_UINT_SAMPLER_3D,
		glu::TYPE_SAMPLER_2D_MULTISAMPLE,
		glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
		glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
		glu::TYPE_IMAGE_2D,
		glu::TYPE_IMAGE_CUBE,
		glu::TYPE_IMAGE_2D_ARRAY,
		glu::TYPE_IMAGE_3D,
		glu::TYPE_INT_IMAGE_2D,
		glu::TYPE_INT_IMAGE_CUBE,
		glu::TYPE_INT_IMAGE_2D_ARRAY,
		glu::TYPE_INT_IMAGE_3D,
		glu::TYPE_UINT_IMAGE_2D,
		glu::TYPE_UINT_IMAGE_CUBE,
		glu::TYPE_UINT_IMAGE_2D_ARRAY,
		glu::TYPE_UINT_IMAGE_3D,
		glu::TYPE_UINT_ATOMIC_COUNTER
	};

	for (;;)
	{
		const glu::DataType type = s_types[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_types)-1)];

		if (!excludeOpaqueTypes					||
			glu::isDataTypeScalarOrVector(type)	||
			glu::isDataTypeMatrix(type))
			return type;
	}
}

static ResourceDefinition::Node::SharedPtr generateRandomVariableDefinition (de::Random&								rnd,
																			 const ResourceDefinition::Node::SharedPtr&	parentStructure,
																			 glu::DataType								baseType,
																			 const glu::Layout&							layout,
																			 bool										allowUnsized)
{
	const int							maxNesting			= 4;
	ResourceDefinition::Node::SharedPtr	currentStructure	= parentStructure;
	const bool							canBeInsideAStruct	= layout.binding == -1 && !isDataTypeLayoutQualified(baseType);

	for (int nestNdx = 0; nestNdx < maxNesting; ++nestNdx)
	{
		if (allowUnsized && nestNdx == 0 && rnd.getFloat() < 0.2)
			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		else if (rnd.getFloat() < 0.3 && canBeInsideAStruct)
			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StructMember(currentStructure));
		else if (rnd.getFloat() < 0.3)
			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
		else
			break;
	}

	return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Variable(currentStructure, baseType));
}

static ResourceDefinition::Node::SharedPtr generateRandomCoreShaderSet (de::Random& rnd)
{
	if (rnd.getFloat() < 0.5f)
	{
		// compute only
		const ResourceDefinition::Node::SharedPtr program(new ResourceDefinition::Program());
		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	}
	else if (rnd.getFloat() < 0.5f)
	{
		// vertex and fragment
		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
		ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);

		if (rnd.getBool())
		{
			shaderSet->setStage(glu::SHADERTYPE_VERTEX, true);
			shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());
		}
		else
		{
			shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
			shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, true);
		}

		return ResourceDefinition::Node::SharedPtr(shaderSet);
	}
	else
	{
		// separate vertex or fragment
		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program(true));
		const glu::ShaderType						shaderType	= (rnd.getBool()) ? (glu::SHADERTYPE_VERTEX) : (glu::SHADERTYPE_FRAGMENT);

		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
	}
}

static ResourceDefinition::Node::SharedPtr generateRandomExtShaderSet (de::Random& rnd)
{
	if (rnd.getFloat() < 0.5f)
	{
		// whole pipeline
		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
		ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);

		shaderSet->setStage(glu::SHADERTYPE_VERTEX, rnd.getBool());
		shaderSet->setStage(glu::SHADERTYPE_FRAGMENT, rnd.getBool());

		// tess shader are either both or neither present. Make cases interesting
		// by forcing one extended shader to always have reference
		if (rnd.getBool())
		{
			shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, true);

			if (rnd.getBool())
			{
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
			}
		}
		else
		{
			shaderSet->setStage(glu::SHADERTYPE_GEOMETRY, rnd.getBool());

			if (rnd.getBool())
			{
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, true);
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, rnd.getBool());
			}
			else
			{
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_CONTROL, rnd.getBool());
				shaderSet->setStage(glu::SHADERTYPE_TESSELLATION_EVALUATION, true);
			}
		}

		return ResourceDefinition::Node::SharedPtr(shaderSet);
	}
	else
	{
		// separate
		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program(true));
		const int									selector	= rnd.getInt(0, 2);
		const glu::ShaderType						shaderType	= (selector == 0) ? (glu::SHADERTYPE_GEOMETRY)
																: (selector == 1) ? (glu::SHADERTYPE_TESSELLATION_CONTROL)
																: (selector == 2) ? (glu::SHADERTYPE_TESSELLATION_EVALUATION)
																:					(glu::SHADERTYPE_LAST);

		return ResourceDefinition::Node::SharedPtr(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
	}
}

static ResourceDefinition::Node::SharedPtr generateRandomShaderSet (de::Random& rnd, bool onlyExtensionStages)
{
	if (!onlyExtensionStages)
		return generateRandomCoreShaderSet(rnd);
	else
		return generateRandomExtShaderSet(rnd);
}

static glu::Layout generateRandomUniformBlockLayout (de::Random& rnd)
{
	glu::Layout layout;

	if (rnd.getBool())
		layout.binding = rnd.getInt(0, 5);

	if (rnd.getBool())
		layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);

	return layout;
}

static glu::Layout generateRandomBufferBlockLayout (de::Random& rnd)
{
	return generateRandomUniformBlockLayout(rnd);
}

static glu::Layout generateRandomVariableLayout (de::Random& rnd, glu::DataType type, bool interfaceBlockMember)
{
	glu::Layout layout;

	if ((glu::isDataTypeAtomicCounter(type) || glu::isDataTypeImage(type) || glu::isDataTypeSampler(type)) && rnd.getBool())
		layout.binding = rnd.getInt(0, 5);

	if (glu::isDataTypeAtomicCounter(type) && rnd.getBool())
		layout.offset = rnd.getInt(0, 3) * 4;

	if (glu::isDataTypeMatrix(type) && interfaceBlockMember && rnd.getBool())
		layout.matrixOrder = (rnd.getBool()) ? (glu::MATRIXORDER_COLUMN_MAJOR) : (glu::MATRIXORDER_ROW_MAJOR);

	return layout;
}

static void generateUniformRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
{
	de::Random									rnd					(index * 0x12345);
	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, onlyExtensionStages);
	const bool									interfaceBlock		= rnd.getBool();
	const glu::DataType							type				= generateRandomDataType(rnd, interfaceBlock);
	const glu::Layout							layout				= generateRandomVariableLayout(rnd, type, interfaceBlock);
	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	uniform				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_UNIFORM));
	ResourceDefinition::Node::SharedPtr			currentStructure	= uniform;

	if (interfaceBlock)
	{
		const bool namedBlock = rnd.getBool();

		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, generateRandomUniformBlockLayout(rnd)));

		if (namedBlock && rnd.getBool())
			currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));

		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));
	}

	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
	currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, false);

	targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_UNIFORM, PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK), de::toString(index).c_str()));
}

static void generateUniformCaseRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
{
	const int numBasicCases		= 40;
	const int numTessGeoCases	= 40;

	for (int ndx = 0; ndx < numBasicCases; ++ndx)
		generateUniformRandomCase(context, targetGroup, ndx, false);
	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
		generateUniformRandomCase(context, targetGroup, numBasicCases + ndx, true);
}

class UniformInterfaceTestGroup : public TestCaseGroup
{
public:
			UniformInterfaceTestGroup	(Context& context);
	void	init						(void);
};

UniformInterfaceTestGroup::UniformInterfaceTestGroup (Context& context)
	: TestCaseGroup(context, "uniform", "Uniform interace")
{
}

void UniformInterfaceTestGroup::init (void)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	computeShader	(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Query array size");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArraySizeContents);
	}

	// .array_stride
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_stride", "Query array stride");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockArrayStrideContents);
	}

	// .atomic_counter_buffer_index
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "atomic_counter_buffer_index", "Query atomic counter buffer index");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED, generateUniformBlockAtomicCounterBufferIndexContents);
	}

	// .block_index
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "block_index", "Query block index");
		addChild(blockGroup);
		generateUniformBlockBlockIndexContents(m_context, blockGroup);
	}

	// .location
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Query location");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_DEFAULT | BLOCKFLAG_NAMED | BLOCKFLAG_UNNAMED, generateUniformBlockLocationContents);
	}

	// .matrix_row_major
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_row_major", "Query matrix row_major");
		addChild(blockGroup);
		generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixOrderCaseBlockContentCases);
	}

	// .matrix_stride
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "matrix_stride", "Query matrix stride");
		addChild(blockGroup);
		generateUniformMatrixCaseBlocks(m_context, computeShader, blockGroup, generateUniformMatrixStrideCaseBlockContentCases);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Query name length");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockNameLengthContents);
	}

	// .offset
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "offset", "Query offset");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockOffsetContents);
	}

	// .referenced_by_shader
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by_shader", "Query referenced by shader");
		addChild(blockGroup);
		generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateUniformReferencedByShaderSingleBlockContentCases);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Query type");
		addChild(blockGroup);
		generateUniformCaseBlocks(m_context, computeShader, blockGroup, BLOCKFLAG_ALL, generateUniformBlockTypeContents);
	}

	// .random
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Random");
		addChild(blockGroup);
		generateUniformCaseRandomCases(m_context, blockGroup);
	}
}

static void generateBufferBackedInterfaceResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
{
	targetGroup->addChild(new ResourceListTestCase(context, targetResource, interface, blockName));
}

static void generateBufferBackedInterfaceNameLengthCase (Context& context, const ResourceDefinition::Node::SharedPtr& targetResource, tcu::TestCaseGroup* const targetGroup, ProgramInterface interface, const char* blockName)
{
	targetGroup->addChild(new ResourceTestCase(context, targetResource, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_NAME_LENGTH), blockName));
}

static void generateBufferBackedInterfaceResourceBasicBlockTypes (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup* const, ProgramInterface interface, const char* blockName))
{
	const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	storageQualifier	(new ResourceDefinition::StorageQualifier(defaultBlock, storage));
	const ResourceDefinition::Node::SharedPtr	binding				(new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, 1)));
	const ProgramInterface						programInterface	= (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, true));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "named_block");
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, false));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "unnamed_block");
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 3));
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array");
	}

	// .block_array_single_element
	{
		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 1));
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		blockContentGenerator(context, dummyVariable, targetGroup, programInterface, "block_array_single_element");
	}
}

static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
{
	const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	storageQualifier	(new ResourceDefinition::StorageQualifier(defaultBlock, storage));

	for (int ndx = 0; ndx < 2; ++ndx)
	{
		const bool									explicitBinding		= (ndx == 1);
		const int									bindingNdx			= (explicitBinding) ? (1) : (-1);
		const std::string							nameSuffix			= (explicitBinding) ? ("_explicit_binding") : ("");
		const ResourceDefinition::Node::SharedPtr	binding				(new ResourceDefinition::LayoutQualifier(storageQualifier, glu::Layout(-1, bindingNdx)));
		const ProgramInterface						programInterface	= (storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) : (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK);

		// .named_block*
		{
			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, true));
			const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("named_block" + nameSuffix).c_str()));
		}

		// .unnamed_block*
		{
			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(binding, false));
			const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("unnamed_block" + nameSuffix).c_str()));
		}

		// .block_array*
		{
			const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(binding, 3));
			const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
			const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_BUFFER_BINDING), ("block_array" + nameSuffix).c_str()));
		}
	}
}

template <glu::Storage Storage>
static void generateBufferBlockReferencedByShaderSingleBlockContentCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
{
	const ProgramInterface						programInterface	= (Storage == glu::STORAGE_UNIFORM) ? (PROGRAMINTERFACE_UNIFORM_BLOCK) :
																      (Storage == glu::STORAGE_BUFFER) ? (PROGRAMINTERFACE_SHADER_STORAGE_BLOCK) :
																      (PROGRAMINTERFACE_LAST);
	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	storage				(new ResourceDefinition::StorageQualifier(defaultBlock, Storage));

	DE_UNREF(expandLevel);

	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(storage, true));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "named_block"));
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(storage, false));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "unnamed_block"));
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr arrayElement	(new ResourceDefinition::ArrayElement(storage, 3));
		const ResourceDefinition::Node::SharedPtr block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		const ResourceDefinition::Node::SharedPtr dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		targetGroup->addChild(new ResourceTestCase(context, dummyVariable, ProgramResourceQueryTestTarget(programInterface, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER), "block_array"));
	}
}

static void generateBufferBackedInterfaceResourceActiveVariablesCase (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
{
	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "named_block",		"Named block",		storage,	InterfaceBlockActiveVariablesTestCase::CASE_NAMED_BLOCK));
	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "unnamed_block",	"Unnamed block",	storage,	InterfaceBlockActiveVariablesTestCase::CASE_UNNAMED_BLOCK));
	targetGroup->addChild(new InterfaceBlockActiveVariablesTestCase(context, "block_array",		"Block array",		storage,	InterfaceBlockActiveVariablesTestCase::CASE_BLOCK_ARRAY));
}

static void generateBufferBackedInterfaceResourceBufferDataSizeCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
{
	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "named_block",	"Named block",		storage,	InterfaceBlockDataSizeTestCase::CASE_NAMED_BLOCK));
	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "unnamed_block",	"Unnamed block",	storage,	InterfaceBlockDataSizeTestCase::CASE_UNNAMED_BLOCK));
	targetGroup->addChild(new InterfaceBlockDataSizeTestCase(context, "block_array",	"Block array",		storage,	InterfaceBlockDataSizeTestCase::CASE_BLOCK_ARRAY));
}

class BufferBackedBlockInterfaceTestGroup : public TestCaseGroup
{
public:
						BufferBackedBlockInterfaceTestGroup	(Context& context, glu::Storage interfaceBlockStorage);
	void				init								(void);

private:
	static const char*	getGroupName						(glu::Storage storage);
	static const char*	getGroupDescription					(glu::Storage storage);

	const glu::Storage	m_storage;
};

BufferBackedBlockInterfaceTestGroup::BufferBackedBlockInterfaceTestGroup(Context& context, glu::Storage storage)
	: TestCaseGroup	(context, getGroupName(storage), getGroupDescription(storage))
	, m_storage		(storage)
{
	DE_ASSERT(storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM);
}

void BufferBackedBlockInterfaceTestGroup::init (void)
{
	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceResourceListCase);
	}

	// .active_variables
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "active_variables", "Active variables");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceActiveVariablesCase(m_context, blockGroup, m_storage);
	}

	// .buffer_binding
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_binding", "Buffer binding");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceBufferBindingCases(m_context, blockGroup, m_storage);
	}

	// .buffer_data_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "buffer_data_size", "Buffer data size");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceBufferDataSizeCases(m_context, blockGroup, m_storage);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, m_storage, generateBufferBackedInterfaceNameLengthCase);
	}

	// .referenced_by
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Referenced by shader");
		addChild(blockGroup);

		if (m_storage == glu::STORAGE_UNIFORM)
			generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
		else if (m_storage == glu::STORAGE_BUFFER)
			generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_BUFFER>);
		else
			DE_ASSERT(false);
	}
}

const char* BufferBackedBlockInterfaceTestGroup::getGroupName (glu::Storage storage)
{
	switch (storage)
	{
		case glu::STORAGE_UNIFORM:	return "uniform_block";
		case glu::STORAGE_BUFFER:	return "shader_storage_block";
		default:
			DE_ASSERT("false");
			return DE_NULL;
	}
}

const char* BufferBackedBlockInterfaceTestGroup::getGroupDescription (glu::Storage storage)
{
	switch (storage)
	{
		case glu::STORAGE_UNIFORM:	return "Uniform block interface";
		case glu::STORAGE_BUFFER:	return "Shader storage block interface";
		default:
			DE_ASSERT("false");
			return DE_NULL;
	}
}

class AtomicCounterTestGroup : public TestCaseGroup
{
public:
			AtomicCounterTestGroup	(Context& context);
	void	init					(void);
};

AtomicCounterTestGroup::AtomicCounterTestGroup (Context& context)
	: TestCaseGroup(context, "atomic_counter_buffer", "Atomic counter buffer")
{
}

void AtomicCounterTestGroup::init (void)
{
	static const struct
	{
		const char*	name;
		deUint32	flags;
	} pipelines[] =
	{
		{
			"vertex_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT)
		},
		{
			"vertex_tess_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)
		},
		{
			"vertex_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY)
		},
		{
			"vertex_tess_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
		},
	};

	// .resource_list
	addChild(new AtomicCounterResourceListCase(m_context, "resource_list", "Resource list"));

	// .active_variables
	addChild(new AtomicCounterActiveVariablesCase(m_context, "active_variables", "Active variables"));

	// .buffer_binding
	addChild(new AtomicCounterBufferBindingCase(m_context, "buffer_binding", "Buffer binding"));

	// .buffer_data_size
	addChild(new AtomicCounterBufferDataSizeCase(m_context, "buffer_data_size", "Buffer binding"));

	// .referenced_by
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_compute",				"",	false,	(1 << glu::SHADERTYPE_COMPUTE),										(1 << glu::SHADERTYPE_COMPUTE)));
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_vertex",		"",	true,	(1 << glu::SHADERTYPE_VERTEX),										(1 << glu::SHADERTYPE_VERTEX)));
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_fragment",	"",	true,	(1 << glu::SHADERTYPE_FRAGMENT),									(1 << glu::SHADERTYPE_FRAGMENT)));
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_geometry",	"",	true,	(1 << glu::SHADERTYPE_GEOMETRY),									(1 << glu::SHADERTYPE_GEOMETRY)));
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_ctrl",	"",	true,	(1 << glu::SHADERTYPE_TESSELLATION_CONTROL),						(1 << glu::SHADERTYPE_TESSELLATION_CONTROL)));
	addChild(new AtomicCounterReferencedByCase(m_context, "referenced_by_separable_tess_eval",	"",	true,	(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),						(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION)));

	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
	{
		addChild(new AtomicCounterReferencedByCase(m_context, (std::string() + "referenced_by_" + pipelines[pipelineNdx].name).c_str(), "", false, pipelines[pipelineNdx].flags, pipelines[pipelineNdx].flags));

		for (deUint32 stageNdx = 0; stageNdx < glu::SHADERTYPE_LAST; ++stageNdx)
		{
			const deUint32 currentBit = (1u << stageNdx);
			if (currentBit > pipelines[pipelineNdx].flags)
				break;
			if (currentBit & pipelines[pipelineNdx].flags)
			{
				const char*			stageName	= (stageNdx == glu::SHADERTYPE_VERTEX)					? ("vertex")
												: (stageNdx == glu::SHADERTYPE_FRAGMENT)				? ("fragment")
												: (stageNdx == glu::SHADERTYPE_GEOMETRY)				? ("geo")
												: (stageNdx == glu::SHADERTYPE_TESSELLATION_CONTROL)	? ("tess_ctrl")
												: (stageNdx == glu::SHADERTYPE_TESSELLATION_EVALUATION)	? ("tess_eval")
												: (DE_NULL);
				const std::string	name		= std::string() + "referenced_by_" + pipelines[pipelineNdx].name + "_only_" + stageName;

				addChild(new AtomicCounterReferencedByCase(m_context, name.c_str(), "", false, pipelines[pipelineNdx].flags, currentBit));
			}
		}
	}
}

static void generateProgramInputOutputShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, bool withCompute, bool inputCase, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
{
	static const struct
	{
		const char*		name;
		glu::ShaderType	stage;
	} singleStageCases[] =
	{
		{ "separable_vertex",		glu::SHADERTYPE_VERTEX					},
		{ "separable_fragment",		glu::SHADERTYPE_FRAGMENT				},
		{ "separable_tess_ctrl",	glu::SHADERTYPE_TESSELLATION_CONTROL	},
		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION	},
		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY				},
	};

	// .vertex_fragment
	{
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(false));
		ResourceDefinition::ShaderSet*				shaderSetPtr	= new ResourceDefinition::ShaderSet(program, glu::GLSL_VERSION_310_ES);
		const ResourceDefinition::Node::SharedPtr	shaderSet		(shaderSetPtr);
		const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shaderSet));

		shaderSetPtr->setStage(glu::SHADERTYPE_VERTEX, inputCase);
		shaderSetPtr->setStage(glu::SHADERTYPE_FRAGMENT, !inputCase);

		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT));
	}

	// .separable_*
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
	{
		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(true));
		const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));
		const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));

		targetGroup->addChild(blockGroup);
		blockContentGenerator(context, defaultBlock, blockGroup, (1 << singleStageCases[ndx].stage));
	}

	// .compute
	if (withCompute)
	{
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "compute", "Compute");
		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(true));
		const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
		const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));

		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, defaultBlock, blockGroup, (1 << glu::SHADERTYPE_COMPUTE));
	}

	// .interface_blocks
	{
		static const struct
		{
			const char*			inputName;
			glu::ShaderType		inputStage;
			glu::Storage		inputStorage;
			const char*			outputName;
			glu::ShaderType		outputStage;
			glu::Storage		outputStorage;
		} ioBlockTypes[] =
		{
			{
				"in",
				glu::SHADERTYPE_FRAGMENT,
				glu::STORAGE_IN,
				"out",
				glu::SHADERTYPE_VERTEX,
				glu::STORAGE_OUT,
			},
			{
				"patch_in",
				glu::SHADERTYPE_TESSELLATION_EVALUATION,
				glu::STORAGE_PATCH_IN,
				"patch_out",
				glu::SHADERTYPE_TESSELLATION_CONTROL,
				glu::STORAGE_PATCH_OUT,
			},
		};

		tcu::TestCaseGroup* const ioBlocksGroup = new TestCaseGroup(context, "interface_blocks", "Interface blocks");
		targetGroup->addChild(ioBlocksGroup);

		// .in/out
		// .sample in/out
		// .patch in/out
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioBlockTypes); ++ndx)
		{
			const char* const							name			= (inputCase) ? (ioBlockTypes[ndx].inputName) : (ioBlockTypes[ndx].outputName);
			const glu::ShaderType						shaderType		= (inputCase) ? (ioBlockTypes[ndx].inputStage) : (ioBlockTypes[ndx].outputStage);
			const glu::Storage							storageType		= (inputCase) ? (ioBlockTypes[ndx].inputStorage) : (ioBlockTypes[ndx].outputStorage);
			tcu::TestCaseGroup* const					ioBlockGroup	= new TestCaseGroup(context, name, "");
			const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(true));
			const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, shaderType, glu::GLSL_VERSION_310_ES));
			const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
			const ResourceDefinition::Node::SharedPtr	storage			(new ResourceDefinition::StorageQualifier(defaultBlock, storageType));

			ioBlocksGroup->addChild(ioBlockGroup);

			// .named_block
			{
				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(storage, true));
				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");

				ioBlockGroup->addChild(blockGroup);

				blockContentGenerator(context, block, blockGroup, (1 << shaderType));
			}

			// .named_block_explicit_location
			{
				const ResourceDefinition::Node::SharedPtr	layout		(new ResourceDefinition::LayoutQualifier(storage, glu::Layout(3)));
				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(layout, true));
				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block_explicit_location", "Named block with explicit location");

				ioBlockGroup->addChild(blockGroup);

				blockContentGenerator(context, block, blockGroup, (1 << shaderType));
			}

			// .unnamed_block
			{
				const ResourceDefinition::Node::SharedPtr	block		(new ResourceDefinition::InterfaceBlock(storage, false));
				tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");

				ioBlockGroup->addChild(blockGroup);

				blockContentGenerator(context, block, blockGroup, (1 << shaderType));
			}

			// .block_array
			{
				const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(storage));
				const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
				tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "block_array", "Block array");

				ioBlockGroup->addChild(blockGroup);

				blockContentGenerator(context, block, blockGroup, (1 << shaderType));
			}
		}
	}
}

static void generateProgramInputBlockContents (Context&										context,
											   const ResourceDefinition::Node::SharedPtr&	parentStructure,
											   tcu::TestCaseGroup*							targetGroup,
											   deUint32										presentShadersMask,
											   bool											includeEmpty,
											   void											(*genCase)(Context&										context,
																									   const ResourceDefinition::Node::SharedPtr&	parentStructure,
																									   tcu::TestCaseGroup*							targetGroup,
																									   ProgramInterface								interface,
																									   const char*									name))
{
	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	input			= (inDefaultBlock)
																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
																	: (parentStructure);
	const glu::ShaderType						firstStage		= getShaderMaskFirstStage(presentShadersMask);

	// .empty
	if (includeEmpty && inDefaultBlock)
		genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "empty");

	if (firstStage == glu::SHADERTYPE_VERTEX)
	{
		// .var
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
		genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
	}
	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
		}
		// .var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(input));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_struct");
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var_array");
		}
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
			 firstStage == glu::SHADERTYPE_GEOMETRY)
	{
		// arrayed interface

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "var");
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays

		// .patch_var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var");
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchInput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_struct");
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchInput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_INPUT, "patch_var_array");
		}
	}
	else if (firstStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

static void generateProgramOutputBlockContents (Context&										context,
												const ResourceDefinition::Node::SharedPtr&		parentStructure,
												tcu::TestCaseGroup*								targetGroup,
												deUint32										presentShadersMask,
												bool											includeEmpty,
												void											(*genCase)(Context&										context,
																										   const ResourceDefinition::Node::SharedPtr&	parentStructure,
																										   tcu::TestCaseGroup*							targetGroup,
																										   ProgramInterface								interface,
																										   const char*									name))
{
	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	output			= (inDefaultBlock)
																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
																	: (parentStructure);
	const glu::ShaderType						lastStage		= getShaderMaskLastStage(presentShadersMask);

	// .empty
	if (includeEmpty && inDefaultBlock)
		genCase(context, parentStructure, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "empty");

	if (lastStage == glu::SHADERTYPE_VERTEX						||
		lastStage == glu::SHADERTYPE_GEOMETRY					||
		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
		!inDefaultBlock)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
		}
		// .var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_struct");
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
		}
	}
	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var_array");
		}
	}
	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "var");
		}
		// extension forbids use arrays of structs
		// extension forbids use array of arrays

		// .patch_var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var");
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchOutput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_struct");
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchOutput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			genCase(context, variable, targetGroup, PROGRAMINTERFACE_PROGRAM_OUTPUT, "patch_var_array");
		}
	}
	else if (lastStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

static void addProgramInputOutputResourceListCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
{
	ResourceListTestCase* const resourceListCase = new ResourceListTestCase(context, parentStructure, programInterface);

	DE_ASSERT(deStringEqual(name, resourceListCase->getName()));
	DE_UNREF(name);
	targetGroup->addChild(resourceListCase);
}

static void generateProgramInputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
}

static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
}

template <ProgramResourcePropFlags TargetProp>
static void addProgramInputOutputResourceTestCase (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramInterface programInterface, const char* name)
{
	ResourceTestCase* const resourceTestCase = new ResourceTestCase(context, parentStructure, ProgramResourceQueryTestTarget(programInterface, TargetProp), name);
	targetGroup->addChild(resourceTestCase);
}

template <ProgramResourcePropFlags TargetProp>
static void generateProgramInputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
}

template <ProgramResourcePropFlags TargetProp>
static void generateProgramOutputBasicBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
}

static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	input			= (inDefaultBlock)
																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
																	: (parentStructure);
	const glu::ShaderType						firstStage		= getShaderMaskFirstStage(presentShadersMask);

	if (firstStage == glu::SHADERTYPE_VERTEX)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
	}
	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(input, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// .var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(input));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
		}
		// .var_struct_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
		}
		// .var_array_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
		}
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
			 firstStage == glu::SHADERTYPE_GEOMETRY)
	{
		// arrayed interface

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(input, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays

		// .patch_var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchInput, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
		}
		// .patch_var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchInput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
		}
		// .patch_var_struct_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchInput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
		}
		// .patch_var_array_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchInput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_INPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
		}
	}
	else if (firstStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

static void generateProgramOutputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	const bool									inDefaultBlock	= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	output			= (inDefaultBlock)
																	? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
																	: (parentStructure);
	const glu::ShaderType						lastStage		= getShaderMaskLastStage(presentShadersMask);

	if (lastStage == glu::SHADERTYPE_VERTEX						||
		lastStage == glu::SHADERTYPE_GEOMETRY					||
		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
		!inDefaultBlock)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// .var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct"));
		}
		// .var_struct_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_struct_explicit_location"));
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
		}
		// .var_array_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
		}
	}
	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
	{
		// .var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(output, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// .var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array"));
		}
		// .var_array_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(1)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_array_explicit_location"));
		}
	}
	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var"));
		}
		// .var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(output, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "var_explicit_location"));
		}
		// extension forbids use arrays of structs
		// extension forbids use array of arrays

		// .patch_var
		{
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(patchOutput, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var"));
		}
		// .patch_var_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(layout, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_explicit_location"));
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(patchOutput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct"));
		}
		// .patch_var_struct_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(structMbr, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_struct_explicit_location"));
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(patchOutput));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array"));
		}
		// .patch_var_array_explicit_location
		{
			const ResourceDefinition::Node::SharedPtr layout	(new ResourceDefinition::LayoutQualifier(patchOutput, glu::Layout(2)));
			const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(layout));
			const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_PROGRAM_OUTPUT, PROGRAMRESOURCEPROP_LOCATION), "patch_var_array_explicit_location"));
		}
	}
	else if (lastStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

static void generateProgramInputOutputReferencedByCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::Storage storage)
{
	// all whole pipelines
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_fragment",			"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_FRAGMENT));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_fragment",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_FRAGMENT));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_geo_fragment",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_GEO_FRAGMENT));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_vertex_tess_geo_fragment",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_VERTEX_TESS_GEO_FRAGMENT));

	// all partial pipelines
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_vertex",		"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_VERTEX));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_fragment",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_FRAGMENT));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_geometry",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_GEOMETRY));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
	targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl",	"",	storage,	ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));

	// patch
	if (storage == glu::STORAGE_IN)
		targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_eval_patch_in", "", glu::STORAGE_PATCH_IN, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_EVAL));
	else if (storage == glu::STORAGE_OUT)
		targetGroup->addChild(new ProgramInputOutputReferencedByCase(context, "referenced_by_separable_tess_ctrl_patch_out", "", glu::STORAGE_PATCH_OUT, ProgramInputOutputReferencedByCase::CASE_SEPARABLE_TESS_CTRL));
	else
		DE_ASSERT(false);
}

template <ProgramInterface interface>
static void generateProgramInputOutputTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool allowMatrixCases, int expandLevel)
{
	static const struct
	{
		glu::DataType	type;
		bool			isMatrix;
		int				level;
	} variableTypes[] =
	{
		{ glu::TYPE_FLOAT,			false,		0	},
		{ glu::TYPE_INT,			false,		1	},
		{ glu::TYPE_UINT,			false,		1	},
		{ glu::TYPE_FLOAT_VEC2,		false,		2	},
		{ glu::TYPE_FLOAT_VEC3,		false,		1	},
		{ glu::TYPE_FLOAT_VEC4,		false,		2	},
		{ glu::TYPE_INT_VEC2,		false,		0	},
		{ glu::TYPE_INT_VEC3,		false,		2	},
		{ glu::TYPE_INT_VEC4,		false,		2	},
		{ glu::TYPE_UINT_VEC2,		false,		2	},
		{ glu::TYPE_UINT_VEC3,		false,		2	},
		{ glu::TYPE_UINT_VEC4,		false,		0	},
		{ glu::TYPE_FLOAT_MAT2,		true,		2	},
		{ glu::TYPE_FLOAT_MAT2X3,	true,		2	},
		{ glu::TYPE_FLOAT_MAT2X4,	true,		2	},
		{ glu::TYPE_FLOAT_MAT3X2,	true,		0	},
		{ glu::TYPE_FLOAT_MAT3,		true,		2	},
		{ glu::TYPE_FLOAT_MAT3X4,	true,		2	},
		{ glu::TYPE_FLOAT_MAT4X2,	true,		2	},
		{ glu::TYPE_FLOAT_MAT4X3,	true,		2	},
		{ glu::TYPE_FLOAT_MAT4,		true,		2	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		if (!allowMatrixCases && variableTypes[ndx].isMatrix)
			continue;

		if (variableTypes[ndx].level <= expandLevel)
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(interface, PROGRAMRESOURCEPROP_TYPE)));
		}
	}
}

static void generateProgramInputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	const bool									inDefaultBlock						= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	input								= (inDefaultBlock)
																						? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_IN)))
																						: (parentStructure);
	const glu::ShaderType						firstStage							= getShaderMaskFirstStage(presentShadersMask);
	const int									interfaceBlockExpansionReducement	= (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable

	if (firstStage == glu::SHADERTYPE_VERTEX)
	{
		// Only basic types (and no booleans)
		generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, input, targetGroup, true, 2 - interfaceBlockExpansionReducement);
	}
	else if (firstStage == glu::SHADERTYPE_FRAGMENT || !inDefaultBlock)
	{
		const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(input, glu::INTERPOLATION_FLAT));

		// Only basic types, arrays of basic types, struct of basic types (and no booleans)
		{
			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
		}
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(flatShading));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, blockGroup, true, 2 - interfaceBlockExpansionReducement);
		}
		{
			const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(flatShading));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Struct types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMember, blockGroup, true, 2 - interfaceBlockExpansionReducement);
		}
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_CONTROL ||
			 firstStage == glu::SHADERTYPE_GEOMETRY)
	{
		// arrayed interface

		// Only basic types (and no booleans)
		const ResourceDefinition::Node::SharedPtr arrayElement(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElement, targetGroup, true, 2);
	}
	else if (firstStage == glu::SHADERTYPE_TESSELLATION_EVALUATION)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchInput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_IN));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(input, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 2);
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays

		// .patch_var
		{
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var", "Basic types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, patchInput, blockGroup, true, 1);
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr	structMbr		(new ResourceDefinition::StructMember(patchInput));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, structMbr, blockGroup, true, 1);
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(patchInput));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_INPUT>(context, arrayElem, blockGroup, true, 1);
		}
	}
	else if (firstStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

static void generateProgramOutputTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask)
{
	const bool									inDefaultBlock						= parentStructure->getType() == ResourceDefinition::Node::TYPE_DEFAULT_BLOCK;
	const ResourceDefinition::Node::SharedPtr	output								= (inDefaultBlock)
																						? (ResourceDefinition::Node::SharedPtr(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_OUT)))
																						: (parentStructure);
	const glu::ShaderType						lastStage							= getShaderMaskLastStage(presentShadersMask);
	const int									interfaceBlockExpansionReducement	= (!inDefaultBlock) ? (1) : (0); // lesser expansions on block members to keep test counts reasonable

	if (lastStage == glu::SHADERTYPE_VERTEX						||
		lastStage == glu::SHADERTYPE_GEOMETRY					||
		lastStage == glu::SHADERTYPE_TESSELLATION_EVALUATION	||
		!inDefaultBlock)
	{
		const ResourceDefinition::Node::SharedPtr flatShading(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));

		// Only basic types, arrays of basic types, struct of basic types (and no booleans)
		{
			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, flatShading, blockGroup, true, 2 - interfaceBlockExpansionReducement);
		}
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement			(new ResourceDefinition::ArrayElement(flatShading));
			tcu::TestCaseGroup* const					blockGroup				= new TestCaseGroup(context, "array", "Array types");
			const int									typeExpansionReducement	= (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
			const int									expansionLevel			= 2 - interfaceBlockExpansionReducement - typeExpansionReducement;

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, true, expansionLevel);
		}
		{
			const ResourceDefinition::Node::SharedPtr	structMember			(new ResourceDefinition::StructMember(flatShading));
			tcu::TestCaseGroup* const					blockGroup				= new TestCaseGroup(context, "struct", "Struct types");
			const int									typeExpansionReducement	= (lastStage != glu::SHADERTYPE_VERTEX) ? (1) : (0); // lesser expansions on other stages
			const int									expansionLevel			= 2 - interfaceBlockExpansionReducement - typeExpansionReducement;

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
		}
	}
	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
	{
		// only basic type and basic type array (and no booleans or matrices)
		{
			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
		}
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(output));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
		}
	}
	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));

		// .var
		{
			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(output, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 2);
		}
		// extension forbids use arrays of structs
		// extension forbids use arrays of arrays

		// .patch_var
		{
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var", "Basic types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, patchOutput, blockGroup, true, 1);
		}
		// .patch_var_struct
		{
			const ResourceDefinition::Node::SharedPtr	structMbr		(new ResourceDefinition::StructMember(patchOutput));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_struct", "Struct types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMbr, blockGroup, true, 1);
		}
		// .patch_var_array
		{
			const ResourceDefinition::Node::SharedPtr	arrayElem		(new ResourceDefinition::ArrayElement(patchOutput));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "patch_var_array", "Array types, per-patch");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElem, blockGroup, true, 1);
		}
	}
	else if (lastStage == glu::SHADERTYPE_COMPUTE)
	{
		// nada
	}
	else
		DE_ASSERT(false);
}

class ProgramInputTestGroup : public TestCaseGroup
{
public:
			ProgramInputTestGroup	(Context& context);
	void	init					(void);
};

ProgramInputTestGroup::ProgramInputTestGroup (Context& context)
	: TestCaseGroup(context, "program_input", "Program input")
{
}

void ProgramInputTestGroup::init (void)
{
	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, true, generateProgramInputResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .location
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputLocationBlockContents);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
	}

	// .referenced_by
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
		addChild(blockGroup);
		generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_IN);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputTypeBlockContents);
	}

	// .is_per_patch
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, true, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
	}
}

class ProgramOutputTestGroup : public TestCaseGroup
{
public:
			ProgramOutputTestGroup	(Context& context);
	void	init					(void);
};

ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context)
	: TestCaseGroup(context, "program_output", "Program output")
{
}

void ProgramOutputTestGroup::init (void)
{
	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, true, false, generateProgramOutputResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .location
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputLocationBlockContents);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
	}

	// .referenced_by
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "referenced_by", "Reference by shader");
		addChild(blockGroup);
		generateProgramInputOutputReferencedByCases(m_context, blockGroup, glu::STORAGE_OUT);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "type", "Type");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputTypeBlockContents);
	}

	// .is_per_patch
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "is_per_patch", "Is per patch");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, false, false, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
	}
}

static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
{
	static const struct
	{
		const char*	name;
		deUint32	stageBits;
		deUint32	lastStageBit;
		bool		reducedSet;
	} pipelines[] =
	{
		{
			"vertex_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT),
			(1 << glu::SHADERTYPE_VERTEX),
			false
		},
		{
			"vertex_tess_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
			(1 << glu::SHADERTYPE_TESSELLATION_EVALUATION),
			true
		},
		{
			"vertex_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_GEOMETRY),
			(1 << glu::SHADERTYPE_GEOMETRY),
			true
		},
		{
			"vertex_tess_geo_fragment",
			(1 << glu::SHADERTYPE_VERTEX) | (1 << glu::SHADERTYPE_FRAGMENT) | (1 << glu::SHADERTYPE_TESSELLATION_CONTROL) | (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION) | (1 << glu::SHADERTYPE_GEOMETRY),
			(1 << glu::SHADERTYPE_GEOMETRY),
			true
		},
	};
	static const struct
	{
		const char*		name;
		glu::ShaderType	stage;
		bool			reducedSet;
	} singleStageCases[] =
	{
		{ "separable_vertex",		glu::SHADERTYPE_VERTEX,						false	},
		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION,	true	},
		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY,					true	},
	};

	// monolithic pipeline
	for (int pipelineNdx = 0; pipelineNdx < DE_LENGTH_OF_ARRAY(pipelines); ++pipelineNdx)
	{
		TestCaseGroup* const						blockGroup		= new TestCaseGroup(context, pipelines[pipelineNdx].name, "");
		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
		const ResourceDefinition::Node::SharedPtr	shaderSet		(new ResourceDefinition::ShaderSet(program,
																									   glu::GLSL_VERSION_310_ES,
																									   pipelines[pipelineNdx].stageBits,
																									   pipelines[pipelineNdx].lastStageBit));

		targetGroup->addChild(blockGroup);
		blockContentGenerator(context, shaderSet, blockGroup, pipelines[pipelineNdx].reducedSet);
	}

	// separable pipeline
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(singleStageCases); ++ndx)
	{
		TestCaseGroup* const						blockGroup			= new TestCaseGroup(context, singleStageCases[ndx].name, "");
		const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program(true));
		const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, singleStageCases[ndx].stage, glu::GLSL_VERSION_310_ES));

		targetGroup->addChild(blockGroup);
		blockContentGenerator(context, shader, blockGroup, singleStageCases[ndx].reducedSet);
	}
}

static void generateTransformFeedbackResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
{
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));

	DE_UNREF(reducedSet);

	// .builtin_gl_position
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
		targetGroup->addChild(new FeedbackResourceListTestCase(context, xfbTarget, "builtin_gl_position"));
	}
	// .default_block_basic_type
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_basic_type"));
	}
	// .default_block_struct_member
	{
		const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(structMbr));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_struct_member"));
	}
	// .default_block_array
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(xfbTarget));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array"));
	}
	// .default_block_array_element
	{
		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new FeedbackResourceListTestCase(context, variable, "default_block_array_element"));
	}
}

template <ProgramResourcePropFlags TargetProp>
static void generateTransformFeedbackVariableBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
{
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));

	DE_UNREF(reducedSet);

	// .builtin_gl_position
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
		targetGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "builtin_gl_position"));
	}
	// .default_block_basic_type
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_basic_type"));
	}
	// .default_block_struct_member
	{
		const ResourceDefinition::Node::SharedPtr structMbr	(new ResourceDefinition::StructMember(output));
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(structMbr));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_struct_member"));
	}
	// .default_block_array
	{
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(output));
		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(xfbTarget));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(arrayElem, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array"));
	}
	// .default_block_array_element
	{
		const ResourceDefinition::Node::SharedPtr arrayElem	(new ResourceDefinition::ArrayElement(output));
		const ResourceDefinition::Node::SharedPtr xfbTarget	(new ResourceDefinition::TransformFeedbackTarget(arrayElem));
		const ResourceDefinition::Node::SharedPtr variable	(new ResourceDefinition::Variable(xfbTarget, glu::TYPE_FLOAT_VEC4));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, TargetProp), "default_block_array_element"));
	}
}

static void generateTransformFeedbackVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
{
	static const struct
	{
		glu::DataType	type;
		bool			important;
	} variableTypes[] =
	{
		{ glu::TYPE_FLOAT,			true	},
		{ glu::TYPE_INT,			true	},
		{ glu::TYPE_UINT,			true	},

		{ glu::TYPE_FLOAT_VEC2,		false	},
		{ glu::TYPE_FLOAT_VEC3,		true	},
		{ glu::TYPE_FLOAT_VEC4,		false	},

		{ glu::TYPE_INT_VEC2,		false	},
		{ glu::TYPE_INT_VEC3,		true	},
		{ glu::TYPE_INT_VEC4,		false	},

		{ glu::TYPE_UINT_VEC2,		true	},
		{ glu::TYPE_UINT_VEC3,		false	},
		{ glu::TYPE_UINT_VEC4,		false	},

		{ glu::TYPE_FLOAT_MAT2,		false	},
		{ glu::TYPE_FLOAT_MAT2X3,	false	},
		{ glu::TYPE_FLOAT_MAT2X4,	false	},
		{ glu::TYPE_FLOAT_MAT3X2,	false	},
		{ glu::TYPE_FLOAT_MAT3,		false	},
		{ glu::TYPE_FLOAT_MAT3X4,	true	},
		{ glu::TYPE_FLOAT_MAT4X2,	false	},
		{ glu::TYPE_FLOAT_MAT4X3,	false	},
		{ glu::TYPE_FLOAT_MAT4,		false	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		if (variableTypes[ndx].important || !reducedSet)
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].type));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE)));
		}
	}
}

static void generateTransformFeedbackVariableTypeBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool reducedSet)
{
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	output			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_OUT));
	const ResourceDefinition::Node::SharedPtr	flatShading		(new ResourceDefinition::InterpolationQualifier(output, glu::INTERPOLATION_FLAT));

	// Only builtins, basic types, arrays of basic types, struct of basic types (and no booleans)
	{
		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(defaultBlock, "gl_Position"));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "builtin", "Built-in outputs");

		targetGroup->addChild(blockGroup);
		blockGroup->addChild(new ResourceTestCase(context, xfbTarget, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING, PROGRAMRESOURCEPROP_TYPE), "gl_position"));
	}
	{
		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(flatShading));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "basic_type", "Basic types");

		targetGroup->addChild(blockGroup);
		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
	}
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(flatShading));
		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(arrayElement));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");

		targetGroup->addChild(blockGroup);
		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
	}
	{
		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(flatShading));
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(xfbTarget));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "whole_array", "Whole array");

		targetGroup->addChild(blockGroup);
		generateTransformFeedbackVariableBasicTypeCases(context, arrayElement, blockGroup, reducedSet);
	}
	{
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(flatShading));
		const ResourceDefinition::Node::SharedPtr	xfbTarget		(new ResourceDefinition::TransformFeedbackTarget(structMember));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Struct types");

		targetGroup->addChild(blockGroup);
		generateTransformFeedbackVariableBasicTypeCases(context, xfbTarget, blockGroup, reducedSet);
	}
}

class TransformFeedbackVaryingTestGroup : public TestCaseGroup
{
public:
			TransformFeedbackVaryingTestGroup	(Context& context);
	void	init								(void);
};

TransformFeedbackVaryingTestGroup::TransformFeedbackVaryingTestGroup (Context& context)
	: TestCaseGroup(context, "transform_feedback_varying", "Transform feedback varyings")
{
}

void TransformFeedbackVaryingTestGroup::init (void)
{
	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, generateTransformFeedbackVariableTypeBlockContents);
	}
}

static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*))
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	bufferStorage	(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");

		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, buffer, blockGroup);
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");

		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, buffer, blockGroup);
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "block_array", "Block array");

		targetGroup->addChild(blockGroup);

		blockContentGenerator(context, buffer, blockGroup);
	}
}

static void generateBufferVariableResourceListBlockContentsProxy (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	generateBufferBackedResourceListBlockContentCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, 4);
}

static void generateBufferVariableArraySizeSubCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup, ProgramResourcePropFlags targetProp, bool sizedArray, bool extendedCases)
{
	const ProgramResourceQueryTestTarget	queryTarget		(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp);
	tcu::TestCaseGroup*						aggregateGroup;

	// .types
	if (extendedCases)
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(context.getTestContext(), "types", "Types");
		targetGroup->addChild(blockGroup);

		generateVariableCases(context, parentStructure, blockGroup, queryTarget, (sizedArray) ? (2) : (1), false);
	}

	// .aggregates
	if (extendedCases)
	{
		aggregateGroup = new tcu::TestCaseGroup(context.getTestContext(), "aggregates", "Aggregate types");
		targetGroup->addChild(aggregateGroup);
	}
	else
		aggregateGroup = targetGroup;

	// .float_*
	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);

	// .bool_*
	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL, (extendedCases && sizedArray) ? (1) : (0), !extendedCases);

	// .bvec3_*
	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_BOOL_VEC3, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);

	// .vec4_*
	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_FLOAT_VEC4, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);

	// .ivec2_*
	generateBufferBackedArrayStrideTypeAggregateCases(context, parentStructure, aggregateGroup, queryTarget.interface, glu::TYPE_INT_VEC2, (extendedCases && sizedArray) ? (2) : (1), !extendedCases);
}

template <ProgramResourcePropFlags TargetProp>
static void generateBufferVariableArrayCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* const targetGroup)
{
	const ProgramResourceQueryTestTarget	queryTarget			(PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp);
	const bool								namedNonArrayBlock	= static_cast<const ResourceDefinition::InterfaceBlock*>(parentStructure.get())->m_named && parentStructure->getEnclosingNode()->getType() != ResourceDefinition::Node::TYPE_ARRAY_ELEMENT;

	// .non_array
	if (namedNonArrayBlock)
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "non_array", "Non-array target");
		targetGroup->addChild(blockGroup);

		generateVariableCases(context, parentStructure, blockGroup, queryTarget, 1, false);
	}

	// .sized
	{
		const ResourceDefinition::Node::SharedPtr	sized		(new ResourceDefinition::ArrayElement(parentStructure));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "sized", "Sized target");
		targetGroup->addChild(blockGroup);

		generateBufferVariableArraySizeSubCases(context, sized, blockGroup, TargetProp, true, namedNonArrayBlock);
	}

	// .unsized
	{
		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
		targetGroup->addChild(blockGroup);

		generateBufferVariableArraySizeSubCases(context, unsized, blockGroup, TargetProp, false, namedNonArrayBlock);
	}
}

static void generateBufferVariableBlockIndexCases (Context& context, tcu::TestCaseGroup* const targetGroup)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	bufferStorage	(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
	const ResourceDefinition::Node::SharedPtr	binding			(new ResourceDefinition::LayoutQualifier(bufferStorage, glu::Layout(-1, 0)));

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, true));
		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "named_block"));
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(binding, false));
		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "unnamed_block"));
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(binding));
		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		const ResourceDefinition::Node::SharedPtr	variable		(new ResourceDefinition::Variable(buffer, glu::TYPE_FLOAT_VEC4));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BLOCK_INDEX), "block_array"));
	}
}

static void generateBufferVariableMatrixCaseBlocks (Context& context, tcu::TestCaseGroup* const targetGroup, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, bool))
{
	static const struct
	{
		const char*			name;
		const char*			description;
		bool				namedBlock;
		bool				extendedBasicTypeCases;
		glu::MatrixOrder	order;
	} children[] =
	{
		{ "named_block",				"Named uniform block",		true,	true,	glu::MATRIXORDER_LAST			},
		{ "named_block_row_major",		"Named uniform block",		true,	false,	glu::MATRIXORDER_ROW_MAJOR		},
		{ "named_block_col_major",		"Named uniform block",		true,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
		{ "unnamed_block",				"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_LAST			},
		{ "unnamed_block_row_major",	"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_ROW_MAJOR		},
		{ "unnamed_block_col_major",	"Unnamed uniform block",	false,	false,	glu::MATRIXORDER_COLUMN_MAJOR	},
	};

	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));

	for (int childNdx = 0; childNdx < (int)DE_LENGTH_OF_ARRAY(children); ++childNdx)
	{
		ResourceDefinition::Node::SharedPtr	parentStructure	= buffer;
		tcu::TestCaseGroup* const			blockGroup		= new TestCaseGroup(context, children[childNdx].name, children[childNdx].description);

		targetGroup->addChild(blockGroup);

		if (children[childNdx].order != glu::MATRIXORDER_LAST)
		{
			glu::Layout layout;
			layout.matrixOrder = children[childNdx].order;
			parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(parentStructure, layout));
		}

		parentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(parentStructure, children[childNdx].namedBlock));

		blockContentGenerator(context, parentStructure, blockGroup, children[childNdx].extendedBasicTypeCases);
	}
}

static void generateBufferVariableMatrixVariableBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
{
	// all matrix types and some non-matrix

	static const glu::DataType variableTypes[] =
	{
		glu::TYPE_FLOAT,
		glu::TYPE_INT_VEC3,
		glu::TYPE_FLOAT_MAT2,
		glu::TYPE_FLOAT_MAT2X3,
		glu::TYPE_FLOAT_MAT2X4,
		glu::TYPE_FLOAT_MAT3X2,
		glu::TYPE_FLOAT_MAT3,
		glu::TYPE_FLOAT_MAT3X4,
		glu::TYPE_FLOAT_MAT4X2,
		glu::TYPE_FLOAT_MAT4X3,
		glu::TYPE_FLOAT_MAT4,
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx]));
		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp)));
	}
}

static void generateBufferVariableMatrixVariableCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, ProgramResourcePropFlags targetProp)
{
	// Basic aggregates
	generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp, glu::TYPE_FLOAT_MAT3X2, "", 2);

	// Unsized array
	{
		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		const ResourceDefinition::Node::SharedPtr	variable	(new ResourceDefinition::Variable(unsized, glu::TYPE_FLOAT_MAT3X2));

		targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, targetProp), "var_unsized_array"));
	}
}

template <ProgramResourcePropFlags TargetProp>
static void generateBufferVariableMatrixCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, bool extendedTypeCases)
{
	// .types
	if (extendedTypeCases)
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "types", "Types");
		targetGroup->addChild(blockGroup);
		generateBufferVariableMatrixVariableBasicTypeCases(context, parentStructure, blockGroup, TargetProp);
	}

	// .no_qualifier
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "no_qualifier", "No qualifier");
		targetGroup->addChild(blockGroup);
		generateBufferVariableMatrixVariableCases(context, parentStructure, blockGroup, TargetProp);
	}

	// .column_major
	{
		const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_COLUMN_MAJOR)));

		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "column_major", "Column major qualifier");
		targetGroup->addChild(blockGroup);
		generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
	}

	// .row_major
	{
		const ResourceDefinition::Node::SharedPtr matrixOrder(new ResourceDefinition::LayoutQualifier(parentStructure, glu::Layout(-1, -1, -1, glu::FORMATLAYOUT_LAST, glu::MATRIXORDER_ROW_MAJOR)));

		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "row_major", "Row major qualifier");
		targetGroup->addChild(blockGroup);
		generateBufferVariableMatrixVariableCases(context, matrixOrder, blockGroup, TargetProp);
	}
}

static void generateBufferVariableNameLengthCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
{
	// .sized
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
		targetGroup->addChild(blockGroup);

		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 3);
	}

	// .unsized
	{
		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
		targetGroup->addChild(blockGroup);

		generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_NAME_LENGTH, glu::TYPE_FLOAT, "", 2);
	}
}

static void generateBufferVariableOffsetCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
{
	// .sized
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "sized", "Sized target");
		targetGroup->addChild(blockGroup);

		generateBufferBackedVariableAggregateTypeCases(context, parentStructure, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 3);
	}

	// .unsized
	{
		const ResourceDefinition::Node::SharedPtr	unsized		(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unsized", "Unsized target");
		targetGroup->addChild(blockGroup);

		generateBufferBackedVariableAggregateTypeCases(context, unsized, blockGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_OFFSET, glu::TYPE_FLOAT, "", 2);
	}
}

static void generateBufferVariableReferencedByBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
{
	DE_UNREF(expandLevel);

	const ProgramResourceQueryTestTarget		queryTarget		(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER);
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(parentStructure));
	const ResourceDefinition::Node::SharedPtr	storage			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
	const bool									singleShaderCase	= parentStructure->getType() == ResourceDefinition::Node::TYPE_SHADER;

	// .named_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(storage, true));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "named_block", "Named block");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, singleShaderCase);
	}

	// .unnamed_block
	{
		const ResourceDefinition::Node::SharedPtr	buffer		(new ResourceDefinition::InterfaceBlock(storage, false));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "unnamed_block", "Unnamed block");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
	}

	// .block_array
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(storage));
		const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::InterfaceBlock(arrayElement, true));
		tcu::TestCaseGroup* const					blockGroup	= new TestCaseGroup(context, "block_array", "Block array");

		targetGroup->addChild(blockGroup);

		generateBufferReferencedByShaderInterfaceBlockCases(context, buffer, blockGroup, queryTarget, false);
	}
}

template <ProgramResourcePropFlags TargetProp>
static void generateBufferVariableTopLevelCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup)
{
	// basic and aggregate types
	generateBufferBackedVariableAggregateTypeCases(context, parentStructure, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "", 3);

	// basic and aggregate types in an unsized array
	{
		const ResourceDefinition::Node::SharedPtr unsized(new ResourceDefinition::ArrayElement(parentStructure, ResourceDefinition::ArrayElement::UNSIZED_ARRAY));

		generateBufferBackedVariableAggregateTypeCases(context, unsized, targetGroup, PROGRAMINTERFACE_BUFFER_VARIABLE, TargetProp, glu::TYPE_FLOAT_VEC4, "_unsized_array", 2);
	}
}

static void generateBufferVariableTypeBasicTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int expandLevel)
{
	static const struct
	{
		int				level;
		glu::DataType	dataType;
	} variableTypes[] =
	{
		{ 0,	glu::TYPE_FLOAT			},
		{ 1,	glu::TYPE_INT			},
		{ 1,	glu::TYPE_UINT			},
		{ 1,	glu::TYPE_BOOL			},

		{ 3,	glu::TYPE_FLOAT_VEC2	},
		{ 1,	glu::TYPE_FLOAT_VEC3	},
		{ 1,	glu::TYPE_FLOAT_VEC4	},

		{ 3,	glu::TYPE_INT_VEC2		},
		{ 2,	glu::TYPE_INT_VEC3		},
		{ 3,	glu::TYPE_INT_VEC4		},

		{ 3,	glu::TYPE_UINT_VEC2		},
		{ 2,	glu::TYPE_UINT_VEC3		},
		{ 3,	glu::TYPE_UINT_VEC4		},

		{ 3,	glu::TYPE_BOOL_VEC2		},
		{ 2,	glu::TYPE_BOOL_VEC3		},
		{ 3,	glu::TYPE_BOOL_VEC4		},

		{ 2,	glu::TYPE_FLOAT_MAT2	},
		{ 3,	glu::TYPE_FLOAT_MAT2X3	},
		{ 3,	glu::TYPE_FLOAT_MAT2X4	},
		{ 2,	glu::TYPE_FLOAT_MAT3X2	},
		{ 2,	glu::TYPE_FLOAT_MAT3	},
		{ 3,	glu::TYPE_FLOAT_MAT3X4	},
		{ 2,	glu::TYPE_FLOAT_MAT4X2	},
		{ 3,	glu::TYPE_FLOAT_MAT4X3	},
		{ 2,	glu::TYPE_FLOAT_MAT4	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(variableTypes); ++ndx)
	{
		if (variableTypes[ndx].level <= expandLevel)
		{
			const ResourceDefinition::Node::SharedPtr variable(new ResourceDefinition::Variable(parentStructure, variableTypes[ndx].dataType));
			targetGroup->addChild(new ResourceTestCase(context, variable, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_TYPE)));
		}
	}
}

static void generateBufferVariableTypeCases (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, int depth = 3)
{
	// .basic_type
	if (depth > 0)
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic type");
		targetGroup->addChild(blockGroup);
		generateBufferVariableTypeBasicTypeCases(context, parentStructure, blockGroup, depth);
	}
	else
	{
		// flatten bottom-level
		generateBufferVariableTypeBasicTypeCases(context, parentStructure, targetGroup, depth);
	}

	// .array
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Arrays");

		targetGroup->addChild(blockGroup);
		generateBufferVariableTypeCases(context, arrayElement, blockGroup, depth-1);
	}

	// .struct
	if (depth > 0)
	{
		const ResourceDefinition::Node::SharedPtr	structMember	(new ResourceDefinition::StructMember(parentStructure));
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "struct", "Structs");

		targetGroup->addChild(blockGroup);
		generateBufferVariableTypeCases(context, structMember, blockGroup, depth-1);
	}
}

static void generateBufferVariableTypeBlock (Context& context, tcu::TestCaseGroup* targetGroup)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glu::GLSL_VERSION_310_ES));
	const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	buffer			(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
	const ResourceDefinition::Node::SharedPtr	block			(new ResourceDefinition::InterfaceBlock(buffer, true));

	generateBufferVariableTypeCases(context, block, targetGroup);
}

static void generateBufferVariableRandomCase (Context& context, tcu::TestCaseGroup* const targetGroup, int index, bool onlyExtensionStages)
{
	de::Random									rnd					(index * 0x12345);
	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, onlyExtensionStages);
	const glu::DataType							type				= generateRandomDataType(rnd, true);
	const glu::Layout							layout				= generateRandomVariableLayout(rnd, type, true);
	const bool									namedBlock			= rnd.getBool();
	const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));
	const ResourceDefinition::Node::SharedPtr	buffer				(new ResourceDefinition::StorageQualifier(defaultBlock, glu::STORAGE_BUFFER));
	ResourceDefinition::Node::SharedPtr			currentStructure	(new ResourceDefinition::LayoutQualifier(buffer, generateRandomBufferBlockLayout(rnd)));

	if (namedBlock && rnd.getBool())
		currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::ArrayElement(currentStructure));
	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::InterfaceBlock(currentStructure, namedBlock));

	currentStructure = ResourceDefinition::Node::SharedPtr(new ResourceDefinition::LayoutQualifier(currentStructure, layout));
	currentStructure = generateRandomVariableDefinition(rnd, currentStructure, type, layout, true);

	targetGroup->addChild(new ResourceTestCase(context, currentStructure, ProgramResourceQueryTestTarget(PROGRAMINTERFACE_BUFFER_VARIABLE, PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK), de::toString(index).c_str()));
}

static void generateBufferVariableRandomCases (Context& context, tcu::TestCaseGroup* const targetGroup)
{
	const int numBasicCases		= 40;
	const int numTessGeoCases	= 40;

	for (int ndx = 0; ndx < numBasicCases; ++ndx)
		generateBufferVariableRandomCase(context, targetGroup, ndx, false);
	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
		generateBufferVariableRandomCase(context, targetGroup, numBasicCases + ndx, true);
}

class BufferVariableTestGroup : public TestCaseGroup
{
public:
			BufferVariableTestGroup	(Context& context);
	void	init								(void);
};

BufferVariableTestGroup::BufferVariableTestGroup (Context& context)
	: TestCaseGroup(context, "buffer_variable", "Buffer variable")
{
}

void BufferVariableTestGroup::init (void)
{
	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableResourceListBlockContentsProxy);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .array_stride
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
	}

	// .block_index
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
		addChild(blockGroup);
		generateBufferVariableBlockIndexCases(m_context, blockGroup);
	}

	// .is_row_major
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
		addChild(blockGroup);
		generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR>);
	}

	// .matrix_stride
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "matrix_stride", "Matrix stride");
		addChild(blockGroup);
		generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableNameLengthCases);
	}

	// .offset
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableOffsetCases);
	}

	// .referenced_by
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
		addChild(blockGroup);
		generateReferencedByShaderCaseBlocks(m_context, blockGroup, generateBufferVariableReferencedByBlockContents);
	}

	// .top_level_array_size
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_size", "Top-level array size");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE>);
	}

	// .top_level_array_stride
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "top_level_array_stride", "Top-level array stride");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
		addChild(blockGroup);
		generateBufferVariableTypeBlock(m_context, blockGroup);
	}

	// .random
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "random", "Random");
		addChild(blockGroup);
		generateBufferVariableRandomCases(m_context, blockGroup);
	}
}

} // anonymous

ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context)
	: TestCaseGroup(context, "program_interface_query", "Program interface query tests")
{
}

ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
{
}

void ProgramInterfaceQueryTests::init (void)
{
	// Misc queries

	// .buffer_limited_query
	{
		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");

		addChild(group);

		group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
		group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
	}

	// Interfaces

	// .uniform
	addChild(new UniformInterfaceTestGroup(m_context));

	// .uniform_block
	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));

	// .atomic_counter_buffer
	addChild(new AtomicCounterTestGroup(m_context));

	// .program_input
	addChild(new ProgramInputTestGroup(m_context));

	// .program_output
	addChild(new ProgramOutputTestGroup(m_context));

	// .transform_feedback_varying
	addChild(new TransformFeedbackVaryingTestGroup(m_context));

	// .buffer_variable
	addChild(new BufferVariableTestGroup(m_context));

	// .shader_storage_block
	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));
}

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