/*-------------------------------------------------------------------------
 * 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	getPresentMask		(void) 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::getPresentMask (void) const
{
	deUint32 mask = 0;
	for (deUint32 stage = 0; stage < glu::SHADERTYPE_LAST; ++stage)
	{
		if (m_stagePresent[stage])
			mask |= (1u << stage);
	}
	return mask;
}

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
