/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 Google Inc.
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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 Uniform block case.
 */ /*-------------------------------------------------------------------*/

#include "glcUniformBlockCase.hpp"
#include "deInt32.h"
#include "deMemory.h"
#include "deRandom.hpp"
#include "deString.h"
#include "deStringUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluDrawUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluRenderContext.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"

#include <algorithm>
#include <map>

using tcu::TestLog;
using std::string;
using std::vector;
using std::map;

namespace deqp
{
namespace ub
{

struct PrecisionFlagsFmt
{
	deUint32 flags;

	PrecisionFlagsFmt(deUint32 flags_) : flags(flags_)
	{
	}
};

std::ostream& operator<<(std::ostream& str, const PrecisionFlagsFmt& fmt)
{
	// Precision.
	DE_ASSERT(dePop32(fmt.flags & (PRECISION_LOW | PRECISION_MEDIUM | PRECISION_HIGH)) <= 1);
	str << (fmt.flags & PRECISION_LOW ?
				"lowp" :
				fmt.flags & PRECISION_MEDIUM ? "mediump" : fmt.flags & PRECISION_HIGH ? "highp" : "");
	return str;
}

struct LayoutFlagsFmt
{
	deUint32 flags;
	LayoutFlagsFmt(deUint32 flags_) : flags(flags_)
	{
	}
};

std::ostream& operator<<(std::ostream& str, const LayoutFlagsFmt& fmt)
{
	static const struct
	{
		deUint32	bit;
		const char* token;
	} bitDesc[] = { { LAYOUT_SHARED, "shared" },
					{ LAYOUT_PACKED, "packed" },
					{ LAYOUT_STD140, "std140" },
					{ LAYOUT_ROW_MAJOR, "row_major" },
					{ LAYOUT_COLUMN_MAJOR, "column_major" } };

	deUint32 remBits = fmt.flags;
	for (int descNdx = 0; descNdx < DE_LENGTH_OF_ARRAY(bitDesc); descNdx++)
	{
		if (remBits & bitDesc[descNdx].bit)
		{
			if (remBits != fmt.flags)
				str << ", ";
			str << bitDesc[descNdx].token;
			remBits &= ~bitDesc[descNdx].bit;
		}
	}
	DE_ASSERT(remBits == 0);
	return str;
}

// VarType implementation.

VarType::VarType(void) : m_type(TYPE_LAST), m_flags(0)
{
}

VarType::VarType(const VarType& other) : m_type(TYPE_LAST), m_flags(0)
{
	*this = other;
}

VarType::VarType(glu::DataType basicType, deUint32 flags) : m_type(TYPE_BASIC), m_flags(flags)
{
	m_data.basicType = basicType;
}

VarType::VarType(const VarType& elementType, int arraySize) : m_type(TYPE_ARRAY), m_flags(0)
{
	m_data.array.size		 = arraySize;
	m_data.array.elementType = new VarType(elementType);
}

VarType::VarType(const StructType* structPtr) : m_type(TYPE_STRUCT), m_flags(0)
{
	m_data.structPtr = structPtr;
}

VarType::~VarType(void)
{
	if (m_type == TYPE_ARRAY)
		delete m_data.array.elementType;
}

VarType& VarType::operator=(const VarType& other)
{
	if (this == &other)
		return *this; // Self-assignment.

	if (m_type == TYPE_ARRAY)
		delete m_data.array.elementType;

	m_type  = other.m_type;
	m_flags = other.m_flags;
	m_data  = Data();

	if (m_type == TYPE_ARRAY)
	{
		m_data.array.elementType = new VarType(*other.m_data.array.elementType);
		m_data.array.size		 = other.m_data.array.size;
	}
	else
		m_data = other.m_data;

	return *this;
}

// StructType implementation.

void StructType::addMember(const char* name, const VarType& type, deUint32 flags)
{
	m_members.push_back(StructMember(name, type, flags));
}

// Uniform implementation.

Uniform::Uniform(const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags)
{
}

// UniformBlock implementation.

UniformBlock::UniformBlock(const char* blockName) : m_blockName(blockName), m_arraySize(0), m_flags(0)
{
}

struct BlockLayoutEntry
{
	BlockLayoutEntry(void) : size(0)
	{
	}

	std::string		 name;
	int				 size;
	std::vector<int> activeUniformIndices;
};

std::ostream& operator<<(std::ostream& stream, const BlockLayoutEntry& entry)
{
	stream << entry.name << " { name = " << entry.name << ", size = " << entry.size << ", activeUniformIndices = [";

	for (vector<int>::const_iterator i = entry.activeUniformIndices.begin(); i != entry.activeUniformIndices.end(); i++)
	{
		if (i != entry.activeUniformIndices.begin())
			stream << ", ";
		stream << *i;
	}

	stream << "] }";
	return stream;
}

struct UniformLayoutEntry
{
	UniformLayoutEntry(void)
		: type(glu::TYPE_LAST), size(0), blockNdx(-1), offset(-1), arrayStride(-1), matrixStride(-1), isRowMajor(false)
	{
	}

	std::string   name;
	glu::DataType type;
	int			  size;
	int			  blockNdx;
	int			  offset;
	int			  arrayStride;
	int			  matrixStride;
	bool		  isRowMajor;
};

std::ostream& operator<<(std::ostream& stream, const UniformLayoutEntry& entry)
{
	stream << entry.name << " { type = " << glu::getDataTypeName(entry.type) << ", size = " << entry.size
		   << ", blockNdx = " << entry.blockNdx << ", offset = " << entry.offset
		   << ", arrayStride = " << entry.arrayStride << ", matrixStride = " << entry.matrixStride
		   << ", isRowMajor = " << (entry.isRowMajor ? "true" : "false") << " }";
	return stream;
}

class UniformLayout
{
public:
	std::vector<BlockLayoutEntry>   blocks;
	std::vector<UniformLayoutEntry> uniforms;

	int getUniformIndex(const char* name) const;
	int getBlockIndex(const char* name) const;
};

// \todo [2012-01-24 pyry] Speed up lookups using hash.

int UniformLayout::getUniformIndex(const char* name) const
{
	for (int ndx = 0; ndx < (int)uniforms.size(); ndx++)
	{
		if (uniforms[ndx].name == name)
			return ndx;
	}
	return -1;
}

int UniformLayout::getBlockIndex(const char* name) const
{
	for (int ndx = 0; ndx < (int)blocks.size(); ndx++)
	{
		if (blocks[ndx].name == name)
			return ndx;
	}
	return -1;
}

// ShaderInterface implementation.

ShaderInterface::ShaderInterface(void)
{
}

ShaderInterface::~ShaderInterface(void)
{
	for (std::vector<StructType*>::iterator i = m_structs.begin(); i != m_structs.end(); i++)
		delete *i;

	for (std::vector<UniformBlock*>::iterator i = m_uniformBlocks.begin(); i != m_uniformBlocks.end(); i++)
		delete *i;
}

StructType& ShaderInterface::allocStruct(const char* name)
{
	m_structs.reserve(m_structs.size() + 1);
	m_structs.push_back(new StructType(name));
	return *m_structs.back();
}

struct StructNameEquals
{
	std::string name;

	StructNameEquals(const char* name_) : name(name_)
	{
	}

