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