Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.1 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Copy image tests for GL_EXT_copy_image.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fCopyImageTests.hpp"
     25 
     26 #include "tes31TestCase.hpp"
     27 
     28 #include "glsTextureTestUtil.hpp"
     29 
     30 #include "gluContextInfo.hpp"
     31 #include "gluObjectWrapper.hpp"
     32 #include "gluRenderContext.hpp"
     33 #include "gluStrUtil.hpp"
     34 #include "gluTextureUtil.hpp"
     35 #include "gluPixelTransfer.hpp"
     36 
     37 #include "glwEnums.hpp"
     38 #include "glwFunctions.hpp"
     39 
     40 #include "tcuCompressedTexture.hpp"
     41 #include "tcuFloat.hpp"
     42 #include "tcuImageCompare.hpp"
     43 #include "tcuTestLog.hpp"
     44 #include "tcuTexture.hpp"
     45 #include "tcuTextureUtil.hpp"
     46 #include "tcuVector.hpp"
     47 #include "tcuVectorUtil.hpp"
     48 #include "tcuSeedBuilder.hpp"
     49 #include "tcuResultCollector.hpp"
     50 
     51 #include "deArrayBuffer.hpp"
     52 #include "deFloat16.h"
     53 #include "deRandom.hpp"
     54 #include "deStringUtil.hpp"
     55 #include "deUniquePtr.hpp"
     56 #include "deArrayUtil.hpp"
     57 
     58 #include <map>
     59 #include <string>
     60 #include <vector>
     61 
     62 using namespace deqp::gls::TextureTestUtil;
     63 
     64 using tcu::Float;
     65 using tcu::IVec3;
     66 using tcu::Sampler;
     67 using tcu::ScopedLogSection;
     68 using tcu::TestLog;
     69 using tcu::Vec4;
     70 using tcu::SeedBuilder;
     71 
     72 using de::ArrayBuffer;
     73 
     74 using std::map;
     75 using std::string;
     76 using std::vector;
     77 using std::pair;
     78 
     79 namespace deqp
     80 {
     81 namespace gles31
     82 {
     83 namespace Functional
     84 {
     85 namespace
     86 {
     87 
     88 enum ViewClass
     89 {
     90 	VIEWCLASS_128_BITS = 0,
     91 	VIEWCLASS_96_BITS,
     92 	VIEWCLASS_64_BITS,
     93 	VIEWCLASS_48_BITS,
     94 	VIEWCLASS_32_BITS,
     95 	VIEWCLASS_24_BITS,
     96 	VIEWCLASS_16_BITS,
     97 	VIEWCLASS_8_BITS,
     98 
     99 	VIEWCLASS_EAC_R11,
    100 	VIEWCLASS_EAC_RG11,
    101 	VIEWCLASS_ETC2_RGB,
    102 	VIEWCLASS_ETC2_RGBA,
    103 	VIEWCLASS_ETC2_EAC_RGBA,
    104 	VIEWCLASS_ASTC_4x4_RGBA,
    105 	VIEWCLASS_ASTC_5x4_RGBA,
    106 	VIEWCLASS_ASTC_5x5_RGBA,
    107 	VIEWCLASS_ASTC_6x5_RGBA,
    108 	VIEWCLASS_ASTC_6x6_RGBA,
    109 	VIEWCLASS_ASTC_8x5_RGBA,
    110 	VIEWCLASS_ASTC_8x6_RGBA,
    111 	VIEWCLASS_ASTC_8x8_RGBA,
    112 	VIEWCLASS_ASTC_10x5_RGBA,
    113 	VIEWCLASS_ASTC_10x6_RGBA,
    114 	VIEWCLASS_ASTC_10x8_RGBA,
    115 	VIEWCLASS_ASTC_10x10_RGBA,
    116 	VIEWCLASS_ASTC_12x10_RGBA,
    117 	VIEWCLASS_ASTC_12x12_RGBA
    118 };
    119 
    120 const char* viewClassToName (ViewClass viewClass)
    121 {
    122 	switch (viewClass)
    123 	{
    124 		case VIEWCLASS_128_BITS:			return "viewclass_128_bits";
    125 		case VIEWCLASS_96_BITS:				return "viewclass_96_bits";
    126 		case VIEWCLASS_64_BITS:				return "viewclass_64_bits";
    127 		case VIEWCLASS_48_BITS:				return "viewclass_48_bits";
    128 		case VIEWCLASS_32_BITS:				return "viewclass_32_bits";
    129 		case VIEWCLASS_24_BITS:				return "viewclass_24_bits";
    130 		case VIEWCLASS_16_BITS:				return "viewclass_16_bits";
    131 		case VIEWCLASS_8_BITS:				return "viewclass_8_bits";
    132 		case VIEWCLASS_EAC_R11:				return "viewclass_eac_r11";
    133 		case VIEWCLASS_EAC_RG11:			return "viewclass_eac_rg11";
    134 		case VIEWCLASS_ETC2_RGB:			return "viewclass_etc2_rgb";
    135 		case VIEWCLASS_ETC2_RGBA:			return "viewclass_etc2_rgba";
    136 		case VIEWCLASS_ETC2_EAC_RGBA:		return "viewclass_etc2_eac_rgba";
    137 		case VIEWCLASS_ASTC_4x4_RGBA:		return "viewclass_astc_4x4_rgba";
    138 		case VIEWCLASS_ASTC_5x4_RGBA:		return "viewclass_astc_5x4_rgba";
    139 		case VIEWCLASS_ASTC_5x5_RGBA:		return "viewclass_astc_5x5_rgba";
    140 		case VIEWCLASS_ASTC_6x5_RGBA:		return "viewclass_astc_6x5_rgba";
    141 		case VIEWCLASS_ASTC_6x6_RGBA:		return "viewclass_astc_6x6_rgba";
    142 		case VIEWCLASS_ASTC_8x5_RGBA:		return "viewclass_astc_8x5_rgba";
    143 		case VIEWCLASS_ASTC_8x6_RGBA:		return "viewclass_astc_8x6_rgba";
    144 		case VIEWCLASS_ASTC_8x8_RGBA:		return "viewclass_astc_8x8_rgba";
    145 		case VIEWCLASS_ASTC_10x5_RGBA:		return "viewclass_astc_10x5_rgba";
    146 		case VIEWCLASS_ASTC_10x6_RGBA:		return "viewclass_astc_10x6_rgba";
    147 		case VIEWCLASS_ASTC_10x8_RGBA:		return "viewclass_astc_10x8_rgba";
    148 		case VIEWCLASS_ASTC_10x10_RGBA:		return "viewclass_astc_10x10_rgba";
    149 		case VIEWCLASS_ASTC_12x10_RGBA:		return "viewclass_astc_12x10_rgba";
    150 		case VIEWCLASS_ASTC_12x12_RGBA:		return "viewclass_astc_12x12_rgba";
    151 
    152 		default:
    153 			DE_ASSERT(false);
    154 			return NULL;
    155 	}
    156 }
    157 
    158 const char* targetToName (deUint32 target)
    159 {
    160 	switch (target)
    161 	{
    162 		case GL_RENDERBUFFER:		return "renderbuffer";
    163 		case GL_TEXTURE_2D:			return "texture2d";
    164 		case GL_TEXTURE_3D:			return "texture3d";
    165 		case GL_TEXTURE_2D_ARRAY:	return "texture2d_array";
    166 		case GL_TEXTURE_CUBE_MAP:	return "cubemap";
    167 
    168 		default:
    169 			DE_ASSERT(false);
    170 			return NULL;
    171 	}
    172 }
    173 
    174 string formatToName (deUint32 format)
    175 {
    176 	string enumName;
    177 
    178 	if (glu::isCompressedFormat(format))
    179 		enumName = glu::getCompressedTexFormatStr(format).toString().substr(14); // Strip GL_COMPRESSED_
    180 	else
    181 		enumName = glu::getPixelFormatStr(format).toString().substr(3); // Strip GL_
    182 
    183 	return de::toLower(enumName);
    184 }
    185 
    186 bool isFloatFormat (deUint32 format)
    187 {
    188 	if (glu::isCompressedFormat(format))
    189 		return false;
    190 	else
    191 		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
    192 }
    193 
    194 bool isUintFormat (deUint32 format)
    195 {
    196 	if (glu::isCompressedFormat(format))
    197 		return false;
    198 	else
    199 		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
    200 }
    201 
    202 bool isIntFormat (deUint32 format)
    203 {
    204 	if (glu::isCompressedFormat(format))
    205 		return false;
    206 	else
    207 		return tcu::getTextureChannelClass(glu::mapGLInternalFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
    208 }
    209 
    210 bool isTextureTarget (deUint32 target)
    211 {
    212 	return target != GL_RENDERBUFFER;
    213 }
    214 
    215 int getTargetTexDims (deUint32 target)
    216 {
    217 	DE_ASSERT(isTextureTarget(target));
    218 
    219 	switch (target)
    220 	{
    221 		case GL_TEXTURE_1D:
    222 			return 1;
    223 
    224 		case GL_TEXTURE_1D_ARRAY:
    225 		case GL_TEXTURE_2D:
    226 		case GL_TEXTURE_CUBE_MAP:
    227 			return 2;
    228 
    229 		case GL_TEXTURE_2D_ARRAY:
    230 		case GL_TEXTURE_3D:
    231 			return 3;
    232 
    233 		default:
    234 			DE_ASSERT(false);
    235 			return -1;
    236 	}
    237 }
    238 
    239 class ImageInfo
    240 {
    241 public:
    242 					ImageInfo		(deUint32 format, deUint32 target, const IVec3& size);
    243 
    244 	deUint32		getFormat		(void) const { return m_format; }
    245 	deUint32		getTarget		(void) const { return m_target; }
    246 	const IVec3&	getSize			(void) const { return m_size; }
    247 
    248 private:
    249 	deUint32		m_format;
    250 	deUint32		m_target;
    251 	IVec3			m_size;
    252 };
    253 
    254 ImageInfo::ImageInfo (deUint32 format, deUint32 target, const IVec3& size)
    255 	: m_format		(format)
    256 	, m_target		(target)
    257 	, m_size		(size)
    258 {
    259 	DE_ASSERT(m_target == GL_TEXTURE_2D_ARRAY || m_target == GL_TEXTURE_3D || m_size.z() == 1);
    260 	DE_ASSERT(isTextureTarget(m_target) || !glu::isCompressedFormat(m_target));
    261 }
    262 
    263 
    264 SeedBuilder& operator<< (SeedBuilder& builder, const ImageInfo& info)
    265 {
    266 	builder << info.getFormat() << info.getTarget() << info.getSize();
    267 	return builder;
    268 }
    269 
    270 const glu::ObjectTraits& getObjectTraits (const ImageInfo& info)
    271 {
    272 	if (isTextureTarget(info.getTarget()))
    273 		return glu::objectTraits(glu::OBJECTTYPE_TEXTURE);
    274 	else
    275 		return glu::objectTraits(glu::OBJECTTYPE_RENDERBUFFER);
    276 }
    277 
    278 int getLevelCount (const ImageInfo& info)
    279 {
    280 	const deUint32	target	= info.getTarget();
    281 	const IVec3		size	= info.getSize();
    282 
    283 	if (target == GL_RENDERBUFFER)
    284 		return 1;
    285 	else if (target == GL_TEXTURE_2D_ARRAY)
    286 	{
    287 		const int maxSize = de::max(size.x(), size.y());
    288 
    289 		return deLog2Ceil32(maxSize);
    290 	}
    291 	else
    292 	{
    293 		const int maxSize = de::max(size.x(), de::max(size.y(), size.z()));
    294 
    295 		return deLog2Ceil32(maxSize);
    296 	}
    297 }
    298 
    299 // Return format that has more restrictions on texel data.
    300 deUint32 getMoreRestrictiveFormat (deUint32 formatA, deUint32 formatB)
    301 {
    302 	if (formatA == formatB)
    303 		return formatA;
    304 	else if (glu::isCompressedFormat(formatA) && isAstcFormat(glu::mapGLCompressedTexFormat(formatA)))
    305 		return formatA;
    306 	else if (glu::isCompressedFormat(formatB) && isAstcFormat(glu::mapGLCompressedTexFormat(formatB)))
    307 		return formatB;
    308 	else if (isFloatFormat(formatA))
    309 	{
    310 		DE_ASSERT(!isFloatFormat(formatB));
    311 
    312 		return formatA;
    313 	}
    314 	else if (isFloatFormat(formatB))
    315 	{
    316 		DE_ASSERT(!isFloatFormat(formatA));
    317 
    318 		return formatB;
    319 	}
    320 	else if (glu::isCompressedFormat(formatA))
    321 	{
    322 		return formatA;
    323 	}
    324 	else if (glu::isCompressedFormat(formatB))
    325 	{
    326 		return formatB;
    327 	}
    328 	else
    329 		return formatA;
    330 }
    331 
    332 int getTexelBlockSize (deUint32 format)
    333 {
    334 	if (glu::isCompressedFormat(format))
    335 		return tcu::getBlockSize(glu::mapGLCompressedTexFormat(format));
    336 	else
    337 		return glu::mapGLInternalFormat(format).getPixelSize();
    338 }
    339 
    340 IVec3 getTexelBlockPixelSize (deUint32 format)
    341 {
    342 	if (glu::isCompressedFormat(format))
    343 		return tcu::getBlockPixelSize(glu::mapGLCompressedTexFormat(format));
    344 	else
    345 		return IVec3(1, 1, 1);
    346 }
    347 
    348 IVec3 getLevelSize (deUint32 target, const IVec3& baseSize, int level)
    349 {
    350 	IVec3 size;
    351 
    352 	if (target != GL_TEXTURE_2D_ARRAY)
    353 	{
    354 		for (int i = 0; i < 3; i++)
    355 			size[i] = de::max(baseSize[i] >> level, 1);
    356 	}
    357 	else
    358 	{
    359 		for (int i = 0; i < 2; i++)
    360 			size[i] = de::max(baseSize[i] >> level, 1);
    361 
    362 		size[2] = baseSize[2];
    363 	}
    364 
    365 	return size;
    366 }
    367 
    368 bool isColorRenderable (deUint32 format)
    369 {
    370 	switch (format)
    371 	{
    372 		case GL_R8:
    373 		case GL_RG8:
    374 		case GL_RGB8:
    375 		case GL_RGB565:
    376 		case GL_RGB4:
    377 		case GL_RGB5_A1:
    378 		case GL_RGBA8:
    379 		case GL_RGB10_A2:
    380 		case GL_RGB10_A2UI:
    381 		case GL_SRGB8_ALPHA8:
    382 		case GL_R8I:
    383 		case GL_R8UI:
    384 		case GL_R16I:
    385 		case GL_R16UI:
    386 		case GL_R32I:
    387 		case GL_R32UI:
    388 		case GL_RG8I:
    389 		case GL_RG8UI:
    390 		case GL_RG16I:
    391 		case GL_RG16UI:
    392 		case GL_RG32I:
    393 		case GL_RG32UI:
    394 		case GL_RGBA8I:
    395 		case GL_RGBA8UI:
    396 		case GL_RGBA16I:
    397 		case GL_RGBA16UI:
    398 		case GL_RGBA32I:
    399 		case GL_RGBA32UI:
    400 			return true;
    401 
    402 		default:
    403 			return false;
    404 	}
    405 }
    406 
    407 deUint32 getTypeForInternalFormat (deUint32 format)
    408 {
    409 	return glu::getTransferFormat(glu::mapGLInternalFormat(format)).dataType;
    410 }
    411 
    412 void genTexel (de::Random& rng, deUint32 glFormat, int texelBlockSize, const int texelCount, deUint8* buffer)
    413 {
    414 	if (isFloatFormat(glFormat))
    415 	{
    416 		const tcu::TextureFormat		format	= glu::mapGLInternalFormat(glFormat);
    417 		const tcu::PixelBufferAccess	access	(format, texelCount, 1, 1, buffer);
    418 		const tcu::TextureFormatInfo	info	= tcu::getTextureFormatInfo(format);
    419 
    420 		for (int texelNdx = 0; texelNdx < texelCount; texelNdx++)
    421 		{
    422 			const float	red		= rng.getFloat(info.valueMin.x(), info.valueMax.x());
    423 			const float green	= rng.getFloat(info.valueMin.y(), info.valueMax.y());
    424 			const float blue	= rng.getFloat(info.valueMin.z(), info.valueMax.z());
    425 			const float alpha	= rng.getFloat(info.valueMin.w(), info.valueMax.w());
    426 
    427 			const Vec4	color	(red, green, blue, alpha);
    428 
    429 			access.setPixel(color, texelNdx, 0, 0);
    430 		}
    431 	}
    432 	else if (glu::isCompressedFormat(glFormat))
    433 	{
    434 		const tcu::CompressedTexFormat compressedFormat = glu::mapGLCompressedTexFormat(glFormat);
    435 
    436 		if (tcu::isAstcFormat(compressedFormat))
    437 		{
    438 			const int		BLOCK_SIZE				= 16;
    439 			const deUint8	blocks[][BLOCK_SIZE]	=
    440 			{
    441 				// \note All of the following blocks are valid in LDR mode.
    442 				{ 252,	253,	255,	255,	255,	255,	255,	255,	8,		71,		90,		78,		22,		17,		26,		66,		},
    443 				{ 252,	253,	255,	255,	255,	255,	255,	255,	220,	74,		139,	235,	249,	6,		145,	125		},
    444 				{ 252,	253,	255,	255,	255,	255,	255,	255,	223,	251,	28,		206,	54,		251,	160,	174		},
    445 				{ 252,	253,	255,	255,	255,	255,	255,	255,	39,		4,		153,	219,	180,	61,		51,		37		},
    446 				{ 67,	2,		0,		254,	1,		0,		64,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    447 				{ 67,	130,	0,		170,	84,		255,	65,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    448 				{ 67,	2,		129,	38,		51,		229,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    449 				{ 67,	130,	193,	56,		213,	144,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		}
    450 			};
    451 
    452 			DE_ASSERT(texelBlockSize == BLOCK_SIZE);
    453 
    454 			for (int i = 0; i < texelCount; i++)
    455 			{
    456 				const int blockNdx = rng.getInt(0, DE_LENGTH_OF_ARRAY(blocks)-1);
    457 
    458 				deMemcpy(buffer + i * BLOCK_SIZE,  blocks[blockNdx], BLOCK_SIZE);
    459 			}
    460 		}
    461 		else
    462 		{
    463 			for (int i = 0; i < texelBlockSize * texelCount; i++)
    464 			{
    465 				const deUint8 val = rng.getUint8();
    466 
    467 				buffer[i] = val;
    468 			}
    469 		}
    470 	}
    471 	else
    472 	{
    473 		for (int i = 0; i < texelBlockSize * texelCount; i++)
    474 		{
    475 			const deUint8 val = rng.getUint8();
    476 
    477 			buffer[i] = val;
    478 		}
    479 	}
    480 }
    481 
    482 IVec3 divRoundUp (const IVec3& a, const IVec3& b)
    483 {
    484 	IVec3 res;
    485 
    486 	for (int i =0; i < 3; i++)
    487 		res[i] = a[i] / b[i] + ((a[i] % b[i]) ? 1 : 0);
    488 
    489 	return res;
    490 }
    491 
    492 deUint32 mapFaceNdxToFace (int ndx)
    493 {
    494 	const deUint32 cubeFaces[] =
    495 	{
    496 		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    497 		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
    498 
    499 		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
    500 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
    501 
    502 		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    503 		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
    504 	};
    505 
    506 	return de::getSizedArrayElement<6>(cubeFaces, ndx);
    507 }
    508 
    509 deUint32 getFormatForInternalFormat (deUint32 format)
    510 {
    511 	return glu::getTransferFormat(glu::mapGLInternalFormat(format)).format;
    512 }
    513 
    514 void genericTexImage (const glw::Functions&	gl,
    515 					  deUint32				target,
    516 					  int					faceNdx,
    517 					  int					level,
    518 					  const IVec3&			size,
    519 					  deUint32				format,
    520 					  size_t				dataSize,
    521 					  const void*			data)
    522 {
    523 	const deUint32 glTarget = (target == GL_TEXTURE_CUBE_MAP ? mapFaceNdxToFace(faceNdx) : target);
    524 
    525 	DE_ASSERT(target == GL_TEXTURE_CUBE_MAP || faceNdx == 0);
    526 
    527 	if (glu::isCompressedFormat(format))
    528 	{
    529 		switch (getTargetTexDims(target))
    530 		{
    531 			case 2:
    532 				DE_ASSERT(size.z() == 1);
    533 				gl.compressedTexImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, (glw::GLsizei)dataSize, data);
    534 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D failed.");
    535 				break;
    536 
    537 			case 3:
    538 				gl.compressedTexImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, (glw::GLsizei)dataSize, data);
    539 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D failed.");
    540 				break;
    541 
    542 			default:
    543 				DE_ASSERT(false);
    544 		}
    545 	}
    546 	else
    547 	{
    548 		const deUint32	glFormat	= getFormatForInternalFormat(format);
    549 		const deUint32	glType		= getTypeForInternalFormat(format);
    550 
    551 		switch (getTargetTexDims(target))
    552 		{
    553 			case 2:
    554 				DE_ASSERT(size.z() == 1);
    555 				gl.texImage2D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), 0, glFormat, glType, data);
    556 				GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D failed.");
    557 				break;
    558 
    559 			case 3:
    560 				gl.texImage3D(glTarget, level, format, (glw::GLsizei)size.x(), (glw::GLsizei)size.y(), (glw::GLsizei)size.z(), 0, glFormat, glType, data);
    561 				GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D failed.");
    562 				break;
    563 
    564 			default:
    565 				DE_ASSERT(false);
    566 		}
    567 	}
    568 }
    569 
    570 void genTextureImage (const glw::Functions&				gl,
    571 					  de::Random&						rng,
    572 					  deUint32							name,
    573 					  vector<ArrayBuffer<deUint8> >&	levels,
    574 					  const ImageInfo&					info,
    575 					  deUint32							moreRestrictiveFormat)
    576 {
    577 	const int		texelBlockSize			= getTexelBlockSize(info.getFormat());
    578 	const IVec3		texelBlockPixelSize 	= getTexelBlockPixelSize(info.getFormat());
    579 
    580 	levels.resize(getLevelCount(info));
    581 
    582 	gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
    583 	GLU_EXPECT_NO_ERROR(gl.getError(), "Setting pixel store aligment failed.");
    584 
    585 	gl.bindTexture(info.getTarget(), name);
    586 	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding texture failed.");
    587 
    588 	for (int levelNdx = 0; levelNdx < getLevelCount(info); levelNdx++)
    589 	{
    590 		ArrayBuffer<deUint8>&	level					= levels[levelNdx];
    591 
    592 		const int				faceCount				= (info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : 1);
    593 
    594 		const IVec3				levelPixelSize			= getLevelSize(info.getTarget(), info.getSize(), levelNdx);
    595 		const IVec3				levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
    596 		const int				levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
    597 		const int				levelSize 				= levelTexelBlockCount * texelBlockSize;
    598 
    599 		level.setStorage(levelSize * faceCount);
    600 
    601 		for (int faceNdx = 0; faceNdx < faceCount; faceNdx++)
    602 		{
    603 			genTexel(rng, moreRestrictiveFormat, texelBlockSize, levelTexelBlockCount, level.getElementPtr(faceNdx * levelSize));
    604 
    605 			genericTexImage(gl, info.getTarget(), faceNdx, levelNdx, levelPixelSize, info.getFormat(), levelSize, level.getElementPtr(faceNdx * levelSize));
    606 		}
    607 	}
    608 
    609 	gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    610 	gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    611 
    612 	if (info.getTarget() == GL_TEXTURE_3D)
    613 		gl.texParameteri(info.getTarget(), GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    614 
    615 	gl.texParameteri(info.getTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    616 	gl.texParameteri(info.getTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    617 	GLU_EXPECT_NO_ERROR(gl.getError(), "Setting texture parameters failed");
    618 
    619 	gl.bindTexture(info.getTarget(), 0);
    620 	GLU_EXPECT_NO_ERROR(gl.getError(), "Unbinding texture failed.");
    621 }
    622 
    623 void genRenderbufferImage (const glw::Functions&			gl,
    624 						   de::Random&						rng,
    625 						   deUint32							name,
    626 						   vector<ArrayBuffer<deUint8> >&	levels,
    627 						   const ImageInfo&					info,
    628 						   deUint32							moreRestrictiveFormat)
    629 {
    630 	const IVec3					size	= info.getSize();
    631 	const tcu::TextureFormat	format	= glu::mapGLInternalFormat(info.getFormat());
    632 
    633 	DE_ASSERT(info.getTarget() == GL_RENDERBUFFER);
    634 	DE_ASSERT(info.getSize().z() == 1);
    635 	DE_ASSERT(getLevelCount(info) == 1);
    636 	DE_ASSERT(!glu::isCompressedFormat(info.getFormat()));
    637 
    638 	glu::Framebuffer framebuffer(gl);
    639 
    640 	levels.resize(1);
    641 	levels[0].setStorage(format.getPixelSize() * size.x() * size.y());
    642 	tcu::PixelBufferAccess refAccess(format, size.x(), size.y(), 1, levels[0].getPtr());
    643 
    644 	gl.bindRenderbuffer(GL_RENDERBUFFER, name);
    645 	gl.renderbufferStorage(GL_RENDERBUFFER, info.getFormat(), info.getSize().x(), info.getSize().y());
    646 	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding and setting storage for renderbuffer failed.");
    647 
    648 	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
    649 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name);
    650 	GLU_EXPECT_NO_ERROR(gl.getError(), "Binding framebuffer and attaching renderbuffer failed.");
    651 
    652 	{
    653 		vector<deUint8> texelBlock(format.getPixelSize());
    654 
    655 		genTexel(rng, moreRestrictiveFormat, format.getPixelSize(), 1, &(texelBlock[0]));
    656 
    657 		{
    658 			const tcu::ConstPixelBufferAccess texelAccess (format, 1, 1, 1, &(texelBlock[0]));
    659 
    660 			if (isFloatFormat(info.getFormat()))
    661 			{
    662 				const tcu::Vec4 color = texelAccess.getPixel(0, 0, 0);
    663 
    664 				gl.clearBufferfv(GL_COLOR, 0, (const float*)&color);
    665 				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");
    666 
    667 				tcu::clear(refAccess, (tcu::isSRGB(format) ? tcu::linearToSRGB(color) : color));
    668 			}
    669 			else if (isIntFormat(info.getFormat()))
    670 			{
    671 				const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0);
    672 
    673 				gl.clearBufferiv(GL_COLOR, 0, (const deInt32*)&color);
    674 				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");
    675 
    676 				DE_ASSERT(!tcu::isSRGB(format));
    677 				tcu::clear(refAccess, color);
    678 			}
    679 			else if (isUintFormat(info.getFormat()))
    680 			{
    681 				const tcu::IVec4 color = texelAccess.getPixelInt(0, 0, 0);
    682 
    683 				gl.clearBufferuiv(GL_COLOR, 0, (const deUint32*)&color);
    684 				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");
    685 
    686 				DE_ASSERT(!tcu::isSRGB(format));
    687 				tcu::clear(refAccess, color);
    688 			}
    689 			else
    690 			{
    691 				const tcu::Vec4 color = texelAccess.getPixel(0, 0, 0);
    692 
    693 				gl.clearColor(color.x(), color.y(), color.z(), color.w());
    694 				gl.clear(GL_COLOR_BUFFER_BIT);
    695 				GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear renderbuffer.");
    696 
    697 				tcu::clear(refAccess, (tcu::isSRGB(format) ? tcu::linearToSRGB(color) : color));
    698 			}
    699 		}
    700 	}
    701 
    702 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
    703 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
    704 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbufer and framebuffer.");
    705 }
    706 
    707 
    708 
    709 void genImage (const glw::Functions&			gl,
    710 			   de::Random&						rng,
    711 			   deUint32							name,
    712 			   vector<ArrayBuffer<deUint8> >&	levels,
    713 			   const ImageInfo&					info,
    714 			   deUint32							moreRestrictiveFormat)
    715 {
    716 	if (isTextureTarget(info.getTarget()))
    717 		genTextureImage(gl, rng, name, levels, info, moreRestrictiveFormat);
    718 	else
    719 		genRenderbufferImage(gl, rng, name, levels, info, moreRestrictiveFormat);
    720 }
    721 
    722 IVec3 getTexelBlockStride (const ImageInfo& info, int level)
    723 {
    724 	const IVec3	size					= getLevelSize(info.getTarget(), info.getSize(), level);
    725 	const int	texelBlockSize			= getTexelBlockSize(info.getFormat());
    726 	const IVec3 texelBlockPixelSize		= getTexelBlockPixelSize(info.getFormat());
    727 	const IVec3 textureTexelBlockSize	= divRoundUp(size, texelBlockPixelSize);
    728 
    729 	return IVec3(texelBlockSize, textureTexelBlockSize.x() * texelBlockSize, textureTexelBlockSize.x() * textureTexelBlockSize.y() * texelBlockSize);
    730 }
    731 
    732 int sumComponents (const IVec3& v)
    733 {
    734 	int s = 0;
    735 
    736 	for (int i = 0; i < 3; i++)
    737 		s += v[i];
    738 
    739 	return s;
    740 }
    741 
    742 void copyImageData (vector<ArrayBuffer<deUint8> >&			dstImageData,
    743 					const ImageInfo&						dstImageInfo,
    744 					int										dstLevel,
    745 					const IVec3&							dstPos,
    746 
    747 					const vector<ArrayBuffer<deUint8> >&	srcImageData,
    748 					const ImageInfo&						srcImageInfo,
    749 					int										srcLevel,
    750 					const IVec3&							srcPos,
    751 
    752 					const IVec3&							copySize)
    753 {
    754 	const ArrayBuffer<deUint8>&	srcLevelData			= srcImageData[srcLevel];
    755 	ArrayBuffer<deUint8>&		dstLevelData			= dstImageData[dstLevel];
    756 
    757 	const IVec3					srcTexelBlockPixelSize	= getTexelBlockPixelSize(srcImageInfo.getFormat());
    758 	const int					srcTexelBlockSize		= getTexelBlockSize(srcImageInfo.getFormat());
    759 	const IVec3					srcTexelPos				= srcPos / srcTexelBlockPixelSize;
    760 	const IVec3					srcTexelBlockStride		= getTexelBlockStride(srcImageInfo, srcLevel);
    761 
    762 	const IVec3					dstTexelBlockPixelSize	= getTexelBlockPixelSize(dstImageInfo.getFormat());
    763 	const int					dstTexelBlockSize		= getTexelBlockSize(dstImageInfo.getFormat());
    764 	const IVec3					dstTexelPos				= dstPos / dstTexelBlockPixelSize;
    765 	const IVec3					dstTexelBlockStride		= getTexelBlockStride(dstImageInfo, dstLevel);
    766 
    767 	const IVec3					copyTexelBlockCount		= copySize / srcTexelBlockPixelSize;
    768 	const int					texelBlockSize			= srcTexelBlockSize;
    769 
    770 	DE_ASSERT(srcTexelBlockSize == dstTexelBlockSize);
    771 	DE_UNREF(dstTexelBlockSize);
    772 
    773 	DE_ASSERT((copySize.x() % srcTexelBlockPixelSize.x()) == 0);
    774 	DE_ASSERT((copySize.y() % srcTexelBlockPixelSize.y()) == 0);
    775 	DE_ASSERT((copySize.z() % srcTexelBlockPixelSize.z()) == 0);
    776 
    777 	DE_ASSERT((srcPos.x() % srcTexelBlockPixelSize.x()) == 0);
    778 	DE_ASSERT((srcPos.y() % srcTexelBlockPixelSize.y()) == 0);
    779 	DE_ASSERT((srcPos.z() % srcTexelBlockPixelSize.z()) == 0);
    780 
    781 	for (int z = 0; z < copyTexelBlockCount.z(); z++)
    782 	for (int y = 0; y < copyTexelBlockCount.y(); y++)
    783 	{
    784 		const IVec3				blockPos		(0, y, z);
    785 		const deUint8* const	srcPtr			= srcLevelData.getElementPtr(sumComponents((srcTexelPos + blockPos) * srcTexelBlockStride));
    786 		deUint8* const			dstPtr			= dstLevelData.getElementPtr(sumComponents((dstTexelPos + blockPos) * dstTexelBlockStride));
    787 		const int				copyLineSize	= copyTexelBlockCount.x() * texelBlockSize;
    788 
    789 		deMemcpy(dstPtr, srcPtr, copyLineSize);
    790 	}
    791 }
    792 
    793 vector<tcu::ConstPixelBufferAccess> getLevelAccesses (const vector<ArrayBuffer<deUint8> >& data, const ImageInfo& info)
    794 {
    795 	const tcu::TextureFormat			format	= glu::mapGLInternalFormat(info.getFormat());
    796 	const IVec3							size	= info.getSize();
    797 
    798 	vector<tcu::ConstPixelBufferAccess>	result;
    799 
    800 	DE_ASSERT((int)data.size() == getLevelCount(info));
    801 
    802 	for (int level = 0; level < (int)data.size(); level++)
    803 	{
    804 		const IVec3 levelSize = getLevelSize(info.getTarget(), size, level);
    805 
    806 		result.push_back(tcu::ConstPixelBufferAccess(format, levelSize.x(), levelSize.y(), levelSize.z(), data[level].getPtr()));
    807 	}
    808 
    809 	return result;
    810 }
    811 
    812 vector<tcu::ConstPixelBufferAccess> getCubeLevelAccesses (const vector<ArrayBuffer<deUint8> >&	data,
    813 														  const ImageInfo&						info,
    814 														  int									faceNdx)
    815 {
    816 	const tcu::TextureFormat			format				= glu::mapGLInternalFormat(info.getFormat());
    817 	const IVec3							size				= info.getSize();
    818 	const int							texelBlockSize		= getTexelBlockSize(info.getFormat());
    819 	const IVec3							texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat());
    820 	vector<tcu::ConstPixelBufferAccess>	result;
    821 
    822 	DE_ASSERT(info.getTarget() == GL_TEXTURE_CUBE_MAP);
    823 	DE_ASSERT((int)data.size() == getLevelCount(info));
    824 
    825 	for (int level = 0; level < (int)data.size(); level++)
    826 	{
    827 		const IVec3 levelPixelSize			= getLevelSize(info.getTarget(), size, level);
    828 		const IVec3	levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
    829 		const int	levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
    830 		const int	levelSize				= levelTexelBlockCount * texelBlockSize;
    831 
    832 		result.push_back(tcu::ConstPixelBufferAccess(format, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), data[level].getElementPtr(levelSize * faceNdx)));
    833 	}
    834 
    835 	return result;
    836 }
    837 
    838 void copyImage (const glw::Functions&					gl,
    839 
    840 				deUint32								dstName,
    841 				vector<ArrayBuffer<deUint8> >&			dstImageData,
    842 				const ImageInfo&						dstImageInfo,
    843 				int										dstLevel,
    844 				const IVec3&							dstPos,
    845 
    846 				deUint32								srcName,
    847 				const vector<ArrayBuffer<deUint8> >&	srcImageData,
    848 				const ImageInfo&						srcImageInfo,
    849 				int										srcLevel,
    850 				const IVec3&							srcPos,
    851 
    852 				const IVec3&							copySize)
    853 {
    854 	gl.copyImageSubData(srcName, srcImageInfo.getTarget(), srcLevel, srcPos.x(), srcPos.y(), srcPos.z(),
    855 						dstName, dstImageInfo.getTarget(), dstLevel, dstPos.x(), dstPos.y(), dstPos.z(),
    856 						copySize.x(), copySize.y(), copySize.z());
    857 
    858 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyImageSubData failed.");
    859 
    860 	copyImageData(dstImageData, dstImageInfo, dstLevel, dstPos,
    861 				  srcImageData, srcImageInfo, srcLevel, srcPos, copySize);
    862 }
    863 
    864 void verifyTexture2DView (tcu::TestContext&			testContext,
    865 						  glu::RenderContext&		renderContext,
    866 						  TextureRenderer&			renderer,
    867 						  tcu::ResultCollector&		results,
    868 						  de::Random&				rng,
    869 						  deUint32					name,
    870 						  const ImageInfo&			info,
    871 						  const tcu::Texture2DView&	refTexture)
    872 {
    873 	tcu::TestLog&					log				= testContext.getLog();
    874 	const glw::Functions&			gl				= renderContext.getFunctions();
    875 	const tcu::RGBA					threshold		= renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
    876 	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
    877 	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);
    878 
    879 	ReferenceParams					renderParams	(TEXTURETYPE_2D);
    880 
    881 	renderParams.samplerType	= getSamplerType(format);
    882 	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
    883 	renderParams.colorScale		= spec.lookupScale;
    884 	renderParams.colorBias		= spec.lookupBias;
    885 
    886 	gl.activeTexture(GL_TEXTURE0);
    887 	gl.bindTexture(GL_TEXTURE_2D, name);
    888 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");
    889 
    890 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    891 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    892 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    893 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    894 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
    895 
    896 	for (int level = 0; level < getLevelCount(info); level++)
    897 	{
    898 		const IVec3				levelSize		= getLevelSize(info.getTarget(), info.getSize(), level);
    899 		const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
    900 
    901 		vector<float>			texCoord;
    902 		tcu::Surface			renderedFrame	(viewport.width, viewport.height);
    903 		tcu::Surface			referenceFrame	(viewport.width, viewport.height);
    904 
    905 		renderParams.baseLevel	= level;
    906 		renderParams.maxLevel	= level;
    907 
    908 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
    909 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
    910 
    911 		computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
    912 
    913 		// Setup base viewport.
    914 		gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
    915 
    916 		// Draw.
    917 		renderer.renderQuad(0, &texCoord[0], renderParams);
    918 		glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
    919 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
    920 
    921 		// Compute reference.
    922 		sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
    923 
    924 		// Compare and log.
    925 		if (!pixelThresholdCompare(log, ("Level" + de::toString(level)).c_str(), ("Render level " + de::toString(level)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
    926 			results.fail("Image comparison of level " + de::toString(level) + " failed.");
    927 		else
    928 			log << TestLog::Message << "Image comparison of level " << level << " passed." << TestLog::EndMessage;
    929 	}
    930 
    931 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    932 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000);
    933 
    934 	gl.bindTexture(GL_TEXTURE_2D, 0);
    935 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
    936 }
    937 
    938 void decompressTextureLevel (const tcu::TexDecompressionParams&		params,
    939 							 ArrayBuffer<deUint8>&					levelData,
    940 							 tcu::PixelBufferAccess& 				levelAccess,
    941 							 const tcu::CompressedTexFormat&		compressedFormat,
    942 							 const tcu::TextureFormat&				decompressedFormat,
    943 							 const IVec3&							levelPixelSize,
    944 							 const void*							data)
    945 {
    946 	levelData.setStorage(levelPixelSize.x() * levelPixelSize.y() * levelPixelSize.z() * decompressedFormat.getPixelSize());
    947 	levelAccess = tcu::PixelBufferAccess(decompressedFormat, levelPixelSize.x(), levelPixelSize.y(), levelPixelSize.z(), levelData.getPtr());
    948 
    949 	tcu::decompress(levelAccess, compressedFormat, (const deUint8*)data, params);
    950 }
    951 
    952 void decompressTexture (vector<ArrayBuffer<deUint8> >&			levelDatas,
    953 						vector<tcu::PixelBufferAccess>& 		levelAccesses,
    954 						glu::RenderContext&						renderContext,
    955 						const ImageInfo&						info,
    956 						const vector<ArrayBuffer<deUint8> >&	data)
    957 {
    958 	const tcu::CompressedTexFormat	compressedFormat	= glu::mapGLCompressedTexFormat(info.getFormat());
    959 	const tcu::TextureFormat		decompressedFormat	= tcu::getUncompressedFormat(compressedFormat);
    960 	const IVec3						size				= info.getSize();
    961 	de::UniquePtr<glu::ContextInfo>	ctxInfo				(glu::ContextInfo::create(renderContext));
    962 	tcu::TexDecompressionParams		decompressParams;
    963 
    964 	if (tcu::isAstcFormat(compressedFormat))
    965 	{
    966 		if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr"))
    967 			decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR);
    968 		else if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
    969 			decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR);
    970 		else
    971 			DE_ASSERT(false);
    972 	}
    973 
    974 	levelDatas.resize(getLevelCount(info));
    975 	levelAccesses.resize(getLevelCount(info));
    976 
    977 	for (int level = 0; level < getLevelCount(info); level++)
    978 	{
    979 		const IVec3					levelPixelSize	= getLevelSize(info.getTarget(), size, level);
    980 		de::ArrayBuffer<deUint8>&	levelData		= levelDatas[level];
    981 		tcu::PixelBufferAccess&		levelAccess 	= levelAccesses[level];
    982 
    983 		decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, data[level].getPtr());
    984 	}
    985 }
    986 
    987 void verifyTexture2D (tcu::TestContext&						testContext,
    988 					  glu::RenderContext&					renderContext,
    989 					  TextureRenderer&						textureRenderer,
    990 					  tcu::ResultCollector&					results,
    991 					  de::Random&							rng,
    992 					  deUint32								name,
    993 					  const vector<ArrayBuffer<deUint8> >&	data,
    994 					  const ImageInfo&						info)
    995 {
    996 	if (glu::isCompressedFormat(info.getFormat()))
    997 	{
    998 		vector<de::ArrayBuffer<deUint8> >	levelDatas;
    999 		vector<tcu::PixelBufferAccess>		levelAccesses;
   1000 
   1001 		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);
   1002 
   1003 		{
   1004 			const tcu::Texture2DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
   1005 
   1006 			verifyTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1007 		}
   1008 	}
   1009 	else
   1010 	{
   1011 		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
   1012 		const tcu::Texture2DView					refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));
   1013 
   1014 		verifyTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1015 	}
   1016 }
   1017 
   1018 void verifyTexture3DView (tcu::TestContext&			testContext,
   1019 						  glu::RenderContext&		renderContext,
   1020 						  TextureRenderer&			renderer,
   1021 						  tcu::ResultCollector&		results,
   1022 						  de::Random&				rng,
   1023 						  deUint32					name,
   1024 						  const ImageInfo&			info,
   1025 						  const tcu::Texture3DView&	refTexture)
   1026 {
   1027 	tcu::TestLog&					log				= testContext.getLog();
   1028 	const glw::Functions&			gl				= renderContext.getFunctions();
   1029 	const tcu::RGBA					threshold		= renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
   1030 	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
   1031 	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);
   1032 
   1033 	ReferenceParams					renderParams	(TEXTURETYPE_3D);
   1034 
   1035 	renderParams.samplerType	= getSamplerType(format);
   1036 	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
   1037 	renderParams.colorScale		= spec.lookupScale;
   1038 	renderParams.colorBias		= spec.lookupBias;
   1039 
   1040 	gl.activeTexture(GL_TEXTURE0);
   1041 	gl.bindTexture(GL_TEXTURE_3D, name);
   1042 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");
   1043 
   1044 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1045 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1046 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
   1047 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   1048 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1049 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
   1050 
   1051 	for (int level = 0; level < getLevelCount(info); level++)
   1052 	{
   1053 		const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
   1054 
   1055 		renderParams.baseLevel	= level;
   1056 		renderParams.maxLevel	= level;
   1057 
   1058 		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, level);
   1059 		gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, level);
   1060 
   1061 		for (int slice = 0; slice < levelSize.z(); slice++)
   1062 		{
   1063 			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
   1064 			const float				r				= (float(slice) + 0.5f) / levelSize.z();
   1065 			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
   1066 			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
   1067 			vector<float>			texCoord;
   1068 
   1069 			computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2));
   1070 
   1071 			// Setup base viewport.
   1072 			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
   1073 
   1074 			// Draw.
   1075 			renderer.renderQuad(0, &texCoord[0], renderParams);
   1076 			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
   1077 			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
   1078 
   1079 			// Compute reference.
   1080 			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
   1081 
   1082 			// Compare and log.
   1083 			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))
   1084 				results.fail("Image comparison of level " + de::toString(level) + " and slice " + de::toString(slice) + " failed.");
   1085 			else
   1086 				log << TestLog::Message << "Image comparison of level " << level << " and slice " << slice << " passed." << TestLog::EndMessage;;
   1087 		}
   1088 	}
   1089 
   1090 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
   1091 	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1000);
   1092 
   1093 	gl.bindTexture(GL_TEXTURE_3D, 0);
   1094 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
   1095 }
   1096 
   1097 void verifyTexture3D (tcu::TestContext&						testContext,
   1098 					  glu::RenderContext&					renderContext,
   1099 					  TextureRenderer&						textureRenderer,
   1100 					  tcu::ResultCollector&					results,
   1101 					  de::Random&							rng,
   1102 					  deUint32								name,
   1103 					  const vector<ArrayBuffer<deUint8> >&	data,
   1104 					  const ImageInfo&						info)
   1105 {
   1106 	if (glu::isCompressedFormat(info.getFormat()))
   1107 	{
   1108 		vector<de::ArrayBuffer<deUint8> >	levelDatas;
   1109 		vector<tcu::PixelBufferAccess>		levelAccesses;
   1110 
   1111 		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);
   1112 
   1113 		{
   1114 			const tcu::Texture3DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
   1115 
   1116 			verifyTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1117 		}
   1118 	}
   1119 	else
   1120 	{
   1121 		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
   1122 		const tcu::Texture3DView					refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));
   1123 
   1124 		verifyTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1125 	}
   1126 }
   1127 
   1128 void verifyTextureCubemapView (tcu::TestContext&			testContext,
   1129 							   glu::RenderContext&			renderContext,
   1130 							   TextureRenderer&				renderer,
   1131 							   tcu::ResultCollector&		results,
   1132 							   de::Random&					rng,
   1133 							   deUint32						name,
   1134 							   const ImageInfo&				info,
   1135 							   const tcu::TextureCubeView&	refTexture)
   1136 {
   1137 	tcu::TestLog&					log				= testContext.getLog();
   1138 	const glw::Functions&			gl				= renderContext.getFunctions();
   1139 	const tcu::RGBA					threshold		= renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
   1140 	const tcu::TextureFormat		format			= refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X).getFormat();
   1141 	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);
   1142 
   1143 	ReferenceParams					renderParams	(TEXTURETYPE_CUBE);
   1144 
   1145 	renderParams.samplerType	= getSamplerType(format);
   1146 	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
   1147 	renderParams.colorScale		= spec.lookupScale;
   1148 	renderParams.colorBias		= spec.lookupBias;
   1149 
   1150 	gl.activeTexture(GL_TEXTURE0);
   1151 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, name);
   1152 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");
   1153 
   1154 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1155 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1156 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   1157 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1158 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
   1159 
   1160 	for (int level = 0; level < getLevelCount(info); level++)
   1161 	{
   1162 		const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
   1163 
   1164 		// \note It seems we can't reliably sample two smallest texture levels with cubemaps
   1165 		if (levelSize.x() < 4 && levelSize.y() < 4)
   1166 			continue;
   1167 
   1168 		renderParams.baseLevel	= level;
   1169 		renderParams.maxLevel	= level;
   1170 
   1171 		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, level);
   1172 		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, level);
   1173 
   1174 		for (int face = 0; face < 6; face++)
   1175 		{
   1176 			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
   1177 			const string			cubemapFaceName	= glu::getCubeMapFaceStr(mapFaceNdxToFace(face)).toString();
   1178 			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
   1179 			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
   1180 			vector<float>			texCoord;
   1181 
   1182 			computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(face)));
   1183 
   1184 			// Setup base viewport.
   1185 			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
   1186 
   1187 			// Draw.
   1188 			renderer.renderQuad(0, &texCoord[0], renderParams);
   1189 			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
   1190 			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
   1191 
   1192 			// Compute reference.
   1193 			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
   1194 
   1195 			// Compare and log.
   1196 			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))
   1197 				results.fail("Image comparison of level " + de::toString(level) + " and face " + cubemapFaceName + " failed.");
   1198 			else
   1199 				log << TestLog::Message << "Image comparison of level " << level << " and face " << cubemapFaceName << " passed." << TestLog::EndMessage;
   1200 		}
   1201 	}
   1202 
   1203 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
   1204 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1000);
   1205 
   1206 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
   1207 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
   1208 }
   1209 
   1210 void verifyTextureCubemap (tcu::TestContext&					testContext,
   1211 						   glu::RenderContext&					renderContext,
   1212 						   TextureRenderer&						textureRenderer,
   1213 						   tcu::ResultCollector&				results,
   1214 						   de::Random&							rng,
   1215 						   deUint32								name,
   1216 						   const vector<ArrayBuffer<deUint8> >&	data,
   1217 						   const ImageInfo&						info)
   1218 {
   1219 	if (glu::isCompressedFormat(info.getFormat()))
   1220 	{
   1221 		const tcu::CompressedTexFormat&	compressedFormat	= glu::mapGLCompressedTexFormat(info.getFormat());
   1222 		const tcu::TextureFormat&		decompressedFormat	= tcu::getUncompressedFormat(compressedFormat);
   1223 
   1224 		const int						texelBlockSize		= getTexelBlockSize(info.getFormat());
   1225 		const IVec3						texelBlockPixelSize = getTexelBlockPixelSize(info.getFormat());
   1226 
   1227 		vector<tcu::PixelBufferAccess>	levelAccesses[6];
   1228 		vector<ArrayBuffer<deUint8> >	levelDatas[6];
   1229 		de::UniquePtr<glu::ContextInfo>	ctxInfo				(glu::ContextInfo::create(renderContext));
   1230 		tcu::TexDecompressionParams		decompressParams;
   1231 
   1232 		if (tcu::isAstcFormat(compressedFormat))
   1233 		{
   1234 			if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_hdr"))
   1235 				decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_HDR);
   1236 			else if (ctxInfo->isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
   1237 				decompressParams = tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR);
   1238 			else
   1239 				DE_ASSERT(false);
   1240 		}
   1241 
   1242 		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
   1243 		{
   1244 			levelAccesses[faceNdx].resize(getLevelCount(info));
   1245 			levelDatas[faceNdx].resize(getLevelCount(info));
   1246 		}
   1247 
   1248 		for (int level = 0; level < getLevelCount(info); level++)
   1249 		{
   1250 			for (int faceNdx = 0; faceNdx < 6; faceNdx++)
   1251 			{
   1252 				const IVec3				levelPixelSize			= getLevelSize(info.getTarget(), info.getSize(), level);
   1253 				const IVec3				levelTexelBlockSize		= divRoundUp(levelPixelSize, texelBlockPixelSize);
   1254 				const int				levelTexelBlockCount	= levelTexelBlockSize.x() * levelTexelBlockSize.y() * levelTexelBlockSize.z();
   1255 				const int				levelSize 				= levelTexelBlockCount * texelBlockSize;
   1256 
   1257 				const deUint8*			dataPtr					= data[level].getElementPtr(faceNdx * levelSize);
   1258 				tcu::PixelBufferAccess& levelAccess				= levelAccesses[faceNdx][level];
   1259 				ArrayBuffer<deUint8>&	levelData				= levelDatas[faceNdx][level];
   1260 
   1261 				decompressTextureLevel(decompressParams, levelData, levelAccess, compressedFormat, decompressedFormat, levelPixelSize, dataPtr);
   1262 			}
   1263 		}
   1264 
   1265 		const tcu::ConstPixelBufferAccess* levels[6];
   1266 
   1267 		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
   1268 			levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]);
   1269 
   1270 		{
   1271 			const tcu::TextureCubeView refTexture(getLevelCount(info), levels);
   1272 
   1273 			verifyTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1274 		}
   1275 	}
   1276 	else
   1277 	{
   1278 		const vector<tcu::ConstPixelBufferAccess> levelAccesses[6] =
   1279 		{
   1280 			getCubeLevelAccesses(data, info, 0),
   1281 			getCubeLevelAccesses(data, info, 1),
   1282 			getCubeLevelAccesses(data, info, 2),
   1283 			getCubeLevelAccesses(data, info, 3),
   1284 			getCubeLevelAccesses(data, info, 4),
   1285 			getCubeLevelAccesses(data, info, 5),
   1286 		};
   1287 
   1288 		const tcu::ConstPixelBufferAccess* levels[6];
   1289 
   1290 		for (int faceNdx = 0; faceNdx < 6; faceNdx++)
   1291 			levels[glu::getCubeFaceFromGL(mapFaceNdxToFace(faceNdx))] = &(levelAccesses[faceNdx][0]);
   1292 
   1293 		{
   1294 			const tcu::TextureCubeView refTexture(getLevelCount(info), levels);
   1295 
   1296 			verifyTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1297 		}
   1298 	}
   1299 }
   1300 
   1301 void verifyTexture2DArrayView (tcu::TestContext&				testContext,
   1302 							   glu::RenderContext&				renderContext,
   1303 							   TextureRenderer&					renderer,
   1304 							   tcu::ResultCollector&			results,
   1305 							   de::Random&						rng,
   1306 							   deUint32							name,
   1307 							   const ImageInfo&					info,
   1308 							   const tcu::Texture2DArrayView&	refTexture)
   1309 {
   1310 	tcu::TestLog&					log				= testContext.getLog();
   1311 	const glw::Functions&			gl				= renderContext.getFunctions();
   1312 	const tcu::RGBA					threshold		= renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
   1313 	const tcu::TextureFormat		format			= refTexture.getLevel(0).getFormat();
   1314 	const tcu::TextureFormatInfo	spec			= tcu::getTextureFormatInfo(format);
   1315 
   1316 	ReferenceParams					renderParams	(TEXTURETYPE_2D_ARRAY);
   1317 
   1318 	renderParams.samplerType	= getSamplerType(format);
   1319 	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
   1320 	renderParams.colorScale		= spec.lookupScale;
   1321 	renderParams.colorBias		= spec.lookupBias;
   1322 
   1323 	gl.activeTexture(GL_TEXTURE0);
   1324 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, name);
   1325 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind texture.");
   1326 
   1327 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1328 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   1329 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
   1330 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1331 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
   1332 
   1333 	for (int level = 0; level < getLevelCount(info); level++)
   1334 	{
   1335 		const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
   1336 
   1337 		renderParams.baseLevel	= level;
   1338 		renderParams.maxLevel	= level;
   1339 
   1340 		gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, level);
   1341 		gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, level);
   1342 
   1343 		for (int layer = 0; layer < levelSize.z(); layer++)
   1344 		{
   1345 			const RandomViewport	viewport		(renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
   1346 			tcu::Surface			renderedFrame	(viewport.width, viewport.height);
   1347 			tcu::Surface			referenceFrame	(viewport.width, viewport.height);
   1348 			vector<float>			texCoord;
   1349 
   1350 			computeQuadTexCoord2DArray(texCoord, layer, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
   1351 
   1352 			// Setup base viewport.
   1353 			gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
   1354 
   1355 			// Draw.
   1356 			renderer.renderQuad(0, &texCoord[0], renderParams);
   1357 			glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
   1358 			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
   1359 
   1360 			// Compute reference.
   1361 			sampleTexture(SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
   1362 
   1363 			// Compare and log.
   1364 			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))
   1365 				results.fail("Image comparison of level " + de::toString(level) + " and layer " + de::toString(layer) + " failed.");
   1366 			else
   1367 				log << TestLog::Message << "Image comparison of level " << level << " and layer " << layer << " passed." << TestLog::EndMessage;
   1368 		}
   1369 	}
   1370 
   1371 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
   1372 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000);
   1373 
   1374 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
   1375 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
   1376 }
   1377 
   1378 void verifyTexture2DArray (tcu::TestContext&					testContext,
   1379 						   glu::RenderContext&					renderContext,
   1380 						   TextureRenderer&						textureRenderer,
   1381 						   tcu::ResultCollector&				results,
   1382 						   de::Random&							rng,
   1383 						   deUint32								name,
   1384 						   const vector<ArrayBuffer<deUint8> >&	data,
   1385 						   const ImageInfo&						info)
   1386 {
   1387 	if (glu::isCompressedFormat(info.getFormat()))
   1388 	{
   1389 		vector<de::ArrayBuffer<deUint8> >	levelDatas;
   1390 		vector<tcu::PixelBufferAccess>		levelAccesses;
   1391 
   1392 		decompressTexture(levelDatas, levelAccesses, renderContext, info, data);
   1393 
   1394 		{
   1395 			const tcu::Texture2DArrayView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
   1396 
   1397 			verifyTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1398 		}
   1399 	}
   1400 	else
   1401 	{
   1402 		const vector<tcu::ConstPixelBufferAccess>	levelAccesses	= getLevelAccesses(data, info);
   1403 		const tcu::Texture2DArrayView				refTexture		((int)levelAccesses.size(), &(levelAccesses[0]));
   1404 
   1405 		verifyTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
   1406 	}
   1407 }
   1408 
   1409 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
   1410 {
   1411 	switch (tcu::getTextureChannelClass(format.type))
   1412 	{
   1413 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
   1414 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
   1415 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
   1416 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
   1417 
   1418 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
   1419 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
   1420 
   1421 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
   1422 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
   1423 
   1424 		default:
   1425 			DE_ASSERT(false);
   1426 			return tcu::TextureFormat();
   1427 	}
   1428 }
   1429 
   1430 Vec4 calculateThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
   1431 {
   1432 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
   1433 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
   1434 
   1435 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
   1436 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
   1437 
   1438 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
   1439 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
   1440 
   1441 	{
   1442 		const tcu::IVec4	srcBits		= tcu::getTextureFormatBitDepth(sourceFormat);
   1443 		const tcu::IVec4	readBits	= tcu::getTextureFormatBitDepth(readPixelsFormat);
   1444 
   1445 		return Vec4(1.0f) / ((tcu::IVec4(1) << (tcu::min(srcBits, readBits))) - tcu::IVec4(1)).cast<float>();
   1446 	}
   1447 }
   1448 
   1449 void verifyRenderbuffer (tcu::TestContext&						testContext,
   1450 						 glu::RenderContext&					renderContext,
   1451 						 tcu::ResultCollector&					results,
   1452 						 deUint32								name,
   1453 						 const vector<ArrayBuffer<deUint8> >&	data,
   1454 						 const ImageInfo&						info)
   1455 {
   1456 	const glw::Functions&				gl					= renderContext.getFunctions();
   1457 	TestLog&							log					= testContext.getLog();
   1458 
   1459 	const tcu::TextureFormat			format				= glu::mapGLInternalFormat(info.getFormat());
   1460 	const IVec3							size				= info.getSize();
   1461 	const tcu::ConstPixelBufferAccess	refRenderbuffer		(format, size.x(), size.y(), 1, data[0].getPtr());
   1462 	const tcu::TextureFormat			readPixelsFormat	= getReadPixelFormat(format);
   1463 	tcu::TextureLevel					renderbuffer		(readPixelsFormat, size.x(), size.y());
   1464 
   1465 	DE_ASSERT(size.z() == 1);
   1466 	DE_ASSERT(data.size() == 1);
   1467 
   1468 	{
   1469 		glu::Framebuffer framebuffer(gl);
   1470 
   1471 		gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
   1472 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create and bind framebuffer.");
   1473 
   1474 		gl.bindRenderbuffer(GL_RENDERBUFFER, name);
   1475 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name);
   1476 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind and attach renderbuffer to framebuffer.");
   1477 
   1478 		glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess());
   1479 
   1480 		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
   1481 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
   1482 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbuffer and framebuffer.");
   1483 	}
   1484 
   1485 	if (isFloatFormat(info.getFormat()))
   1486 	{
   1487 		const tcu::UVec4 threshold (2, 2, 2, 2);
   1488 
   1489 		if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
   1490 			results.fail("Image comparison failed.");
   1491 		else
   1492 			log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
   1493 	}
   1494 	else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat()))
   1495 	{
   1496 		const tcu::UVec4 threshold (1, 1, 1, 1);
   1497 
   1498 		if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
   1499 			results.fail("Image comparison failed.");
   1500 		else
   1501 			log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
   1502 	}
   1503 	else
   1504 	{
   1505 		const Vec4 threshold = calculateThreshold(format, readPixelsFormat);
   1506 
   1507 		if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
   1508 			results.fail("Image comparison failed.");
   1509 		else
   1510 			log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
   1511 	}
   1512 }
   1513 
   1514 void verify (tcu::TestContext&						testContext,
   1515 			 glu::RenderContext&					renderContext,
   1516 			 TextureRenderer&						textureRenderer,
   1517 			 tcu::ResultCollector&					results,
   1518 			 de::Random&							rng,
   1519 			 deUint32								name,
   1520 			 const vector<ArrayBuffer<deUint8> >&	data,
   1521 			 const ImageInfo&						info)
   1522 {
   1523 	switch (info.getTarget())
   1524 	{
   1525 		case GL_TEXTURE_2D:
   1526 			verifyTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info);
   1527 			break;
   1528 
   1529 		case GL_TEXTURE_3D:
   1530 			verifyTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info);
   1531 			break;
   1532 
   1533 		case GL_TEXTURE_CUBE_MAP:
   1534 			verifyTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info);
   1535 			break;
   1536 
   1537 		case GL_TEXTURE_2D_ARRAY:
   1538 			verifyTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info);
   1539 			break;
   1540 
   1541 		case GL_RENDERBUFFER:
   1542 			verifyRenderbuffer(testContext, renderContext, results, name, data, info);
   1543 			break;
   1544 
   1545 		default:
   1546 			DE_ASSERT(false);
   1547 	}
   1548 }
   1549 
   1550 void logTestImageInfo (TestLog&			log,
   1551 					   const ImageInfo&	imageInfo)
   1552 {
   1553 	log << TestLog::Message << "Target: " << targetToName(imageInfo.getTarget()) << TestLog::EndMessage;
   1554 	log << TestLog::Message << "Size: " << imageInfo.getSize() << TestLog::EndMessage;
   1555 	log << TestLog::Message << "Levels: " << getLevelCount(imageInfo) << TestLog::EndMessage;
   1556 	log << TestLog::Message << "Format: " << formatToName(imageInfo.getFormat()) << TestLog::EndMessage;
   1557 }
   1558 
   1559 void logTestInfo (TestLog&			log,
   1560 				  const ImageInfo&	srcImageInfo,
   1561 				  const ImageInfo&	dstImageInfo)
   1562 {
   1563 	tcu::ScopedLogSection section(log, "TestCaseInfo", "Test case info");
   1564 
   1565 	log << TestLog::Message << "Testing copying from " << targetToName(srcImageInfo.getTarget()) << " to " << targetToName(dstImageInfo.getTarget()) << "." << TestLog::EndMessage;
   1566 
   1567 	{
   1568 		tcu::ScopedLogSection srcSection(log, "Source image info.", "Source image info.");
   1569 		logTestImageInfo(log, srcImageInfo);
   1570 	}
   1571 
   1572 	{
   1573 		tcu::ScopedLogSection dstSection(log, "Destination image info.", "Destination image info.");
   1574 		logTestImageInfo(log, dstImageInfo);
   1575 	}
   1576 }
   1577 
   1578 class CopyImageTest : public TestCase
   1579 {
   1580 public:
   1581 							CopyImageTest			(Context&			context,
   1582 													 const ImageInfo&	srcImage,
   1583 													 const ImageInfo&	dstImage,
   1584 													 const char*		name,
   1585 													 const char*		description);
   1586 
   1587 							~CopyImageTest			(void);
   1588 
   1589 	void					init					(void);
   1590 	void					deinit					(void);
   1591 
   1592 	TestCase::IterateResult	iterate					(void);
   1593 
   1594 private:
   1595 	void					logTestInfoIter			(void);
   1596 	void					createImagesIter		(void);
   1597 	void					destroyImagesIter		(void);
   1598 	void					verifySourceIter		(void);
   1599 	void					verifyDestinationIter	(void);
   1600 	void					copyImageIter			(void);
   1601 
   1602 	struct State
   1603 	{
   1604 		State (int					seed,
   1605 			   tcu::TestLog&		log,
   1606 			   glu::RenderContext&	renderContext)
   1607 			: rng				(seed)
   1608 			, results			(log)
   1609 			, srcImage			(NULL)
   1610 			, dstImage			(NULL)
   1611 			, textureRenderer	(renderContext, log, glu::GLSL_VERSION_310_ES, glu::PRECISION_HIGHP)
   1612 		{
   1613 		}
   1614 
   1615 		~State (void)
   1616 		{
   1617 			delete srcImage;
   1618 			delete dstImage;
   1619 		}
   1620 
   1621 		de::Random						rng;
   1622 		tcu::ResultCollector			results;
   1623 		glu::ObjectWrapper*				srcImage;
   1624 		glu::ObjectWrapper*				dstImage;
   1625 		TextureRenderer					textureRenderer;
   1626 
   1627 		vector<ArrayBuffer<deUint8> >	srcImageLevels;
   1628 		vector<ArrayBuffer<deUint8> >	dstImageLevels;
   1629 	};
   1630 
   1631 	const ImageInfo	m_srcImageInfo;
   1632 	const ImageInfo	m_dstImageInfo;
   1633 
   1634 	int				m_iteration;
   1635 	State*			m_state;
   1636 };
   1637 
   1638 CopyImageTest::CopyImageTest (Context&			context,
   1639 							  const ImageInfo&	srcImage,
   1640 							  const ImageInfo&	dstImage,
   1641 							  const char*		name,
   1642 							  const char*		description)
   1643 	: TestCase			(context, name, description)
   1644 	, m_srcImageInfo	(srcImage)
   1645 	, m_dstImageInfo	(dstImage)
   1646 
   1647 	, m_iteration		(0)
   1648 	, m_state			(NULL)
   1649 {
   1650 }
   1651 
   1652 CopyImageTest::~CopyImageTest (void)
   1653 {
   1654 	deinit();
   1655 }
   1656 
   1657 void checkFormatSupport (glu::ContextInfo& info, deUint32 format, deUint32 target)
   1658 {
   1659 	if (glu::isCompressedFormat(format))
   1660 	{
   1661 		if (isAstcFormat(glu::mapGLCompressedTexFormat(format)))
   1662 		{
   1663 			DE_ASSERT(target != GL_RENDERBUFFER);
   1664 			if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_hdr") &&
   1665 				!info.isExtensionSupported("GL_OES_texture_compression_astc"))
   1666 			{
   1667 				if (target == GL_TEXTURE_3D)
   1668 					TCU_THROW(NotSupportedError, "TEXTURE_3D target requires HDR astc support.");
   1669 				if (!info.isExtensionSupported("GL_KHR_texture_compression_astc_ldr"))
   1670 					TCU_THROW(NotSupportedError, "Compressed astc texture not supported.");
   1671 			}
   1672 		}
   1673 		else
   1674 		{
   1675 			if (!info.isCompressedTextureFormatSupported(format))
   1676 				TCU_THROW(NotSupportedError, "Compressed texture not supported.");
   1677 		}
   1678 	}
   1679 }
   1680 
   1681 void CopyImageTest::init (void)
   1682 {
   1683 	de::UniquePtr<glu::ContextInfo> ctxInfo(glu::ContextInfo::create(m_context.getRenderContext()));
   1684 
   1685 	if (!ctxInfo->isExtensionSupported("GL_EXT_copy_image"))
   1686 		throw tcu::NotSupportedError("Extension GL_EXT_copy_image not supported.", "", __FILE__, __LINE__);
   1687 
   1688 	checkFormatSupport(*ctxInfo, m_srcImageInfo.getFormat(), m_srcImageInfo.getTarget());
   1689 	checkFormatSupport(*ctxInfo, m_dstImageInfo.getFormat(), m_dstImageInfo.getTarget());
   1690 
   1691 	{
   1692 		SeedBuilder builder;
   1693 
   1694 		builder << 903980
   1695 				<< m_srcImageInfo
   1696 				<< m_dstImageInfo;
   1697 
   1698 		m_state = new State(builder.get(), m_testCtx.getLog(), m_context.getRenderContext());
   1699 	}
   1700 }
   1701 
   1702 void CopyImageTest::deinit (void)
   1703 {
   1704 	delete m_state;
   1705 	m_state = NULL;
   1706 }
   1707 
   1708 void CopyImageTest::logTestInfoIter (void)
   1709 {
   1710 	TestLog& log = m_testCtx.getLog();
   1711 
   1712 	logTestInfo(log, m_srcImageInfo, m_dstImageInfo);
   1713 }
   1714 
   1715 void CopyImageTest::createImagesIter (void)
   1716 {
   1717 	TestLog&				log						= m_testCtx.getLog();
   1718 	glu::RenderContext&		renderContext			= m_context.getRenderContext();
   1719 	const glw::Functions&	gl						= renderContext.getFunctions();
   1720 	const deUint32			moreRestrictiveFormat	= getMoreRestrictiveFormat(m_srcImageInfo.getFormat(), m_dstImageInfo.getFormat());
   1721 	de::Random&				rng						= m_state->rng;
   1722 
   1723 	DE_ASSERT(!m_state->srcImage);
   1724 	DE_ASSERT(!m_state->dstImage);
   1725 
   1726 	m_state->srcImage = new glu::ObjectWrapper(gl, getObjectTraits(m_srcImageInfo));
   1727 	m_state->dstImage = new glu::ObjectWrapper(gl, getObjectTraits(m_dstImageInfo));
   1728 
   1729 	{
   1730 		glu::ObjectWrapper&				srcImage				= *m_state->srcImage;
   1731 		glu::ObjectWrapper&				dstImage				= *m_state->dstImage;
   1732 
   1733 		vector<ArrayBuffer<deUint8> >&	srcImageLevels			= m_state->srcImageLevels;
   1734 		vector<ArrayBuffer<deUint8> >&	dstImageLevels			= m_state->dstImageLevels;
   1735 
   1736 		log << TestLog::Message << "Creating source image." << TestLog::EndMessage;
   1737 		genImage(gl, rng, *srcImage, srcImageLevels, m_srcImageInfo, moreRestrictiveFormat);
   1738 
   1739 		log << TestLog::Message << "Creating destination image." << TestLog::EndMessage;
   1740 		genImage(gl, rng, *dstImage, dstImageLevels, m_dstImageInfo, moreRestrictiveFormat);
   1741 	}
   1742 }
   1743 
   1744 void CopyImageTest::destroyImagesIter (void)
   1745 {
   1746 	TestLog& log = m_testCtx.getLog();
   1747 
   1748 	log << TestLog::Message << "Deleting source image. " << TestLog::EndMessage;
   1749 
   1750 	delete m_state->srcImage;
   1751 	m_state->srcImage = NULL;
   1752 	m_state->srcImageLevels.clear();
   1753 
   1754 	log << TestLog::Message << "Deleting destination image. " << TestLog::EndMessage;
   1755 
   1756 	delete m_state->dstImage;
   1757 	m_state->dstImage = NULL;
   1758 	m_state->dstImageLevels.clear();
   1759 }
   1760 
   1761 void CopyImageTest::verifySourceIter (void)
   1762 {
   1763 	TestLog&						log					= m_testCtx.getLog();
   1764 	const tcu::ScopedLogSection		sourceSection		(log, "Source image verify.", "Source image verify.");
   1765 
   1766 	de::Random&						rng					= m_state->rng;
   1767 	tcu::ResultCollector&			results				= m_state->results;
   1768 	glu::ObjectWrapper&				srcImage			= *m_state->srcImage;
   1769 	vector<ArrayBuffer<deUint8> >&	srcImageLevels		= m_state->srcImageLevels;
   1770 
   1771 	log << TestLog::Message << "Verifying source image." << TestLog::EndMessage;
   1772 
   1773 	verify(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo);
   1774 }
   1775 
   1776 void CopyImageTest::verifyDestinationIter (void)
   1777 {
   1778 	TestLog&						log					= m_testCtx.getLog();
   1779 	const tcu::ScopedLogSection		destinationSection	(log, "Destination image verify.", "Destination image verify.");
   1780 
   1781 	de::Random&						rng					= m_state->rng;
   1782 	tcu::ResultCollector&			results				= m_state->results;
   1783 	glu::ObjectWrapper&				dstImage			= *m_state->dstImage;
   1784 	vector<ArrayBuffer<deUint8> >&	dstImageLevels		= m_state->dstImageLevels;
   1785 
   1786 	log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage;
   1787 
   1788 	verify(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo);
   1789 }
   1790 
   1791 struct Copy
   1792 {
   1793 	Copy (const IVec3&	srcPos_,
   1794 		  int			srcLevel_,
   1795 
   1796 		  const IVec3&	dstPos_,
   1797 		  int			dstLevel_,
   1798 
   1799 		  const IVec3&	size_)
   1800 		: srcPos	(srcPos_)
   1801 		, srcLevel	(srcLevel_)
   1802 
   1803 		, dstPos	(dstPos_)
   1804 		, dstLevel	(dstLevel_)
   1805 		, size		(size_)
   1806 	{
   1807 	}
   1808 
   1809 	IVec3	srcPos;
   1810 	int		srcLevel;
   1811 	IVec3	dstPos;
   1812 	int		dstLevel;
   1813 	IVec3	size;
   1814 };
   1815 
   1816 int getLastFullLevel (const ImageInfo& info)
   1817 {
   1818 	const int	levelCount		= getLevelCount(info);
   1819 	const IVec3	blockPixelSize	= getTexelBlockPixelSize(info.getFormat());
   1820 
   1821 	for (int level = 0; level < levelCount; level++)
   1822 	{
   1823 		const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
   1824 
   1825 		if (levelSize.x() < blockPixelSize.x() || levelSize.y() < blockPixelSize.y() || levelSize.z() < blockPixelSize.z())
   1826 			return level - 1;
   1827 	}
   1828 
   1829 	return levelCount -1;
   1830 }
   1831 
   1832 void generateCopies (vector<Copy>& copies, const ImageInfo& srcInfo, const ImageInfo& dstInfo)
   1833 {
   1834 	const deUint32	srcTarget		= srcInfo.getTarget();
   1835 	const deUint32	dstTarget		= dstInfo.getTarget();
   1836 
   1837 	const bool		srcIsTexture	= isTextureTarget(srcInfo.getTarget());
   1838 	const bool		dstIsTexture	= isTextureTarget(dstInfo.getTarget());
   1839 
   1840 	const bool		srcIsCube		= srcTarget == GL_TEXTURE_CUBE_MAP;
   1841 	const bool		dstIsCube		= dstTarget == GL_TEXTURE_CUBE_MAP;
   1842 
   1843 	const IVec3		srcBlockPixelSize		= getTexelBlockPixelSize(srcInfo.getFormat());
   1844 	const IVec3		dstBlockPixelSize		= getTexelBlockPixelSize(dstInfo.getFormat());
   1845 
   1846 	const int levels[] =
   1847 	{
   1848 		0, 1, -1
   1849 	};
   1850 
   1851 	for (int levelNdx = 0; levelNdx < (srcIsTexture || dstIsTexture ? DE_LENGTH_OF_ARRAY(levels) : 1); levelNdx++)
   1852 	{
   1853 		const int	srcLevel				= (srcIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(srcInfo)) : 0);
   1854 		const int	dstLevel				= (dstIsTexture ? (levels[levelNdx] >= 0 ? levels[levelNdx] : getLastFullLevel(dstInfo)) : 0);
   1855 
   1856 		const IVec3	srcSize					= getLevelSize(srcInfo.getTarget(), srcInfo.getSize(), srcLevel);
   1857 		const IVec3	dstSize					= getLevelSize(dstInfo.getTarget(), dstInfo.getSize(), dstLevel);
   1858 
   1859 		// \note These are rounded down
   1860 		const IVec3	srcCompleteBlockSize	= IVec3(srcSize.x() / srcBlockPixelSize.x(), srcSize.y() / srcBlockPixelSize.y(), (srcIsCube ? 6 : srcSize.z() / srcBlockPixelSize.z()));
   1861 		const IVec3	dstCompleteBlockSize	= IVec3(dstSize.x() / dstBlockPixelSize.x(), dstSize.y() / dstBlockPixelSize.y(), (dstIsCube ? 6 : dstSize.z() / dstBlockPixelSize.z()));
   1862 
   1863 		const IVec3	maxCopyBlockSize		= tcu::min(srcCompleteBlockSize, dstCompleteBlockSize);
   1864 
   1865 		// \note These are rounded down
   1866 		const int	copyBlockWidth			= de::max((2 * (maxCopyBlockSize.x() / 4)) - 1, 1);
   1867 		const int	copyBlockHeight			= de::max((2 * (maxCopyBlockSize.y() / 4)) - 1, 1);
   1868 		const int	copyBlockDepth			= de::max((2 * (maxCopyBlockSize.z() / 4)) - 1, 1);
   1869 
   1870 		// Copy NPOT block from (0,0,0) to other corner on dst
   1871 		{
   1872 			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
   1873 			const IVec3	srcBlockPos		(srcCompleteBlockSize - copyBlockSize);
   1874 			const IVec3	dstBlockPos		(0, 0, 0);
   1875 
   1876 			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
   1877 			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
   1878 			const IVec3 copySize		(copyBlockSize * srcBlockPixelSize);
   1879 
   1880 			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, copySize));
   1881 		}
   1882 
   1883 		// Copy NPOT block to (0,0,0) from other corner on src
   1884 		{
   1885 			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
   1886 			const IVec3	srcBlockPos		(0, 0, 0);
   1887 			const IVec3	dstBlockPos		(dstCompleteBlockSize - copyBlockSize);
   1888 
   1889 			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
   1890 			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
   1891 			const IVec3 copySize		(copyBlockSize * srcBlockPixelSize);
   1892 
   1893 			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, copySize));
   1894 		}
   1895 
   1896 		// Copy NPOT block to (0,0,0) from other corner on src
   1897 		{
   1898 			const IVec3	copyBlockSize	(copyBlockWidth, copyBlockHeight, copyBlockDepth);
   1899 			const IVec3	srcBlockPos		(tcu::max((srcCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0)));
   1900 			const IVec3	dstBlockPos		(tcu::max((dstCompleteBlockSize / 4) * 4 - copyBlockSize, IVec3(0)));
   1901 
   1902 			const IVec3	srcPos			(srcBlockPos * srcBlockPixelSize);
   1903 			const IVec3	dstPos			(dstBlockPos * dstBlockPixelSize);
   1904 			const IVec3 copySize		(copyBlockSize * srcBlockPixelSize);
   1905 
   1906 			copies.push_back(Copy(srcPos, srcLevel, dstPos, dstLevel, copySize));
   1907 		}
   1908 	}
   1909 }
   1910 
   1911 void CopyImageTest::copyImageIter (void)
   1912 {
   1913 	TestLog&						log				= m_testCtx.getLog();
   1914 	const glw::Functions&			gl				= m_context.getRenderContext().getFunctions();
   1915 	glu::ObjectWrapper&				srcImage		= *m_state->srcImage;
   1916 	glu::ObjectWrapper&				dstImage		= *m_state->dstImage;
   1917 
   1918 	vector<ArrayBuffer<deUint8> >&	srcImageLevels	= m_state->srcImageLevels;
   1919 	vector<ArrayBuffer<deUint8> >&	dstImageLevels	= m_state->dstImageLevels;
   1920 	vector<Copy>					copies;
   1921 
   1922 	generateCopies(copies, m_srcImageInfo, m_dstImageInfo);
   1923 
   1924 	for (int copyNdx = 0; copyNdx < (int)copies.size(); copyNdx++)
   1925 	{
   1926 		const Copy& copy = copies[copyNdx];
   1927 
   1928 		log << TestLog::Message << "Copying block " << copy.size << " from source image position " << copy.srcPos << " and mipmap level " << copy.srcLevel
   1929 								<< " to destination image position " << copy.dstPos << " and mipmap level " << copy.dstLevel << TestLog::EndMessage;
   1930 
   1931 		copyImage(gl, *dstImage, dstImageLevels, m_dstImageInfo, copy.dstLevel, copy.dstPos,
   1932 					  *srcImage, srcImageLevels, m_srcImageInfo, copy.srcLevel, copy.srcPos, copy.size);
   1933 	}
   1934 }
   1935 
   1936 TestCase::IterateResult CopyImageTest::iterate (void)
   1937 {
   1938 	void(CopyImageTest::*methods[])(void) =
   1939 	{
   1940 		&CopyImageTest::logTestInfoIter,
   1941 
   1942 		// Render both images and then copy and verify again.
   1943 		&CopyImageTest::createImagesIter,
   1944 		&CopyImageTest::verifySourceIter,
   1945 		&CopyImageTest::verifyDestinationIter,
   1946 		&CopyImageTest::copyImageIter,
   1947 		&CopyImageTest::verifySourceIter,
   1948 		&CopyImageTest::verifyDestinationIter,
   1949 		&CopyImageTest::destroyImagesIter,
   1950 
   1951 		// Create images and immediately copies between thew and verify.
   1952 		&CopyImageTest::createImagesIter,
   1953 		&CopyImageTest::copyImageIter,
   1954 		&CopyImageTest::verifySourceIter,
   1955 		&CopyImageTest::verifyDestinationIter,
   1956 		&CopyImageTest::destroyImagesIter
   1957 	};
   1958 
   1959 	if (m_iteration < DE_LENGTH_OF_ARRAY(methods))
   1960 	{
   1961 		(this->*methods[m_iteration])();
   1962 		m_iteration++;
   1963 		return CONTINUE;
   1964 	}
   1965 	else
   1966 	{
   1967 		m_state->results.setTestContextResult(m_testCtx);
   1968 		return STOP;
   1969 	}
   1970 }
   1971 
   1972 class CopyImageTests : public TestCaseGroup
   1973 {
   1974 public:
   1975 						CopyImageTests			(Context& context);
   1976 						~CopyImageTests			(void);
   1977 
   1978 	void				init					(void);
   1979 
   1980 private:
   1981 						CopyImageTests			(const CopyImageTests& other);
   1982 	CopyImageTests&		operator=				(const CopyImageTests& other);
   1983 };
   1984 
   1985 CopyImageTests::CopyImageTests (Context& context)
   1986 	: TestCaseGroup	(context, "copy_image", "Copy image tests for GL_EXT_copy_image.")
   1987 {
   1988 }
   1989 
   1990 CopyImageTests::~CopyImageTests (void)
   1991 {
   1992 }
   1993 
   1994 int smallestCommonMultiple (int a_, int b_)
   1995 {
   1996 	int	a		= (a_ > b_ ? a_ : b_);
   1997 	int	b		= (a_ > b_ ? b_ : a_);
   1998 	int	result  = 1;
   1999 
   2000 	for (int i = b/2; i > 1; i--)
   2001 	{
   2002 		while ((a % i) == 0 && (b % i) == 0)
   2003 		{
   2004 			result *= i;
   2005 			a /= i;
   2006 			b /= i;
   2007 		}
   2008 	}
   2009 
   2010 	return result * a * b;
   2011 }
   2012 
   2013 IVec3 getTestedSize (deUint32 target, deUint32 format, const IVec3& targetSize)
   2014 {
   2015 	const IVec3 texelBlockPixelSize = getTexelBlockPixelSize(format);
   2016 	const bool	isCube				= target == GL_TEXTURE_CUBE_MAP;
   2017 	const bool	is3D				= target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;
   2018 
   2019 	if (isCube)
   2020 	{
   2021 		const int	multiplier	= smallestCommonMultiple(texelBlockPixelSize.x(), texelBlockPixelSize.y());
   2022 		const int	size		= (1 + (targetSize.x() / multiplier)) * multiplier;
   2023 
   2024 		return IVec3(size, size, 1);
   2025 	}
   2026 	else if (is3D)
   2027 	{
   2028 		return (1 + (targetSize / texelBlockPixelSize)) * texelBlockPixelSize;
   2029 	}
   2030 	else
   2031 	{
   2032 		const int width = (1 + targetSize.x() / texelBlockPixelSize.x()) * texelBlockPixelSize.x();
   2033 		const int height = ((targetSize.y() / texelBlockPixelSize.y()) - 1) * texelBlockPixelSize.y();
   2034 
   2035 		return IVec3(width, height, 1);
   2036 	}
   2037 }
   2038 
   2039 void addCopyTests (TestCaseGroup* root, deUint32 srcFormat, deUint32 dstFormat)
   2040 {
   2041 	const string			groupName	= string(formatToName(srcFormat)) + "_" + formatToName(dstFormat);
   2042 	TestCaseGroup* const	group		= new TestCaseGroup(root->getContext(), groupName.c_str(), groupName.c_str());
   2043 
   2044 	const deUint32 targets[] =
   2045 	{
   2046 		GL_TEXTURE_2D,
   2047 		GL_TEXTURE_3D,
   2048 		GL_TEXTURE_CUBE_MAP,
   2049 		GL_TEXTURE_2D_ARRAY,
   2050 		GL_RENDERBUFFER
   2051 	};
   2052 
   2053 	root->addChild(group);
   2054 
   2055 	for (int srcTargetNdx = 0; srcTargetNdx < DE_LENGTH_OF_ARRAY(targets); srcTargetNdx++)
   2056 	{
   2057 		const deUint32	srcTarget				= targets[srcTargetNdx];
   2058 		const bool		srcIs3D					= srcTarget == GL_TEXTURE_2D_ARRAY || srcTarget == GL_TEXTURE_3D;
   2059 
   2060 		if (glu::isCompressedFormat(srcFormat) && srcTarget == GL_RENDERBUFFER)
   2061 			continue;
   2062 
   2063 		if (srcTarget == GL_RENDERBUFFER && !isColorRenderable(srcFormat))
   2064 			continue;
   2065 
   2066 		if (glu::isCompressedFormat(srcFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(srcFormat)) && srcIs3D)
   2067 			continue;
   2068 
   2069 		for (int dstTargetNdx = 0; dstTargetNdx < DE_LENGTH_OF_ARRAY(targets); dstTargetNdx++)
   2070 		{
   2071 			const deUint32	dstTarget				= targets[dstTargetNdx];
   2072 			const bool		dstIs3D					= dstTarget == GL_TEXTURE_2D_ARRAY || dstTarget == GL_TEXTURE_3D;
   2073 
   2074 			if (glu::isCompressedFormat(dstFormat) && dstTarget == GL_RENDERBUFFER)
   2075 				continue;
   2076 
   2077 			if (dstTarget == GL_RENDERBUFFER && !isColorRenderable(dstFormat))
   2078 				continue;
   2079 
   2080 			if (glu::isCompressedFormat(dstFormat) && !tcu::isAstcFormat(glu::mapGLCompressedTexFormat(dstFormat)) && dstIs3D)
   2081 				continue;
   2082 
   2083 			const string	targetTestName	= string(targetToName(srcTarget)) + "_to_" + targetToName(dstTarget);
   2084 
   2085 			const IVec3		targetSize2D	(128, 128, 1);
   2086 			const IVec3		targetSize3D	(128, 128, 16);
   2087 
   2088 			const IVec3		srcSize			= getTestedSize(srcTarget, srcFormat, (srcIs3D ? targetSize3D : targetSize2D));
   2089 			const IVec3		dstSize			= getTestedSize(dstTarget, dstFormat, (dstIs3D ? targetSize3D : targetSize2D));
   2090 
   2091 			group->addChild(new CopyImageTest(root->getContext(),
   2092 											ImageInfo(srcFormat, srcTarget, srcSize),
   2093 											ImageInfo(dstFormat, dstTarget, dstSize),
   2094 											targetTestName.c_str(), targetTestName.c_str()));
   2095 		}
   2096 	}
   2097 }
   2098 
   2099 void CopyImageTests::init (void)
   2100 {
   2101 	TestCaseGroup* const	nonCompressedGroup	= new TestCaseGroup(m_context, "non_compressed", "Test copying between textures.");
   2102 	TestCaseGroup* const	compressedGroup		= new TestCaseGroup(m_context, "compressed", "Test copying between compressed textures.");
   2103 	TestCaseGroup* const	mixedGroup			= new TestCaseGroup(m_context, "mixed", "Test copying between compressed and non-compressed textures.");
   2104 
   2105 	addChild(nonCompressedGroup);
   2106 	addChild(compressedGroup);
   2107 	addChild(mixedGroup);
   2108 
   2109 	map<ViewClass, vector<deUint32> >							textureFormatViewClasses;
   2110 	map<ViewClass, vector<deUint32> >							compressedTextureFormatViewClasses;
   2111 	map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >	mixedViewClasses;
   2112 
   2113 	// Texture view classes
   2114 	textureFormatViewClasses[VIEWCLASS_128_BITS]		= vector<deUint32>();
   2115 	textureFormatViewClasses[VIEWCLASS_96_BITS]			= vector<deUint32>();
   2116 	textureFormatViewClasses[VIEWCLASS_64_BITS]			= vector<deUint32>();
   2117 	textureFormatViewClasses[VIEWCLASS_48_BITS]			= vector<deUint32>();
   2118 	textureFormatViewClasses[VIEWCLASS_32_BITS]			= vector<deUint32>();
   2119 	textureFormatViewClasses[VIEWCLASS_24_BITS]			= vector<deUint32>();
   2120 	textureFormatViewClasses[VIEWCLASS_16_BITS]			= vector<deUint32>();
   2121 	textureFormatViewClasses[VIEWCLASS_8_BITS]			= vector<deUint32>();
   2122 
   2123 	// 128bit / VIEWCLASS_128_BITS
   2124 	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32F);
   2125 	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32I);
   2126 	textureFormatViewClasses[VIEWCLASS_128_BITS].push_back(GL_RGBA32UI);
   2127 
   2128 	// 96bit / VIEWCLASS_96_BITS
   2129 	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32F);
   2130 	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32I);
   2131 	textureFormatViewClasses[VIEWCLASS_96_BITS].push_back(GL_RGB32UI);
   2132 
   2133 	// 64bit / VIEWCLASS_64_BITS
   2134 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32F);
   2135 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32I);
   2136 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RG32UI);
   2137 
   2138 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16F);
   2139 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16I);
   2140 	textureFormatViewClasses[VIEWCLASS_64_BITS].push_back(GL_RGBA16UI);
   2141 
   2142 	// 48bit / VIEWCLASS_48_BITS
   2143 	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16F);
   2144 	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16I);
   2145 	textureFormatViewClasses[VIEWCLASS_48_BITS].push_back(GL_RGB16UI);
   2146 
   2147 	// 32bit / VIEWCLASS_32_BITS
   2148 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32F);
   2149 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32I);
   2150 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R32UI);
   2151 
   2152 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16F);
   2153 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16I);
   2154 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RG16UI);
   2155 
   2156 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8);
   2157 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8I);
   2158 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8UI);
   2159 
   2160 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_R11F_G11F_B10F);
   2161 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2UI);
   2162 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB10_A2);
   2163 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGBA8_SNORM);
   2164 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_SRGB8_ALPHA8);
   2165 	textureFormatViewClasses[VIEWCLASS_32_BITS].push_back(GL_RGB9_E5);
   2166 
   2167 	// 24bit / VIEWCLASS_24_BITS
   2168 	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8);
   2169 	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8I);
   2170 	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8UI);
   2171 	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_RGB8_SNORM);
   2172 	textureFormatViewClasses[VIEWCLASS_24_BITS].push_back(GL_SRGB8);
   2173 
   2174 	// 16bit / VIEWCLASS_16_BITS
   2175 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16F);
   2176 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16I);
   2177 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_R16UI);
   2178 
   2179 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8);
   2180 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8I);
   2181 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8UI);
   2182 	textureFormatViewClasses[VIEWCLASS_16_BITS].push_back(GL_RG8_SNORM);
   2183 
   2184 	// 8bit / VIEWCLASS_8_BITS
   2185 	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8);
   2186 	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8I);
   2187 	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8UI);
   2188 	textureFormatViewClasses[VIEWCLASS_8_BITS].push_back(GL_R8_SNORM);
   2189 
   2190 	// Compressed texture view classes
   2191 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11]			= vector<deUint32>();
   2192 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11]			= vector<deUint32>();
   2193 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB]			= vector<deUint32>();
   2194 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA]			= vector<deUint32>();
   2195 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA]		= vector<deUint32>();
   2196 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA]		= vector<deUint32>();
   2197 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA]		= vector<deUint32>();
   2198 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA]		= vector<deUint32>();
   2199 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA]		= vector<deUint32>();
   2200 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA]		= vector<deUint32>();
   2201 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA]		= vector<deUint32>();
   2202 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA]		= vector<deUint32>();
   2203 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA]		= vector<deUint32>();
   2204 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA]	= vector<deUint32>();
   2205 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA]	= vector<deUint32>();
   2206 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA]	= vector<deUint32>();
   2207 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA]	= vector<deUint32>();
   2208 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA]	= vector<deUint32>();
   2209 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA]	= vector<deUint32>();
   2210 
   2211 	// VIEWCLASS_EAC_R11
   2212 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_R11_EAC);
   2213 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_R11].push_back(GL_COMPRESSED_SIGNED_R11_EAC);
   2214 
   2215 	// VIEWCLASS_EAC_RG11
   2216 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_RG11_EAC);
   2217 	compressedTextureFormatViewClasses[VIEWCLASS_EAC_RG11].push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
   2218 
   2219 	// VIEWCLASS_ETC2_RGB
   2220 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_RGB8_ETC2);
   2221 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGB].push_back(GL_COMPRESSED_SRGB8_ETC2);
   2222 
   2223 	// VIEWCLASS_ETC2_RGBA
   2224 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
   2225 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_RGBA].push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
   2226 
   2227 	// VIEWCLASS_ETC2_EAC_RGBA
   2228 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
   2229 	compressedTextureFormatViewClasses[VIEWCLASS_ETC2_EAC_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
   2230 
   2231 	// VIEWCLASS_ASTC_4x4_RGBA
   2232 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_4x4_KHR);
   2233 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_4x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
   2234 
   2235 	// VIEWCLASS_ASTC_5x4_RGBA
   2236 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x4_KHR);
   2237 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x4_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
   2238 
   2239 	// VIEWCLASS_ASTC_5x5_RGBA
   2240 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_5x5_KHR);
   2241 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_5x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
   2242 
   2243 	// VIEWCLASS_ASTC_6x5_RGBA
   2244 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x5_KHR);
   2245 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
   2246 
   2247 	// VIEWCLASS_ASTC_6x6_RGBA
   2248 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_6x6_KHR);
   2249 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_6x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
   2250 
   2251 	// VIEWCLASS_ASTC_8x5_RGBA
   2252 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x5_KHR);
   2253 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
   2254 
   2255 	// VIEWCLASS_ASTC_8x6_RGBA
   2256 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x6_KHR);
   2257 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
   2258 
   2259 	// VIEWCLASS_ASTC_8x8_RGBA
   2260 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_8x8_KHR);
   2261 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_8x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
   2262 
   2263 	// VIEWCLASS_ASTC_10x5_RGBA
   2264 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x5_KHR);
   2265 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x5_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
   2266 
   2267 	// VIEWCLASS_ASTC_10x6_RGBA
   2268 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x6_KHR);
   2269 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x6_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
   2270 
   2271 	// VIEWCLASS_ASTC_10x8_RGBA
   2272 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x8_KHR);
   2273 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x8_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
   2274 
   2275 	// VIEWCLASS_ASTC_10x10_RGBA
   2276 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_10x10_KHR);
   2277 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_10x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
   2278 
   2279 	// VIEWCLASS_ASTC_12x10_RGBA
   2280 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x10_KHR);
   2281 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x10_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
   2282 
   2283 	// VIEWCLASS_ASTC_12x12_RGBA
   2284 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_RGBA_ASTC_12x12_KHR);
   2285 	compressedTextureFormatViewClasses[VIEWCLASS_ASTC_12x12_RGBA].push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
   2286 
   2287 	// Mixed view classes
   2288 	mixedViewClasses[VIEWCLASS_128_BITS] = pair<vector<deUint32>, vector<deUint32> >();
   2289 	mixedViewClasses[VIEWCLASS_64_BITS] = pair<vector<deUint32>, vector<deUint32> >();
   2290 
   2291 	// 128 bits
   2292 
   2293 	// Non compressed
   2294 	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32F);
   2295 	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32UI);
   2296 	mixedViewClasses[VIEWCLASS_128_BITS].first.push_back(GL_RGBA32I);
   2297 
   2298 	// Compressed
   2299 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
   2300 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
   2301 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RG11_EAC);
   2302 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
   2303 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_4x4_KHR);
   2304 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x4_KHR);
   2305 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_5x5_KHR);
   2306 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x5_KHR);
   2307 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_6x6_KHR);
   2308 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x5_KHR);
   2309 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x6_KHR);
   2310 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_8x8_KHR);
   2311 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x5_KHR);
   2312 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x6_KHR);
   2313 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x8_KHR);
   2314 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_10x10_KHR);
   2315 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x10_KHR);
   2316 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_RGBA_ASTC_12x12_KHR);
   2317 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
   2318 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
   2319 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
   2320 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
   2321 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
   2322 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
   2323 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
   2324 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
   2325 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
   2326 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
   2327 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
   2328 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
   2329 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
   2330 	mixedViewClasses[VIEWCLASS_128_BITS].second.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
   2331 
   2332 	// 64 bits
   2333 
   2334 	// Non compressed
   2335 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16F);
   2336 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16UI);
   2337 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RGBA16I);
   2338 
   2339 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32F);
   2340 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32UI);
   2341 	mixedViewClasses[VIEWCLASS_64_BITS].first.push_back(GL_RG32I);
   2342 
   2343 	// Compressed
   2344 	mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_R11_EAC);
   2345 	mixedViewClasses[VIEWCLASS_64_BITS].second.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
   2346 
   2347 	for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = textureFormatViewClasses.begin(); viewClassIter != textureFormatViewClasses.end(); ++viewClassIter)
   2348 	{
   2349 		const vector<deUint32>&	formats		= viewClassIter->second;
   2350 		const ViewClass			viewClass	= viewClassIter->first;
   2351 		TestCaseGroup* const	viewGroup	= new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass));
   2352 
   2353 		nonCompressedGroup->addChild(viewGroup);
   2354 
   2355 		for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++)
   2356 		for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++)
   2357 		{
   2358 			const deUint32 srcFormat = formats[srcFormatNdx];
   2359 			const deUint32 dstFormat = formats[dstFormatNdx];
   2360 
   2361 			if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
   2362 				continue;
   2363 
   2364 			addCopyTests(viewGroup, srcFormat, dstFormat);
   2365 		}
   2366 	}
   2367 
   2368 	for (map<ViewClass, vector<deUint32> >::const_iterator viewClassIter = compressedTextureFormatViewClasses.begin(); viewClassIter != compressedTextureFormatViewClasses.end(); ++viewClassIter)
   2369 	{
   2370 		const vector<deUint32>&	formats		= viewClassIter->second;
   2371 		const ViewClass			viewClass	= viewClassIter->first;
   2372 		TestCaseGroup* const	viewGroup	= new TestCaseGroup(m_context, viewClassToName(viewClass), viewClassToName(viewClass));
   2373 
   2374 		compressedGroup->addChild(viewGroup);
   2375 
   2376 		for (int srcFormatNdx = 0; srcFormatNdx < (int)formats.size(); srcFormatNdx++)
   2377 		for (int dstFormatNdx = 0; dstFormatNdx < (int)formats.size(); dstFormatNdx++)
   2378 		{
   2379 			const deUint32 srcFormat = formats[srcFormatNdx];
   2380 			const deUint32 dstFormat = formats[dstFormatNdx];
   2381 
   2382 			if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
   2383 				continue;
   2384 
   2385 			addCopyTests(viewGroup, srcFormat, dstFormat);
   2386 		}
   2387 	}
   2388 
   2389 	for (map<ViewClass, pair<vector<deUint32>, vector<deUint32> > >::const_iterator iter = mixedViewClasses.begin(); iter != mixedViewClasses.end(); ++iter)
   2390 	{
   2391 		const ViewClass			viewClass				= iter->first;
   2392 		const string			viewClassName			= string(viewClassToName(viewClass)) + "_mixed";
   2393 		TestCaseGroup* const	viewGroup				= new TestCaseGroup(m_context, viewClassName.c_str(), viewClassName.c_str());
   2394 
   2395 		const vector<deUint32>	nonCompressedFormats	= iter->second.first;
   2396 		const vector<deUint32>	compressedFormats		= iter->second.second;
   2397 
   2398 		mixedGroup->addChild(viewGroup);
   2399 
   2400 		for (int srcFormatNdx = 0; srcFormatNdx < (int)nonCompressedFormats.size(); srcFormatNdx++)
   2401 		for (int dstFormatNdx = 0; dstFormatNdx < (int)compressedFormats.size(); dstFormatNdx++)
   2402 		{
   2403 			const deUint32 srcFormat = nonCompressedFormats[srcFormatNdx];
   2404 			const deUint32 dstFormat = compressedFormats[dstFormatNdx];
   2405 
   2406 			if (srcFormat != dstFormat && isFloatFormat(srcFormat) && isFloatFormat(dstFormat))
   2407 				continue;
   2408 
   2409 			addCopyTests(viewGroup, srcFormat, dstFormat);
   2410 			addCopyTests(viewGroup, dstFormat, srcFormat);
   2411 		}
   2412 	}
   2413 }
   2414 
   2415 } // anonymous
   2416 
   2417 TestCaseGroup* createCopyImageTests (Context& context)
   2418 {
   2419 	return new CopyImageTests(context);
   2420 }
   2421 
   2422 } // Functional
   2423 } // gles31
   2424 } // deqp
   2425