	bool operator()(const StructType* type) const
	{
		return type->getTypeName() && name == type->getTypeName();
	}
};

const StructType* ShaderInterface::findStruct(const char* name) const
{
	std::vector<StructType*>::const_iterator pos =
		std::find_if(m_structs.begin(), m_structs.end(), StructNameEquals(name));
	return pos != m_structs.end() ? *pos : DE_NULL;
}

void ShaderInterface::getNamedStructs(std::vector<const StructType*>& structs) const
{
	for (std::vector<StructType*>::const_iterator i = m_structs.begin(); i != m_structs.end(); i++)
	{
		if ((*i)->getTypeName() != DE_NULL)
			structs.push_back(*i);
	}
}

UniformBlock& ShaderInterface::allocBlock(const char* name)
{
	m_uniformBlocks.reserve(m_uniformBlocks.size() + 1);
	m_uniformBlocks.push_back(new UniformBlock(name));
	return *m_uniformBlocks.back();
}

namespace // Utilities
{

// Layout computation.

int getDataTypeByteSize(glu::DataType type)
{
	return static_cast<int>(glu::getDataTypeScalarSize(type) * sizeof(deUint32));
}

int getDataTypeByteAlignment(glu::DataType type)
{
	switch (type)
	{
	case glu::TYPE_FLOAT:
	case glu::TYPE_INT:
	case glu::TYPE_UINT:
	case glu::TYPE_BOOL:
		return static_cast<int>(1 * sizeof(deUint32));

	case glu::TYPE_FLOAT_VEC2:
	case glu::TYPE_INT_VEC2:
	case glu::TYPE_UINT_VEC2:
	case glu::TYPE_BOOL_VEC2:
		return static_cast<int>(2 * sizeof(deUint32));

	case glu::TYPE_FLOAT_VEC3:
	case glu::TYPE_INT_VEC3:
	case glu::TYPE_UINT_VEC3:
	case glu::TYPE_BOOL_VEC3: // Fall-through to vec4

	case glu::TYPE_FLOAT_VEC4:
	case glu::TYPE_INT_VEC4:
	case glu::TYPE_UINT_VEC4:
	case glu::TYPE_BOOL_VEC4:
		return static_cast<int>(4 * sizeof(deUint32));

	default:
		DE_ASSERT(false);
		return 0;
	}
}

int getDataTypeArrayStride(glu::DataType type)
{
	DE_ASSERT(!glu::isDataTypeMatrix(type));

	int baseStride	= getDataTypeByteSize(type);
	int vec4Alignment = static_cast<int>(sizeof(deUint32) * 4);

	DE_ASSERT(baseStride <= vec4Alignment);
	return de::max(baseStride, vec4Alignment); // Really? See rule 4.
}

int computeStd140BaseAlignment(const VarType& type)
{
	const int vec4Alignment = static_cast<int>(sizeof(deUint32) * 4);

	if (type.isBasicType())
	{
		glu::DataType basicType = type.getBasicType();

		if (glu::isDataTypeMatrix(basicType))
		{
			bool isRowMajor = !!(type.getFlags() & LAYOUT_ROW_MAJOR);
			int  vecSize =
				isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) : glu::getDataTypeMatrixNumRows(basicType);

			return getDataTypeArrayStride(glu::getDataTypeFloatVec(vecSize));
		}
		else
			return getDataTypeByteAlignment(basicType);
	}
	else if (type.isArrayType())
	{
		int elemAlignment = computeStd140BaseAlignment(type.getElementType());

		// Round up to alignment of vec4
		return deRoundUp32(elemAlignment, vec4Alignment);
	}
	else
	{
		DE_ASSERT(type.isStructType());

		int maxBaseAlignment = 0;

		for (StructType::ConstIterator memberIter = type.getStruct().begin(); memberIter != type.getStruct().end();
			 memberIter++)
			maxBaseAlignment = de::max(maxBaseAlignment, computeStd140BaseAlignment(memberIter->getType()));

		return deRoundUp32(maxBaseAlignment, vec4Alignment);
	}
}

inline deUint32 mergeLayoutFlags(deUint32 prevFlags, deUint32 newFlags)
{
	const deUint32 packingMask = LAYOUT_PACKED | LAYOUT_SHARED | LAYOUT_STD140;
	const deUint32 matrixMask  = LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR;

	deUint32 mergedFlags = 0;

	mergedFlags |= ((newFlags & packingMask) ? newFlags : prevFlags) & packingMask;
	mergedFlags |= ((newFlags & matrixMask) ? newFlags : prevFlags) & matrixMask;

	return mergedFlags;
}

void computeStd140Layout(UniformLayout& layout, int& curOffset, int curBlockNdx, const std::string& curPrefix,
						 const VarType& type, deUint32 layoutFlags)
{
	int baseAlignment = computeStd140BaseAlignment(type);

	curOffset = deAlign32(curOffset, baseAlignment);

	if (type.isBasicType())
	{
		glu::DataType	  basicType = type.getBasicType();
		UniformLayoutEntry entry;

		entry.name		   = curPrefix;
		entry.type		   = basicType;
		entry.size		   = 1;
		entry.arrayStride  = 0;
		entry.matrixStride = 0;
		entry.blockNdx	 = curBlockNdx;

		if (glu::isDataTypeMatrix(basicType))
		{
			// Array of vectors as specified in rules 5 & 7.
			bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR);
			int  vecSize =
				isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) : glu::getDataTypeMatrixNumRows(basicType);
			int numVecs =
				isRowMajor ? glu::getDataTypeMatrixNumRows(basicType) : glu::getDataTypeMatrixNumColumns(basicType);
			int stride = getDataTypeArrayStride(glu::getDataTypeFloatVec(vecSize));

			entry.offset	   = curOffset;
			entry.matrixStride = stride;
			entry.isRowMajor   = isRowMajor;

			curOffset += numVecs * stride;
		}
		else
		{
			// Scalar or vector.
			entry.offset = curOffset;

			curOffset += getDataTypeByteSize(basicType);
		}

		layout.uniforms.push_back(entry);
	}
	else if (type.isArrayType())
	{
		const VarType& elemType = type.getElementType();

		if (elemType.isBasicType() && !glu::isDataTypeMatrix(elemType.getBasicType()))
		{
			// Array of scalars or vectors.
			glu::DataType	  elemBasicType = elemType.getBasicType();
			UniformLayoutEntry entry;
			int				   stride = getDataTypeArrayStride(elemBasicType);

			entry.name		   = curPrefix + "[0]"; // Array uniforms are always postfixed with [0]
			entry.type		   = elemBasicType;
			entry.blockNdx	 = curBlockNdx;
			entry.offset	   = curOffset;
			entry.size		   = type.getArraySize();
			entry.arrayStride  = stride;
			entry.matrixStride = 0;

			curOffset += stride * type.getArraySize();

			layout.uniforms.push_back(entry);
		}
		else if (elemType.isBasicType() && glu::isDataTypeMatrix(elemType.getBasicType()))
		{
			// Array of matrices.
			glu::DataType elemBasicType = elemType.getBasicType();
			bool		  isRowMajor	= !!(layoutFlags & LAYOUT_ROW_MAJOR);
			int			  vecSize		= isRowMajor ? glu::getDataTypeMatrixNumColumns(elemBasicType) :
									   glu::getDataTypeMatrixNumRows(elemBasicType);
			int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(elemBasicType) :
									   glu::getDataTypeMatrixNumColumns(elemBasicType);
			int				   stride = getDataTypeArrayStride(glu::getDataTypeFloatVec(vecSize));
			UniformLayoutEntry entry;

			entry.name		   = curPrefix + "[0]"; // Array uniforms are always postfixed with [0]
			entry.type		   = elemBasicType;
			entry.blockNdx	 = curBlockNdx;
			entry.offset	   = curOffset;
			entry.size		   = type.getArraySize();
			entry.arrayStride  = stride * numVecs;
			entry.matrixStride = stride;
			entry.isRowMajor   = isRowMajor;

			curOffset += numVecs * type.getArraySize() * stride;

			layout.uniforms.push_back(entry);
		}
		else
		{
			DE_ASSERT(elemType.isStructType() || elemType.isArrayType());

			for (int elemNdx = 0; elemNdx < type.getArraySize(); elemNdx++)
				computeStd140Layout(layout, curOffset, curBlockNdx, curPrefix + "[" + de::toString(elemNdx) + "]",
									type.getElementType(), layoutFlags);
		}
	}
	else
	{
		DE_ASSERT(type.isStructType());

		for (StructType::ConstIterator memberIter = type.getStruct().begin(); memberIter != type.getStruct().end();
			 memberIter++)
			computeStd140Layout(layout, curOffset, curBlockNdx, curPrefix + "." + memberIter->getName(),
								memberIter->getType(), layoutFlags);

		curOffset = deAlign32(curOffset, baseAlignment);
	}
}

void computeStd140Layout(UniformLayout& layout, const ShaderInterface& interface)
{
	// \todo [2012-01-23 pyry] Uniforms in default block.

	int numUniformBlocks = interface.getNumUniformBlocks();

	for (int blockNdx = 0; blockNdx < numUniformBlocks; blockNdx++)
	{
		const UniformBlock& block			= interface.getUniformBlock(blockNdx);
		bool				hasInstanceName = block.getInstanceName() != DE_NULL;
		std::string			blockPrefix = hasInstanceName ? (std::string(block.getBlockName()) + ".") : std::string("");
		int					curOffset   = 0;
		int					activeBlockNdx  = (int)layout.blocks.size();
		int					firstUniformNdx = (int)layout.uniforms.size();

		for (UniformBlock::ConstIterator uniformIter = block.begin(); uniformIter != block.end(); uniformIter++)
		{
			const Uniform& uniform = *uniformIter;
			computeStd140Layout(layout, curOffset, activeBlockNdx, blockPrefix + uniform.getName(), uniform.getType(),
								mergeLayoutFlags(block.getFlags(), uniform.getFlags()));
		}

		int uniformIndicesEnd = (int)layout.uniforms.size();
		int blockSize		  = curOffset;
		int numInstances	  = block.isArray() ? block.getArraySize() : 1;

		// Create block layout entries for each instance.
		for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
		{
			// Allocate entry for instance.
			layout.blocks.push_back(BlockLayoutEntry());
			BlockLayoutEntry& blockEntry = layout.blocks.back();

			blockEntry.name = block.getBlockName();
			blockEntry.size = blockSize;

			// Compute active uniform set for block.
			for (int uniformNdx = firstUniformNdx; uniformNdx < uniformIndicesEnd; uniformNdx++)
				blockEntry.activeUniformIndices.push_back(uniformNdx);

			if (block.isArray())
				blockEntry.name += "[" + de::toString(instanceNdx) + "]";
		}
	}
}

