/*-------------------------------------------------------------------------
 * 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 Copy image tests for GL_EXT_copy_image.
 *//*--------------------------------------------------------------------*/

#include "es31fCopyImageTests.hpp"

#include "tes31TestCase.hpp"

#include "glsTextureTestUtil.hpp"

#include "gluContextInfo.hpp"
#include "gluObjectWrapper.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "tcuCompressedTexture.hpp"
#include "tcuFloat.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuSeedBuilder.hpp"
#include "tcuResultCollector.hpp"

#include "deArrayBuffer.hpp"
#include "deFloat16.h"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "deArrayUtil.hpp"

#include <map>
#include <string>
#include <vector>

using namespace deqp::gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

using tcu::Float;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::Sampler;
using tcu::ScopedLogSection;
using tcu::TestLog;
using tcu::Vec4;
using tcu::SeedBuilder;

using de::ArrayBuffer;

using std::map;
using std::string;
using std::vector;
using std::pair;

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

enum ViewClass
{
	VIEWCLASS_128_BITS = 0,
	VIEWCLASS_96_BITS,
	VIEWCLASS_64_BITS,
	VIEWCLASS_48_BITS,
	VIEWCLASS_32_BITS,
	VIEWCLASS_24_BITS,
	VIEWCLASS_16_BITS,
	VIEWCLASS_8_BITS,

	VIEWCLASS_EAC_R11,
	VIEWCLASS_EAC_RG11,
	VIEWCLASS_ETC2_RGB,
	VIEWCLASS_ETC2_RGBA,
	VIEWCLASS_ETC2_EAC_RGBA,
	VIEWCLASS_ASTC_4x4_RGBA,
	VIEWCLASS_ASTC_5x4_RGBA,
	VIEWCLASS_ASTC_5x5_RGBA,
	VIEWCLASS_ASTC_6x5_RGBA,
	VIEWCLASS_ASTC_6x6_RGBA,
	VIEWCLASS_ASTC_8x5_RGBA,
	VIEWCLASS_ASTC_8x6_RGBA,
	VIEWCLASS_ASTC_8x8_RGBA,
	VIEWCLASS_ASTC_10x5_RGBA,
	VIEWCLASS_ASTC_10x6_RGBA,
	VIEWCLASS_ASTC_10x8_RGBA,
	VIEWCLASS_ASTC_10x10_RGBA,
	VIEWCLASS_ASTC_12x10_RGBA,
	VIEWCLASS_ASTC_12x12_RGBA
};

enum Verify
{
	VERIFY_NONE = 0,
	VERIFY_COMPARE_REFERENCE
};

const char* viewClassToName (ViewClass viewClass)
{
	switch (viewClass)
	{
		case VIEWCLASS_128_BITS:			return "viewclass_128_bits";
		case VIEWCLASS_96_BITS:				return "viewclass_96_bits";
		case VIEWCLASS_64_BITS:				return "viewclass_64_bits";
		case VIEWCLASS_48_BITS:				return "viewclass_48_bits";
		case VIEWCLASS_32_BITS:				return "viewclass_32_bits";
		case VIEWCLASS_24_BITS:				return "viewclass_24_bits";
		case VIEWCLASS_16_BITS:				return "viewclass_16_bits";
		case VIEWCLASS_8_BITS:				return "viewclass_8_bits";
		case VIEWCLASS_EAC_R11:				return "viewclass_eac_r11";
		case VIEWCLASS_EAC_RG11:			return "viewclass_eac_rg11";
		case VIEWCLASS_ETC2_RGB:			return "viewclass_etc2_rgb";
		case VIEWCLASS_ETC2_RGBA:			return "viewclass_etc2_rgba";
		case VIEWCLASS_ETC2_EAC_RGBA:		return "viewclass_etc2_eac_rgba";
		case VIEWCLASS_ASTC_4x4_RGBA:		return "viewclass_astc_4x4_rgba";
		case VIEWCLASS_ASTC_5x4_RGBA:		return "viewclass_astc_5x4_rgba";
		case VIEWCLASS_ASTC_5x5_RGBA:		return "viewclass_astc_5x5_rgba";
		case VIEWCLASS_ASTC_6x5_RGBA:		return "viewclass_astc_6x5_rgba";
		case VIEWCLASS_ASTC_6x6_RGBA:		return "viewclass_astc_6x6_rgba";
		case VIEWCLASS_ASTC_8x5_RGBA:		return "viewclass_astc_8x5_rgba";
		case VIEWCLASS_ASTC_8x6_RGBA:		return "viewclass_astc_8x6_rgba";
		case VIEWCLASS_ASTC_8x8_RGBA:		return "viewclass_astc_8x8_rgba";
		case VIEWCLASS_ASTC_10x5_RGBA:		return "viewclass_astc_10x5_rgba";
		case VIEWCLASS_ASTC_10x6_RGBA:		return "viewclass_astc_10x6_rgba";
		case VIEWCLASS_ASTC_10x8_RGBA:		return "viewclass_astc_10x8_rgba";
		case VIEWCLASS_ASTC_10x10_RGBA:		return "viewclass_astc_10x10_rgba";
		case VIEWCLASS_ASTC_12x10_RGBA:		return "viewclass_astc_12x10_rgba";
		case VIEWCLASS_ASTC_12x12_RGBA:		return "viewclass_astc_12x12_rgba";

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

const char* targetToName (deUint32 target)
{
	switch (target)
	{
		case GL_RENDERBUFFER:		return "renderbuffer";
		case GL_TEXTURE_2D:			return "texture2d";
		case GL_TEXTURE_3D:			return "texture3d";
		case GL_TEXTURE_2D_ARRAY:	return "texture2d_array";
		case GL_TEXTURE_CUBE_MAP:	return "cubemap";

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

string formatToName (deUint32 format)
{
	string enumName;

	if (glu::isCompressedFormat(format))
		enumName = glu::getCompressedTextureFormatStr(format).toString().substr(14); // Strip GL_COMPRESSED_
	else
		enumName = glu::getUncompressedTextureFormatStr(format).toString().substr(3); // Strip GL_

	return de::toLower(enumName);
}

bool isFloatFormat (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return false;
	else
		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
}

bool isUintFormat (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return false;
	else
		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
}

bool isIntFormat (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return false;
	else
		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
}

bool isFixedPointFormat (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return false;
	else
	{
		const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type);

		return channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
	}
}

bool isTextureTarget (deUint32 target)
{
	return target != GL_RENDERBUFFER;
}

int getTargetTexDims (deUint32 target)
{
	DE_ASSERT(isTextureTarget(target));

	switch (target)
	{
		case GL_TEXTURE_1D:
			return 1;

		case GL_TEXTURE_1D_ARRAY:
		case GL_TEXTURE_2D:
		case GL_TEXTURE_CUBE_MAP:
			return 2;

		case GL_TEXTURE_2D_ARRAY:
		case GL_TEXTURE_3D:
			return 3;

		default:
			DE_ASSERT(false);
			return -1;
	}
}

class RandomizedRenderGrid
{
public:
					RandomizedRenderGrid	(const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed);
	bool			nextCell				(void);
	IVec2			getOrigin				(void) const;

	const IVec2&	getCellSize				(void) const { return m_cellSize; };
	IVec4			getUsedAreaBoundingBox	(void) const;
	int				getCellCount			(void) const { return m_cellCount; };

private:
	static IVec2	getRandomOffset			(deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount);

	const IVec2		m_targetSize;
	const IVec2		m_cellSize;
	const IVec2		m_grid;
	int				m_currentCell;
	const int		m_cellCount;
	const IVec2		m_baseRandomOffset;
};

RandomizedRenderGrid::RandomizedRenderGrid (const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed)
	: m_targetSize			(targetSize)
	, m_cellSize			(cellSize)
	, m_grid				(targetSize / cellSize)
	, m_currentCell			(0)
	// If the grid exactly fits height, take one row for randomization.
	, m_cellCount			(deMin32(maxCellCount, ((targetSize.y() % cellSize.y()) == 0) && m_grid.y() > 1 ? m_grid.x() * (m_grid.y() - 1) :  m_grid.x() * m_grid.y()))
	, m_baseRandomOffset	(getRandomOffset(seed, targetSize, cellSize, m_grid, m_cellCount))
{
}

IVec2 RandomizedRenderGrid::getRandomOffset (deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount)
{
	de::Random	rng			(seed);
	IVec2		result;
	IVec2		extraSpace = targetSize - (cellSize * grid);

	// If there'll be unused rows, donate them into extra space.
	// (Round the required rows to full cell row to find out how many rows are unused, multiply by size)
	DE_ASSERT(deDivRoundUp32(cellCount, grid.x()) <= grid.y());
	extraSpace.y() += (grid.y() - deDivRoundUp32(cellCount, grid.x())) * cellSize.y();

	DE_ASSERT(targetSize.x() > cellSize.x() && targetSize.y() > cellSize.y());
	// If grid fits perfectly just one row of cells, just give up on randomizing.
	DE_ASSERT(extraSpace.x() > 0 || extraSpace.y() > 0 || grid.y() == 1);
	DE_ASSERT(extraSpace.x() + grid.x() * cellSize.x() == targetSize.x());

	// \note Putting these as ctor params would make evaluation order undefined, I think <sigh>. Hence,
	// no direct return.
	result.x() = rng.getInt(0, extraSpace.x());
	result.y() = rng.getInt(0, extraSpace.y());
	return result;
}

bool RandomizedRenderGrid::nextCell (void)
{
	if (m_currentCell >= getCellCount())
		return false;

	m_currentCell++;
	return true;
}

IVec2 RandomizedRenderGrid::getOrigin (void) const
{
	const int	gridX		  = (m_currentCell - 1) % m_grid.x();
	const int	gridY		  = (m_currentCell - 1) / m_grid.x();
	const IVec2 currentOrigin = (IVec2(gridX, gridY) * m_cellSize) + m_baseRandomOffset;

	DE_ASSERT(currentOrigin.x() >= 0 && (currentOrigin.x() + m_cellSize.x()) <= m_targetSize.x());
	DE_ASSERT(currentOrigin.y() >= 0 && (currentOrigin.y() + m_cellSize.y()) <= m_targetSize.y());

	return currentOrigin;
}

IVec4 RandomizedRenderGrid::getUsedAreaBoundingBox (void) const
{
	const IVec2 lastCell	(de::min(m_currentCell + 1, m_grid.x()), ((m_currentCell + m_grid.x() - 1) / m_grid.x()));
	const IVec2 size		= lastCell * m_cellSize;

	return IVec4(m_baseRandomOffset.x(), m_baseRandomOffset.y(), size.x(), size.y());
}

class ImageInfo
{
public:
					ImageInfo		(deUint32 format, deUint32 target, const IVec3& size);

	deUint32		getFormat		(void) const { return m_format; }
	deUint32		getTarget		(void) const { return m_target; }
	const IVec3&	getSize			(void) const { return m_size; }

private:
	deUint32		m_format;
	deUint32		m_target;
	IVec3			m_size;
};

ImageInfo::ImageInfo (deUint32 format, deUint32 target, const IVec3& size)
	: m_format		(format)
	, m_target		(target)
	, m_size		(size)
{
	DE_ASSERT(m_target == GL_TEXTURE_2D_ARRAY || m_target == GL_TEXTURE_3D || m_size.z() == 1);
	DE_ASSERT(isTextureTarget(m_target) || !glu::isCompressedFormat(m_target));
}


SeedBuilder& operator<< (SeedBuilder& builder, const ImageInfo& info)
{
	builder << info.getFormat() << info.getTarget() << info.getSize();
	return builder;
}

const glu::ObjectTraits& getObjectTraits (const ImageInfo& info)
{
	if (isTextureTarget(info.getTarget()))
		return glu::objectTraits(glu::OBJECTTYPE_TEXTURE);
	else
		return glu::objectTraits(glu::OBJECTTYPE_RENDERBUFFER);
}

int getLevelCount (const ImageInfo& info)
{
	const deUint32	target	= info.getTarget();
	const IVec3		size	= info.getSize();

	if (target == GL_RENDERBUFFER)
		return 1;
	else if (target == GL_TEXTURE_2D_ARRAY)
	{
		const int maxSize = de::max(size.x(), size.y());

		return deLog2Ceil32(maxSize);
	}
	else
	{
		const int maxSize = de::max(size.x(), de::max(size.y(), size.z()));

		return deLog2Ceil32(maxSize);
	}
}

IVec3 getLevelSize (deUint32 target, const IVec3& baseSize, int level)
{
	IVec3 size;

	if (target != GL_TEXTURE_2D_ARRAY)
	{
		for (int i = 0; i < 3; i++)
			size[i] = de::max(baseSize[i] >> level, 1);
	}
	else
	{
		for (int i = 0; i < 2; i++)
			size[i] = de::max(baseSize[i] >> level, 1);

		size[2] = baseSize[2];
	}

	return size;
}

deUint32 mapFaceNdxToFace (int ndx)
{
	const deUint32 cubeFaces[] =
	{
		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,

		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,

		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
	};

	return de::getSizedArrayElement<6>(cubeFaces, ndx);
}

// Class for iterating over mip levels and faces/slices/... of a texture.
class TextureImageIterator
{
public:
						TextureImageIterator	(const ImageInfo info, int levelCount);
						~TextureImageIterator	(void)							{}

	// Need to call next image once, newly constructed not readable, except for getSize
	bool				nextImage				(void);
	bool				hasNextImage			(void) const					{ return (m_currentLevel < (m_levelCount - 1)) || m_currentImage < (m_levelImageCount - 1); }

	int					getMipLevel				(void) const					{ return m_currentLevel; }
	int					getMipLevelCount		(void) const					{ return m_levelCount; }
	int					getCurrentImage			(void) const					{ return m_currentImage;}
	int					getLevelImageCount		(void) const					{ return m_levelImageCount; }
	IVec2				getSize					(void) const					{ return m_levelSize.toWidth<2>(); }	// Assume that image sizes never grow over iteration
	deUint32			getTarget				(void) const					{ return m_info.getTarget(); }

private:
	int					m_levelImageCount;		// Need to be defined in CTOR for the hasNextImage to work!
	const ImageInfo		m_info;
	int					m_currentLevel;
	IVec3				m_levelSize;
	int					m_currentImage;
	const int			m_levelCount;
};

TextureImageIterator::TextureImageIterator (const ImageInfo info, int levelCount)
	: m_levelImageCount	(info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : getLevelSize(info.getTarget(), info.getSize(), 0).z())
	, m_info			(info)
	, m_currentLevel	(0)
	, m_levelSize		(getLevelSize(info.getTarget(), info.getSize(), 0))
	, m_currentImage	(-1)
	, m_levelCount		(levelCount)
{
	DE_ASSERT(m_levelCount <= getLevelCount(info));
}

bool TextureImageIterator::nextImage (void)
{
	if (!hasNextImage())
		return false;

	m_currentImage++;
	if (m_currentImage == m_levelImageCount)
	{
		m_currentLevel++;
		m_currentImage		= 0;

		m_levelSize			= getLevelSize(m_info.getTarget(), m_info.getSize(), m_currentLevel);

		if (getTarget() == GL_TEXTURE_CUBE_MAP)
			m_levelImageCount = 6;
		else
			m_levelImageCount = m_levelSize.z();
	}
	DE_ASSERT(m_currentLevel < m_levelCount);
	DE_ASSERT(m_currentImage < m_levelImageCount);
	return true;
}

// Get name
string getTextureImageName (int textureTarget, int mipLevel, int imageIndex)
{
	std::ostringstream result;
	result << "Level";
	result << mipLevel;
	switch (textureTarget)
	{
		case GL_TEXTURE_2D:			break;
		case GL_TEXTURE_3D:			result << "Slice" << imageIndex; break;
		case GL_TEXTURE_CUBE_MAP:	result << "Face" << imageIndex; break;
		case GL_TEXTURE_2D_ARRAY:	result << "Layer" << imageIndex; break;
		default:
			DE_FATAL("Unsupported texture target");
			break;
	}
	return result.str();
}

// Get description
string getTextureImageDescription (int textureTarget, int mipLevel, int imageIndex)
{
	std::ostringstream result;
	result << "level ";
	result << mipLevel;

	switch (textureTarget)
	{
		case GL_TEXTURE_2D:			break;
		case GL_TEXTURE_3D:			result << " and Slice " << imageIndex; break;
		case GL_TEXTURE_CUBE_MAP:	result << " and Face " << imageIndex; break;
		case GL_TEXTURE_2D_ARRAY:	result << " and Layer " << imageIndex; break;
		default:
			DE_FATAL("Unsupported texture target");
			break;
	}
	return result.str();
}

// Compute texture coordinates
void computeQuadTexCoords(vector<float>& texCoord, const TextureImageIterator& iteration)
{
	const int currentImage = iteration.getCurrentImage();
	switch (iteration.getTarget())
	{
		case GL_TEXTURE_2D:
			computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
			break;

		case GL_TEXTURE_3D:
		{
			const float r = (float(currentImage) + 0.5f) / (float)iteration.getLevelImageCount();
			computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2));
			break;
		}

		case GL_TEXTURE_CUBE_MAP:
			computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(currentImage)));
			break;

		case GL_TEXTURE_2D_ARRAY:
			computeQuadTexCoord2DArray(texCoord, currentImage, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
			break;

		default:
			DE_FATAL("Unsupported texture target");
	}
}

