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