// Value generator.

void generateValue(const UniformLayoutEntry& entry, void* basePtr, de::Random& rnd)
{
	glu::DataType scalarType = glu::getDataTypeScalarType(entry.type);
	int			  scalarSize = glu::getDataTypeScalarSize(entry.type);
	bool		  isMatrix   = glu::isDataTypeMatrix(entry.type);
	int			  numVecs	= isMatrix ? (entry.isRowMajor ? glu::getDataTypeMatrixNumRows(entry.type) :
												 glu::getDataTypeMatrixNumColumns(entry.type)) :
							 1;
	int		  vecSize  = scalarSize / numVecs;
	bool	  isArray  = entry.size > 1;
	const int compSize = sizeof(deUint32);

	DE_ASSERT(scalarSize % numVecs == 0);

	for (int elemNdx = 0; elemNdx < entry.size; elemNdx++)
	{
		deUint8* elemPtr = (deUint8*)basePtr + entry.offset + (isArray ? elemNdx * entry.arrayStride : 0);

		for (int vecNdx = 0; vecNdx < numVecs; vecNdx++)
		{
			deUint8* vecPtr = elemPtr + (isMatrix ? vecNdx * entry.matrixStride : 0);

			for (int compNdx = 0; compNdx < vecSize; compNdx++)
			{
				deUint8* compPtr = vecPtr + compSize * compNdx;

				switch (scalarType)
				{
				case glu::TYPE_FLOAT:
					*((float*)compPtr) = (float)rnd.getInt(-9, 9);
					break;
				case glu::TYPE_INT:
					*((int*)compPtr) = rnd.getInt(-9, 9);
					break;
				case glu::TYPE_UINT:
					*((deUint32*)compPtr) = (deUint32)rnd.getInt(0, 9);
					break;
				// \note Random bit pattern is used for true values. Spec states that all non-zero values are
				//       interpreted as true but some implementations fail this.
				case glu::TYPE_BOOL:
					*((deUint32*)compPtr) = rnd.getBool() ? rnd.getUint32() | 1u : 0u;
					break;
				default:
					DE_ASSERT(false);
				}
			}
		}
	}
}

void generateValues(const UniformLayout& layout, const std::map<int, void*>& blockPointers, deUint32 seed)
{
	de::Random rnd(seed);
	int		   numBlocks = (int)layout.blocks.size();

	for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
	{
		void* basePtr	= blockPointers.find(blockNdx)->second;
		int   numEntries = (int)layout.blocks[blockNdx].activeUniformIndices.size();

		for (int entryNdx = 0; entryNdx < numEntries; entryNdx++)
		{
			const UniformLayoutEntry& entry = layout.uniforms[layout.blocks[blockNdx].activeUniformIndices[entryNdx]];
			generateValue(entry, basePtr, rnd);
		}
	}
}

// Shader generator.

static const char* s_compareFuncs =
	"mediump float compare_float    (highp float a, highp float b)  { return abs(a - b) < 0.05 ? 1.0 : 0.0; }\n"
	"mediump float compare_vec2     (highp vec2 a, highp vec2 b)    { return compare_float(a.x, "
	"b.x)*compare_float(a.y, b.y); }\n"
	"mediump float compare_vec3     (highp vec3 a, highp vec3 b)    { return compare_float(a.x, "
	"b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }\n"
	"mediump float compare_vec4     (highp vec4 a, highp vec4 b)    { return compare_float(a.x, "
	"b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }\n"
	"mediump float compare_mat2     (highp mat2 a, highp mat2 b)    { return compare_vec2(a[0], "
	"b[0])*compare_vec2(a[1], b[1]); }\n"
	"mediump float compare_mat2x3   (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], "
	"b[0])*compare_vec3(a[1], b[1]); }\n"
	"mediump float compare_mat2x4   (highp mat2x4 a, highp mat2x4 b){ return compare_vec4(a[0], "
	"b[0])*compare_vec4(a[1], b[1]); }\n"
	"mediump float compare_mat3x2   (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], "
	"b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }\n"
	"mediump float compare_mat3     (highp mat3 a, highp mat3 b)    { return compare_vec3(a[0], "
	"b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }\n"
	"mediump float compare_mat3x4   (highp mat3x4 a, highp mat3x4 b){ return compare_vec4(a[0], "
	"b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }\n"
	"mediump float compare_mat4x2   (highp mat4x2 a, highp mat4x2 b){ return compare_vec2(a[0], "
	"b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }\n"
	"mediump float compare_mat4x3   (highp mat4x3 a, highp mat4x3 b){ return compare_vec3(a[0], "
	"b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }\n"
	"mediump float compare_mat4     (highp mat4 a, highp mat4 b)    { return compare_vec4(a[0], "
	"b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }\n"
	"mediump float compare_int      (highp int a, highp int b)      { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_ivec2    (highp ivec2 a, highp ivec2 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_ivec3    (highp ivec3 a, highp ivec3 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_ivec4    (highp ivec4 a, highp ivec4 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_uint     (highp uint a, highp uint b)    { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_uvec2    (highp uvec2 a, highp uvec2 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_uvec3    (highp uvec3 a, highp uvec3 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_uvec4    (highp uvec4 a, highp uvec4 b)  { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_bool     (bool a, bool b)                { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_bvec2    (bvec2 a, bvec2 b)              { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_bvec3    (bvec3 a, bvec3 b)              { return a == b ? 1.0 : 0.0; }\n"
	"mediump float compare_bvec4    (bvec4 a, bvec4 b)              { return a == b ? 1.0 : 0.0; }\n";

struct Indent
{
	int level;

	Indent(int level_) : level(level_)
	{
	}
};

std::ostream& operator<<(std::ostream& str, const Indent& indent)
{
	for (int i = 0; i < indent.level; i++)
		str << "\t";
	return str;
}

void generateDeclaration(std::ostringstream& src, const VarType& type, const char* name, int indentLevel,
						 deUint32 unusedHints);
void generateDeclaration(std::ostringstream& src, const Uniform& uniform, int indentLevel);
void generateDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel);

void generateLocalDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel);
void generateFullDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel);

void generateDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel)
{
	DE_ASSERT(structType.getTypeName() != DE_NULL);
	generateFullDeclaration(src, structType, indentLevel);
	src << ";\n";
}

void generateFullDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel)
{
	src << "struct";
	if (structType.getTypeName())
		src << " " << structType.getTypeName();
	src << "\n" << Indent(indentLevel) << "{\n";

	for (StructType::ConstIterator memberIter = structType.begin(); memberIter != structType.end(); memberIter++)
	{
		src << Indent(indentLevel + 1);
		generateDeclaration(src, memberIter->getType(), memberIter->getName(), indentLevel + 1,
							memberIter->getFlags() & UNUSED_BOTH);
	}

	src << Indent(indentLevel) << "}";
}

void generateLocalDeclaration(std::ostringstream& src, const StructType& structType, int indentLevel)
{
	if (structType.getTypeName() == DE_NULL)
		generateFullDeclaration(src, structType, indentLevel);
	else
		src << structType.getTypeName();
}

void generateDeclaration(std::ostringstream& src, const VarType& type, const char* name, int indentLevel,
						 deUint32 unusedHints)
{
	deUint32 flags = type.getFlags();

	if ((flags & LAYOUT_MASK) != 0)
		src << "layout(" << LayoutFlagsFmt(flags & LAYOUT_MASK) << ") ";

	if ((flags & PRECISION_MASK) != 0)
		src << PrecisionFlagsFmt(flags & PRECISION_MASK) << " ";

	if (type.isBasicType())
		src << glu::getDataTypeName(type.getBasicType()) << " " << name;
	else if (type.isArrayType())
	{
		std::vector<int> arraySizes;
		const VarType*   curType = &type;
		while (curType->isArrayType())
		{
			arraySizes.push_back(curType->getArraySize());
			curType = &curType->getElementType();
		}

		if (curType->isBasicType())
		{
			if ((curType->getFlags() & PRECISION_MASK) != 0)
				src << PrecisionFlagsFmt(curType->getFlags() & PRECISION_MASK) << " ";
			src << glu::getDataTypeName(curType->getBasicType());
		}
		else
		{
			DE_ASSERT(curType->isStructType());
			generateLocalDeclaration(src, curType->getStruct(), indentLevel + 1);
		}

		src << " " << name;

		for (std::vector<int>::const_reverse_iterator sizeIter = arraySizes.rbegin(); sizeIter != arraySizes.rend();
			 sizeIter++)
			src << "[" << *sizeIter << "]";
	}
	else
	{
		generateLocalDeclaration(src, type.getStruct(), indentLevel + 1);
		src << " " << name;
	}

	src << ";";

	// Print out unused hints.
	if (unusedHints != 0)
		src << " // unused in "
			<< (unusedHints == UNUSED_BOTH ?
					"both shaders" :
					unusedHints == UNUSED_VERTEX ? "vertex shader" :
												   unusedHints == UNUSED_FRAGMENT ? "fragment shader" : "???");

	src << "\n";
}