// Struct for storing each reference image with necessary metadata.
struct CellContents
{
	IVec2			origin;
	tcu::Surface	reference;
	std::string		name;
	std::string		description;
};

// Return format that has more restrictions on texel data.
deUint32 getMoreRestrictiveFormat (deUint32 formatA, deUint32 formatB)
{
	if (formatA == formatB)
		return formatA;
	else if (glu::isCompressedFormat(formatA) && isAstcFormat(glu::mapGLCompressedTexFormat(formatA)))
		return formatA;
	else if (glu::isCompressedFormat(formatB) && isAstcFormat(glu::mapGLCompressedTexFormat(formatB)))
		return formatB;
	else if (isFloatFormat(formatA))
	{
		DE_ASSERT(!isFloatFormat(formatB));

		return formatA;
	}
	else if (isFloatFormat(formatB))
	{
		DE_ASSERT(!isFloatFormat(formatA));

		return formatB;
	}
	else if (glu::isCompressedFormat(formatA))
	{
		return formatA;
	}
	else if (glu::isCompressedFormat(formatB))
	{
		return formatB;
	}
	else
		return formatA;
}

int getTexelBlockSize (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return tcu::getBlockSize(glu::mapGLCompressedTexFormat(format));
	else
		return glu::mapGLInternalFormat(format).getPixelSize();
}

IVec3 getTexelBlockPixelSize (deUint32 format)
{
	if (glu::isCompressedFormat(format))
		return tcu::getBlockPixelSize(glu::mapGLCompressedTexFormat(format));
	else
		return IVec3(1, 1, 1);
}

bool isColorRenderable (deUint32 format)
{
	switch (format)
	{
		case GL_R8:
		case GL_RG8:
		case GL_RGB8:
		case GL_RGB565:
		case GL_RGB4:
		case GL_RGB5_A1:
		case GL_RGBA8:
		case GL_RGB10_A2:
		case GL_RGB10_A2UI:
		case GL_SRGB8_ALPHA8:
		case GL_R8I:
		case GL_R8UI:
		case GL_R16I:
		case GL_R16UI:
		case GL_R32I:
		case GL_R32UI:
		case GL_RG8I:
		case GL_RG8UI:
		case GL_RG16I:
		case GL_RG16UI:
		case GL_RG32I:
		case GL_RG32UI:
		case GL_RGBA8I:
		case GL_RGBA8UI:
		case GL_RGBA16I:
		case GL_RGBA16UI:
		case GL_RGBA32I:
		case GL_RGBA32UI:
			return true;

		default:
			return false;
	}
}

deUint32 getTypeForInternalFormat (deUint32 format)
{
	return glu::getTransferFormat(glu::mapGLInternalFormat(format)).dataType;
}

void genTexel (de::Random& rng, deUint32 glFormat, int texelBlockSize, const int texelCount, deUint8* buffer)
{
	if (isFloatFormat(glFormat))
	{
		const tcu::TextureFormat		format	= glu::mapGLInternalFormat(glFormat);
		const tcu::PixelBufferAccess	access	(format, texelCount, 1, 1, buffer);
		const tcu::TextureFormatInfo	info	= tcu::getTextureFormatInfo(format);

		for (int texelNdx = 0; texelNdx < texelCount; texelNdx++)
		{
			const float	red		= rng.getFloat(info.valueMin.x(), info.valueMax.x());
			const float green	= rng.getFloat(info.valueMin.y(), info.valueMax.y());
			const float blue	= rng.getFloat(info.valueMin.z(), info.valueMax.z());
			const float alpha	= rng.getFloat(info.valueMin.w(), info.valueMax.w());

			const Vec4	color	(red, green, blue, alpha);

			access.setPixel(color, texelNdx, 0, 0);
		}
	}
	else if (glu::isCompressedFormat(glFormat))
	{
		const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(glFormat);

		if (tcu::isAstcFormat(compressedFormat))
		{
			const int		BLOCK_SIZE				= 16;
			const deUint8	blocks[][BLOCK_SIZE]	=
			{
				// \note All of the following blocks are valid in LDR mode.
				{ 252,	253,	255,	255,	255,	255,	255,	255,	8,		71,		90,		78,		22,		17,		26,		66,		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	220,	74,		139,	235,	249,	6,		145,	125		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	223,	251,	28,		206,	54,		251,	160,	174		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	39,		4,		153,	219,	180,	61,		51,		37		},
				{ 67,	2,		0,		254,	1,		0,		64,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	130,	0,		170,	84,		255,	65,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	2,		129,	38,		51,		229,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	130,	193,	56,		213,	144,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		}
			};

			DE_ASSERT(texelBlockSize == BLOCK_SIZE);

			for (int i = 0; i < texelCount; i++)
			{
				const int blockNdx = rng.getInt(0, DE_LENGTH_OF_ARRAY(blocks)-1);

				deMemcpy(buffer + i * BLOCK_SIZE,  blocks[blockNdx], BLOCK_SIZE);
			}
		}
		else
		{
			for (int i = 0; i < texelBlockSize * texelCount; i++)
			{
				const deUint8 val = rng.getUint8();

				buffer[i] = val;
			}
		}
	}
	else
	{
		for (int i = 0; i < texelBlockSize * texelCount; i++)
		{
			const deUint8 val = rng.getUint8();

			buffer[i] = val;
		}
	}
}

