/*-------------------------------------------------------------------------
 * 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 tcu::Float;
using tcu::IVec3;
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
};

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

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

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;
}

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

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

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

	ReferenceParams					renderParams	(TEXTURETYPE_2D);

	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.");

	for (int level = 0; level < getLevelCount(info); level++)
	{
		const IVec3				levelSize		= getLevelSize(info.getTarget(), info.getSize(), level);
		const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());

		vector<float>			texCoord;
		tcu::Surface			renderedFrame	(viewport.width, viewport.height);
		tcu::Surface			referenceFrame	(viewport.width, viewport.height);

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

		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

		// Setup base viewport.
		gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

		// Draw.
		renderer.renderQuad(0, &texCoord[0], renderParams);
		glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");

		// Compute reference.
		sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);

		// Compare and log.
		if (!pixelThresholdCompare(log, ("Level" + de::toString(level)).c_str(), ("Render level " + de::toString(level)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
			results.fail("Image comparison of level " + de::toString(level) + " failed.");
		else
			log << TestLog::Message << "Image comparison of level " << level << " passed." << TestLog::EndMessage;
	}

	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000);

	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"))
			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 verifyTexture2D (tcu::TestContext&						testContext,
					  glu::RenderContext&					renderContext,
					  TextureRenderer&						textureRenderer,
					  tcu::ResultCollector&					results,
					  de::Random&							rng,
					  deUint32								name,
					  const vector<ArrayBuffer<deUint8> >&	data,
					  const ImageInfo&						info)
{
	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]));

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

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

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

	ReferenceParams					renderParams	(TEXTURETYPE_3D);

	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.");

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

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

		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, level);
		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, level);

		for (int slice = 0; slice < levelSize.z(); slice++)
		{
			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
			const float				r				= (float(slice) + 0.5f) / (float)levelSize.z();
			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
			vector<float>			texCoord;

			computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2));

			// Setup base viewport.
			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

			// Draw.
			renderer.renderQuad(0, &texCoord[0], renderParams);
			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");

			// Compute reference.
			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);

			// Compare and log.
			if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Slice" + de::toString(slice)).c_str(), ("Render level " + de::toString(level) + ", Slice" + de::toString(slice)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
				results.fail("Image comparison of level " + de::toString(level) + " and slice " + de::toString(slice) + " failed.");
			else
				log << TestLog::Message << "Image comparison of level " << level << " and slice " << slice << " passed." << TestLog::EndMessage;;
		}
	}

	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1000);

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

void verifyTexture3D (tcu::TestContext&						testContext,
					  glu::RenderContext&					renderContext,
					  TextureRenderer&						textureRenderer,
					  tcu::ResultCollector&					results,
					  de::Random&							rng,
					  deUint32								name,
					  const vector<ArrayBuffer<deUint8> >&	data,
					  const ImageInfo&						info)
{
	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]));

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

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

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

	ReferenceParams					renderParams	(TEXTURETYPE_CUBE);

	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.");

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

		// \note It seems we can't reliably sample two smallest texture levels with cubemaps
		if (levelSize.x() < 4 && levelSize.y() < 4)
			continue;

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

		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, level);
		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, level);

		for (int face = 0; face < 6; face++)
		{
			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
			const string			cubemapFaceName	= glu::getCubeMapFaceStr(mapFaceNdxToFace(face)).toString();
			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
			vector<float>			texCoord;

			computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(face)));

			// Setup base viewport.
			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

			// Draw.
			renderer.renderQuad(0, &texCoord[0], renderParams);
			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");

			// Compute reference.
			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);

			// Compare and log.
			if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Face" + cubemapFaceName).c_str(), ("Render level " + de::toString(level) + ", Face " + cubemapFaceName).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
				results.fail("Image comparison of level " + de::toString(level) + " and face " + cubemapFaceName + " failed.");
			else
				log << TestLog::Message << "Image comparison of level " << level << " and face " << cubemapFaceName << " passed." << TestLog::EndMessage;
		}
	}

	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1000);

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

void verifyTextureCubemap (tcu::TestContext&					testContext,
						   glu::RenderContext&					renderContext,
						   TextureRenderer&						textureRenderer,
						   tcu::ResultCollector&				results,
						   de::Random&							rng,
						   deUint32								name,
						   const vector<ArrayBuffer<deUint8> >&	data,
						   const ImageInfo&						info)
{
	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"))
				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);

			verifyTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
		}
	}
	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);

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

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

	ReferenceParams					renderParams	(TEXTURETYPE_2D_ARRAY);

	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.");

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

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

		gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, level);
		gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, level);

		for (int layer = 0; layer < levelSize.z(); layer++)
		{
			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
			vector<float>			texCoord;

			computeQuadTexCoord2DArray(texCoord, layer, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

			// Setup base viewport.
			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

			// Draw.
			renderer.renderQuad(0, &texCoord[0], renderParams);
			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");

			// Compute reference.
			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);

			// Compare and log.
			if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Layer" + de::toString(layer)).c_str(), ("Render level " + de::toString(level) + ", Layer" + de::toString(layer)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
				results.fail("Image comparison of level " + de::toString(level) + " and layer " + de::toString(layer) + " failed.");
			else
				log << TestLog::Message << "Image comparison of level " << level << " and layer " << layer << " passed." << TestLog::EndMessage;
		}
	}

	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000);

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

void verifyTexture2DArray (tcu::TestContext&					testContext,
						   glu::RenderContext&					renderContext,
						   TextureRenderer&						textureRenderer,
						   tcu::ResultCollector&				results,
						   de::Random&							rng,
						   deUint32								name,
						   const vector<ArrayBuffer<deUint8> >&	data,
						   const ImageInfo&						info)
{
	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]));

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

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

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 verifyRenderbuffer (tcu::TestContext&						testContext,
						 glu::RenderContext&					renderContext,
						 tcu::ResultCollector&					results,
						 deUint32								name,
						 const vector<ArrayBuffer<deUint8> >&	data,
						 const ImageInfo&						info)
{
	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.");

		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 (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 verify (tcu::TestContext&						testContext,
			 glu::RenderContext&					renderContext,
			 TextureRenderer&						textureRenderer,
			 tcu::ResultCollector&					results,
			 de::Random&							rng,
			 deUint32								name,
			 const vector<ArrayBuffer<deUint8> >&	data,
			 const ImageInfo&						info)
{
	switch (info.getTarget())
	{
		case GL_TEXTURE_2D:
			verifyTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info);
			break;

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

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

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

		case GL_RENDERBUFFER:
			verifyRenderbuffer(testContext, renderContext, results, name, data, info);
			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					copyImageIter			(void);

	struct State
	{
		State (int					seed,
			   tcu::TestLog&		log,
			   glu::RenderContext&	renderContext)
			: rng				(seed)
			, results			(log)
			, srcImage			(NULL)
			, dstImage			(NULL)
			, textureRenderer	(renderContext, log, glu::GLSL_VERSION_310_ES, 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_hdr") &&
				!info.isExtensionSupported("GL_OES_texture_compression_astc"))
			{
				if (target == GL_TEXTURE_3D)
					TCU_THROW(NotSupportedError, "TEXTURE_3D target requires HDR astc support.");
				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)
{
	de::UniquePtr<glu::ContextInfo> ctxInfo(glu::ContextInfo::create(m_context.getRenderContext()));
	const bool						isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));

	if (!isES32 && !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(), m_context.getRenderContext());
	checkFormatSupport(*ctxInfo, m_dstImageInfo.getFormat(), m_dstImageInfo.getTarget(), m_context.getRenderContext());

	{
		SeedBuilder builder;

		builder << 903980
				<< m_srcImageInfo
				<< m_dstImageInfo;

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

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;

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

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;

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

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)
{
	void(CopyImageTest::*methods[])(void) =
	{
		&CopyImageTest::logTestInfoIter,

		// Render both images and then copy and verify again.
		&CopyImageTest::createImagesIter,
		&CopyImageTest::verifySourceIter,
		&CopyImageTest::verifyDestinationIter,
		&CopyImageTest::copyImageIter,
		&CopyImageTest::verifySourceIter,
		&CopyImageTest::verifyDestinationIter,
		&CopyImageTest::destroyImagesIter,

		// Create images and immediately copies between thew and verify.
		&CopyImageTest::createImagesIter,
		&CopyImageTest::copyImageIter,
		&CopyImageTest::verifySourceIter,
		&CopyImageTest::verifyDestinationIter,
		&CopyImageTest::destroyImagesIter
	};

	if (m_iteration < DE_LENGTH_OF_ARRAY(methods))
	{
		(this->*methods[m_iteration])();
		m_iteration++;
		return CONTINUE;
	}
	else
	{
		m_state->results.setTestContextResult(m_testCtx);
		return STOP;
	}
}

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

	void				init					(void);

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

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

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

			const IVec3		targetSize2D	(128, 128, 1);
			const IVec3		targetSize3D	(128, 128, 16);

			const IVec3		srcSize			= getTestedSize(srcTarget, srcFormat, (srcIs3D ? targetSize3D : targetSize2D));
			const IVec3		dstSize			= getTestedSize(dstTarget, dstFormat, (dstIs3D ? targetSize3D : targetSize2D));

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

void CopyImageTests::init (void)
{
	TestCaseGroup* const	nonCompressedGroup	= new TestCaseGroup(m_context, "non_compressed", "Test copying between textures.");
	TestCaseGroup* const	compressedGroup		= new TestCaseGroup(m_context, "compressed", "Test copying between compressed textures.");
	TestCaseGroup* const	mixedGroup			= new TestCaseGroup(m_context, "mixed", "Test copying between compressed and non-compressed textures.");

	addChild(nonCompressedGroup);
	addChild(compressedGroup);
	addChild(mixedGroup);

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

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

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

	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)
{
	return new CopyImageTests(context);
}

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