void generateDeclaration(std::ostringstream& src, const Uniform& uniform, int indentLevel)
{
	if ((uniform.getFlags() & LAYOUT_MASK) != 0)
		src << "layout(" << LayoutFlagsFmt(uniform.getFlags() & LAYOUT_MASK) << ") ";

	generateDeclaration(src, uniform.getType(), uniform.getName(), indentLevel, uniform.getFlags() & UNUSED_BOTH);
}

void generateDeclaration(std::ostringstream& src, const UniformBlock& block)
{
	if ((block.getFlags() & LAYOUT_MASK) != 0)
		src << "layout(" << LayoutFlagsFmt(block.getFlags() & LAYOUT_MASK) << ") ";

	src << "uniform " << block.getBlockName();
	src << "\n{\n";

	for (UniformBlock::ConstIterator uniformIter = block.begin(); uniformIter != block.end(); uniformIter++)
	{
		src << Indent(1);
		generateDeclaration(src, *uniformIter, 1 /* indent level */);
	}

	src << "}";

	if (block.getInstanceName() != DE_NULL)
	{
		src << " " << block.getInstanceName();
		if (block.isArray())
			src << "[" << block.getArraySize() << "]";
	}
	else
		DE_ASSERT(!block.isArray());

	src << ";\n";
}

void generateValueSrc(std::ostringstream& src, const UniformLayoutEntry& entry, const void* basePtr, int elementNdx)
{
	glu::DataType  scalarType = glu::getDataTypeScalarType(entry.type);
	int			   scalarSize = glu::getDataTypeScalarSize(entry.type);
	bool		   isArray	= entry.size > 1;
	const deUint8* elemPtr	= (const deUint8*)basePtr + entry.offset + (isArray ? elementNdx * entry.arrayStride : 0);
	const int	  compSize   = sizeof(deUint32);

	if (scalarSize > 1)
		src << glu::getDataTypeName(entry.type) << "(";

	if (glu::isDataTypeMatrix(entry.type))
	{
		int numRows = glu::getDataTypeMatrixNumRows(entry.type);
		int numCols = glu::getDataTypeMatrixNumColumns(entry.type);

		DE_ASSERT(scalarType == glu::TYPE_FLOAT);

		// Constructed in column-wise order.
		for (int colNdx = 0; colNdx < numCols; colNdx++)
		{
			for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
			{
				const deUint8* compPtr = elemPtr + (entry.isRowMajor ? rowNdx * entry.matrixStride + colNdx * compSize :
																	   colNdx * entry.matrixStride + rowNdx * compSize);

				if (colNdx > 0 || rowNdx > 0)
					src << ", ";

				src << de::floatToString(*((const float*)compPtr), 1);
			}
		}
	}
	else
	{
		for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
		{
			const deUint8* compPtr = elemPtr + scalarNdx * compSize;

			if (scalarNdx > 0)
				src << ", ";

			switch (scalarType)
			{
			case glu::TYPE_FLOAT:
				src << de::floatToString(*((const float*)compPtr), 1);
				break;
			case glu::TYPE_INT:
				src << *((const int*)compPtr);
				break;
			case glu::TYPE_UINT:
				src << *((const deUint32*)compPtr) << "u";
				break;
			case glu::TYPE_BOOL:
				src << (*((const deUint32*)compPtr) != 0u ? "true" : "false");
				break;
			default:
				DE_ASSERT(false);
			}
		}
	}

	if (scalarSize > 1)
		src << ")";
}

void generateCompareSrc(std::ostringstream& src, const char* resultVar, const VarType& type, const char* srcName,
						const char* apiName, const UniformLayout& layout, const void* basePtr, deUint32 unusedMask)
{
	if (type.isBasicType() || (type.isArrayType() && type.getElementType().isBasicType()))
	{
		// Basic type or array of basic types.
		bool		  isArray	 = type.isArrayType();
		glu::DataType elementType = isArray ? type.getElementType().getBasicType() : type.getBasicType();
		const char*   typeName	= glu::getDataTypeName(elementType);
		std::string   fullApiName = string(apiName) + (isArray ? "[0]" : ""); // Arrays are always postfixed with [0]
		int			  uniformNdx  = layout.getUniformIndex(fullApiName.c_str());
		const UniformLayoutEntry& entry = layout.uniforms[uniformNdx];

		if (isArray)
		{
			for (int elemNdx = 0; elemNdx < type.getArraySize(); elemNdx++)
			{
				src << "\tresult *= compare_" << typeName << "(" << srcName << "[" << elemNdx << "], ";
				generateValueSrc(src, entry, basePtr, elemNdx);
				src << ");\n";
			}
		}
		else
		{
			src << "\tresult *= compare_" << typeName << "(" << srcName << ", ";
			generateValueSrc(src, entry, basePtr, 0);
			src << ");\n";
		}
	}
	else if (type.isArrayType())
	{
		const VarType& elementType = type.getElementType();
		DE_ASSERT(!elementType.isArrayType());

		for (int elementNdx = 0; elementNdx < type.getArraySize(); elementNdx++)
		{
			std::string op = string("[") + de::toString(elementNdx) + "]";
			generateCompareSrc(src, resultVar, elementType, (string(srcName) + op).c_str(),
							   (string(apiName) + op).c_str(), layout, basePtr, unusedMask);
		}
	}
	else
	{
		DE_ASSERT(type.isStructType());

		for (StructType::ConstIterator memberIter = type.getStruct().begin(); memberIter != type.getStruct().end();
			 memberIter++)
		{
			if (memberIter->getFlags() & unusedMask)
				continue; // Skip member.

			string op = string(".") + memberIter->getName();
			generateCompareSrc(src, resultVar, memberIter->getType(), (string(srcName) + op).c_str(),
							   (string(apiName) + op).c_str(), layout, basePtr, unusedMask);
		}
	}
}

void generateCompareSrc(std::ostringstream& src, const char* resultVar, const ShaderInterface& interface,
						const UniformLayout& layout, const std::map<int, void*>& blockPointers, bool isVertex)
{
	deUint32 unusedMask = isVertex ? UNUSED_VERTEX : UNUSED_FRAGMENT;

	for (int blockNdx = 0; blockNdx < interface.getNumUniformBlocks(); blockNdx++)
	{
		const UniformBlock& block = interface.getUniformBlock(blockNdx);

		if ((block.getFlags() & (isVertex ? DECLARE_VERTEX : DECLARE_FRAGMENT)) == 0)
			continue; // Skip.

		bool		hasInstanceName = block.getInstanceName() != DE_NULL;
		bool		isArray			= block.isArray();
		int			numInstances	= isArray ? block.getArraySize() : 1;
		std::string apiPrefix		= hasInstanceName ? string(block.getBlockName()) + "." : string("");

		DE_ASSERT(!isArray || hasInstanceName);

		for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
		{
			std::string instancePostfix   = isArray ? string("[") + de::toString(instanceNdx) + "]" : string("");
			std::string blockInstanceName = block.getBlockName() + instancePostfix;
			std::string srcPrefix =
				hasInstanceName ? string(block.getInstanceName()) + instancePostfix + "." : string("");
			int   activeBlockNdx = layout.getBlockIndex(blockInstanceName.c_str());
			void* basePtr		 = blockPointers.find(activeBlockNdx)->second;

			for (UniformBlock::ConstIterator uniformIter = block.begin(); uniformIter != block.end(); uniformIter++)
			{
				const Uniform& uniform = *uniformIter;

				if (uniform.getFlags() & unusedMask)
					continue; // Don't read from that uniform.

				generateCompareSrc(src, resultVar, uniform.getType(), (srcPrefix + uniform.getName()).c_str(),
								   (apiPrefix + uniform.getName()).c_str(), layout, basePtr, unusedMask);
			}
		}
	}
}