IVec3 divRoundUp (const IVec3& a, const IVec3& b)
{
	IVec3 res;

	for (int i =0; i < 3; i++)
		res[i] = a[i] / b[i] + ((a[i] % b[i]) ? 1 : 0);

	return res;
}

deUint32 getFormatForInternalFormat (deUint32 format)
{
	return glu::getTransferFormat(glu::mapGLInternalFormat(format)).format;
}

void genericTexImage (const glw::Functions&	gl,
					  deUint32				target,
					  int					faceNdx,
					  int					level,
					  const IVec3&			size,
					  deUint32				format,
					  size_t				dataSize,
					  const void*			data)
{
	const deUint32 glTarget = (target == GL_TEXTURE_CUBE_MAP ? mapFaceNdxToFace(faceNdx) : target);

	DE_ASSERT(target == GL_TEXTURE_CUBE_MAP || faceNdx == 0);

	if (glu::isCompressedFormat(format))
	{
		switch (getTargetTexDims(target))
		{
			case 2:
				DE_ASSERT(size.z() == 1);
				gl.compressedTexImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, (glw::GLsizei)dataSize, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D failed.");
				break;

			case 3:
				gl.compressedTexImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, (glw::GLsizei)dataSize, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D failed.");
				break;

			default:
				DE_ASSERT(false);
		}
	}
	else
	{
		const deUint32	glFormat	= getFormatForInternalFormat(format);
		const deUint32	glType		= getTypeForInternalFormat(format);

		switch (getTargetTexDims(target))
		{
			case 2:
				DE_ASSERT(size.z() == 1);
				gl.texImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, glFormat, glType, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D failed.");
				break;

			case 3:
				gl.texImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, glFormat, glType, data);
				GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D failed.");
				break;

			default:
				DE_ASSERT(false);
		}
	}
}

void genTextureImage (const glw::Functions&				gl,
					  de::Random&						rng,
					  deUint32							name,
					  vector<ArrayBuffer<deUint8> >&	levels,
					  const ImageInfo&					info,
					  deUint32							moreRestrictiveFormat)
{
	const int		texelBlockSize			= getTexelBlockSize(info.getFormat());
	const IVec3		texelBlockPixelSize		= getTexelBlockPixelSize(info.getFormat());

	levels.resize(getLevelCount(info));

	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Setting pixel store aligment failed.");

	gl.bindTexture(info.getTarget(), name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding texture failed.");

	for (int levelNdx = 0; levelNdx < getLevelCount(info); levelNdx++)
	{
		ArrayBuffer<deUint8>&	level					= levels[levelNdx];

		const int				faceCount				= (info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : 1);

		const IVec3				levelPixelSize			= getLevelSize(info.getTarget(), info.getSize(), levelNdx);
		const IVec3				levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
		const int				levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
		const int				levelSize				= levelTexelBlockCount * texelBlockSize;

		level.setStorage(levelSize * faceCount);

		for (int faceNdx = 0; faceNdx < faceCount; faceNdx++)
		{
			genTexel(rng, moreRestrictiveFormat, texelBlockSize, levelTexelBlockCount, level.getElementPtr(faceNdx * levelSize));

			genericTexImage(gl, info.getTarget(), faceNdx, levelNdx, levelPixelSize, info.getFormat(), levelSize, level.getElementPtr(faceNdx * levelSize));
		}
	}

	gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	if (info.getTarget() == GL_TEXTURE_3D)
		gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

	gl.texParameteri(info.getTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(info.getTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Setting texture parameters failed");

	gl.bindTexture(info.getTarget(), 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Unbinding texture failed.");
}

void genRenderbufferImage (const glw::Functions&			gl,
						   de::Random&						rng,
						   deUint32							name,
						   vector<ArrayBuffer<deUint8> >&	levels,
						   const ImageInfo&					info,
						   deUint32							moreRestrictiveFormat)
{
	const IVec3					size	= info.getSize();
	const tcu::TextureFormat	format	= glu::mapGLInternalFormat(info.getFormat());

	DE_ASSERT(info.getTarget() == GL_RENDERBUFFER);
	DE_ASSERT(info.getSize().z() == 1);
	DE_ASSERT(getLevelCount(info) == 1);
	DE_ASSERT(!glu::isCompressedFormat(info.getFormat()));

	glu::Framebuffer framebuffer(gl);

	levels.resize(1);
	levels[0].setStorage(format.getPixelSize() * size.x() * size.y());
	tcu::PixelBufferAccess refAccess(format, size.x(), size.y(), 1, levels[0].getPtr());

	gl.bindRenderbuffer(GL_RENDERBUFFER, name);
	gl.renderbufferStorage(GL_RENDERBUFFER, info.getFormat(), info.getSize().x(), info.getSize().y());
	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding and setting storage for renderbuffer failed.");

	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding framebuffer and attaching renderbuffer failed.");

	{
		vector<deUint8> texelBlock(format.getPixelSize());

		if (isFixedPointFormat(info.getFormat()))
		{
			// All zeroes is only bit pattern that fixed point values can be
			// cleared to and that is valid floating point value.
			if (isFloatFormat(moreRestrictiveFormat))
				deMemset(&texelBlock[0], 0x0, texelBlock.size());
			else
			{
				// Fixed point values can be only cleared to all 0 or 1.
				const deInt32 fill = rng.getBool() ? 0xFF : 0x0;
				deMemset(&texelBlock[0], fill, texelBlock.size());
			}
		}
		else
			genTexel(rng, moreRestrictiveFormat, format.getPixelSize(), 1, &(texelBlock[0]));

		{
			const tcu::ConstPixelBufferAccess texelAccess (format, 1, 1, 1, &(texelBlock[0]));

			if (isIntFormat(info.getFormat()))
			{
				const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0);

				gl.clearBufferiv(GL_COLOR, 0, (const deInt32*)&color);
				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");

				DE_ASSERT(!tcu::isSRGB(format));
				tcu::clear(refAccess, color);
			}
			else if (isUintFormat(info.getFormat()))
			{
				const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0);

				gl.clearBufferuiv(GL_COLOR, 0, (const deUint32*)&color);
				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");

				DE_ASSERT(!tcu::isSRGB(format));
				tcu::clear(refAccess, color);
			}
			else
			{
				const tcu::Vec4 rawColor	= texelAccess.getPixel(0, 0, 0);
				const tcu::Vec4 linearColor	= (tcu::isSRGB(format) ? tcu::sRGBToLinear(rawColor) : rawColor);

				// rawColor bit pattern has been chosen to be "safe" in the destination format. For sRGB
				// formats, the clear color is in linear space. Since we want the resulting bit pattern
				// to be safe after implementation linear->sRGB transform, we must apply the inverting
				// transform to the clear color.

				if (isFloatFormat(info.getFormat()))
				{
					gl.clearBufferfv(GL_COLOR, 0, (const float*)&linearColor);
				}
				else
				{
					// fixed-point
					gl.clearColor(linearColor.x(), linearColor.y(), linearColor.z(), linearColor.w());
					gl.clear(GL_COLOR_BUFFER_BIT);
				}
				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");

				tcu::clear(refAccess, rawColor);
			}
		}
	}

	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbufer and framebuffer.");
}

void genImage (const glw::Functions&			gl,
			   de::Random&						rng,
			   deUint32							name,
			   vector<ArrayBuffer<deUint8> >&	levels,
			   const ImageInfo&					info,
			   deUint32							moreRestrictiveFormat)
{
	if (isTextureTarget(info.getTarget()))
		genTextureImage(gl, rng, name, levels, info, moreRestrictiveFormat);
	else
		genRenderbufferImage(gl, rng, name, levels, info, moreRestrictiveFormat);
}

IVec3 getTexelBlockStride (const ImageInfo& info, int level)
{
	const IVec3	size					= getLevelSize(info.getTarget(), info.getSize(), level);
	const int	texelBlockSize			= getTexelBlockSize(info.getFormat());
	const IVec3 texelBlockPixelSize		= getTexelBlockPixelSize(info.getFormat());
	const IVec3 textureTexelBlockSize	= divRoundUp(size, texelBlockPixelSize);

	return IVec3(texelBlockSize, textureTexelBlockSize.x() * texelBlockSize, textureTexelBlockSize.x() * textureTexelBlockSize.y() * texelBlockSize);
}

int sumComponents (const IVec3& v)
{
	int s = 0;

	for (int i = 0; i < 3; i++)
		s += v[i];

	return s;
}

void copyImageData (vector<ArrayBuffer<deUint8> >&			dstImageData,
					const ImageInfo&						dstImageInfo,
					int										dstLevel,
					const IVec3&							dstPos,

					const vector<ArrayBuffer<deUint8> >&	srcImageData,
					const ImageInfo&						srcImageInfo,
					int										srcLevel,
					const IVec3&							srcPos,

					const IVec3&							copySize)
{
	const ArrayBuffer<deUint8>&	srcLevelData			= srcImageData[srcLevel];
	ArrayBuffer<deUint8>&		dstLevelData			= dstImageData[dstLevel];

	const IVec3					srcTexelBlockPixelSize	= getTexelBlockPixelSize(srcImageInfo.getFormat());
	const int					srcTexelBlockSize		= getTexelBlockSize(srcImageInfo.getFormat());
	const IVec3					srcTexelPos				= srcPos / srcTexelBlockPixelSize;
	const IVec3					srcTexelBlockStride		= getTexelBlockStride(srcImageInfo, srcLevel);

	const IVec3					dstTexelBlockPixelSize	= getTexelBlockPixelSize(dstImageInfo.getFormat());
	const int					dstTexelBlockSize		= getTexelBlockSize(dstImageInfo.getFormat());
	const IVec3					dstTexelPos				= dstPos / dstTexelBlockPixelSize;
	const IVec3					dstTexelBlockStride		= getTexelBlockStride(dstImageInfo, dstLevel);

	const IVec3					copyTexelBlockCount		= copySize / srcTexelBlockPixelSize;
	const int					texelBlockSize			= srcTexelBlockSize;

	DE_ASSERT(srcTexelBlockSize == dstTexelBlockSize);
	DE_UNREF(dstTexelBlockSize);

	DE_ASSERT((copySize.x() % srcTexelBlockPixelSize.x()) == 0);
	DE_ASSERT((copySize.y() % srcTexelBlockPixelSize.y()) == 0);
	DE_ASSERT((copySize.z() % srcTexelBlockPixelSize.z()) == 0);

	DE_ASSERT((srcPos.x() % srcTexelBlockPixelSize.x()) == 0);
	DE_ASSERT((srcPos.y() % srcTexelBlockPixelSize.y()) == 0);
	DE_ASSERT((srcPos.z() % srcTexelBlockPixelSize.z()) == 0);

	for (int z = 0; z < copyTexelBlockCount.z(); z++)
	for (int y = 0; y < copyTexelBlockCount.y(); y++)
	{
		const IVec3				blockPos		(0, y, z);
		const deUint8* const	srcPtr			= srcLevelData.getElementPtr(sumComponents((srcTexelPos + blockPos) * srcTexelBlockStride));
		deUint8* const			dstPtr			= dstLevelData.getElementPtr(sumComponents((dstTexelPos + blockPos) * dstTexelBlockStride));
		const int				copyLineSize	= copyTexelBlockCount.x() * texelBlockSize;

		deMemcpy(dstPtr, srcPtr, copyLineSize);
	}
}

vector<tcu::ConstPixelBufferAccess> getLevelAccesses (const vector<ArrayBuffer<deUint8> >& data, const ImageInfo& info)
{
	const tcu::TextureFormat			format	= glu::mapGLInternalFormat(info.getFormat());
	const IVec3							size	= info.getSize();

	vector<tcu::ConstPixelBufferAccess>	result;

	DE_ASSERT((int)data.size() == getLevelCount(info));

	for (int level = 0; level < (int)data.size(); level++)
	{
		const IVec3 levelSize = getLevelSize(info.getTarget(), size, level);

		result.push_back(tcu::ConstPixelBufferAccess(format, levelSize.x(), levelSize.y(), levelSize.z(), data[level].getPtr()));
	}

	return result;
}

vector<tcu::ConstPixelBufferAccess> getCubeLevelAccesses (const vector<ArrayBuffer<deUint8> >&	data,
														  const ImageInfo&						info,
														  int									faceNdx)
{
	const tcu::TextureFormat			format				= glu::mapGLInternalFormat(info.getFormat());
	const IVec3							size				= info.getSize();
	const int							texelBlockSize		= getTexelBlockSize(info.getFormat());
	const IVec3							texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat());
	vector<tcu::ConstPixelBufferAccess>	result;

	DE_ASSERT(info.getTarget() == GL_TEXTURE_CUBE_MAP);
	DE_ASSERT((int)data.size() == getLevelCount(info));

	for (int level = 0; level < (int)data.size(); level++)
	{
		const IVec3 levelPixelSize			= getLevelSize(info.getTarget(), size, level);
		const IVec3	levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
		const int	levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
		const int	levelSize				= levelTexelBlockCount * texelBlockSize;

		result.push_back(tcu::ConstPixelBufferAccess(format, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), data[level].getElementPtr(levelSize * faceNdx)));
	}

	return result;
}

