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