void generateVertexShader(std::ostringstream& src, glu::GLSLVersion glslVersion, const ShaderInterface& interface,
						  const UniformLayout& layout, const std::map<int, void*>& blockPointers)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  de::inRange<int>(glslVersion, glu::GLSL_VERSION_330, glu::GLSL_VERSION_430));

	src << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	src << "in highp vec4 a_position;\n";
	src << "out mediump float v_vtxResult;\n";
	src << "\n";

	std::vector<const StructType*> namedStructs;
	interface.getNamedStructs(namedStructs);
	for (std::vector<const StructType*>::const_iterator structIter = namedStructs.begin();
		 structIter != namedStructs.end(); structIter++)
		generateDeclaration(src, **structIter, 0);

	for (int blockNdx = 0; blockNdx < interface.getNumUniformBlocks(); blockNdx++)
	{
		const UniformBlock& block = interface.getUniformBlock(blockNdx);
		if (block.getFlags() & DECLARE_VERTEX)
			generateDeclaration(src, block);
	}

	// Comparison utilities.
	src << "\n" << s_compareFuncs;

	src << "\n"
		   "void main (void)\n"
		   "{\n"
		   "    gl_Position = a_position;\n"
		   "    mediump float result = 1.0;\n";

	// Value compare.
	generateCompareSrc(src, "result", interface, layout, blockPointers, true);

	src << "    v_vtxResult = result;\n"
		   "}\n";
}

void generateFragmentShader(std::ostringstream& src, glu::GLSLVersion glslVersion, const ShaderInterface& interface,
							const UniformLayout& layout, const std::map<int, void*>& blockPointers)
{
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_310_ES ||
			  de::inRange<int>(glslVersion, glu::GLSL_VERSION_330, glu::GLSL_VERSION_430));

	src << glu::getGLSLVersionDeclaration(glslVersion) << "\n";
	src << "in mediump float v_vtxResult;\n";
	src << "layout(location = 0) out mediump vec4 dEQP_FragColor;\n";
	src << "\n";

	std::vector<const StructType*> namedStructs;
	interface.getNamedStructs(namedStructs);
	for (std::vector<const StructType*>::const_iterator structIter = namedStructs.begin();
		 structIter != namedStructs.end(); structIter++)
		generateDeclaration(src, **structIter, 0);

	for (int blockNdx = 0; blockNdx < interface.getNumUniformBlocks(); blockNdx++)
	{
		const UniformBlock& block = interface.getUniformBlock(blockNdx);
		if (block.getFlags() & DECLARE_FRAGMENT)
			generateDeclaration(src, block);
	}

	// Comparison utilities.
	src << "\n" << s_compareFuncs;

	src << "\n"
		   "void main (void)\n"
		   "{\n"
		   "    mediump float result = 1.0;\n";

	// Value compare.
	generateCompareSrc(src, "result", interface, layout, blockPointers, false);

	src << "    dEQP_FragColor = vec4(1.0, v_vtxResult, result, 1.0);\n"
		   "}\n";
}

void getGLUniformLayout(const glw::Functions& gl, UniformLayout& layout, deUint32 program)
{
	int numActiveUniforms = 0;
	int numActiveBlocks   = 0;

	gl.getProgramiv(program, GL_ACTIVE_UNIFORMS, &numActiveUniforms);
	gl.getProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get number of uniforms and uniform blocks");

	// Block entries.
	layout.blocks.resize(numActiveBlocks);
	for (int blockNdx = 0; blockNdx < numActiveBlocks; blockNdx++)
	{
		BlockLayoutEntry& entry = layout.blocks[blockNdx];
		int				  size;
		int				  nameLen;
		int				  numBlockUniforms;

		gl.getActiveUniformBlockiv(program, (deUint32)blockNdx, GL_UNIFORM_BLOCK_DATA_SIZE, &size);
		gl.getActiveUniformBlockiv(program, (deUint32)blockNdx, GL_UNIFORM_BLOCK_NAME_LENGTH, &nameLen);
		gl.getActiveUniformBlockiv(program, (deUint32)blockNdx, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numBlockUniforms);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform block query failed");

		// \note Some implementations incorrectly return 0 as name length even though the length should include null terminator.
		std::vector<char> nameBuf(nameLen > 0 ? nameLen : 1);
		gl.getActiveUniformBlockName(program, (deUint32)blockNdx, (glw::GLsizei)nameBuf.size(), DE_NULL, &nameBuf[0]);

		entry.name = std::string(&nameBuf[0]);
		entry.size = size;
		entry.activeUniformIndices.resize(numBlockUniforms);

		if (numBlockUniforms > 0)
			gl.getActiveUniformBlockiv(program, (deUint32)blockNdx, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES,
									   &entry.activeUniformIndices[0]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform block query failed");
	}

	if (numActiveUniforms > 0)
	{
		// Uniform entries.
		std::vector<deUint32> uniformIndices(numActiveUniforms);
		for (int i			  = 0; i < numActiveUniforms; i++)
			uniformIndices[i] = (deUint32)i;

		std::vector<int> types(numActiveUniforms);
		std::vector<int> sizes(numActiveUniforms);
		std::vector<int> nameLengths(numActiveUniforms);
		std::vector<int> blockIndices(numActiveUniforms);
		std::vector<int> offsets(numActiveUniforms);
		std::vector<int> arrayStrides(numActiveUniforms);
		std::vector<int> matrixStrides(numActiveUniforms);
		std::vector<int> rowMajorFlags(numActiveUniforms);

		// Execute queries.
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0], GL_UNIFORM_TYPE,
							   &types[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0], GL_UNIFORM_SIZE,
							   &sizes[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0], GL_UNIFORM_NAME_LENGTH,
							   &nameLengths[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0], GL_UNIFORM_BLOCK_INDEX,
							   &blockIndices[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0], GL_UNIFORM_OFFSET,
							   &offsets[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0],
							   GL_UNIFORM_ARRAY_STRIDE, &arrayStrides[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0],
							   GL_UNIFORM_MATRIX_STRIDE, &matrixStrides[0]);
		gl.getActiveUniformsiv(program, (glw::GLsizei)uniformIndices.size(), &uniformIndices[0],
							   GL_UNIFORM_IS_ROW_MAJOR, &rowMajorFlags[0]);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Active uniform query failed");

		// Translate to LayoutEntries
		layout.uniforms.resize(numActiveUniforms);
		for (int uniformNdx = 0; uniformNdx < numActiveUniforms; uniformNdx++)
		{
			UniformLayoutEntry& entry = layout.uniforms[uniformNdx];
			std::vector<char>   nameBuf(nameLengths[uniformNdx]);
			glw::GLsizei		nameLen = 0;
			int					size	= 0;
			deUint32			type	= GL_NONE;

			gl.getActiveUniform(program, (deUint32)uniformNdx, (glw::GLsizei)nameBuf.size(), &nameLen, &size, &type,
								&nameBuf[0]);

			GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform name query failed");

			// \note glGetActiveUniform() returns length without \0 and glGetActiveUniformsiv() with \0
			if (nameLen + 1 != nameLengths[uniformNdx] || size != sizes[uniformNdx] ||
				type != (deUint32)types[uniformNdx])
				TCU_FAIL("Values returned by glGetActiveUniform() don't match with values queried with "
						 "glGetActiveUniformsiv().");

			entry.name		   = std::string(&nameBuf[0]);
			entry.type		   = glu::getDataTypeFromGLType(types[uniformNdx]);
			entry.size		   = sizes[uniformNdx];
			entry.blockNdx	 = blockIndices[uniformNdx];
			entry.offset	   = offsets[uniformNdx];
			entry.arrayStride  = arrayStrides[uniformNdx];
			entry.matrixStride = matrixStrides[uniformNdx];
			entry.isRowMajor   = rowMajorFlags[uniformNdx] != GL_FALSE;
		}
	}
}

void copyUniformData(const UniformLayoutEntry& dstEntry, void* dstBlockPtr, const UniformLayoutEntry& srcEntry,
					 const void* srcBlockPtr)
{
	deUint8*	   dstBasePtr = (deUint8*)dstBlockPtr + dstEntry.offset;
	const deUint8* srcBasePtr = (const deUint8*)srcBlockPtr + srcEntry.offset;

	DE_ASSERT(dstEntry.size <= srcEntry.size);
	DE_ASSERT(dstEntry.type == srcEntry.type);

	int		  scalarSize = glu::getDataTypeScalarSize(dstEntry.type);
	bool	  isMatrix   = glu::isDataTypeMatrix(dstEntry.type);
	const int compSize   = sizeof(deUint32);

	for (int elementNdx = 0; elementNdx < dstEntry.size; elementNdx++)
	{
		deUint8*	   dstElemPtr = dstBasePtr + elementNdx * dstEntry.arrayStride;
		const deUint8* srcElemPtr = srcBasePtr + elementNdx * srcEntry.arrayStride;

		if (isMatrix)
		{
			int numRows = glu::getDataTypeMatrixNumRows(dstEntry.type);
			int numCols = glu::getDataTypeMatrixNumColumns(dstEntry.type);

			for (int colNdx = 0; colNdx < numCols; colNdx++)
			{
				for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
				{
					deUint8* dstCompPtr =
						dstElemPtr + (dstEntry.isRowMajor ? rowNdx * dstEntry.matrixStride + colNdx * compSize :
															colNdx * dstEntry.matrixStride + rowNdx * compSize);
					const deUint8* srcCompPtr =
						srcElemPtr + (srcEntry.isRowMajor ? rowNdx * srcEntry.matrixStride + colNdx * compSize :
															colNdx * srcEntry.matrixStride + rowNdx * compSize);
					deMemcpy(dstCompPtr, srcCompPtr, compSize);
				}
			}
		}
		else
			deMemcpy(dstElemPtr, srcElemPtr, scalarSize * compSize);
	}
}