void copyImage (const glw::Functions&					gl,

				deUint32								dstName,
				vector<ArrayBuffer<deUint8> >&			dstImageData,
				const ImageInfo&						dstImageInfo,
				int										dstLevel,
				const IVec3&							dstPos,

				deUint32								srcName,
				const vector<ArrayBuffer<deUint8> >&	srcImageData,
				const ImageInfo&						srcImageInfo,
				int										srcLevel,
				const IVec3&							srcPos,

				const IVec3&							copySize)
{
	gl.copyImageSubData(srcName, srcImageInfo.getTarget(), srcLevel, srcPos.x(), srcPos.y(), srcPos.z(),
						dstName, dstImageInfo.getTarget(), dstLevel, dstPos.x(), dstPos.y(), dstPos.z(),
						copySize.x(), copySize.y(), copySize.z());

	GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyImageSubData failed.");

	copyImageData(dstImageData, dstImageInfo, dstLevel, dstPos,
				  srcImageData, srcImageInfo, srcLevel, srcPos, copySize);
}

template<class TextureView>
void renderTexture (glu::RenderContext&		renderContext,
					TextureRenderer&		renderer,
					ReferenceParams&		renderParams,
					tcu::ResultCollector&	results,
					de::Random&				rng,
					const TextureView&		refTexture,
					const Verify			verify,
					TextureImageIterator&	imageIterator,
					tcu::TestLog&			log)
{
	const tcu::RenderTarget&	renderTarget		= renderContext.getRenderTarget();
	const tcu::RGBA				threshold			= renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	const glw::Functions&		gl					= renderContext.getFunctions();
	const IVec2					renderTargetSize	= IVec2(renderTarget.getWidth(), renderTarget.getHeight());

	while (imageIterator.hasNextImage())
	{
		// \note: Reserve space upfront to avoid assigning tcu::Surface, which incurs buffer mem copy. Using a
		// conservative estimate for simplicity
		const int				imagesOnLevel	= imageIterator.getLevelImageCount();
		const int				imageEstimate	= (imageIterator.getMipLevelCount() - imageIterator.getMipLevel()) * imagesOnLevel;
		RandomizedRenderGrid	renderGrid		(renderTargetSize, imageIterator.getSize(), imageEstimate, rng.getUint32());
		vector<CellContents>	cellContents	(renderGrid.getCellCount());
		int						cellsUsed		= 0;

		// \note: Ordering of conditions is significant. If put the other way around, the code would skip one of the
		// images if the grid runs out of cells before the texture runs out of images. Advancing one grid cell over the
		// needed number has no negative impact.
		while (renderGrid.nextCell() && imageIterator.nextImage())
		{
			const int		level	  = imageIterator.getMipLevel();
			const IVec2		levelSize = imageIterator.getSize();
			const IVec2		origin	  = renderGrid.getOrigin();
			vector<float>	texCoord;

			DE_ASSERT(imageIterator.getTarget() != GL_TEXTURE_CUBE_MAP || levelSize.x() >= 4 || levelSize.y() >= 4);

			renderParams.baseLevel	= level;
			renderParams.maxLevel	= level;

			gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, level);
			gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, level);

			computeQuadTexCoords(texCoord, imageIterator);

			// Setup base viewport.
			gl.viewport(origin.x(), origin.y(), levelSize.x(), levelSize.y());

			// Draw.
			renderer.renderQuad(0, &texCoord[0], renderParams);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render.");

			if (verify == VERIFY_COMPARE_REFERENCE)
			{
				const int	target					= imageIterator.getTarget();
				const int	imageIndex				= imageIterator.getCurrentImage();

				cellContents[cellsUsed].origin		= origin;
				cellContents[cellsUsed].name		= getTextureImageName(target, level, imageIndex);
				cellContents[cellsUsed].description	= getTextureImageDescription(target, level, imageIndex);

				cellContents[cellsUsed].reference.setSize(levelSize.x(), levelSize.y());

				// Compute reference.
				sampleTexture(tcu::SurfaceAccess(cellContents[cellsUsed].reference, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
				cellsUsed++;
			}
		}

		if (cellsUsed > 0)
		{
			const IVec4		boundingBox		= renderGrid.getUsedAreaBoundingBox();
			tcu::Surface	renderedFrame	(boundingBox[2], boundingBox[3]);

			glu::readPixels(renderContext, boundingBox.x(), boundingBox.y(), renderedFrame.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to read pixels.");

			for (int idx = 0; idx < cellsUsed; idx++)
			{
				const CellContents&					cell		 (cellContents[idx]);
				const IVec2							cellOrigin	 = cell.origin - boundingBox.toWidth<2>();
				const tcu::ConstPixelBufferAccess	resultAccess = getSubregion(renderedFrame.getAccess(), cellOrigin.x(), cellOrigin.y(), cell.reference.getWidth(), cell.reference.getHeight());

				if (!intThresholdCompare(log, cell.name.c_str(), cell.description.c_str(), cell.reference.getAccess(), resultAccess, threshold.toIVec().cast<deUint32>(), tcu::COMPARE_LOG_ON_ERROR))
					results.fail("Image comparison of " + cell.description + " failed.");
				else
					log << TestLog::Message << "Image comparison of " << cell.description << " passed." << TestLog::EndMessage;;
			}
		}
	}

	gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, 0);
	gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, 1000);
}

void renderTexture2DView (tcu::TestContext&			testContext,
						  glu::RenderContext&		renderContext,
						  TextureRenderer&			renderer,
						  tcu::ResultCollector&		results,
						  de::Random&				rng,
						  deUint32					name,
						  const ImageInfo&			info,
						  const tcu::Texture2DView&	refTexture,
						  Verify					verify)
{
	tcu::TestLog&					log				= testContext.getLog();
	const glw::Functions&			gl				= renderContext.getFunctions();
	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);

	ReferenceParams					renderParams	(TEXTURETYPE_2D);
	TextureImageIterator			imageIterator	(info, getLevelCount(info));

	renderParams.samplerType	= getSamplerType(format);
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");

	renderTexture<tcu::Texture2DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);

	gl.bindTexture(GL_TEXTURE_2D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
}

void decompressTextureLevel (const tcu::TexDecompressionParams&		params,
							 ArrayBuffer<deUint8>&					levelData,
							 tcu::PixelBufferAccess&				levelAccess,
							 const tcu::CompressedTexFormat&		compressedFormat,
							 const tcu::TextureFormat&				decompressedFormat,
							 const IVec3&							levelPixelSize,
							 const void*							data)
{
	levelData.setStorage(levelPixelSize.x() * levelPixelSize.y() * levelPixelSize.z() * decompressedFormat.getPixelSize());
	levelAccess = tcu::PixelBufferAccess(decompressedFormat, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), levelData.getPtr());

	tcu::decompress(levelAccess, compressedFormat, (const deUint8*)data, params);
}

