/*-------------------------------------------------------------------------
 * 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 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 supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

	if ((m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_CONTROL) || m_programDefinition->hasStage(glu::SHADERTYPE_TESSELLATION_EVALUATION)) &&
		!supportsES32 && !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) &&
		!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
	{
		throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
	}
	if (programContainsIOBlocks(m_programDefinition) &&
		!supportsES32 && !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)
	{
		// dummyZero is a uniform that may be added by
		// generateProgramInterfaceProgramSources.  Omit it here to avoid
		// confusion about the output.
		if (resourceList[ndx] != getDummyZeroUniformName())
			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 dummyZero,
			// mismatch causes errors otherwise.  dummyZero is a uniform that
			// may be added by generateProgramInterfaceProgramSources.
			if (deStringBeginsWith(resourceList[ndx].c_str(), "gl_") == DE_FALSE &&
				resourceList[ndx] != getDummyZeroUniformName())
			{
				m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource list contains unexpected resource name " << resourceList[ndx] << tcu::TestLog::EndMessage;
				error = true;
			}
			else
				m_testCtx.getLog() << tcu::TestLog::Message << "Note, resource list contains unknown built-in " << resourceList[ndx] << ". This variable is ignored." << tcu::TestLog::EndMessage;
		}
	}

	return !error;
}

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

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

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

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

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

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

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

	return !error;
}

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

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

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

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

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

	return true;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

				break;
			}

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

			default:
				break;
		}
	}

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

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

// Resouce property query case

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

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

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

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

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

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

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

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

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

	delete m_program;
	m_program = DE_NULL;

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

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

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

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

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

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

	DE_ASSERT(false);
	return "";
}

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

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

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

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

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

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

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

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

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

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

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

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

		DE_ASSERT(xfbDef->m_builtinVarName);

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

	DE_ASSERT(false);
	return DE_NULL;
}

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

private:
	IterateResult	iterate							(void);
};

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

ResourceNameBufferLimitCase::~ResourceNameBufferLimitCase (void)
{
}

ResourceNameBufferLimitCase::IterateResult ResourceNameBufferLimitCase::iterate (void)
{
	static const char* const computeSource =	"${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					supportsES32		= glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

	if ((m_presentStagesMask & tessellationMask) != 0 && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if ((m_presentStagesMask & geometryMask) != 0 && !supportsES32 && !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 bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

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

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

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

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

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

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

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

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

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

	return STOP;
}

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

		CASE_SEPARABLE_VERTEX,
		CASE_SEPARABLE_FRAGMENT,
		CASE_SEPARABLE_GEOMETRY,
		CASE_SEPARABLE_TESS_CTRL,
		CASE_SEPARABLE_TESS_EVAL,

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

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

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

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

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

void ProgramInputOutputReferencedByCase::init (void)
{
	const bool hasTessellationShader =	(m_caseType == CASE_VERTEX_TESS_FRAGMENT)		||
										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
										(m_caseType == CASE_SEPARABLE_TESS_CTRL)		||
										(m_caseType == CASE_SEPARABLE_TESS_EVAL);
	const bool hasGeometryShader =		(m_caseType == CASE_VERTEX_GEO_FRAGMENT)		||
										(m_caseType == CASE_VERTEX_TESS_GEO_FRAGMENT)	||
										(m_caseType == CASE_SEPARABLE_GEOMETRY);
	const bool supportsES32 =			glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

	if (hasTessellationShader && !supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
		throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
	if (hasGeometryShader && !supportsES32 && !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 dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

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

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

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

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

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

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

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

static void generateBufferBackedInterfaceResourceBufferBindingCases (Context& context, tcu::TestCaseGroup* targetGroup, glu::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 dummyVariable	(new ResourceDefinition::Variable(block, glu::TYPE_BOOL_VEC3));

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

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

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

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

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

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

	DE_UNREF(expandLevel);

	DE_ASSERT(programInterface != PROGRAMINTERFACE_LAST);

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

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

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

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

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

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

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

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

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

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

	const glu::Storage	m_storage;
};

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

void BufferBackedBlockInterfaceTestGroup::init (void)
{
	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, void (*blockContentGenerator)(Context&, const ResourceDefinition::Node::SharedPtr&, tcu::TestCaseGroup*, deUint32))
{
	static const struct
	{
		const char*		name;
		glu::ShaderType	stage;
	} singleStageCases[] =
	{
		{ "separable_vertex",		glu::SHADERTYPE_VERTEX					},
		{ "separable_fragment",		glu::SHADERTYPE_FRAGMENT				},
		{ "separable_tess_ctrl",	glu::SHADERTYPE_TESSELLATION_CONTROL	},
		{ "separable_tess_eval",	glu::SHADERTYPE_TESSELLATION_EVALUATION	},
		{ "separable_geometry",		glu::SHADERTYPE_GEOMETRY				},
	};

	// .vertex_fragment
	{
		tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "vertex_fragment", "Vertex and fragment");
		const ResourceDefinition::Node::SharedPtr	program			(new ResourceDefinition::Program(false));
		ResourceDefinition::ShaderSet*				shaderSetPtr	= new ResourceDefinition::ShaderSet(program, 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));
	}

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

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

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

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

				ioBlockGroup->addChild(blockGroup);

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

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

				ioBlockGroup->addChild(blockGroup);

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

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

				ioBlockGroup->addChild(blockGroup);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, structMember, blockGroup, true, expansionLevel);
		}
	}
	else if (lastStage == glu::SHADERTYPE_FRAGMENT)
	{
		// only basic type and basic type array (and no booleans or matrices)
		{
			tcu::TestCaseGroup* const blockGroup = new TestCaseGroup(context, "basic_type", "Basic types");
			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, output, blockGroup, false, 2);
		}
		{
			const ResourceDefinition::Node::SharedPtr	arrayElement	(new ResourceDefinition::ArrayElement(output));
			tcu::TestCaseGroup* const					blockGroup		= new TestCaseGroup(context, "array", "Array types");

			targetGroup->addChild(blockGroup);
			generateProgramInputOutputTypeBasicTypeCases<PROGRAMINTERFACE_PROGRAM_OUTPUT>(context, arrayElement, blockGroup, false, 2);
		}
	}
	else if (lastStage == glu::SHADERTYPE_TESSELLATION_CONTROL)
	{
		// arrayed interface
		const ResourceDefinition::Node::SharedPtr patchOutput(new ResourceDefinition::StorageQualifier(parentStructure, glu::STORAGE_PATCH_OUT));

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

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

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

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

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

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

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

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

void ProgramInputTestGroup::init (void)
{
	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, 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, 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, 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, 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, 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, generateProgramInputBasicBlockContents<PROGRAMRESOURCEPROP_IS_PER_PATCH>);
	}
}

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

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

void ProgramOutputTestGroup::init (void)
{
	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, 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, 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, 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, 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, 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, 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)
	: TestCaseGroup(context, "program_interface_query", "Program interface query tests")
{
}

ProgramInterfaceQueryTests::~ProgramInterfaceQueryTests (void)
{
}

void ProgramInterfaceQueryTests::init (void)
{
	// Misc queries

	// .buffer_limited_query
	{
		tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "buffer_limited_query", "Queries limited by the buffer size");

		addChild(group);

		group->addChild(new ResourceNameBufferLimitCase(m_context, "resource_name_query", "Test GetProgramResourceName with too small a buffer"));
		group->addChild(new ResourceQueryBufferLimitCase(m_context, "resource_query", "Test GetProgramResourceiv with too small a buffer"));
	}

	// Interfaces

	// .uniform
	addChild(new UniformInterfaceTestGroup(m_context));

	// .uniform_block
	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_UNIFORM));

	// .atomic_counter_buffer
	addChild(new AtomicCounterTestGroup(m_context));

	// .program_input
	addChild(new ProgramInputTestGroup(m_context));

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

	// .transform_feedback_varying
	addChild(new TransformFeedbackVaryingTestGroup(m_context));

	// .buffer_variable
	addChild(new BufferVariableTestGroup(m_context));

	// .shader_storage_block
	addChild(new BufferBackedBlockInterfaceTestGroup(m_context, glu::STORAGE_BUFFER));
}

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