void copyUniformData(const UniformLayout& dstLayout, const std::map<int, void*>& dstBlockPointers,
					 const UniformLayout& srcLayout, const std::map<int, void*>& srcBlockPointers)
{
	// \note Src layout is used as reference in case of activeUniforms happens to be incorrect in dstLayout blocks.
	int numBlocks = (int)srcLayout.blocks.size();

	for (int srcBlockNdx = 0; srcBlockNdx < numBlocks; srcBlockNdx++)
	{
		const BlockLayoutEntry& srcBlock	= srcLayout.blocks[srcBlockNdx];
		const void*				srcBlockPtr = srcBlockPointers.find(srcBlockNdx)->second;
		int						dstBlockNdx = dstLayout.getBlockIndex(srcBlock.name.c_str());
		void*					dstBlockPtr = dstBlockNdx >= 0 ? dstBlockPointers.find(dstBlockNdx)->second : DE_NULL;

		if (dstBlockNdx < 0)
			continue;

		for (vector<int>::const_iterator srcUniformNdxIter = srcBlock.activeUniformIndices.begin();
			 srcUniformNdxIter != srcBlock.activeUniformIndices.end(); srcUniformNdxIter++)
		{
			const UniformLayoutEntry& srcEntry		= srcLayout.uniforms[*srcUniformNdxIter];
			int						  dstUniformNdx = dstLayout.getUniformIndex(srcEntry.name.c_str());

			if (dstUniformNdx < 0)
				continue;

			copyUniformData(dstLayout.uniforms[dstUniformNdx], dstBlockPtr, srcEntry, srcBlockPtr);
		}
	}
}

} // anonymous (utilities)

class UniformBufferManager
{
public:
	UniformBufferManager(const glu::RenderContext& renderCtx);
	~UniformBufferManager(void);

	deUint32 allocBuffer(void);

private:
	UniformBufferManager(const UniformBufferManager& other);
	UniformBufferManager& operator=(const UniformBufferManager& other);

	const glu::RenderContext& m_renderCtx;
	std::vector<deUint32>	 m_buffers;
};

UniformBufferManager::UniformBufferManager(const glu::RenderContext& renderCtx) : m_renderCtx(renderCtx)
{
}

UniformBufferManager::~UniformBufferManager(void)
{
	if (!m_buffers.empty())
		m_renderCtx.getFunctions().deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]);
}

deUint32 UniformBufferManager::allocBuffer(void)
{
	deUint32 buf = 0;

	m_buffers.reserve(m_buffers.size() + 1);
	m_renderCtx.getFunctions().genBuffers(1, &buf);
	GLU_EXPECT_NO_ERROR(m_renderCtx.getFunctions().getError(), "Failed to allocate uniform buffer");
	m_buffers.push_back(buf);

	return buf;
}

} // ub

using namespace ub;

// UniformBlockCase.

UniformBlockCase::UniformBlockCase(Context& context, const char* name, const char* description,
								   glu::GLSLVersion glslVersion, BufferMode bufferMode)
	: TestCase(context, name, description), m_glslVersion(glslVersion), m_bufferMode(bufferMode)
{
	// \todo [2013-05-25 pyry] Support other versions as well.
	DE_ASSERT(glslVersion == glu::GLSL_VERSION_300_ES || glslVersion == glu::GLSL_VERSION_330);
}

UniformBlockCase::~UniformBlockCase(void)
{
}