void decompressTexture (vector<ArrayBuffer<deUint8> >&			levelDatas,
						vector<tcu::PixelBufferAccess>&			levelAccesses,
						glu::RenderContext&						renderContext,
						const ImageInfo&						info,
						const vector<ArrayBuffer<deUint8> >&	data)
{
	const tcu::CompressedTexFormat	compressedFormat	= glu::mapGLCompressedTexFormat(info.getFormat());
	const tcu::TextureFormat		decompressedFormat	= tcu::getUncompressedFormat(compressedFormat);
	const IVec3						size				= info.getSize();
	const bool						isES32				= glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));

	de::UniquePtr<glu::ContextInfo>	ctxInfo				(glu::ContextInfo::create(renderContext));
	tcu::TexDecompressionParams		decompressParams;

	if (tcu::isAstcFormat(compressedFormat))
	{
		if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && !tcu::isAstcSRGBFormat(compressedFormat))
			decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR);
		else if (isES32 || ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
			decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR);
		else
			DE_ASSERT(false);
	}

	levelDatas.resize(getLevelCount(info));
	levelAccesses.resize(getLevelCount(info));

	for (int level = 0; level < getLevelCount(info); level++)
	{
		const IVec3					levelPixelSize	= getLevelSize(info.getTarget(), size, level);
		de::ArrayBuffer<deUint8>&	levelData		= levelDatas[level];
		tcu::PixelBufferAccess&		levelAccess		= levelAccesses[level];

		decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, data[level].getPtr());
	}
}

void renderTexture2D (tcu::TestContext&						testContext,
					  glu::RenderContext&					renderContext,
					  TextureRenderer&						textureRenderer,
					  tcu::ResultCollector&					results,
					  de::Random&							rng,
					  deUint32								name,
					  const vector<ArrayBuffer<deUint8> >&	data,
					  const ImageInfo&						info,
					  Verify								verify)
{
	if (glu::isCompressedFormat(info.getFormat()))
	{
		vector<de::ArrayBuffer<deUint8> >	levelDatas;
		vector<tcu::PixelBufferAccess>		levelAccesses;

		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);

		{
			const tcu::Texture2DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));

			renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
		}
	}
	else
	{
		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
		const tcu::Texture2DView					refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));

		renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
	}
}

void renderTexture3DView (tcu::TestContext&			testContext,
						  glu::RenderContext&		renderContext,
						  TextureRenderer&			renderer,
						  tcu::ResultCollector&		results,
						  de::Random&				rng,
						  deUint32					name,
						  const ImageInfo&			info,
						  const tcu::Texture3DView&	refTexture,
						  Verify					verify)
{
	tcu::TestLog&					log				= testContext.getLog();
	const glw::Functions&			gl				= renderContext.getFunctions();
	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);

	ReferenceParams					renderParams	(TEXTURETYPE_3D);
	TextureImageIterator			imageIterator	(info, getLevelCount(info));

	renderParams.samplerType	= getSamplerType(format);
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_3D, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");

	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");

	renderTexture<tcu::Texture3DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);

	gl.bindTexture(GL_TEXTURE_3D, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
}

void renderTexture3D (tcu::TestContext&						testContext,
					  glu::RenderContext&					renderContext,
					  TextureRenderer&						textureRenderer,
					  tcu::ResultCollector&					results,
					  de::Random&							rng,
					  deUint32								name,
					  const vector<ArrayBuffer<deUint8> >&	data,
					  const ImageInfo&						info,
				      Verify								verify)
{
	if (glu::isCompressedFormat(info.getFormat()))
	{
		vector<de::ArrayBuffer<deUint8> >	levelDatas;
		vector<tcu::PixelBufferAccess>		levelAccesses;

		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);

		{
			const tcu::Texture3DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));

			renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
		}
	}
	else
	{
		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
		const tcu::Texture3DView					refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));

		renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
	}
}

void renderTextureCubemapView (tcu::TestContext&			testContext,
							   glu::RenderContext&			renderContext,
							   TextureRenderer&				renderer,
							   tcu::ResultCollector&		results,
							   de::Random&					rng,
							   deUint32						name,
							   const ImageInfo&				info,
							   const tcu::TextureCubeView&	refTexture,
							   Verify						verify)
{
	tcu::TestLog&					log				= testContext.getLog();
	const glw::Functions&			gl				= renderContext.getFunctions();
	const tcu::TextureFormat		format			= refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X).getFormat();
	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);

	ReferenceParams					renderParams	(TEXTURETYPE_CUBE);
    // \note It seems we can't reliably sample two smallest texture levels with cubemaps
	TextureImageIterator			imageIterator	(info, getLevelCount(info) - 2);

	renderParams.samplerType	= getSamplerType(format);
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");

	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");

	renderTexture<tcu::TextureCubeView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);

	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
}

void renderTextureCubemap (tcu::TestContext&					testContext,
						   glu::RenderContext&					renderContext,
						   TextureRenderer&						textureRenderer,
						   tcu::ResultCollector&				results,
						   de::Random&							rng,
						   deUint32								name,
						   const vector<ArrayBuffer<deUint8> >&	data,
						   const ImageInfo&						info,
						   Verify								verify)
{
	if (glu::isCompressedFormat(info.getFormat()))
	{
		const tcu::CompressedTexFormat&	compressedFormat	= glu::mapGLCompressedTexFormat(info.getFormat());
		const tcu::TextureFormat&		decompressedFormat	= tcu::getUncompressedFormat(compressedFormat);

		const int						texelBlockSize		= getTexelBlockSize(info.getFormat());
		const IVec3						texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat());

		const bool						isES32				= glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));

		vector<tcu::PixelBufferAccess>	levelAccesses[6];
		vector<ArrayBuffer<deUint8> >	levelDatas[6];
		de::UniquePtr<glu::ContextInfo>	ctxInfo				(glu::ContextInfo::create(renderContext));
		tcu::TexDecompressionParams		decompressParams;

		if (tcu::isAstcFormat(compressedFormat))
		{
			if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr") && !tcu::isAstcSRGBFormat(compressedFormat))
				decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR);
			else if (isES32 || ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
				decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR);
			else
				DE_ASSERT(false);
		}

		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
		{
			levelAccesses[faceNdx].resize(getLevelCount(info));
			levelDatas[faceNdx].resize(getLevelCount(info));
		}

		for (int level = 0; level < getLevelCount(info); level++)
		{
			for (int faceNdx = 0; faceNdx < 6; faceNdx++)
			{
				const IVec3				levelPixelSize			= getLevelSize(info.getTarget(), info.getSize(), level);
				const IVec3				levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
				const int				levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
				const int				levelSize				= levelTexelBlockCount * texelBlockSize;

				const deUint8*			dataPtr					= data[level].getElementPtr(faceNdx * levelSize);
				tcu::PixelBufferAccess& levelAccess				= levelAccesses[faceNdx][level];
				ArrayBuffer<deUint8>&	levelData				= levelDatas[faceNdx][level];

				decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, dataPtr);
			}
		}

		const tcu::ConstPixelBufferAccess* levels[6];

		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
			levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]);

		{
			const tcu::TextureCubeView refTexture(getLevelCount(info), levels);

			renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
		}
	}
	else
	{
		const vector<tcu::ConstPixelBufferAccess> levelAccesses[6] =
		{
			getCubeLevelAccesses(data, info, 0),
			getCubeLevelAccesses(data, info, 1),
			getCubeLevelAccesses(data, info, 2),
			getCubeLevelAccesses(data, info, 3),
			getCubeLevelAccesses(data, info, 4),
			getCubeLevelAccesses(data, info, 5),
		};

		const tcu::ConstPixelBufferAccess* levels[6];

		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
			levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]);

		{
			const tcu::TextureCubeView refTexture(getLevelCount(info), levels);

			renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
		}
	}
}

void renderTexture2DArrayView (tcu::TestContext&				testContext,
							   glu::RenderContext&				renderContext,
							   TextureRenderer&					renderer,
							   tcu::ResultCollector&			results,
							   de::Random&						rng,
							   deUint32							name,
							   const ImageInfo&					info,
							   const tcu::Texture2DArrayView&	refTexture,
							   Verify							verify)
{
	tcu::TestLog&					log				= testContext.getLog();
	const glw::Functions&			gl				= renderContext.getFunctions();
	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);

	ReferenceParams					renderParams	(TEXTURETYPE_2D_ARRAY);
	TextureImageIterator			imageIterator	(info, getLevelCount(info));

	renderParams.samplerType	= getSamplerType(format);
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, name);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");

	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");

	renderTexture<tcu::Texture2DArrayView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);

	gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
}

void renderTexture2DArray (tcu::TestContext&					testContext,
						   glu::RenderContext&					renderContext,
						   TextureRenderer&						textureRenderer,
						   tcu::ResultCollector&				results,
						   de::Random&							rng,
						   deUint32								name,
						   const vector<ArrayBuffer<deUint8> >&	data,
						   const ImageInfo&						info,
						   Verify								verify)
{
	if (glu::isCompressedFormat(info.getFormat()))
	{
		vector<de::ArrayBuffer<deUint8> >	levelDatas;
		vector<tcu::PixelBufferAccess>		levelAccesses;

		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);

		{
			const tcu::Texture2DArrayView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));

			renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
		}
	}
	else
	{
		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
		const tcu::Texture2DArrayView				refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));

		renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
	}
}

tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
{
	switch (tcu::getTextureChannelClass(format.type))
	{
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);

		default:
			DE_ASSERT(false);
			return tcu::TextureFormat();
	}
}

Vec4 calculateThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
{
	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);

	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);

	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);

	{
		const tcu::IVec4	srcBits		= tcu::getTextureFormatBitDepth(sourceFormat);
		const tcu::IVec4	readBits	= tcu::getTextureFormatBitDepth(readPixelsFormat);

		return Vec4(1.0f) / ((tcu::IVec4(1) << (tcu::min(srcBits, readBits))) - tcu::IVec4(1)).cast<float>();
	}
}

void renderRenderbuffer (tcu::TestContext&						testContext,
						 glu::RenderContext&					renderContext,
						 tcu::ResultCollector&					results,
						 deUint32								name,
						 const vector<ArrayBuffer<deUint8> >&	data,
						 const ImageInfo&						info,
						 Verify									verify)
{
	const glw::Functions&				gl					= renderContext.getFunctions();
	TestLog&							log					= testContext.getLog();

	const tcu::TextureFormat			format				= glu::mapGLInternalFormat(info.getFormat());
	const IVec3							size				= info.getSize();
	const tcu::ConstPixelBufferAccess	refRenderbuffer		(format, size.x(), size.y(), 1, data[0].getPtr());
	const tcu::TextureFormat			readPixelsFormat	= getReadPixelFormat(format);
	tcu::TextureLevel					renderbuffer		(readPixelsFormat, size.x(), size.y());

	DE_ASSERT(size.z() == 1);
	DE_ASSERT(data.size() == 1);

	{
		glu::Framebuffer framebuffer(gl);

		gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create and bind framebuffer.");

		gl.bindRenderbuffer(GL_RENDERBUFFER, name);
		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind and attach renderbuffer to framebuffer.");

		if (verify)
			glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess());

		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbuffer and framebuffer.");
	}

	if (verify == VERIFY_COMPARE_REFERENCE)
	{
		if (isFloatFormat(info.getFormat()))
		{
			const tcu::UVec4 threshold (2, 2, 2, 2);

			if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
				results.fail("Image comparison failed.");
			else
				log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
		}
		else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat()))
		{
			const tcu::UVec4 threshold (1, 1, 1, 1);

			if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
				results.fail("Image comparison failed.");
			else
				log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
		}
		else
		{
			const Vec4 threshold = calculateThreshold(format, readPixelsFormat);

			if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
				results.fail("Image comparison failed.");
			else
				log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
		}
	}
}

