Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 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 Texture wrap mode tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fTextureWrapTests.hpp"
     25 #include "glsTextureTestUtil.hpp"
     26 #include "gluTexture.hpp"
     27 #include "gluStrUtil.hpp"
     28 #include "gluTextureUtil.hpp"
     29 #include "gluPixelTransfer.hpp"
     30 #include "tcuTestLog.hpp"
     31 #include "tcuTextureUtil.hpp"
     32 #include "tcuCompressedTexture.hpp"
     33 #include "tcuVectorUtil.hpp"
     34 #include "tcuTexLookupVerifier.hpp"
     35 #include "deRandom.hpp"
     36 #include "deStringUtil.hpp"
     37 #include "deMemory.h"
     38 
     39 #include "glwEnums.hpp"
     40 #include "glwFunctions.hpp"
     41 
     42 namespace deqp
     43 {
     44 namespace gles3
     45 {
     46 namespace Functional
     47 {
     48 
     49 using tcu::TestLog;
     50 using tcu::CompressedTexture;
     51 using std::vector;
     52 using std::string;
     53 using tcu::Sampler;
     54 using namespace glu;
     55 using namespace gls::TextureTestUtil;
     56 
     57 //! Checks whether any ASTC version (LDR, HDR, full) is supported.
     58 static inline bool isASTCSupported (const glu::ContextInfo& contextInfo)
     59 {
     60 	const vector<string>& extensions = contextInfo.getExtensions();
     61 
     62 	for (int extNdx = 0; extNdx < (int)extensions.size(); extNdx++)
     63 	{
     64 		const string& ext = extensions[extNdx];
     65 
     66 		if (ext == "GL_KHR_texture_compression_astc_ldr" ||
     67 			ext == "GL_KHR_texture_compression_astc_hdr" ||
     68 			ext == "GL_OES_texture_compression_astc")
     69 			return true;
     70 	}
     71 
     72 	return false;
     73 }
     74 
     75 enum
     76 {
     77 	VIEWPORT_WIDTH		= 256,
     78 	VIEWPORT_HEIGHT		= 256
     79 };
     80 
     81 class TextureWrapCase : public tcu::TestCase
     82 {
     83 public:
     84 									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
     85 									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames);
     86 									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, CompressedTexture::Format compressedFormat, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
     87 									~TextureWrapCase		(void);
     88 
     89 	void							init					(void);
     90 	void							deinit					(void);
     91 	IterateResult					iterate					(void);
     92 
     93 private:
     94 									TextureWrapCase			(const TextureWrapCase& other);
     95 	TextureWrapCase&				operator=				(const TextureWrapCase& other);
     96 
     97 	struct Case
     98 	{
     99 		tcu::Vec2 bottomLeft;
    100 		tcu::Vec2 topRight;
    101 
    102 		Case (void) {}
    103 		Case (const tcu::Vec2& bl, const tcu::Vec2& tr) : bottomLeft(bl), topRight(tr) {}
    104 	};
    105 
    106 	glu::RenderContext&				m_renderCtx;
    107 	const glu::ContextInfo&			m_renderCtxInfo;
    108 
    109 	const deUint32					m_format;
    110 	const deUint32					m_dataType;
    111 	const CompressedTexture::Format	m_compressedFormat;
    112 	const deUint32					m_wrapS;
    113 	const deUint32					m_wrapT;
    114 	const deUint32					m_minFilter;
    115 	const deUint32					m_magFilter;
    116 
    117 	int								m_width;
    118 	int								m_height;
    119 	const std::vector<std::string>	m_filenames;
    120 
    121 	vector<Case>					m_cases;
    122 	int								m_caseNdx;
    123 
    124 	glu::Texture2D*					m_texture;
    125 	TextureRenderer					m_renderer;
    126 };
    127 
    128 TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
    129 	: TestCase				(testCtx, name, description)
    130 	, m_renderCtx			(renderCtx)
    131 	, m_renderCtxInfo		(ctxInfo)
    132 	, m_format				(format)
    133 	, m_dataType			(dataType)
    134 	, m_compressedFormat	(CompressedTexture::FORMAT_LAST)
    135 	, m_wrapS				(wrapS)
    136 	, m_wrapT				(wrapT)
    137 	, m_minFilter			(minFilter)
    138 	, m_magFilter			(magFilter)
    139 	, m_width				(width)
    140 	, m_height				(height)
    141 	, m_caseNdx				(0)
    142 	, m_texture				(DE_NULL)
    143 	, m_renderer			(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
    144 {
    145 }
    146 
    147 TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames)
    148 	: TestCase				(testCtx, name, description)
    149 	, m_renderCtx			(renderCtx)
    150 	, m_renderCtxInfo		(ctxInfo)
    151 	, m_format				(GL_NONE)
    152 	, m_dataType			(GL_NONE)
    153 	, m_compressedFormat	(CompressedTexture::FORMAT_LAST)
    154 	, m_wrapS				(wrapS)
    155 	, m_wrapT				(wrapT)
    156 	, m_minFilter			(minFilter)
    157 	, m_magFilter			(magFilter)
    158 	, m_width				(0)
    159 	, m_height				(0)
    160 	, m_filenames			(filenames)
    161 	, m_caseNdx				(0)
    162 	, m_texture				(DE_NULL)
    163 	, m_renderer			(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
    164 {
    165 }
    166 
    167 TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, CompressedTexture::Format compressedFormat, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
    168 	: TestCase				(testCtx, name, description)
    169 	, m_renderCtx			(renderCtx)
    170 	, m_renderCtxInfo		(ctxInfo)
    171 	, m_format				(GL_NONE)
    172 	, m_dataType			(GL_NONE)
    173 	, m_compressedFormat	(compressedFormat)
    174 	, m_wrapS				(wrapS)
    175 	, m_wrapT				(wrapT)
    176 	, m_minFilter			(minFilter)
    177 	, m_magFilter			(magFilter)
    178 	, m_width				(width)
    179 	, m_height				(height)
    180 	, m_caseNdx				(0)
    181 	, m_texture				(DE_NULL)
    182 	, m_renderer			(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
    183 {
    184 }
    185 
    186 
    187 TextureWrapCase::~TextureWrapCase (void)
    188 {
    189 	deinit();
    190 }
    191 
    192 void TextureWrapCase::init (void)
    193 {
    194 	// Load or generate texture.
    195 
    196 	if (!m_filenames.empty())
    197 	{
    198 		// Load compressed texture from file.
    199 
    200 		DE_ASSERT(m_width == 0 && m_height == 0 && m_format == GL_NONE && m_dataType == GL_NONE);
    201 
    202 		m_texture	= glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
    203 		m_width		= m_texture->getRefTexture().getWidth();
    204 		m_height	= m_texture->getRefTexture().getHeight();
    205 	}
    206 	else if (m_compressedFormat != CompressedTexture::FORMAT_LAST)
    207 	{
    208 		// Generate compressed texture.
    209 
    210 		DE_ASSERT(m_format == GL_NONE && m_dataType == GL_NONE);
    211 
    212 		if (tcu::isEtcFormat(m_compressedFormat))
    213 		{
    214 			// Create ETC texture. Any content is valid.
    215 
    216 			tcu::CompressedTexture	compressedTexture	(m_compressedFormat, m_width, m_height);
    217 			const int				dataSize			= compressedTexture.getDataSize();
    218 			deUint8* const			data				= (deUint8*)compressedTexture.getData();
    219 			de::Random				rnd					(deStringHash(getName()));
    220 
    221 			for (int i = 0; i < dataSize; i++)
    222 				data[i] = rnd.getUint32() & 0xff;
    223 
    224 			m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
    225 		}
    226 		else if (tcu::isASTCFormat(m_compressedFormat))
    227 		{
    228 			// Create ASTC texture by picking from a set of pre-generated blocks.
    229 
    230 			static const int		BLOCK_SIZE				= 16;
    231 			static const deUint8	blocks[][BLOCK_SIZE]	=
    232 			{
    233 				// \note All of the following blocks are valid in LDR mode.
    234 				{ 252,	253,	255,	255,	255,	255,	255,	255,	8,		71,		90,		78,		22,		17,		26,		66,		},
    235 				{ 252,	253,	255,	255,	255,	255,	255,	255,	220,	74,		139,	235,	249,	6,		145,	125		},
    236 				{ 252,	253,	255,	255,	255,	255,	255,	255,	223,	251,	28,		206,	54,		251,	160,	174		},
    237 				{ 252,	253,	255,	255,	255,	255,	255,	255,	39,		4,		153,	219,	180,	61,		51,		37		},
    238 				{ 67,	2,		0,		254,	1,		0,		64,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    239 				{ 67,	130,	0,		170,	84,		255,	65,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    240 				{ 67,	2,		129,	38,		51,		229,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
    241 				{ 67,	130,	193,	56,		213,	144,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		}
    242 			};
    243 
    244 			if (!isASTCSupported(m_renderCtxInfo)) // \note Any level of ASTC support is enough, since we're only using LDR blocks.
    245 				throw tcu::NotSupportedError("ASTC not supported");
    246 
    247 			tcu::CompressedTexture	compressedTexture	(m_compressedFormat, m_width, m_height);
    248 			const int				dataSize			= compressedTexture.getDataSize();
    249 			deUint8* const			data				= (deUint8*)compressedTexture.getData();
    250 			de::Random				rnd					(deStringHash(getName()));
    251 			DE_ASSERT(dataSize % BLOCK_SIZE == 0);
    252 
    253 			for (int i = 0; i < dataSize/BLOCK_SIZE; i++)
    254 				deMemcpy(&data[i*BLOCK_SIZE], &blocks[rnd.getInt(0, DE_LENGTH_OF_ARRAY(blocks)-1)][0], BLOCK_SIZE);
    255 
    256 			m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
    257 		}
    258 		else
    259 			DE_ASSERT(false);
    260 	}
    261 	else
    262 	{
    263 		m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
    264 
    265 		// Fill level 0.
    266 		m_texture->getRefTexture().allocLevel(0);
    267 		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));
    268 
    269 		m_texture->upload();
    270 	}
    271 
    272 	// Sub-cases.
    273 
    274 	m_cases.push_back(Case(tcu::Vec2(-1.5f, -3.0f), tcu::Vec2(1.5f, 2.5f)));
    275 	m_cases.push_back(Case(tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f)));
    276 	DE_ASSERT(m_caseNdx == 0);
    277 
    278 	// Initialize to success, set to failure later if needed.
    279 
    280 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    281 }
    282 
    283 void TextureWrapCase::deinit (void)
    284 {
    285 	delete m_texture;
    286 	m_texture = DE_NULL;
    287 
    288 	m_renderer.clear();
    289 }
    290 
    291 TextureWrapCase::IterateResult TextureWrapCase::iterate (void)
    292 {
    293 	const glw::Functions&			gl								= m_renderCtx.getFunctions();
    294 	TestLog&						log								= m_testCtx.getLog();
    295 	const RandomViewport			viewport						(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()) + m_caseNdx);
    296 	tcu::Surface					renderedFrame					(viewport.width, viewport.height);
    297 	tcu::Surface					referenceFrame					(viewport.width, viewport.height);
    298 	ReferenceParams					refParams						(TEXTURETYPE_2D);
    299 	const tcu::TextureFormat		texFormat						= m_texture->getRefTexture().getFormat();
    300 	vector<float>					texCoord;
    301 	const tcu::TextureFormatInfo	texFormatInfo					= tcu::getTextureFormatInfo(texFormat);
    302 	// \note For non-sRGB ASTC formats, the values are fp16 in range [0..1], not the range assumed given by tcu::getTextureFormatInfo().
    303 	const bool						useDefaultColorScaleAndBias		= !tcu::isASTCFormat(m_compressedFormat) || tcu::isASTCSRGBFormat(m_compressedFormat);
    304 
    305 	// Bind to unit 0.
    306 	gl.activeTexture(GL_TEXTURE0);
    307 	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
    308 
    309 	// Setup filtering and wrap modes.
    310 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
    311 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
    312 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
    313 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
    314 
    315 	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
    316 
    317 	// Parameters for reference images.
    318 	refParams.sampler		= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
    319 	refParams.lodMode		= LODMODE_EXACT;
    320 	refParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
    321 	refParams.colorScale	= useDefaultColorScaleAndBias ? texFormatInfo.lookupScale	: tcu::Vec4(1.0f);
    322 	refParams.colorBias		= useDefaultColorScaleAndBias ? texFormatInfo.lookupBias	: tcu::Vec4(0.0f);
    323 
    324 	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
    325 	computeQuadTexCoord2D(texCoord, m_cases[m_caseNdx].bottomLeft, m_cases[m_caseNdx].topRight);
    326 	m_renderer.renderQuad(0, &texCoord[0], refParams);
    327 	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
    328 
    329 	{
    330 		const tcu::ScopedLogSection		section			(log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
    331 		const bool						isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
    332 		const bool						isSRGB			= texFormat.order == tcu::TextureFormat::sRGB || texFormat.order == tcu::TextureFormat::sRGBA;
    333 		const tcu::PixelFormat			pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
    334 		const tcu::IVec4				colorBits		= tcu::max(getBitsVec(pixelFormat) - (isNearestOnly && !isSRGB ? 1 : 2), tcu::IVec4(0));
    335 		tcu::LodPrecision				lodPrecision;
    336 		tcu::LookupPrecision			lookupPrecision;
    337 
    338 		lodPrecision.derivateBits		= 18;
    339 		lodPrecision.lodBits			= 5;
    340 		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
    341 		lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
    342 		lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
    343 		lookupPrecision.colorMask		= getCompareMask(pixelFormat);
    344 
    345 		log << TestLog::Message << "Note: lookup coordinates: bottom-left " << m_cases[m_caseNdx].bottomLeft << ", top-right " << m_cases[m_caseNdx].topRight << TestLog::EndMessage;
    346 
    347 		const bool isOk = verifyTextureResult(m_testCtx, renderedFrame.getAccess(), m_texture->getRefTexture(),
    348 											  &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);
    349 
    350 		if (!isOk)
    351 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
    352 	}
    353 
    354 	m_caseNdx++;
    355 	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
    356 }
    357 
    358 TextureWrapTests::TextureWrapTests (Context& context)
    359 	: TestCaseGroup(context, "wrap", "Wrap Mode Tests")
    360 {
    361 }
    362 
    363 TextureWrapTests::~TextureWrapTests (void)
    364 {
    365 }
    366 
    367 void TextureWrapTests::init (void)
    368 {
    369 	static const struct
    370 	{
    371 		const char*		name;
    372 		deUint32		mode;
    373 	} wrapModes[] =
    374 	{
    375 		{ "clamp",		GL_CLAMP_TO_EDGE },
    376 		{ "repeat",		GL_REPEAT },
    377 		{ "mirror",		GL_MIRRORED_REPEAT }
    378 	};
    379 
    380 	static const struct
    381 	{
    382 		const char*		name;
    383 		deUint32		mode;
    384 	} filteringModes[] =
    385 	{
    386 		{ "nearest",	GL_NEAREST },
    387 		{ "linear",		GL_LINEAR }
    388 	};
    389 
    390 #define FOR_EACH(ITERATOR, ARRAY, BODY)	\
    391 	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
    392 		BODY
    393 
    394 	// RGBA8 cases.
    395 	{
    396 		static const struct
    397 		{
    398 			const char*		name;
    399 			int				width;
    400 			int				height;
    401 		} rgba8Sizes[] =
    402 		{
    403 			{ "pot",		64, 128 },
    404 			{ "npot",		63, 112 }
    405 		};
    406 
    407 		{
    408 			TestCaseGroup* const rgba8Group = new TestCaseGroup(m_context, "rgba8", "");
    409 			addChild(rgba8Group);
    410 
    411 			FOR_EACH(size,		rgba8Sizes,
    412 			FOR_EACH(wrapS,		wrapModes,
    413 			FOR_EACH(wrapT,		wrapModes,
    414 			FOR_EACH(filter,	filteringModes,
    415 				{
    416 					const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + rgba8Sizes[size].name;
    417 					rgba8Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
    418 															 GL_RGBA, GL_UNSIGNED_BYTE,
    419 															 wrapModes[wrapS].mode,
    420 															 wrapModes[wrapT].mode,
    421 															 filteringModes[filter].mode, filteringModes[filter].mode,
    422 															 rgba8Sizes[size].width, rgba8Sizes[size].height));
    423 
    424 				}))));
    425 		}
    426 	}
    427 
    428 	// ETC1 cases.
    429 	{
    430 		TestCaseGroup* const etc1Group = new TestCaseGroup(m_context, "etc1", "");
    431 		addChild(etc1Group);
    432 
    433 		// Power-of-two ETC1 texture
    434 		std::vector<std::string> potFilenames;
    435 		potFilenames.push_back("data/etc1/photo_helsinki_mip_0.pkm");
    436 
    437 		FOR_EACH(wrapS,		wrapModes,
    438 		FOR_EACH(wrapT,		wrapModes,
    439 		FOR_EACH(filter,	filteringModes,
    440 			{
    441 				const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_pot";
    442 				etc1Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
    443 														wrapModes[wrapS].mode,
    444 														wrapModes[wrapT].mode,
    445 														filteringModes[filter].mode, filteringModes[filter].mode,
    446 														potFilenames));
    447 
    448 			})));
    449 
    450 		std::vector<std::string> npotFilenames;
    451 		npotFilenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
    452 
    453 		// NPOT ETC1 texture
    454 		FOR_EACH(wrapS,		wrapModes,
    455 		FOR_EACH(wrapT,		wrapModes,
    456 		FOR_EACH(filter,	filteringModes,
    457 			{
    458 				const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_npot";
    459 				etc1Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
    460 														wrapModes[wrapS].mode,
    461 														wrapModes[wrapT].mode,
    462 														filteringModes[filter].mode, filteringModes[filter].mode,
    463 														npotFilenames));
    464 			})));
    465 	}
    466 
    467 	// ETC-2 (and EAC) cases.
    468 	{
    469 		static const struct
    470 		{
    471 			const char*					name;
    472 			CompressedTexture::Format	format;
    473 		} etc2Formats[] =
    474 		{
    475 			{ "eac_r11",							CompressedTexture::EAC_R11,							},
    476 			{ "eac_signed_r11",						CompressedTexture::EAC_SIGNED_R11,					},
    477 			{ "eac_rg11",							CompressedTexture::EAC_RG11,						},
    478 			{ "eac_signed_rg11",					CompressedTexture::EAC_SIGNED_RG11,					},
    479 			{ "etc2_rgb8",							CompressedTexture::ETC2_RGB8,						},
    480 			{ "etc2_srgb8",							CompressedTexture::ETC2_SRGB8,						},
    481 			{ "etc2_rgb8_punchthrough_alpha1",		CompressedTexture::ETC2_RGB8_PUNCHTHROUGH_ALPHA1,	},
    482 			{ "etc2_srgb8_punchthrough_alpha1",		CompressedTexture::ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,	},
    483 			{ "etc2_eac_rgba8",						CompressedTexture::ETC2_EAC_RGBA8,					},
    484 			{ "etc2_eac_srgb8_alpha8",				CompressedTexture::ETC2_EAC_SRGB8_ALPHA8,			}
    485 		};
    486 
    487 		static const struct
    488 		{
    489 			const char*		name;
    490 			int				width;
    491 			int				height;
    492 		} etc2Sizes[] =
    493 		{
    494 			{ "pot",	64,		128	},
    495 			{ "npot",	123,	107	}
    496 		};
    497 
    498 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(etc2Formats); formatNdx++)
    499 		{
    500 			TestCaseGroup* const formatGroup = new TestCaseGroup(m_context, etc2Formats[formatNdx].name, "");
    501 			addChild(formatGroup);
    502 
    503 			FOR_EACH(size,		etc2Sizes,
    504 			FOR_EACH(wrapS,		wrapModes,
    505 			FOR_EACH(wrapT,		wrapModes,
    506 			FOR_EACH(filter,	filteringModes,
    507 				{
    508 					const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + etc2Sizes[size].name;
    509 					formatGroup->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
    510 															  etc2Formats[formatNdx].format,
    511 															  wrapModes[wrapS].mode,
    512 															  wrapModes[wrapT].mode,
    513 															  filteringModes[filter].mode, filteringModes[filter].mode,
    514 															  etc2Sizes[size].width, etc2Sizes[size].height));
    515 				}))));
    516 		}
    517 	}
    518 
    519 	// ASTC cases.
    520 	{
    521 		for (int formatI = 0; formatI < CompressedTexture::FORMAT_LAST; formatI++)
    522 		{
    523 			const CompressedTexture::Format format = (CompressedTexture::Format)formatI;
    524 			if (!tcu::isASTCFormat(format))
    525 				continue;
    526 
    527 			{
    528 				const tcu::IVec3		blockSize		= tcu::getASTCBlockSize(format);
    529 				const string			formatName		= "astc_" + de::toString(blockSize.x()) + "x" + de::toString(blockSize.y()) + (tcu::isASTCSRGBFormat(format) ? "_srgb" : "");
    530 				TestCaseGroup* const	formatGroup		= new TestCaseGroup(m_context, formatName.c_str(), "");
    531 				addChild(formatGroup);
    532 
    533 				DE_ASSERT(blockSize.z() == 1);
    534 
    535 				// \note This array is NOT static.
    536 				const struct
    537 				{
    538 					const char*		name;
    539 					int				width;
    540 					int				height;
    541 				} formatSizes[] =
    542 				{
    543 					{ "divisible",		blockSize.x()*10,		blockSize.y()*10	},
    544 					{ "not_divisible",	blockSize.x()*10+1,		blockSize.y()*10+1	},
    545 				};
    546 
    547 				FOR_EACH(size,		formatSizes,
    548 				FOR_EACH(wrapS,		wrapModes,
    549 				FOR_EACH(wrapT,		wrapModes,
    550 				FOR_EACH(filter,	filteringModes,
    551 					{
    552 						string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + formatSizes[size].name;
    553 						formatGroup->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
    554 																  format,
    555 																  wrapModes[wrapS].mode,
    556 																  wrapModes[wrapT].mode,
    557 																  filteringModes[filter].mode, filteringModes[filter].mode,
    558 																  formatSizes[size].width, formatSizes[size].height));
    559 					}))));
    560 			}
    561 		}
    562 	}
    563 }
    564 
    565 } // Functional
    566 } // gles3
    567 } // deqp
    568