UniformBlockCase::IterateResult UniformBlockCase::iterate(void)
{
	TestLog&			  log = m_testCtx.getLog();
	const glw::Functions& gl  = m_context.getRenderContext().getFunctions();
	UniformLayout		  refLayout; //!< std140 layout.
	vector<deUint8>		  data;		 //!< Data.
	map<int, void*> blockPointers;   //!< Reference block pointers.

	// Initialize result to pass.
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	// Compute reference layout.
	computeStd140Layout(refLayout, m_interface);

	// Assign storage for reference values.
	{
		int totalSize = 0;
		for (vector<BlockLayoutEntry>::const_iterator blockIter = refLayout.blocks.begin();
			 blockIter != refLayout.blocks.end(); blockIter++)
			totalSize += blockIter->size;
		data.resize(totalSize);

		// Pointers for each block.
		int curOffset = 0;
		for (int blockNdx = 0; blockNdx < (int)refLayout.blocks.size(); blockNdx++)
		{
			blockPointers[blockNdx] = &data[0] + curOffset;
			curOffset += refLayout.blocks[blockNdx].size;
		}
	}

	// Generate values.
	generateValues(refLayout, blockPointers, 1 /* seed */);

	// Generate shaders and build program.
	std::ostringstream vtxSrc;
	std::ostringstream fragSrc;

	generateVertexShader(vtxSrc, m_glslVersion, m_interface, refLayout, blockPointers);
	generateFragmentShader(fragSrc, m_glslVersion, m_interface, refLayout, blockPointers);

	glu::ShaderProgram program(m_context.getRenderContext(),
							   glu::makeVtxFragSources(vtxSrc.str().c_str(), fragSrc.str().c_str()));
	log << program;

	if (!program.isOk())
	{
		// Compile failed.
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed");
		return STOP;
	}

	// Query layout from GL.
	UniformLayout glLayout;
	getGLUniformLayout(gl, glLayout, program.getProgram());

	// Print layout to log.
	log << TestLog::Section("ActiveUniformBlocks", "Active Uniform Blocks");
	for (int blockNdx = 0; blockNdx < (int)glLayout.blocks.size(); blockNdx++)
		log << TestLog::Message << blockNdx << ": " << glLayout.blocks[blockNdx] << TestLog::EndMessage;
	log << TestLog::EndSection;

	log << TestLog::Section("ActiveUniforms", "Active Uniforms");
	for (int uniformNdx = 0; uniformNdx < (int)glLayout.uniforms.size(); uniformNdx++)
		log << TestLog::Message << uniformNdx << ": " << glLayout.uniforms[uniformNdx] << TestLog::EndMessage;
	log << TestLog::EndSection;

	// Check that we can even try rendering with given layout.
	if (!checkLayoutIndices(glLayout) || !checkLayoutBounds(glLayout) || !compareTypes(refLayout, glLayout))
	{
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid layout");
		return STOP; // It is not safe to use the given layout.
	}

	// Verify all std140 blocks.
	if (!compareStd140Blocks(refLayout, glLayout))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid std140 layout");

	// Verify all shared blocks - all uniforms should be active, and certain properties match.
	if (!compareSharedBlocks(refLayout, glLayout))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid shared layout");

	// Check consistency with index queries
	if (!checkIndexQueries(program.getProgram(), glLayout))
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsintent block index query results");

	// Use program.
	gl.useProgram(program.getProgram());

	// Assign binding points to all active uniform blocks.
	for (int blockNdx = 0; blockNdx < (int)glLayout.blocks.size(); blockNdx++)
	{
		deUint32 binding = (deUint32)blockNdx; // \todo [2012-01-25 pyry] Randomize order?
		gl.uniformBlockBinding(program.getProgram(), (deUint32)blockNdx, binding);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set uniform block bindings");

	// Allocate buffers, write data and bind to targets.
	UniformBufferManager bufferManager(m_context.getRenderContext());
	if (m_bufferMode == BUFFERMODE_PER_BLOCK)
	{
		int						 numBlocks = (int)glLayout.blocks.size();
		vector<vector<deUint8> > glData(numBlocks);
		map<int, void*> glBlockPointers;

		for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
		{
			glData[blockNdx].resize(glLayout.blocks[blockNdx].size);
			glBlockPointers[blockNdx] = &glData[blockNdx][0];
		}

		copyUniformData(glLayout, glBlockPointers, refLayout, blockPointers);

		for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
		{
			deUint32 buffer  = bufferManager.allocBuffer();
			deUint32 binding = (deUint32)blockNdx;

			gl.bindBuffer(GL_UNIFORM_BUFFER, buffer);
			gl.bufferData(GL_UNIFORM_BUFFER, (glw::GLsizeiptr)glData[blockNdx].size(), &glData[blockNdx][0],
						  GL_STATIC_DRAW);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload uniform buffer data");

			gl.bindBufferBase(GL_UNIFORM_BUFFER, binding, buffer);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase(GL_UNIFORM_BUFFER) failed");
		}
	}
	else
	{
		DE_ASSERT(m_bufferMode == BUFFERMODE_SINGLE);

		int totalSize		 = 0;
		int curOffset		 = 0;
		int numBlocks		 = (int)glLayout.blocks.size();
		int bindingAlignment = m_context.getContextInfo().getInt(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
		map<int, int> glBlockOffsets;

		// Compute total size and offsets.
		curOffset = 0;
		for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
		{
			if (bindingAlignment > 0)
				curOffset			 = deRoundUp32(curOffset, bindingAlignment);
			glBlockOffsets[blockNdx] = curOffset;
			curOffset += glLayout.blocks[blockNdx].size;
		}
		totalSize = curOffset;

		// Assign block pointers.
		vector<deUint8> glData(totalSize);
		map<int, void*> glBlockPointers;

		for (int blockNdx			  = 0; blockNdx < numBlocks; blockNdx++)
			glBlockPointers[blockNdx] = &glData[glBlockOffsets[blockNdx]];

		// Copy to gl format.
		copyUniformData(glLayout, glBlockPointers, refLayout, blockPointers);

		// Allocate buffer and upload data.
		deUint32 buffer = bufferManager.allocBuffer();
		gl.bindBuffer(GL_UNIFORM_BUFFER, buffer);
		if (!glData.empty())
			gl.bufferData(GL_UNIFORM_BUFFER, (glw::GLsizeiptr)glData.size(), &glData[0], GL_STATIC_DRAW);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to upload uniform buffer data");

		// Bind ranges to binding points.
		curOffset = 0;
		for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
		{
			deUint32 binding = (deUint32)blockNdx;
			gl.bindBufferRange(GL_UNIFORM_BUFFER, binding, buffer, (glw::GLintptr)glBlockOffsets[blockNdx],
							   (glw::GLsizeiptr)glLayout.blocks[blockNdx].size);
			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange(GL_UNIFORM_BUFFER) failed");
			curOffset += glLayout.blocks[blockNdx].size;
		}
	}

	bool renderOk = render(program);
	if (!renderOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image compare failed");

	return STOP;
}

bool UniformBlockCase::compareStd140Blocks(const UniformLayout& refLayout, const UniformLayout& cmpLayout) const
{
	TestLog& log	   = m_testCtx.getLog();
	bool	 isOk	  = true;
	int		 numBlocks = m_interface.getNumUniformBlocks();

	for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
	{
		const UniformBlock& block		 = m_interface.getUniformBlock(blockNdx);
		bool				isArray		 = block.isArray();
		std::string			instanceName = string(block.getBlockName()) + (isArray ? "[0]" : "");
		int					refBlockNdx  = refLayout.getBlockIndex(instanceName.c_str());
		int					cmpBlockNdx  = cmpLayout.getBlockIndex(instanceName.c_str());
		bool				isUsed		 = (block.getFlags() & (DECLARE_VERTEX | DECLARE_FRAGMENT)) != 0;

		if ((block.getFlags() & LAYOUT_STD140) == 0)
			continue; // Not std140 layout.

		DE_ASSERT(refBlockNdx >= 0);

		if (cmpBlockNdx < 0)
		{
			// Not found, should it?
			if (isUsed)
			{
				log << TestLog::Message << "Error: Uniform block '" << instanceName << "' not found"
					<< TestLog::EndMessage;
				isOk = false;
			}

			continue; // Skip block.
		}

		const BlockLayoutEntry& refBlockLayout = refLayout.blocks[refBlockNdx];
		const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];

		// \todo [2012-01-24 pyry] Verify that activeUniformIndices is correct.
		// \todo [2012-01-24 pyry] Verify all instances.
		if (refBlockLayout.activeUniformIndices.size() != cmpBlockLayout.activeUniformIndices.size())
		{
			log << TestLog::Message << "Error: Number of active uniforms differ in block '" << instanceName
				<< "' (expected " << refBlockLayout.activeUniformIndices.size() << ", got "
				<< cmpBlockLayout.activeUniformIndices.size() << ")" << TestLog::EndMessage;
			isOk = false;
		}

		for (vector<int>::const_iterator ndxIter = refBlockLayout.activeUniformIndices.begin();
			 ndxIter != refBlockLayout.activeUniformIndices.end(); ndxIter++)
		{
			const UniformLayoutEntry& refEntry	= refLayout.uniforms[*ndxIter];
			int						  cmpEntryNdx = cmpLayout.getUniformIndex(refEntry.name.c_str());

			if (cmpEntryNdx < 0)
			{
				log << TestLog::Message << "Error: Uniform '" << refEntry.name << "' not found" << TestLog::EndMessage;
				isOk = false;
				continue;
			}

			const UniformLayoutEntry& cmpEntry = cmpLayout.uniforms[cmpEntryNdx];

			if (refEntry.type != cmpEntry.type || refEntry.size != cmpEntry.size ||
				refEntry.offset != cmpEntry.offset || refEntry.arrayStride != cmpEntry.arrayStride ||
				refEntry.matrixStride != cmpEntry.matrixStride || refEntry.isRowMajor != cmpEntry.isRowMajor)
			{
				log << TestLog::Message << "Error: Layout mismatch in '" << refEntry.name << "':\n"
					<< "  expected: type = " << glu::getDataTypeName(refEntry.type) << ", size = " << refEntry.size
					<< ", offset = " << refEntry.offset << ", array stride = " << refEntry.arrayStride
					<< ", matrix stride = " << refEntry.matrixStride
					<< ", row major = " << (refEntry.isRowMajor ? "true" : "false") << "\n"
					<< "  got: type = " << glu::getDataTypeName(cmpEntry.type) << ", size = " << cmpEntry.size
					<< ", offset = " << cmpEntry.offset << ", array stride = " << cmpEntry.arrayStride
					<< ", matrix stride = " << cmpEntry.matrixStride
					<< ", row major = " << (cmpEntry.isRowMajor ? "true" : "false") << TestLog::EndMessage;
				isOk = false;
			}
		}
	}

	return isOk;
}

bool UniformBlockCase::compareSharedBlocks(const UniformLayout& refLayout, const UniformLayout& cmpLayout) const
{
	TestLog& log	   = m_testCtx.getLog();
	bool	 isOk	  = true;
	int		 numBlocks = m_interface.getNumUniformBlocks();

	for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
	{
		const UniformBlock& block		 = m_interface.getUniformBlock(blockNdx);
		bool				isArray		 = block.isArray();
		std::string			instanceName = string(block.getBlockName()) + (isArray ? "[0]" : "");
		int					refBlockNdx  = refLayout.getBlockIndex(instanceName.c_str());
		int					cmpBlockNdx  = cmpLayout.getBlockIndex(instanceName.c_str());
		bool				isUsed		 = (block.getFlags() & (DECLARE_VERTEX | DECLARE_FRAGMENT)) != 0;

		if ((block.getFlags() & LAYOUT_SHARED) == 0)
			continue; // Not shared layout.

		DE_ASSERT(refBlockNdx >= 0);

		if (cmpBlockNdx < 0)
		{
			// Not found, should it?
			if (isUsed)
			{
				log << TestLog::Message << "Error: Uniform block '" << instanceName << "' not found"
					<< TestLog::EndMessage;
				isOk = false;
			}

			continue; // Skip block.
		}

		const BlockLayoutEntry& refBlockLayout = refLayout.blocks[refBlockNdx];
		const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];

		if (refBlockLayout.activeUniformIndices.size() != cmpBlockLayout.activeUniformIndices.size())
		{
			log << TestLog::Message << "Error: Number of active uniforms differ in block '" << instanceName
				<< "' (expected " << refBlockLayout.activeUniformIndices.size() << ", got "
				<< cmpBlockLayout.activeUniformIndices.size() << ")" << TestLog::EndMessage;
			isOk = false;
		}

		for (vector<int>::const_iterator ndxIter = refBlockLayout.activeUniformIndices.begin();
			 ndxIter != refBlockLayout.activeUniformIndices.end(); ndxIter++)
		{
			const UniformLayoutEntry& refEntry	= refLayout.uniforms[*ndxIter];
			int						  cmpEntryNdx = cmpLayout.getUniformIndex(refEntry.name.c_str());

			if (cmpEntryNdx < 0)
			{
				log << TestLog::Message << "Error: Uniform '" << refEntry.name << "' not found" << TestLog::EndMessage;
				isOk = false;
				continue;
			}

			const UniformLayoutEntry& cmpEntry = cmpLayout.uniforms[cmpEntryNdx];

			if (refEntry.type != cmpEntry.type || refEntry.size != cmpEntry.size ||
				refEntry.isRowMajor != cmpEntry.isRowMajor)
			{
				log << TestLog::Message << "Error: Layout mismatch in '" << refEntry.name << "':\n"
					<< "  expected: type = " << glu::getDataTypeName(refEntry.type) << ", size = " << refEntry.size
					<< ", row major = " << (refEntry.isRowMajor ? "true" : "false") << "\n"
					<< "  got: type = " << glu::getDataTypeName(cmpEntry.type) << ", size = " << cmpEntry.size
					<< ", row major = " << (cmpEntry.isRowMajor ? "true" : "false") << TestLog::EndMessage;
				isOk = false;
			}
		}
	}

	return isOk;
}

bool UniformBlockCase::compareTypes(const UniformLayout& refLayout, const UniformLayout& cmpLayout) const
{
	TestLog& log	   = m_testCtx.getLog();
	bool	 isOk	  = true;
	int		 numBlocks = m_interface.getNumUniformBlocks();

	for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
	{
		const UniformBlock& block		 = m_interface.getUniformBlock(blockNdx);
		bool				isArray		 = block.isArray();
		int					numInstances = isArray ? block.getArraySize() : 1;

		for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
		{
			std::ostringstream instanceName;

			instanceName << block.getBlockName();
			if (isArray)
				instanceName << "[" << instanceNdx << "]";

			int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.str().c_str());

			if (cmpBlockNdx < 0)
				continue;

			const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx];

			for (vector<int>::const_iterator ndxIter = cmpBlockLayout.activeUniformIndices.begin();
				 ndxIter != cmpBlockLayout.activeUniformIndices.end(); ndxIter++)
			{
				const UniformLayoutEntry& cmpEntry	= cmpLayout.uniforms[*ndxIter];
				int						  refEntryNdx = refLayout.getUniformIndex(cmpEntry.name.c_str());

				if (refEntryNdx < 0)
				{
					log << TestLog::Message << "Error: Uniform '" << cmpEntry.name << "' not found in reference layout"
						<< TestLog::EndMessage;
					isOk = false;
					continue;
				}

				const UniformLayoutEntry& refEntry = refLayout.uniforms[refEntryNdx];

				// \todo [2012-11-26 pyry] Should we check other properties as well?
				if (refEntry.type != cmpEntry.type)
				{
					log << TestLog::Message << "Error: Uniform type mismatch in '" << refEntry.name << "':\n"
						<< "  expected: " << glu::getDataTypeName(refEntry.type) << "\n"
						<< "  got: " << glu::getDataTypeName(cmpEntry.type) << TestLog::EndMessage;
					isOk = false;
				}
			}
		}
	}

	return isOk;
}