void render (tcu::TestContext&						testContext,
			 glu::RenderContext&					renderContext,
			 TextureRenderer&						textureRenderer,
			 tcu::ResultCollector&					results,
			 de::Random&							rng,
			 deUint32								name,
			 const vector<ArrayBuffer<deUint8> >&	data,
			 const ImageInfo&						info,
			 Verify									verify)
{
	switch (info.getTarget())
	{
		case GL_TEXTURE_2D:
			renderTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
			break;

		case GL_TEXTURE_3D:
			renderTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
			break;

		case GL_TEXTURE_CUBE_MAP:
			renderTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
			break;

		case GL_TEXTURE_2D_ARRAY:
			renderTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
			break;

		case GL_RENDERBUFFER:
			renderRenderbuffer(testContext, renderContext, results, name, data, info, verify);
			break;

		default:
			DE_ASSERT(false);
	}
}

void logTestImageInfo (TestLog&			log,
					   const ImageInfo&	imageInfo)
{
	log << TestLog::Message << "Target: " << targetToName(imageInfo.getTarget()) << TestLog::EndMessage;
	log << TestLog::Message << "Size: " << imageInfo.getSize() << TestLog::EndMessage;
	log << TestLog::Message << "Levels: " << getLevelCount(imageInfo) << TestLog::EndMessage;
	log << TestLog::Message << "Format: " << formatToName(imageInfo.getFormat()) << TestLog::EndMessage;
}

void logTestInfo (TestLog&			log,
				  const ImageInfo&	srcImageInfo,
				  const ImageInfo&	dstImageInfo)
{
	tcu::ScopedLogSection section(log, "TestCaseInfo", "Test case info");

	log << TestLog::Message << "Testing copying from " << targetToName(srcImageInfo.getTarget()) << " to " << targetToName(dstImageInfo.getTarget()) << "." << TestLog::EndMessage;

	{
		tcu::ScopedLogSection srcSection(log, "Source image info.", "Source image info.");
		logTestImageInfo(log, srcImageInfo);
	}

	{
		tcu::ScopedLogSection dstSection(log, "Destination image info.", "Destination image info.");
		logTestImageInfo(log, dstImageInfo);
	}
}

class CopyImageTest : public TestCase
{
public:
							CopyImageTest			(Context&			context,
													 const ImageInfo&	srcImage,
													 const ImageInfo&	dstImage,
													 const char*		name,
													 const char*		description);

							~CopyImageTest			(void);

	void					init					(void);
	void					deinit					(void);

	TestCase::IterateResult	iterate					(void);

private:

	void					logTestInfoIter			(void);
	void					createImagesIter		(void);
	void					destroyImagesIter		(void);
	void					verifySourceIter		(void);
	void					verifyDestinationIter	(void);
	void					renderSourceIter		(void);
	void					renderDestinationIter	(void);
	void					copyImageIter			(void);

	typedef void (CopyImageTest::*IterationFunc)(void);

	struct Iteration
	{
		Iteration (int methodCount_, const IterationFunc* methods_)
			: methodCount	(methodCount_)
			, methods		(methods_)
		{
		}

		int						methodCount;
		const IterationFunc*	methods;
	};

	struct State
	{
		State (int					seed,
			   tcu::TestLog&		log,
			   glu::RenderContext&	renderContext)
			: rng				(seed)
			, results			(log)
			, srcImage			(NULL)
			, dstImage			(NULL)
			, textureRenderer	(renderContext, log, glu::getContextTypeGLSLVersion(renderContext.getType()), glu::PRECISION_HIGHP)
		{
		}

		~State (void)
		{
			delete srcImage;
			delete dstImage;
		}

		de::Random						rng;
		tcu::ResultCollector			results;
		glu::ObjectWrapper*				srcImage;
		glu::ObjectWrapper*				dstImage;
		TextureRenderer					textureRenderer;

		vector<ArrayBuffer<deUint8> >	srcImageLevels;
		vector<ArrayBuffer<deUint8> >	dstImageLevels;
	};

	const ImageInfo	m_srcImageInfo;
	const ImageInfo	m_dstImageInfo;

	int				m_iteration;
	State*			m_state;
};

CopyImageTest::CopyImageTest (Context&			context,
							  const ImageInfo&	srcImage,
							  const ImageInfo&	dstImage,
							  const char*		name,
							  const char*		description)
	: TestCase			(context, name, description)
	, m_srcImageInfo	(srcImage)
	, m_dstImageInfo	(dstImage)

	, m_iteration		(0)
	, m_state			(NULL)
{
}

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

void checkFormatSupport (glu::ContextInfo& info, deUint32 format, deUint32 target, glu::RenderContext& ctx)
{
	const bool isES32 = glu::contextSupports(ctx.getType(), glu::ApiType::es(3, 2));

	if (glu::isCompressedFormat(format))
	{
		if (isAstcFormat(glu::mapGLCompressedTexFormat(format)))
		{
			DE_ASSERT(target != GL_RENDERBUFFER);
			if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_sliced_3d") &&
				!info.isExtensionSupported("GL_KHR_texture_compression_astc_hdr") &&
				!info.isExtensionSupported("GL_OES_texture_compression_astc"))
			{
				if (target == GL_TEXTURE_3D)
					TCU_THROW(NotSupportedError, "TEXTURE_3D target not supported.");
				if (!isES32 && !info.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
					TCU_THROW(NotSupportedError, "Compressed astc texture not supported.");
			}
		}
		else
		{
			if (!info.isCompressedTextureFormatSupported(format))
				TCU_THROW(NotSupportedError, "Compressed texture not supported.");
		}
	}
}

void CopyImageTest::init (void)
{
	auto&							rc				= m_context.getRenderContext();
	de::UniquePtr<glu::ContextInfo> ctxInfo			(glu::ContextInfo::create(rc));
	const bool						isES32orGL45	= glu::contextSupports(rc.getType(), glu::ApiType::es(3, 2)) ||
													  glu::contextSupports(rc.getType(), glu::ApiType::core(4, 5));

	if (!isES32orGL45 && !ctxInfo->isExtensionSupported("GL_EXT_copy_image"))
		throw tcu::NotSupportedError("Extension GL_EXT_copy_image not supported.", "", __FILE__, __LINE__);

	checkFormatSupport(*ctxInfo, m_srcImageInfo.getFormat(), m_srcImageInfo.getTarget(), rc);
	checkFormatSupport(*ctxInfo, m_dstImageInfo.getFormat(), m_dstImageInfo.getTarget(), rc);

	{
		SeedBuilder builder;

		builder << 903980
				<< m_srcImageInfo
				<< m_dstImageInfo;

		m_state = new State(builder.get(), m_testCtx.getLog(), rc);
	}
}

void CopyImageTest::deinit (void)
{
	delete m_state;
	m_state = NULL;
}

void CopyImageTest::logTestInfoIter (void)
{
	TestLog& log = m_testCtx.getLog();

	logTestInfo(log, m_srcImageInfo, m_dstImageInfo);
}

void CopyImageTest::createImagesIter (void)
{
	TestLog&				log						= m_testCtx.getLog();
	glu::RenderContext&		renderContext			= m_context.getRenderContext();
	const glw::Functions&	gl						= renderContext.getFunctions();
	const deUint32			moreRestrictiveFormat	= getMoreRestrictiveFormat(m_srcImageInfo.getFormat(), m_dstImageInfo.getFormat());
	de::Random&				rng						= m_state->rng;

	DE_ASSERT(!m_state->srcImage);
	DE_ASSERT(!m_state->dstImage);

	m_state->srcImage = new glu::ObjectWrapper(gl, getObjectTraits(m_srcImageInfo));
	m_state->dstImage = new glu::ObjectWrapper(gl, getObjectTraits(m_dstImageInfo));

	{
		glu::ObjectWrapper&				srcImage				= *m_state->srcImage;
		glu::ObjectWrapper&				dstImage				= *m_state->dstImage;

		vector<ArrayBuffer<deUint8> >&	srcImageLevels			= m_state->srcImageLevels;
		vector<ArrayBuffer<deUint8> >&	dstImageLevels			= m_state->dstImageLevels;

		log << TestLog::Message << "Creating source image." << TestLog::EndMessage;
		genImage(gl, rng, *srcImage, srcImageLevels, m_srcImageInfo, moreRestrictiveFormat);

		log << TestLog::Message << "Creating destination image." << TestLog::EndMessage;
		genImage(gl, rng, *dstImage, dstImageLevels, m_dstImageInfo, moreRestrictiveFormat);
	}
}

void CopyImageTest::destroyImagesIter (void)
{
	TestLog& log = m_testCtx.getLog();

	log << TestLog::Message << "Deleting source image. " << TestLog::EndMessage;

	delete m_state->srcImage;
	m_state->srcImage = NULL;
	m_state->srcImageLevels.clear();

	log << TestLog::Message << "Deleting destination image. " << TestLog::EndMessage;

	delete m_state->dstImage;
	m_state->dstImage = NULL;
	m_state->dstImageLevels.clear();
}

void CopyImageTest::verifySourceIter (void)
{
	TestLog&						log					= m_testCtx.getLog();
	const tcu::ScopedLogSection		sourceSection		(log, "Source image verify.", "Source image verify.");

	de::Random&						rng					= m_state->rng;
	tcu::ResultCollector&			results				= m_state->results;
	glu::ObjectWrapper&				srcImage			= *m_state->srcImage;
	vector<ArrayBuffer<deUint8> >&	srcImageLevels		= m_state->srcImageLevels;

	log << TestLog::Message << "Verifying source image." << TestLog::EndMessage;

	render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_COMPARE_REFERENCE);
}

void CopyImageTest::verifyDestinationIter (void)
{
	TestLog&						log					= m_testCtx.getLog();
	const tcu::ScopedLogSection		destinationSection	(log, "Destination image verify.", "Destination image verify.");

	de::Random&						rng					= m_state->rng;
	tcu::ResultCollector&			results				= m_state->results;
	glu::ObjectWrapper&				dstImage			= *m_state->dstImage;
	vector<ArrayBuffer<deUint8> >&	dstImageLevels		= m_state->dstImageLevels;

	log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage;

	render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_COMPARE_REFERENCE);
}

