/*-------------------------------------------------------------------------
 * 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 "tcuStringTemplate.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;
}

static bool checkSupport(Context& ctx)
{
	auto ctxType = ctx.getRenderContext().getType();
	return contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
		   contextSupports(ctxType, glu::ApiType::core(4, 5));
}

static std::string specializeShader(Context& context, const char* code)
{
	const glu::GLSLVersion				glslVersion			= glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
	std::map<std::string, std::string>	specializationMap;

	specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);

	return tcu::StringTemplate(code).specialize(specializationMap);
}

namespace ResourceDefinition
{

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

		TYPE_LAST
	};

	typedef de::SharedPtr<const Node> SharedPtr;

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

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

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

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

	const bool m_separable;
};

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

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

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

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

	const glu::Storage	m_storage;
};

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

	const glu::DataType	m_dataType;
};

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

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

	const bool	m_named;
};

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

	const int m_arraySize;

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

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

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

	const glu::Layout m_layout;
};

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

	const glu::Interpolation m_interpolation;
};

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

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

	deUint32	getReferencingMask	(void) const;

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

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

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

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

		DE_ASSERT(stagePresent || !stageReferencing);

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

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

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

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

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

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

	const char* const m_builtinVarName;
};

} // ResourceDefinition

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

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

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

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

		enum BindingType
		{
			BINDING_VARIABLE,
			BINDING_INTERFACE_BLOCK,
			BINDING_DEFAULT_BLOCK
		};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

				boundObject = BINDING_INTERFACE_BLOCK;

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

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

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

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

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

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

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

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

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

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

				program->setSeparable(programDef->m_separable);

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

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

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

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

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

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

		// empty default block

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

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

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

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

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

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

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

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

				DE_ASSERT(feedbackTarget->m_builtinVarName != DE_NULL);

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

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

	return program;
}

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

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

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

// Resource list query case

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

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

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

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

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

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

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

void ResourceListTestCase::init (void)
{
	m_programDefinition	= generateProgramDefinitionFromResource(m_targetResource.get()).release();
	const bool supportsES32orGL45 = checkSupport(m_context);

	if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
		!supportsES32orGL45 && !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) &&
		!supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
	{
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
	}
	if (programContainsIOBlocks(m_programDefinition) &&
		!supportsES32orGL45 && !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)
	{
		// unusedZero is a uniform that may be added by
		// generateProgramInterfaceProgramSources.  Omit it here to avoid
		// confusion about the output.
		if (resourceList[ndx] != getUnusedZeroUniformName())
			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 or the variable unusedZero,
			// mismatch causes errors otherwise.  unusedZero is a uniform that
			// may be added by generateProgramInterfaceProgramSources.
			if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
				resourceList[ndx] != getUnusedZeroUniformName())
			{
				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 "";
}

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 =	"${GLSL_VERSION_DECL}\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(specializeShader(m_context, 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 =	"${GLSL_VERSION_DECL}\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(specializeShader(m_context, 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)
{
	const glu::GLSLVersion				glslVersion	= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	ProgramInterfaceDefinition::Shader*	shader;

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

	// 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;
	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

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

	{
		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);
	const glu::GLSLVersion		glslVersion			= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	const bool					supportsES32orGL45	= checkSupport(m_context);

	if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32orGL45 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32orGL45 && !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, glslVersion)->getDefaultBlock().variables.push_back(atomicVar);
		else if (m_presentStagesMask & (1 << shaderType))
			m_program->addShader((glu::ShaderType)shaderType, glslVersion);
	}

	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)
{
	const glu::RenderContext& rc = m_context.getRenderContext();
	const bool isES32orGL45 = glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) ||
							  glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5));

	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,		(isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")	},
		{ GL_REFERENCED_BY_TESS_EVALUATION_SHADER,	glu::SHADERTYPE_TESSELLATION_EVALUATION,	(isES32orGL45 ? DE_NULL : "GL_EXT_tessellation_shader")	},
		{ GL_REFERENCED_BY_GEOMETRY_SHADER,			glu::SHADERTYPE_GEOMETRY,					(isES32orGL45 ? DE_NULL : "GL_EXT_geometry_shader")		},
	};

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

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	checkAndLogProgram(program, m_program, rc.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);
	const bool supportsES32orGL45 =		checkSupport(m_context);

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

	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	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, glslVersion)->getDefaultBlock().variables.push_back(targetDeclArr);
		}
		else
		{
			m_program->addShader(shaderType, glslVersion)->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, glslVersion);
		ProgramInterfaceDefinition::Shader*	fragment	= m_program->addShader(glu::SHADERTYPE_FRAGMENT, glslVersion);

		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, glslVersion);
			ProgramInterfaceDefinition::Shader* tessEval = m_program->addShader(glu::SHADERTYPE_TESSELLATION_EVALUATION, glslVersion);

			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, glslVersion);

			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, glu::GLSLVersion glslVersion)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
	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, glu::GLSLVersion glslVersion, 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, glslVersion));

		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,
																												glslVersion,
																												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,
																											glslVersion,
																											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, glu::GLSLVersion glslVersion)
{
	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, glslVersion));
	}
	else if (rnd.getFloat() < 0.5f)
	{
		// vertex and fragment
		const ResourceDefinition::Node::SharedPtr	program		(new ResourceDefinition::Program());
		ResourceDefinition::ShaderSet*				shaderSet	= new ResourceDefinition::ShaderSet(program, glslVersion);

		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, glslVersion));
	}
}

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

		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, glslVersion));
	}
}

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

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, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
{
	de::Random									rnd					(index * 0x12345);
	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, glslVersion, 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, glu::GLSLVersion glslVersion)
{
	const int numBasicCases		= 40;
	const int numTessGeoCases	= 40;

	for (int ndx = 0; ndx < numBasicCases; ++ndx)
		generateUniformRandomCase(context, targetGroup, glslVersion, ndx, false);
	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
		generateUniformRandomCase(context, targetGroup, glslVersion, 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)
{
	glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	computeShader	(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));

	// .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, glslVersion);
	}

	// .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, glslVersion, 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, glslVersion);
	}
}

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::GLSLVersion glslVersion, 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, glslVersion));
	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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

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

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

		blockContentGenerator(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		blockContentGenerator(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

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

static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, glu::Storage storage)
{
	const ResourceDefinition::Node::SharedPtr	program				(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader				(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
	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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

			targetGroup->addChild(new ResourceTestCase(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

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

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

		targetGroup->addChild(new ResourceTestCase(context, unusedVariable, 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 unusedVariable(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

		targetGroup->addChild(new ResourceTestCase(context, unusedVariable, 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)
{
	const glu::GLSLVersion	glslVersion	= glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateBufferBackedInterfaceResourceBasicBlockTypes(m_context, blockGroup, glslVersion, 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, glslVersion, 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, glslVersion, 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, glslVersion, generateBufferBlockReferencedByShaderSingleBlockContentCases<glu::STORAGE_UNIFORM>);
		else if (m_storage == glu::STORAGE_BUFFER)
			generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, 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_FATAL("invalid storage enum value");
			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_FATAL("invalid storage enum value");
			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, glu::GLSLVersion glslVersion, bool withCompute, bool inputCase, bool isGL45, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32, bool))
{
	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, glslVersion);
		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), isGL45);
	}

	// .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, glslVersion));
		const ResourceDefinition::Node::SharedPtr	defaultBlock		(new ResourceDefinition::DefaultBlock(shader));

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

	// .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, glslVersion));
		const ResourceDefinition::Node::SharedPtr	defaultBlock	(new ResourceDefinition::DefaultBlock(shader));

		targetGroup->addChild(blockGroup);

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

	// .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, glslVersion));
			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), isGL45);
			}

			// .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), isGL45);
			}

			// .unnamed_block
			if (!isGL45)
			{
				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), isGL45);
			}

			// .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), isGL45);
			}
		}
	}
}

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, bool isGL45)
{
	DE_UNREF(isGL45);
	generateProgramInputBlockContents(context, parentStructure, targetGroup, presentShadersMask, true, addProgramInputOutputResourceListCase);
}

static void generateProgramOutputResourceListBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
{
	DE_UNREF(isGL45);
	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, bool isGL45)
{
	DE_UNREF(isGL45);
	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, bool isGL45)
{
	DE_UNREF(isGL45);
	generateProgramOutputBlockContents(context, parentStructure, targetGroup, presentShadersMask, false, addProgramInputOutputResourceTestCase<TargetProp>);
}

static void generateProgramInputLocationBlockContents (Context& context, const ResourceDefinition::Node::SharedPtr& parentStructure, tcu::TestCaseGroup* targetGroup, deUint32 presentShadersMask, bool isGL45)
{
	DE_UNREF(isGL45);
	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 bool									inBlockArray	= DE_TRUE == deStringEqual("block_array", targetGroup->getName());

	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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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, bool isGL45)
{
	DE_UNREF(isGL45);
	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 bool									inBlockArray	= DE_TRUE == deStringEqual("block_array", targetGroup->getName());

	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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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
		if (!inBlockArray)
		{
			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, bool isGL45)
{
	DE_UNREF(isGL45);
	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, bool isGL45)
{
	DE_UNREF(isGL45);
	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, bool is_GL45);
	void	init					(void);

private:
	bool m_isGL45;
};

ProgramInputTestGroup::ProgramInputTestGroup (Context& context, bool is_GL45)
	: TestCaseGroup(context, "program_input", "Program input")
	, m_isGL45(is_GL45)
{
}

void ProgramInputTestGroup::init (void)
{
	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, true, m_isGL45, generateProgramInputResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .location
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, generateProgramInputLocationBlockContents);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, true, m_isGL45, 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, glslVersion, false, true, m_isGL45, 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, glslVersion, false, true, m_isGL45, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
	}
}

class ProgramOutputTestGroup : public TestCaseGroup
{
public:
			ProgramOutputTestGroup	(Context& context, bool is_GL45);
	void	init					(void);

private:
	bool m_isGL45;
};

ProgramOutputTestGroup::ProgramOutputTestGroup (Context& context, bool is_GL45)
	: TestCaseGroup(context, "program_output", "Program output")
	, m_isGL45(is_GL45)
{
}

void ProgramOutputTestGroup::init (void)
{
	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "resource_list", "Resource list");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, true, false, m_isGL45, generateProgramOutputResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "array_size", "Array size");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .location
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "location", "Location");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, generateProgramOutputLocationBlockContents);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new tcu::TestCaseGroup(m_testCtx, "name_length", "Name length");
		addChild(blockGroup);
		generateProgramInputOutputShaderCaseBlocks(m_context, blockGroup, glslVersion, false, false, m_isGL45, 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, glslVersion, false, false, m_isGL45, 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, glslVersion, false, false, m_isGL45, generateProgramOutputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
	}
}

static void generateTransformFeedbackShaderCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, 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,
																									   glslVersion,
																									   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, glslVersion));

		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)
{
	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackResourceListBlockContents);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableBlockContents<PROGRAMRESOURCEPROP_NAME_LENGTH>);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
		addChild(blockGroup);
		generateTransformFeedbackShaderCaseBlocks(m_context, blockGroup, glslVersion, generateTransformFeedbackVariableTypeBlockContents);
	}
}

static void generateBufferVariableBufferCaseBlocks (Context& context, tcu::TestCaseGroup* targetGroup, glu::GLSLVersion glslVersion, 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, glslVersion));
	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, glu::GLSLVersion glslVersion, tcu::TestCaseGroup* const targetGroup)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
	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, glu::GLSLVersion glslVersion, 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, glslVersion));
	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, glu::GLSLVersion glslVersion)
{
	const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program());
	const ResourceDefinition::Node::SharedPtr	shader			(new ResourceDefinition::Shader(program, glu::SHADERTYPE_COMPUTE, glslVersion));
	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, glu::GLSLVersion glslVersion, int index, bool onlyExtensionStages)
{
	de::Random									rnd					(index * 0x12345);
	const ResourceDefinition::Node::SharedPtr	shader				= generateRandomShaderSet(rnd, glslVersion, 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, glu::GLSLVersion glslVersion)
{
	const int numBasicCases		= 40;
	const int numTessGeoCases	= 40;

	for (int ndx = 0; ndx < numBasicCases; ++ndx)
		generateBufferVariableRandomCase(context, targetGroup, glslVersion, ndx, false);
	for (int ndx = 0; ndx < numTessGeoCases; ++ndx)
		generateBufferVariableRandomCase(context, targetGroup, glslVersion, 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)
{
	const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(m_context.getRenderContext().getType());

	// .resource_list
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "resource_list", "Resource list");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableResourceListBlockContentsProxy);
	}

	// .array_size
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_size", "Array size");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_SIZE>);
	}

	// .array_stride
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "array_stride", "Array stride");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableArrayCases<PROGRAMRESOURCEPROP_ARRAY_STRIDE>);
	}

	// .block_index
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "block_index", "Block index");
		addChild(blockGroup);
		generateBufferVariableBlockIndexCases(m_context, glslVersion, blockGroup);
	}

	// .is_row_major
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "is_row_major", "Is row major");
		addChild(blockGroup);
		generateBufferVariableMatrixCaseBlocks(m_context, blockGroup, glslVersion, 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, glslVersion, generateBufferVariableMatrixCases<PROGRAMRESOURCEPROP_MATRIX_STRIDE>);
	}

	// .name_length
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "name_length", "Name length");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableNameLengthCases);
	}

	// .offset
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "offset", "Offset");
		addChild(blockGroup);
		generateBufferVariableBufferCaseBlocks(m_context, blockGroup, glslVersion, generateBufferVariableOffsetCases);
	}

	// .referenced_by
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "referenced_by", "Referenced by");
		addChild(blockGroup);
		generateReferencedByShaderCaseBlocks(m_context, blockGroup, glslVersion, 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, glslVersion, 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, glslVersion, generateBufferVariableTopLevelCases<PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE>);
	}

	// .type
	{
		tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(m_context, "type", "Type");
		addChild(blockGroup);
		generateBufferVariableTypeBlock(m_context, blockGroup, glslVersion);
	}

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

} // anonymous

ProgramInterfaceQueryTests::ProgramInterfaceQueryTests (Context& context, bool is_GL45)
	: TestCaseGroup(context, "program_interface_query", "Program interface query tests")
	, m_isGL45 (is_GL45)
{
}

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, m_isGL45));

	// .program_output
	addChild(new ProgramOutputTestGroup(m_context, m_isGL45));

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