bool UniformBlockCase::checkLayoutIndices(const UniformLayout& layout) const
{
	TestLog& log		 = m_testCtx.getLog();
	int		 numUniforms = (int)layout.uniforms.size();
	int		 numBlocks   = (int)layout.blocks.size();
	bool	 isOk		 = true;

	// Check uniform block indices.
	for (int uniformNdx = 0; uniformNdx < numUniforms; uniformNdx++)
	{
		const UniformLayoutEntry& uniform = layout.uniforms[uniformNdx];

		if (uniform.blockNdx < 0 || !deInBounds32(uniform.blockNdx, 0, numBlocks))
		{
			log << TestLog::Message << "Error: Invalid block index in uniform '" << uniform.name << "'"
				<< TestLog::EndMessage;
			isOk = false;
		}
	}

	// Check active uniforms.
	for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
	{
		const BlockLayoutEntry& block = layout.blocks[blockNdx];

		for (vector<int>::const_iterator uniformIter = block.activeUniformIndices.begin();
			 uniformIter != block.activeUniformIndices.end(); uniformIter++)
		{
			if (!deInBounds32(*uniformIter, 0, numUniforms))
			{
				log << TestLog::Message << "Error: Invalid active uniform index " << *uniformIter << " in block '"
					<< block.name << "'" << TestLog::EndMessage;
				isOk = false;
			}
		}
	}

	return isOk;
}

bool UniformBlockCase::checkLayoutBounds(const UniformLayout& layout) const
{
	TestLog& log		 = m_testCtx.getLog();
	int		 numUniforms = (int)layout.uniforms.size();
	bool	 isOk		 = true;

	for (int uniformNdx = 0; uniformNdx < numUniforms; uniformNdx++)
	{
		const UniformLayoutEntry& uniform = layout.uniforms[uniformNdx];

		if (uniform.blockNdx < 0)
			continue;

		const BlockLayoutEntry& block	= layout.blocks[uniform.blockNdx];
		bool					isMatrix = glu::isDataTypeMatrix(uniform.type);
		int						numVecs = isMatrix ? (uniform.isRowMajor ? glu::getDataTypeMatrixNumRows(uniform.type) :
													   glu::getDataTypeMatrixNumColumns(uniform.type)) :
								 1;
		int numComps = isMatrix ? (uniform.isRowMajor ? glu::getDataTypeMatrixNumColumns(uniform.type) :
														glu::getDataTypeMatrixNumRows(uniform.type)) :
								  glu::getDataTypeScalarSize(uniform.type);
		int		  numElements = uniform.size;
		const int compSize	= sizeof(deUint32);
		int		  vecSize	 = numComps * compSize;

		int minOffset = 0;
		int maxOffset = 0;

		// For negative strides.
		minOffset = de::min(minOffset, (numVecs - 1) * uniform.matrixStride);
		minOffset = de::min(minOffset, (numElements - 1) * uniform.arrayStride);
		minOffset = de::min(minOffset, (numElements - 1) * uniform.arrayStride + (numVecs - 1) * uniform.matrixStride);

		maxOffset = de::max(maxOffset, vecSize);
		maxOffset = de::max(maxOffset, (numVecs - 1) * uniform.matrixStride + vecSize);
		maxOffset = de::max(maxOffset, (numElements - 1) * uniform.arrayStride + vecSize);
		maxOffset = de::max(maxOffset,
							(numElements - 1) * uniform.arrayStride + (numVecs - 1) * uniform.matrixStride + vecSize);

		if (uniform.offset + minOffset < 0 || uniform.offset + maxOffset > block.size)
		{
			log << TestLog::Message << "Error: Uniform '" << uniform.name << "' out of block bounds"
				<< TestLog::EndMessage;
			isOk = false;
		}
	}

	return isOk;
}

bool UniformBlockCase::checkIndexQueries(deUint32 program, const UniformLayout& layout) const
{
	tcu::TestLog&		  log   = m_testCtx.getLog();
	const glw::Functions& gl	= m_context.getRenderContext().getFunctions();
	bool				  allOk = true;

	// \note Spec mandates that uniform blocks are assigned consecutive locations from 0
	//       to ACTIVE_UNIFORM_BLOCKS. BlockLayoutEntries are stored in that order in UniformLayout.
	for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++)
	{
		const BlockLayoutEntry& block	  = layout.blocks[blockNdx];
		const int				queriedNdx = gl.getUniformBlockIndex(program, block.name.c_str());

		if (queriedNdx != blockNdx)
		{
			log << TestLog::Message << "ERROR: glGetUniformBlockIndex(" << block.name << ") returned " << queriedNdx
				<< ", expected " << blockNdx << "!" << TestLog::EndMessage;
			allOk = false;
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex()");
	}

	return allOk;
}

bool UniformBlockCase::render(glu::ShaderProgram& program) const
{
	tcu::TestLog&			 log = m_testCtx.getLog();
	const glw::Functions&	gl  = m_context.getRenderContext().getFunctions();
	de::Random				 rnd(deStringHash(getName()));
	const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
	const int				 viewportW	= de::min(renderTarget.getWidth(), 128);
	const int				 viewportH	= de::min(renderTarget.getHeight(), 128);
	const int				 viewportX	= rnd.getInt(0, renderTarget.getWidth() - viewportW);
	const int				 viewportY	= rnd.getInt(0, renderTarget.getHeight() - viewportH);

	// Draw
	{
		const float position[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f,
								   +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f };
		const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };

		gl.viewport(viewportX, viewportY, viewportW, viewportH);

		glu::VertexArrayBinding posArray = glu::va::Float("a_position", 4, 4, 0, &position[0]);
		glu::draw(m_context.getRenderContext(), program.getProgram(), 1, &posArray,
				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed");
	}

	// Verify that all pixels are white.
	{
		tcu::Surface pixels(viewportW, viewportH);
		int			 numFailedPixels = 0;

		glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, pixels.getAccess());
		GLU_EXPECT_NO_ERROR(gl.getError(), "Reading pixels failed");

		for (int y = 0; y < pixels.getHeight(); y++)
		{
			for (int x = 0; x < pixels.getWidth(); x++)
			{
				if (pixels.getPixel(x, y) != tcu::RGBA::white())
					numFailedPixels += 1;
			}
		}

		if (numFailedPixels > 0)
		{
			log << TestLog::Image("Image", "Rendered image", pixels);
			log << TestLog::Message << "Image comparison failed, got " << numFailedPixels << " non-white pixels"
				<< TestLog::EndMessage;
		}

		return numFailedPixels == 0;
	}
}

} // deqp