void CopyImageTest::renderSourceIter (void)
{
	TestLog&						log					= m_testCtx.getLog();
	const tcu::ScopedLogSection		sourceSection		(log, "Source image verify.", "Source image verify.");

	de::Random&						rng					= m_state->rng;
	tcu::ResultCollector&			results				= m_state->results;
	glu::ObjectWrapper&				srcImage			= *m_state->srcImage;
	vector<ArrayBuffer<deUint8> >&	srcImageLevels		= m_state->srcImageLevels;

	log << TestLog::Message << "Verifying source image." << TestLog::EndMessage;

	render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_NONE);
}

void CopyImageTest::renderDestinationIter (void)
{
	TestLog&						log					= m_testCtx.getLog();
	const tcu::ScopedLogSection		destinationSection	(log, "Destination image verify.", "Destination image verify.");

	de::Random&						rng					= m_state->rng;
	tcu::ResultCollector&			results				= m_state->results;
	glu::ObjectWrapper&				dstImage			= *m_state->dstImage;
	vector<ArrayBuffer<deUint8> >&	dstImageLevels		= m_state->dstImageLevels;

	log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage;

	render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_NONE);
}

struct Copy
{
	Copy (const IVec3&	srcPos_,
		  int			srcLevel_,

		  const IVec3&	dstPos_,
		  int			dstLevel_,

		  const IVec3&	size_,
		  const IVec3&	dstSize_)
		: srcPos	(srcPos_)
		, srcLevel	(srcLevel_)

		, dstPos	(dstPos_)
		, dstLevel	(dstLevel_)

		, size		(size_)
		, dstSize	(dstSize_)
	{
	}

	IVec3	srcPos;
	int		srcLevel;
	IVec3	dstPos;
	int		dstLevel;
	IVec3	size;
	IVec3	dstSize;	//!< used only for logging
};

int getLastFullLevel (const ImageInfo& info)
{
	const int	levelCount		= getLevelCount(info);
	const IVec3	blockPixelSize	= getTexelBlockPixelSize(info.getFormat());

	for (int level = 0; level < levelCount; level++)
	{
		const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);

		if (levelSize.x() < blockPixelSize.x() || levelSize.y() < blockPixelSize.y() || levelSize.z() < blockPixelSize.z())
			return level - 1;
	}

	return levelCount -1;
}

void generateCopies (vector<Copy>& copies, const ImageInfo& srcInfo, const ImageInfo& dstInfo)
{
	const deUint32	srcTarget		= srcInfo.getTarget();
	const deUint32	dstTarget		= dstInfo.getTarget();

	const bool		srcIsTexture	= isTextureTarget(srcInfo.getTarget());
	const bool		dstIsTexture	= isTextureTarget(dstInfo.getTarget());

	const bool		srcIsCube		= srcTarget == GL_TEXTURE_CUBE_MAP;
	const bool		dstIsCube		= dstTarget == GL_TEXTURE_CUBE_MAP;

	const IVec3		srcBlockPixelSize		= getTexelBlockPixelSize(srcInfo.getFormat());
	const IVec3		dstBlockPixelSize		= getTexelBlockPixelSize(dstInfo.getFormat());

	const int levels[] =
	{
		0, 1, -1
	};

	for (int levelNdx = 0; levelNdx < (srcIsTexture || dstIsTexture ? DE_LENGTH_OF_ARRAY(levels) : 1); levelNdx++)
	{
		const int	srcLevel				= (srcIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(srcInfo)) : 0);
		const int	dstLevel				= (dstIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(dstInfo)) : 0);

		const IVec3	srcSize					= getLevelSize(srcInfo.getTarget(), srcInfo.getSize(), srcLevel);
		const IVec3	dstSize					= getLevelSize(dstInfo.getTarget(), dstInfo.getSize(), dstLevel);

		// \note These are rounded down
		const IVec3	srcCompleteBlockSize	= IVec3(srcSize.x() / srcBlockPixelSize.x(), srcSize.y() / srcBlockPixelSize.y(), (srcIsCube ? 6 : srcSize.z() / srcBlockPixelSize.z()));
		const IVec3	dstCompleteBlockSize	= IVec3(dstSize.x() / dstBlockPixelSize.x(), dstSize.y() / dstBlockPixelSize.y(), (dstIsCube ? 6 : dstSize.z() / dstBlockPixelSize.z()));

		const IVec3	maxCopyBlockSize		= tcu::min(srcCompleteBlockSize, dstCompleteBlockSize);

		// \note These are rounded down
		const int	copyBlockWidth			= de::max((2 * (maxCopyBlockSize.x() / 4)) - 1, 1);
		const int	copyBlockHeight			= de::max((2 * (maxCopyBlockSize.y() / 4)) - 1, 1);
		const int	copyBlockDepth			= de::max((2 * (maxCopyBlockSize.z() / 4)) - 1, 1);

		// Copy NPOT block to (0,0,0) from other corner on src
		{
			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
			const IVec3	srcBlockPos		(srcCompleteBlockSize - copyBlockSize);
			const IVec3	dstBlockPos		(0, 0, 0);

			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
			const IVec3 srcCopySize		(copyBlockSize * srcBlockPixelSize);
			const IVec3 dstCopySize		(copyBlockSize * dstBlockPixelSize);

			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize));
		}

		// Copy NPOT block from (0,0,0) to other corner on dst
		{
			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
			const IVec3	srcBlockPos		(0, 0, 0);
			const IVec3	dstBlockPos		(dstCompleteBlockSize - copyBlockSize);

			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
			const IVec3 srcCopySize		(copyBlockSize * srcBlockPixelSize);
			const IVec3 dstCopySize		(copyBlockSize * dstBlockPixelSize);

			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize));
		}

		// Copy NPOT block near the corner with high coordinates
		{
			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
			const IVec3	srcBlockPos		(tcu::max((srcCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0)));
			const IVec3	dstBlockPos		(tcu::max((dstCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0)));

			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
			const IVec3 srcCopySize		(copyBlockSize * srcBlockPixelSize);
			const IVec3 dstCopySize		(copyBlockSize * dstBlockPixelSize);

			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, srcCopySize, dstCopySize));
		}
	}
}

void CopyImageTest::copyImageIter (void)
{
	TestLog&						log				= m_testCtx.getLog();
	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
	glu::ObjectWrapper&				srcImage		= *m_state->srcImage;
	glu::ObjectWrapper&				dstImage		= *m_state->dstImage;

	vector<ArrayBuffer<deUint8> >&	srcImageLevels	= m_state->srcImageLevels;
	vector<ArrayBuffer<deUint8> >&	dstImageLevels	= m_state->dstImageLevels;
	vector<Copy>					copies;

	generateCopies(copies, m_srcImageInfo, m_dstImageInfo);

	for (int copyNdx = 0; copyNdx < (int)copies.size(); copyNdx++)
	{
		const Copy& copy = copies[copyNdx];

		log	<< TestLog::Message
			<< "Copying area with size " << copy.size
			<< " from source image position " << copy.srcPos << " and mipmap level " << copy.srcLevel
			<< " to destination image position " << copy.dstPos << " and mipmap level " << copy.dstLevel << ". "
			<< "Size in destination format is " << copy.dstSize
			<< TestLog::EndMessage;

		copyImage(gl, *dstImage, dstImageLevels, m_dstImageInfo, copy.dstLevel, copy.dstPos,
					  *srcImage, srcImageLevels, m_srcImageInfo, copy.srcLevel, copy.srcPos, copy.size);
	}
}

TestCase::IterateResult CopyImageTest::iterate (void)
{
	// Note: Returning from iterate() has two side-effects: it touches
	// watchdog and calls eglSwapBuffers. For the first it's important
	// to keep work per iteration reasonable to avoid
	// timeouts. Because of the latter, it's prudent to do more than
	// trivial amount of work. Otherwise we'll end up waiting for a
	// new buffer in swap, it seems.

	// The split below tries to combine trivial work with actually
	// expensive rendering iterations without having too much
	// rendering in one iteration to avoid timeouts.
	const IterationFunc iteration1[] =
	{
		&CopyImageTest::logTestInfoIter,
		&CopyImageTest::createImagesIter,
		&CopyImageTest::renderSourceIter
	};
	const IterationFunc iteration2[] =
	{
		&CopyImageTest::renderDestinationIter
	};
	const IterationFunc iteration3[] =
	{
		&CopyImageTest::copyImageIter,
		&CopyImageTest::verifySourceIter
	};
	const IterationFunc iteration4[] =
	{
		&CopyImageTest::verifyDestinationIter,
		&CopyImageTest::destroyImagesIter
	};
	const IterationFunc iteration5[] =
	{
		&CopyImageTest::createImagesIter,
		&CopyImageTest::copyImageIter,
		&CopyImageTest::verifySourceIter
	};
	const IterationFunc iteration6[] =
	{
		&CopyImageTest::verifyDestinationIter,
		&CopyImageTest::destroyImagesIter
	};
	const Iteration iterations[] =
	{
		Iteration(DE_LENGTH_OF_ARRAY(iteration1), iteration1),
		Iteration(DE_LENGTH_OF_ARRAY(iteration2), iteration2),
		Iteration(DE_LENGTH_OF_ARRAY(iteration3), iteration3),
		Iteration(DE_LENGTH_OF_ARRAY(iteration4), iteration4),
		Iteration(DE_LENGTH_OF_ARRAY(iteration5), iteration5),
		Iteration(DE_LENGTH_OF_ARRAY(iteration6), iteration6)
	};

	DE_ASSERT(m_iteration < DE_LENGTH_OF_ARRAY(iterations));
	for (int method = 0; method < iterations[m_iteration].methodCount; method++)
		(this->*iterations[m_iteration].methods[method])();

	m_iteration++;

	if (m_iteration < DE_LENGTH_OF_ARRAY(iterations))
	{
		return CONTINUE;
	}
	else
	{
		m_state->results.setTestContextResult(m_testCtx);
		return STOP;
	}
}

class CopyImageTests : public TestCaseGroup
{
public:
						CopyImageTests			(Context& context, bool is_GL45);
						~CopyImageTests			(void);

	void				init					(void);

private:
						CopyImageTests			(const CopyImageTests& other);
	CopyImageTests&		operator=				(const CopyImageTests& other);
	bool				m_isGL45;
};

CopyImageTests::CopyImageTests (Context& context, bool is_GL45)
	: TestCaseGroup	(context, "copy_image", "Copy image tests for GL_EXT_copy_image.")
	, m_isGL45 (is_GL45)
{
}

CopyImageTests::~CopyImageTests (void)
{
}

int smallestCommonMultiple (int a_, int b_)
{
	int	a		= (a_ > b_ ? a_ : b_);
	int	b		= (a_ > b_ ? b_ : a_);
	int	result  = 1;

	for (int i = b/2; i > 1; i--)
	{
		while ((a % i) == 0 && (b % i) == 0)
		{
			result *= i;
			a /= i;
			b /= i;
		}
	}

	return result * a * b;
}

IVec3 getTestedSize (deUint32 target, deUint32 format, const IVec3& targetSize)
{
	const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(format);
	const bool	isCube				= target == GL_TEXTURE_CUBE_MAP;
	const bool	is3D				= target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;

	if (isCube)
	{
		const int	multiplier	= smallestCommonMultiple(texelBlockPixelSize.x(), texelBlockPixelSize.y());
		const int	size		= (1 + (targetSize.x() / multiplier)) * multiplier;

		return IVec3(size, size, 1);
	}
	else if (is3D)
	{
		return (1 + (targetSize / texelBlockPixelSize)) * texelBlockPixelSize;
	}
	else
	{
		const int width = (1 + targetSize.x() / texelBlockPixelSize.x()) * texelBlockPixelSize.x();
		const int height = ((targetSize.y() / texelBlockPixelSize.y()) - 1) * texelBlockPixelSize.y();

		return IVec3(width, height, 1);
	}
}

void addCopyTests (TestCaseGroup* root, deUint32 srcFormat, deUint32 dstFormat)
{
	const string			groupName	= string(formatToName(srcFormat)) + "_" + formatToName(dstFormat);
	TestCaseGroup* const	group		= new TestCaseGroup(root->getContext(), groupName.c_str(), groupName.c_str());

	const deUint32 targets[] =
	{
		GL_TEXTURE_2D,
		GL_TEXTURE_3D,
		GL_TEXTURE_CUBE_MAP,
		GL_TEXTURE_2D_ARRAY,
		GL_RENDERBUFFER
	};

	root->addChild(group);

	for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(targets); srcTargetNdx++)
	{
		const deUint32	srcTarget				= targets[srcTargetNdx];
		const bool		srcIs3D					= srcTarget == GL_TEXTURE_2D_ARRAY || srcTarget == GL_TEXTURE_3D;

		if (glu::isCompressedFormat(srcFormat) && srcTarget == GL_RENDERBUFFER)
			continue;

		if (srcTarget == GL_RENDERBUFFER && !isColorRenderable(srcFormat))
			continue;

		if (glu::isCompressedFormat(srcFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(srcFormat)) && srcIs3D)
			continue;

		for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(targets); dstTargetNdx++)
		{
			const deUint32	dstTarget				= targets[dstTargetNdx];
			const bool		dstIs3D					= dstTarget == GL_TEXTURE_2D_ARRAY || dstTarget == GL_TEXTURE_3D;

			if (glu::isCompressedFormat(dstFormat) && dstTarget == GL_RENDERBUFFER)
				continue;

			if (dstTarget == GL_RENDERBUFFER && !isColorRenderable(dstFormat))
				continue;

			if (glu::isCompressedFormat(dstFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(dstFormat)) && dstIs3D)
				continue;

			const string	targetTestName	= string(targetToName(srcTarget)) + "_to_" + targetToName(dstTarget);

			// Compressed formats require more space to fit all block size combinations.
			const bool		isCompressedCase	= glu::isCompressedFormat(srcFormat) || glu::isCompressedFormat(dstFormat);
			const IVec3		targetSize			= isCompressedCase ? IVec3(128, 128, 16) : IVec3(64, 64, 8);
			const IVec3		srcSize				= getTestedSize(srcTarget, srcFormat, targetSize);
			const IVec3		dstSize				= getTestedSize(dstTarget, dstFormat, targetSize);

			group->addChild(new CopyImageTest(root->getContext(),
											ImageInfo(srcFormat, srcTarget, srcSize),
											ImageInfo(dstFormat, dstTarget, dstSize),
											targetTestName.c_str(), targetTestName.c_str()));
		}
	}
}

void CopyImageTests::init (void)
{
	map<ViewClass, vector<deUint32> >							textureFormatViewClasses;
	map<ViewClass, vector<deUint32> >							compressedTextureFormatViewClasses;
	map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >	mixedViewClasses;

	// Texture view classes
	textureFormatViewClasses[VIEWCLASS_128_BITS]		= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_96_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_64_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_48_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_32_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_24_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_16_BITS]			= vector<deUint32>();
	textureFormatViewClasses[VIEWCLASS_8_BITS]			= vector<deUint32>();

	// 128bit / VIEWCLASS_128_BITS
	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32F);
	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32I);
	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32UI);

	// 96bit / VIEWCLASS_96_BITS
	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32F);
	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32I);
	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32UI);

	// 64bit / VIEWCLASS_64_BITS
	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32F);
	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32I);
	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32UI);

	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16F);
	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16I);
	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16UI);

	// 48bit / VIEWCLASS_48_BITS
	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16F);
	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16I);
	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16UI);

	// 32bit / VIEWCLASS_32_BITS
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32F);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32I);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32UI);

	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16F);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16I);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16UI);

	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8I);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8UI);

	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R11F_G11F_B10F);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2UI);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8_SNORM);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_SRGB8_ALPHA8);
	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB9_E5);

	// 24bit / VIEWCLASS_24_BITS
	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8);
	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8I);
	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8UI);
	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8_SNORM);
	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_SRGB8);

	// 16bit / VIEWCLASS_16_BITS
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16F);
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16I);
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16UI);

	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8);
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8I);
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8UI);
	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8_SNORM);

	// 8bit / VIEWCLASS_8_BITS
	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8);
	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8I);
	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8UI);
	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8_SNORM);

	// Compressed texture view classes
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11]			= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11]			= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB]			= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA]			= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA]		= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA]	= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA]	= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA]	= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA]	= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA]	= vector<deUint32>();
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA]	= vector<deUint32>();

	// VIEWCLASS_EAC_R11
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_R11_EAC);
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_SIGNED_R11_EAC);

	// VIEWCLASS_EAC_RG11
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_RG11_EAC);
	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_SIGNED_RG11_EAC);

	// VIEWCLASS_ETC2_RGB
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_RGB8_ETC2);
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_SRGB8_ETC2);

	// VIEWCLASS_ETC2_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);

	// VIEWCLASS_ETC2_EAC_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);

	// VIEWCLASS_ASTC_4x4_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_4x4);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4);

	// VIEWCLASS_ASTC_5x4_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x4);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4);

	// VIEWCLASS_ASTC_5x5_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x5);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5);

	// VIEWCLASS_ASTC_6x5_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x5);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5);

	// VIEWCLASS_ASTC_6x6_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x6);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6);

	// VIEWCLASS_ASTC_8x5_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x5);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5);

	// VIEWCLASS_ASTC_8x6_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x6);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6);

	// VIEWCLASS_ASTC_8x8_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x8);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8);

	// VIEWCLASS_ASTC_10x5_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x5);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5);

	// VIEWCLASS_ASTC_10x6_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x6);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6);

	// VIEWCLASS_ASTC_10x8_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x8);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8);

	// VIEWCLASS_ASTC_10x10_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x10);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10);

	// VIEWCLASS_ASTC_12x10_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x10);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10);

	// VIEWCLASS_ASTC_12x12_RGBA
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x12);
	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12);

	// Mixed view classes
	mixedViewClasses[VIEWCLASS_128_BITS] = pair<vector<deUint32>, vector<deUint32> >();
	mixedViewClasses[VIEWCLASS_64_BITS] = pair<vector<deUint32>, vector<deUint32> >();

	// 128 bits

	// Non compressed
	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32F);
	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32UI);
	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32I);

	// Compressed
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RG11_EAC);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_4x4);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x4);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x8);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x8);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x10);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x10);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x12);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10);
	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12);

	// 64 bits

	// Non compressed
	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16F);
	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16UI);
	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16I);

	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32F);
	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32UI);
	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32I);

	// Compressed
	mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_R11_EAC);
	mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_SIGNED_R11_EAC);

	{
		TestCaseGroup* const	nonCompressedGroup	= new TestCaseGroup(m_context, "non_compressed", "Test copying between textures.");
		addChild(nonCompressedGroup);
		for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = textureFormatViewClasses.begin(); viewClassIter != textureFormatViewClasses.end(); ++viewClassIter)
		{
			const vector<deUint32>&	formats		= viewClassIter->second;
			const ViewClass			viewClass	= viewClassIter->first;
			TestCaseGroup* const	viewGroup	= new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass));

			nonCompressedGroup->addChild(viewGroup);

			for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++)
			for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++)
			{
				const deUint32 srcFormat = formats[srcFormatNdx];
				const deUint32 dstFormat = formats[dstFormatNdx];

				if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
					continue;

				addCopyTests(viewGroup, srcFormat, dstFormat);
			}
		}
	}

	// ES only
	if (!m_isGL45)
	{
		TestCaseGroup* const	compressedGroup		= new TestCaseGroup(m_context, "compressed", "Test copying between compressed textures.");
		addChild(compressedGroup);

		for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = compressedTextureFormatViewClasses.begin(); viewClassIter != compressedTextureFormatViewClasses.end(); ++viewClassIter)
		{
			const vector<deUint32>&	formats		= viewClassIter->second;
			const ViewClass			viewClass	= viewClassIter->first;
			TestCaseGroup* const	viewGroup	= new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass));

			compressedGroup->addChild(viewGroup);

			for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++)
			for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++)
			{
				const deUint32 srcFormat = formats[srcFormatNdx];
				const deUint32 dstFormat = formats[dstFormatNdx];

				if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
					continue;

				addCopyTests(viewGroup, srcFormat, dstFormat);
			}
		}
	}

	// ES only
	if (!m_isGL45)
	{
		TestCaseGroup* const	mixedGroup			= new TestCaseGroup(m_context, "mixed", "Test copying between compressed and non-compressed textures.");
		addChild(mixedGroup);


		for (map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >::const_iterator iter = mixedViewClasses.begin(); iter != mixedViewClasses.end(); ++iter)
		{
			const ViewClass			viewClass				= iter->first;
			const string			viewClassName			= string(viewClassToName(viewClass)) + "_mixed";
			TestCaseGroup* const	viewGroup				= new TestCaseGroup(m_context, viewClassName.c_str(), viewClassName.c_str());

			const vector<deUint32>	nonCompressedFormats	= iter->second.first;
			const vector<deUint32>	compressedFormats		= iter->second.second;

			mixedGroup->addChild(viewGroup);

			for (int srcFormatNdx = 0; srcFormatNdx < (int)nonCompressedFormats.size(); srcFormatNdx++)
			for (int dstFormatNdx = 0; dstFormatNdx < (int)compressedFormats.size(); dstFormatNdx++)
			{
				const deUint32 srcFormat = nonCompressedFormats[srcFormatNdx];
				const deUint32 dstFormat = compressedFormats[dstFormatNdx];

				if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
					continue;

				addCopyTests(viewGroup, srcFormat, dstFormat);
				addCopyTests(viewGroup, dstFormat, srcFormat);
			}
		}
	}
}

} // anonymous

TestCaseGroup* createCopyImageTests (Context& context, bool is_GL45)
{
	return new CopyImageTests(context, is_GL45);
}

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