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 format tests.
22 *
23 * Constants:
24 *  + nearest-neighbor filtering
25 *  + no mipmaps
26 *  + full texture coordinate range (but not outside) tested
27 *  + accessed from fragment shader
28 *  + texture unit 0
29 *  + named texture object
30 *
31 * Variables:
32 *  + texture format
33 *  + texture type: 2D or cubemap
34 *//*--------------------------------------------------------------------*/
35
36#include "es3fTextureFormatTests.hpp"
37#include "gluPixelTransfer.hpp"
38#include "gluStrUtil.hpp"
39#include "gluTexture.hpp"
40#include "gluTextureUtil.hpp"
41#include "glsTextureTestUtil.hpp"
42#include "tcuTextureUtil.hpp"
43#include "deStringUtil.hpp"
44#include "deRandom.hpp"
45#include "glwEnums.hpp"
46#include "glwFunctions.hpp"
47
48using std::vector;
49using std::string;
50using tcu::TestLog;
51
52namespace deqp
53{
54namespace gles3
55{
56namespace Functional
57{
58
59using namespace deqp::gls;
60using namespace deqp::gls::TextureTestUtil;
61using tcu::Sampler;
62
63// Texture2DFormatCase
64
65class Texture2DFormatCase : public tcu::TestCase
66{
67public:
68							Texture2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height);
69							Texture2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height);
70							~Texture2DFormatCase	(void);
71
72	void					init					(void);
73	void					deinit					(void);
74	IterateResult			iterate					(void);
75
76private:
77							Texture2DFormatCase		(const Texture2DFormatCase& other);
78	Texture2DFormatCase&	operator=				(const Texture2DFormatCase& other);
79
80	glu::RenderContext&		m_renderCtx;
81
82	deUint32				m_format;
83	deUint32				m_dataType;
84	int						m_width;
85	int						m_height;
86
87	glu::Texture2D*			m_texture;
88	TextureRenderer			m_renderer;
89};
90
91Texture2DFormatCase::Texture2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
92	: TestCase		(testCtx, name, description)
93	, m_renderCtx	(renderCtx)
94	, m_format		(format)
95	, m_dataType	(dataType)
96	, m_width		(width)
97	, m_height		(height)
98	, m_texture		(DE_NULL)
99	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
100{
101}
102
103Texture2DFormatCase::Texture2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height)
104	: TestCase		(testCtx, name, description)
105	, m_renderCtx	(renderCtx)
106	, m_format		(internalFormat)
107	, m_dataType	(GL_NONE)
108	, m_width		(width)
109	, m_height		(height)
110	, m_texture		(DE_NULL)
111	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
112{
113}
114
115Texture2DFormatCase::~Texture2DFormatCase (void)
116{
117	deinit();
118}
119
120void Texture2DFormatCase::init (void)
121{
122	TestLog&				log		= m_testCtx.getLog();
123	tcu::TextureFormat		fmt		= m_dataType ? glu::mapGLTransferFormat(m_format, m_dataType) : glu::mapGLInternalFormat(m_format);
124	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
125	std::ostringstream		fmtName;
126
127	if (m_dataType)
128		fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
129	else
130		fmtName << glu::getPixelFormatStr(m_format);
131
132	log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
133							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
134		<< TestLog::EndMessage;
135
136	m_texture = m_dataType != GL_NONE
137			  ? new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height)	// Implicit internal format.
138			  : new glu::Texture2D(m_renderCtx, m_format, m_width, m_height);				// Explicit internal format.
139
140	// Fill level 0.
141	m_texture->getRefTexture().allocLevel(0);
142	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
143}
144
145void Texture2DFormatCase::deinit (void)
146{
147	delete m_texture;
148	m_texture = DE_NULL;
149
150	m_renderer.clear();
151}
152
153Texture2DFormatCase::IterateResult Texture2DFormatCase::iterate (void)
154{
155	TestLog&				log					= m_testCtx.getLog();
156	const glw::Functions&	gl					= m_renderCtx.getFunctions();
157	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
158	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
159	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
160	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
161	vector<float>			texCoord;
162	ReferenceParams			renderParams		(TEXTURETYPE_2D);
163	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
164	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
165	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
166	const deUint32			minFilter			= GL_NEAREST;
167	const deUint32			magFilter			= GL_NEAREST;
168
169	renderParams.flags			|= RenderParams::LOG_ALL;
170	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
171	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
172	renderParams.colorScale		= spec.lookupScale;
173	renderParams.colorBias		= spec.lookupBias;
174
175	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
176
177	log << TestLog::Message << "Texture parameters:"
178							<< "\n  WRAP_S = " << glu::getTextureParameterValueStr(GL_TEXTURE_WRAP_S, wrapS)
179							<< "\n  WRAP_T = " << glu::getTextureParameterValueStr(GL_TEXTURE_WRAP_T, wrapT)
180							<< "\n  MIN_FILTER = " << glu::getTextureParameterValueStr(GL_TEXTURE_MIN_FILTER, minFilter)
181							<< "\n  MAG_FILTER = " << glu::getTextureParameterValueStr(GL_TEXTURE_MAG_FILTER, magFilter)
182		<< TestLog::EndMessage;
183
184	// Setup base viewport.
185	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
186
187	// Upload texture data to GL.
188	m_texture->upload();
189
190	// Bind to unit 0.
191	gl.activeTexture(GL_TEXTURE0);
192	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
193
194	// Setup nearest neighbor filtering and clamp-to-edge.
195	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
196	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
197	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
198	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
199
200	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
201
202	// Draw.
203	m_renderer.renderQuad(0, &texCoord[0], renderParams);
204	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
205	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
206
207	// Compute reference.
208	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
209
210	// Compare and log.
211	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
212
213	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
214							isOk ? "Pass"				: "Image comparison failed");
215
216	return STOP;
217}
218
219// TextureCubeFormatCase
220
221class TextureCubeFormatCase : public tcu::TestCase
222{
223public:
224							TextureCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height);
225							TextureCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height);
226							~TextureCubeFormatCase	(void);
227
228	void					init					(void);
229	void					deinit					(void);
230	IterateResult			iterate					(void);
231
232private:
233							TextureCubeFormatCase	(const TextureCubeFormatCase& other);
234	TextureCubeFormatCase&	operator=				(const TextureCubeFormatCase& other);
235
236	bool					testFace				(tcu::CubeFace face);
237
238	glu::RenderContext&		m_renderCtx;
239
240	deUint32				m_format;
241	deUint32				m_dataType;
242	int						m_width;
243	int						m_height;
244
245	glu::TextureCube*		m_texture;
246	TextureRenderer			m_renderer;
247
248	int						m_curFace;
249	bool					m_isOk;
250};
251
252TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
253	: TestCase		(testCtx, name, description)
254	, m_renderCtx	(renderCtx)
255	, m_format		(format)
256	, m_dataType	(dataType)
257	, m_width		(width)
258	, m_height		(height)
259	, m_texture		(DE_NULL)
260	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
261	, m_curFace		(0)
262	, m_isOk		(false)
263{
264}
265
266TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height)
267	: TestCase		(testCtx, name, description)
268	, m_renderCtx	(renderCtx)
269	, m_format		(internalFormat)
270	, m_dataType	(GL_NONE)
271	, m_width		(width)
272	, m_height		(height)
273	, m_texture		(DE_NULL)
274	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
275	, m_curFace		(0)
276	, m_isOk		(false)
277{
278}
279
280TextureCubeFormatCase::~TextureCubeFormatCase (void)
281{
282	deinit();
283}
284
285void TextureCubeFormatCase::init (void)
286{
287	TestLog&				log		= m_testCtx.getLog();
288	tcu::TextureFormat		fmt		= m_dataType ? glu::mapGLTransferFormat(m_format, m_dataType) : glu::mapGLInternalFormat(m_format);
289	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
290	std::ostringstream		fmtName;
291
292	if (m_dataType)
293		fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
294	else
295		fmtName << glu::getPixelFormatStr(m_format);
296
297	log << TestLog::Message << "Cube map texture, " << fmtName.str() << ", " << m_width << "x" << m_height
298							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
299		<< TestLog::EndMessage;
300
301	DE_ASSERT(m_width == m_height);
302	m_texture = m_dataType != GL_NONE
303			  ? new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_width)	// Implicit internal format.
304		      : new glu::TextureCube(m_renderCtx, m_format, m_width);				// Explicit internal format.
305
306	// Fill level 0.
307	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
308	{
309		tcu::Vec4 gMin, gMax;
310
311		switch (face)
312		{
313			case 0: gMin = spec.valueMin.swizzle(0, 1, 2, 3); gMax = spec.valueMax.swizzle(0, 1, 2, 3); break;
314			case 1: gMin = spec.valueMin.swizzle(2, 1, 0, 3); gMax = spec.valueMax.swizzle(2, 1, 0, 3); break;
315			case 2: gMin = spec.valueMin.swizzle(1, 2, 0, 3); gMax = spec.valueMax.swizzle(1, 2, 0, 3); break;
316			case 3: gMin = spec.valueMax.swizzle(0, 1, 2, 3); gMax = spec.valueMin.swizzle(0, 1, 2, 3); break;
317			case 4: gMin = spec.valueMax.swizzle(2, 1, 0, 3); gMax = spec.valueMin.swizzle(2, 1, 0, 3); break;
318			case 5: gMin = spec.valueMax.swizzle(1, 2, 0, 3); gMax = spec.valueMin.swizzle(1, 2, 0, 3); break;
319			default:
320				DE_ASSERT(false);
321		}
322
323		m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
324		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), gMin, gMax);
325	}
326
327	// Upload texture data to GL.
328	m_texture->upload();
329
330	// Initialize iteration state.
331	m_curFace	= 0;
332	m_isOk		= true;
333}
334
335void TextureCubeFormatCase::deinit (void)
336{
337	delete m_texture;
338	m_texture = DE_NULL;
339
340	m_renderer.clear();
341}
342
343bool TextureCubeFormatCase::testFace (tcu::CubeFace face)
344{
345	TestLog&				log					= m_testCtx.getLog();
346	const glw::Functions&	gl					= m_renderCtx.getFunctions();
347	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName())+(deUint32)face);
348	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
349	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
350	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
351	vector<float>			texCoord;
352	ReferenceParams			renderParams		(TEXTURETYPE_CUBE);
353	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
354
355	renderParams.samplerType				= getSamplerType(m_texture->getRefTexture().getFormat());
356	renderParams.sampler					= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
357	renderParams.sampler.seamlessCubeMap	= true;
358	renderParams.colorScale					= spec.lookupScale;
359	renderParams.colorBias					= spec.lookupBias;
360
361	// Log render info on first face.
362	if (face == tcu::CUBEFACE_NEGATIVE_X)
363		renderParams.flags |= RenderParams::LOG_ALL;
364
365	computeQuadTexCoordCube(texCoord, face);
366
367	// \todo [2011-10-28 pyry] Image set name / section?
368	log << TestLog::Message << face << TestLog::EndMessage;
369
370	// Setup base viewport.
371	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
372
373	// Bind to unit 0.
374	gl.activeTexture(GL_TEXTURE0);
375	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
376
377	// Setup nearest neighbor filtering and clamp-to-edge.
378	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
379	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
380	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
381	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
382
383	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
384
385	m_renderer.renderQuad(0, &texCoord[0], renderParams);
386	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
387	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
388
389	// Compute reference.
390	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
391
392	// Compare and log.
393	return compareImages(log, referenceFrame, renderedFrame, threshold);
394}
395
396TextureCubeFormatCase::IterateResult TextureCubeFormatCase::iterate (void)
397{
398	// Execute test for all faces.
399	if (!testFace((tcu::CubeFace)m_curFace))
400		m_isOk = false;
401
402	m_curFace += 1;
403
404	if (m_curFace == tcu::CUBEFACE_LAST)
405	{
406		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
407								m_isOk ? "Pass"					: "Image comparison failed");
408		return STOP;
409	}
410	else
411		return CONTINUE;
412}
413
414// Texture2DArrayFormatCase
415
416class Texture2DArrayFormatCase : public tcu::TestCase
417{
418public:
419										Texture2DArrayFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int numLayers);
420										Texture2DArrayFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height, int numLayers);
421										~Texture2DArrayFormatCase	(void);
422
423	void								init						(void);
424	void								deinit						(void);
425	IterateResult						iterate						(void);
426
427private:
428										Texture2DArrayFormatCase	(const Texture2DArrayFormatCase& other);
429	Texture2DArrayFormatCase&			operator=					(const Texture2DArrayFormatCase& other);
430
431	bool								testLayer					(int layerNdx);
432
433	glu::RenderContext&					m_renderCtx;
434
435	deUint32							m_format;
436	deUint32							m_dataType;
437	int									m_width;
438	int									m_height;
439	int									m_numLayers;
440
441	glu::Texture2DArray*				m_texture;
442	TextureTestUtil::TextureRenderer	m_renderer;
443
444	int									m_curLayer;
445};
446
447Texture2DArrayFormatCase::Texture2DArrayFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int numLayers)
448	: TestCase		(testCtx, name, description)
449	, m_renderCtx	(renderCtx)
450	, m_format		(format)
451	, m_dataType	(dataType)
452	, m_width		(width)
453	, m_height		(height)
454	, m_numLayers	(numLayers)
455	, m_texture		(DE_NULL)
456	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
457	, m_curLayer	(0)
458{
459}
460
461Texture2DArrayFormatCase::Texture2DArrayFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height, int numLayers)
462	: TestCase		(testCtx, name, description)
463	, m_renderCtx	(renderCtx)
464	, m_format		(internalFormat)
465	, m_dataType	(GL_NONE)
466	, m_width		(width)
467	, m_height		(height)
468	, m_numLayers	(numLayers)
469	, m_texture		(DE_NULL)
470	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
471	, m_curLayer	(0)
472{
473}
474
475Texture2DArrayFormatCase::~Texture2DArrayFormatCase (void)
476{
477	deinit();
478}
479
480void Texture2DArrayFormatCase::init (void)
481{
482	m_texture = m_dataType != GL_NONE
483			  ? new glu::Texture2DArray(m_renderCtx, m_format, m_dataType, m_width, m_height, m_numLayers)	// Implicit internal format.
484			  : new glu::Texture2DArray(m_renderCtx, m_format, m_width, m_height, m_numLayers);				// Explicit internal format.
485
486	tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
487
488	// Fill level 0.
489	m_texture->getRefTexture().allocLevel(0);
490	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
491
492	// Initialize state.
493	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
494	m_curLayer = 0;
495}
496
497void Texture2DArrayFormatCase::deinit (void)
498{
499	delete m_texture;
500	m_texture = DE_NULL;
501
502	m_renderer.clear();
503}
504
505bool Texture2DArrayFormatCase::testLayer (int layerNdx)
506{
507	const glw::Functions&	gl					= m_renderCtx.getFunctions();
508	TestLog&				log					= m_testCtx.getLog();
509	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
510	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
511	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
512	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
513	vector<float>			texCoord;
514	ReferenceParams			renderParams		(TEXTURETYPE_2D_ARRAY);
515	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
516
517	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
518	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
519	renderParams.colorScale		= spec.lookupScale;
520	renderParams.colorBias		= spec.lookupBias;
521
522	computeQuadTexCoord2DArray(texCoord, layerNdx, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
523
524	// Setup base viewport.
525	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
526
527	// Upload texture data to GL.
528	m_texture->upload();
529
530	// Bind to unit 0.
531	gl.activeTexture(GL_TEXTURE0);
532	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture->getGLTexture());
533
534	// Setup nearest neighbor filtering and clamp-to-edge.
535	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
536	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
537	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
538	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
539
540	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
541
542	// Draw.
543	m_renderer.renderQuad(0, &texCoord[0], renderParams);
544	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
545
546	// Compute reference.
547	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
548
549	// Compare and log.
550	return compareImages(log, (string("Layer" + de::toString(layerNdx))).c_str(), (string("Layer " + de::toString(layerNdx))).c_str(), referenceFrame, renderedFrame, threshold);
551}
552
553Texture2DArrayFormatCase::IterateResult Texture2DArrayFormatCase::iterate (void)
554{
555	// Execute test for all layers.
556	bool isOk = testLayer(m_curLayer);
557
558	if (!isOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
559		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
560
561	m_curLayer += 1;
562
563	return m_curLayer < m_texture->getRefTexture().getNumLayers() ? CONTINUE : STOP;
564}
565
566// Texture2DFormatCase
567
568class Texture3DFormatCase : public tcu::TestCase
569{
570public:
571										Texture3DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int depth);
572										Texture3DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height, int depth);
573										~Texture3DFormatCase	(void);
574
575	void								init					(void);
576	void								deinit					(void);
577	IterateResult						iterate					(void);
578
579private:
580										Texture3DFormatCase		(const Texture3DFormatCase& other);
581	Texture3DFormatCase&				operator=				(const Texture3DFormatCase& other);
582
583	bool								testSlice				(int sliceNdx);
584
585	glu::RenderContext&					m_renderCtx;
586
587	deUint32							m_format;
588	deUint32							m_dataType;
589	int									m_width;
590	int									m_height;
591	int									m_depth;
592
593	glu::Texture3D*						m_texture;
594	TextureTestUtil::TextureRenderer	m_renderer;
595
596	int									m_curSlice;
597};
598
599Texture3DFormatCase::Texture3DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int depth)
600	: TestCase		(testCtx, name, description)
601	, m_renderCtx	(renderCtx)
602	, m_format		(format)
603	, m_dataType	(dataType)
604	, m_width		(width)
605	, m_height		(height)
606	, m_depth		(depth)
607	, m_texture		(DE_NULL)
608	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
609	, m_curSlice	(0)
610{
611}
612
613Texture3DFormatCase::Texture3DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 internalFormat, int width, int height, int depth)
614	: TestCase		(testCtx, name, description)
615	, m_renderCtx	(renderCtx)
616	, m_format		(internalFormat)
617	, m_dataType	(GL_NONE)
618	, m_width		(width)
619	, m_height		(height)
620	, m_depth		(depth)
621	, m_texture		(DE_NULL)
622	, m_renderer	(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
623	, m_curSlice	(0)
624{
625}
626
627Texture3DFormatCase::~Texture3DFormatCase (void)
628{
629	deinit();
630}
631
632void Texture3DFormatCase::init (void)
633{
634	m_texture = m_dataType != GL_NONE
635			  ? new glu::Texture3D(m_renderCtx, m_format, m_dataType, m_width, m_height, m_depth)	// Implicit internal format.
636			  : new glu::Texture3D(m_renderCtx, m_format, m_width, m_height, m_depth);				// Explicit internal format.
637
638	tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
639
640	// Fill level 0.
641	m_texture->getRefTexture().allocLevel(0);
642	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
643
644	// Initialize state.
645	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
646	m_curSlice = 0;
647}
648
649void Texture3DFormatCase::deinit (void)
650{
651	delete m_texture;
652	m_texture = DE_NULL;
653
654	m_renderer.clear();
655}
656
657bool Texture3DFormatCase::testSlice (int sliceNdx)
658{
659	TestLog&				log					= m_testCtx.getLog();
660	const glw::Functions&	gl					= m_renderCtx.getFunctions();
661	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
662	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
663	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
664	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
665	vector<float>			texCoord;
666	ReferenceParams			renderParams		(TEXTURETYPE_3D);
667	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
668	float					r					= ((float)sliceNdx + 0.5f) / (float)m_depth;
669
670	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
671	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
672	renderParams.colorScale		= spec.lookupScale;
673	renderParams.colorBias		= spec.lookupBias;
674
675	computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0,1,2));
676
677	// Setup base viewport.
678	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
679
680	// Upload texture data to GL.
681	m_texture->upload();
682
683	// Bind to unit 0.
684	gl.activeTexture(GL_TEXTURE0);
685	gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());
686
687	// Setup nearest neighbor filtering and clamp-to-edge.
688	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
689	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
690	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
691	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
692
693	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
694
695	// Draw.
696	m_renderer.renderQuad(0, &texCoord[0], renderParams);
697	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
698
699	// Compute reference.
700	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
701
702	// Compare and log.
703	return compareImages(log, (string("Slice" + de::toString(sliceNdx))).c_str(), (string("Slice " + de::toString(sliceNdx))).c_str(), referenceFrame, renderedFrame, threshold);
704}
705
706Texture3DFormatCase::IterateResult Texture3DFormatCase::iterate (void)
707{
708	// Execute test for all slices.
709	bool isOk = testSlice(m_curSlice);
710
711	if (!isOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
712		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
713
714	m_curSlice += 1;
715
716	return m_curSlice < m_texture->getRefTexture().getDepth() ? CONTINUE : STOP;
717}
718
719// Compressed2FormatCase
720
721class Compressed2DFormatCase : public tcu::TestCase
722{
723public:
724										Compressed2DFormatCase		(tcu::TestContext&					testCtx,
725																	 glu::RenderContext&				renderCtx,
726																	 const glu::ContextInfo&			renderCtxInfo,
727																	 const char*						name,
728																	 const char*						description,
729																	 tcu::CompressedTexture::Format		format,
730																	 deUint32							randomSeed,
731																	 int								width,
732																	 int								height);
733										~Compressed2DFormatCase		(void);
734
735	void								init						(void);
736	void								deinit						(void);
737	IterateResult						iterate						(void);
738
739private:
740										Compressed2DFormatCase		(const Compressed2DFormatCase& other);
741	Compressed2DFormatCase&				operator=					(const Compressed2DFormatCase& other);
742
743	glu::RenderContext&					m_renderCtx;
744	const glu::ContextInfo&				m_renderCtxInfo;
745
746	tcu::CompressedTexture::Format		m_format;
747
748	deUint32							m_randomSeed;
749	int									m_width;
750	int									m_height;
751
752	glu::Texture2D*						m_texture;
753	TextureTestUtil::TextureRenderer	m_renderer;
754};
755
756Compressed2DFormatCase::Compressed2DFormatCase (tcu::TestContext&				testCtx,
757												glu::RenderContext&				renderCtx,
758												const glu::ContextInfo&			renderCtxInfo,
759												const char*						name,
760												const char*						description,
761												tcu::CompressedTexture::Format	format,
762												deUint32						randomSeed,
763												int								width,
764												int								height)
765	: TestCase			(testCtx, name, description)
766	, m_renderCtx		(renderCtx)
767	, m_renderCtxInfo	(renderCtxInfo)
768	, m_format			(format)
769	, m_randomSeed		(randomSeed)
770	, m_width			(width)
771	, m_height			(height)
772	, m_texture			(DE_NULL)
773	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
774{
775}
776
777Compressed2DFormatCase::~Compressed2DFormatCase (void)
778{
779	deinit();
780}
781
782void Compressed2DFormatCase::init (void)
783{
784	// Create texture.
785	tcu::CompressedTexture	compressedTexture	(m_format, m_width, m_height);
786	int						dataSize			= compressedTexture.getDataSize();
787	deUint8*				data				= (deUint8*)compressedTexture.getData();
788	de::Random				rnd					(m_randomSeed);
789
790	for (int i = 0; i < dataSize; i++)
791		data[i] = rnd.getUint32() & 0xff;
792
793	m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
794}
795
796void Compressed2DFormatCase::deinit (void)
797{
798	delete m_texture;
799	m_texture = DE_NULL;
800
801	m_renderer.clear();
802}
803
804Compressed2DFormatCase::IterateResult Compressed2DFormatCase::iterate (void)
805{
806	const glw::Functions&	gl					= m_renderCtx.getFunctions();
807	TestLog&				log					= m_testCtx.getLog();
808	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
809	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
810	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
811	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
812	vector<float>			texCoord;
813	ReferenceParams			renderParams		(TEXTURETYPE_2D);
814	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
815
816	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
817	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
818	renderParams.colorScale		= spec.lookupScale;
819	renderParams.colorBias		= spec.lookupBias;
820
821	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
822
823	// Setup base viewport.
824	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
825
826	// Bind to unit 0.
827	gl.activeTexture(GL_TEXTURE0);
828	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
829
830	// Setup nearest neighbor filtering and clamp-to-edge.
831	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
832	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
833	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
834	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
835
836	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
837
838	// Draw.
839	m_renderer.renderQuad(0, &texCoord[0], renderParams);
840	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
841
842	// Compute reference.
843	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
844
845	// Compare and log.
846	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
847
848	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
849							isOk ? "Pass"				: "Image comparison failed");
850
851	return STOP;
852}
853
854// CompressedCubeFormatCase
855
856class CompressedCubeFormatCase : public tcu::TestCase
857{
858public:
859										CompressedCubeFormatCase	(tcu::TestContext& testCtx,
860																	 glu::RenderContext& renderCtx,
861																	 const glu::ContextInfo& renderCtxInfo,
862																	 const char* name,
863																	 const char* description,
864																	 tcu::CompressedTexture::Format format,
865																	 deUint32 randomSeed,
866																	 int width,
867																	 int height);
868										~CompressedCubeFormatCase	(void);
869
870	void								init						(void);
871	void								deinit						(void);
872	IterateResult						iterate						(void);
873
874private:
875										CompressedCubeFormatCase	(const CompressedCubeFormatCase& other);
876	CompressedCubeFormatCase&			operator=					(const CompressedCubeFormatCase& other);
877
878	bool								testFace					(tcu::CubeFace face);
879
880	glu::RenderContext&					m_renderCtx;
881	const glu::ContextInfo&				m_renderCtxInfo;
882
883	tcu::CompressedTexture::Format		m_format;
884
885	deUint32							m_randomSeed;
886	int									m_width;
887	int									m_height;
888
889	glu::TextureCube*					m_texture;
890	TextureTestUtil::TextureRenderer	m_renderer;
891
892	int									m_curFace;
893	bool								m_isOk;
894};
895
896CompressedCubeFormatCase::CompressedCubeFormatCase (tcu::TestContext& testCtx,
897													glu::RenderContext& renderCtx,
898													const glu::ContextInfo& renderCtxInfo,
899													const char* name,
900													const char* description,
901													tcu::CompressedTexture::Format format,
902													deUint32 randomSeed,
903													int width,
904													int height)
905	: TestCase			(testCtx, name, description)
906	, m_renderCtx		(renderCtx)
907	, m_renderCtxInfo	(renderCtxInfo)
908	, m_format			(format)
909	, m_randomSeed		(randomSeed)
910	, m_width			(width)
911	, m_height			(height)
912	, m_texture			(DE_NULL)
913	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
914	, m_curFace			(0)
915	, m_isOk			(false)
916{
917}
918
919CompressedCubeFormatCase::~CompressedCubeFormatCase (void)
920{
921	deinit();
922}
923
924void CompressedCubeFormatCase::init (void)
925{
926	vector<tcu::CompressedTexture>	levels	(tcu::CUBEFACE_LAST);
927	de::Random						rnd		(m_randomSeed);
928
929	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
930	{
931		levels[face].setStorage(m_format, m_width, m_height);
932
933		int			dataSize	= levels[face].getDataSize();
934		deUint8*	data		= (deUint8*)levels[face].getData();
935
936		for (int i = 0; i < dataSize; i++)
937			data[i] = rnd.getUint32() & 0xff;
938	}
939
940	m_texture = new glu::TextureCube(m_renderCtx, m_renderCtxInfo, 1, &levels[0]);
941
942	m_curFace	= 0;
943	m_isOk		= true;
944}
945
946void CompressedCubeFormatCase::deinit (void)
947{
948	delete m_texture;
949	m_texture = DE_NULL;
950
951	m_renderer.clear();
952}
953
954bool CompressedCubeFormatCase::testFace (tcu::CubeFace face)
955{
956	const glw::Functions&	gl					= m_renderCtx.getFunctions();
957	TestLog&				log					= m_testCtx.getLog();
958	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(), m_texture->getRefTexture().getSize(), deStringHash(getName())+(deUint32)face);
959	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
960	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
961	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
962	vector<float>			texCoord;
963	ReferenceParams			renderParams		(TEXTURETYPE_CUBE);
964	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
965
966	renderParams.samplerType				= getSamplerType(m_texture->getRefTexture().getFormat());
967	renderParams.sampler					= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
968	renderParams.sampler.seamlessCubeMap	= true;
969	renderParams.colorScale					= spec.lookupScale;
970	renderParams.colorBias					= spec.lookupBias;
971
972	computeQuadTexCoordCube(texCoord, face);
973
974	log << TestLog::Message << face << TestLog::EndMessage;
975
976	// Setup base viewport.
977	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
978
979	// Bind to unit 0.
980	gl.activeTexture(GL_TEXTURE0);
981	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
982
983	// Setup nearest neighbor filtering and clamp-to-edge.
984	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
985	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
986	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
987	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
988
989	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
990
991	m_renderer.renderQuad(0, &texCoord[0], renderParams);
992	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
993
994	// Compute reference.
995	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
996
997	// Compare and log.
998	return compareImages(log, referenceFrame, renderedFrame, threshold);
999}
1000
1001CompressedCubeFormatCase::IterateResult CompressedCubeFormatCase::iterate (void)
1002{
1003	// Execute test for all faces.
1004	if (!testFace((tcu::CubeFace)m_curFace))
1005		m_isOk = false;
1006
1007	m_curFace += 1;
1008
1009	if (m_curFace == tcu::CUBEFACE_LAST)
1010	{
1011		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
1012								m_isOk ? "Pass"					: "Image comparison failed");
1013		return STOP;
1014	}
1015	else
1016		return CONTINUE;
1017}
1018
1019// Texture2DFileCase
1020
1021class Texture2DFileCase : public tcu::TestCase
1022{
1023public:
1024								Texture2DFileCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
1025								~Texture2DFileCase		(void);
1026
1027	void						init					(void);
1028	void						deinit					(void);
1029	IterateResult				iterate					(void);
1030
1031private:
1032								Texture2DFileCase		(const Texture2DFileCase& other);
1033	Texture2DFileCase&			operator=				(const Texture2DFileCase& other);
1034
1035	glu::RenderContext&			m_renderCtx;
1036	const glu::ContextInfo&		m_renderCtxInfo;
1037
1038	std::vector<std::string>	m_filenames;
1039
1040	glu::Texture2D*				m_texture;
1041	TextureRenderer				m_renderer;
1042};
1043
1044Texture2DFileCase::Texture2DFileCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
1045	: TestCase			(testCtx, name, description)
1046	, m_renderCtx		(renderCtx)
1047	, m_renderCtxInfo	(renderCtxInfo)
1048	, m_filenames		(filenames)
1049	, m_texture			(DE_NULL)
1050	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1051{
1052}
1053
1054Texture2DFileCase::~Texture2DFileCase (void)
1055{
1056	deinit();
1057}
1058
1059void Texture2DFileCase::init (void)
1060{
1061	// Create texture.
1062	m_texture = glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
1063}
1064
1065void Texture2DFileCase::deinit (void)
1066{
1067	delete m_texture;
1068	m_texture = DE_NULL;
1069
1070	m_renderer.clear();
1071}
1072
1073Texture2DFileCase::IterateResult Texture2DFileCase::iterate (void)
1074{
1075	const glw::Functions&	gl					= m_renderCtx.getFunctions();
1076	TestLog&				log					= m_testCtx.getLog();
1077	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
1078	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
1079	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
1080	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
1081	vector<float>			texCoord;
1082
1083	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
1084
1085	// Setup base viewport.
1086	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
1087
1088	// Bind to unit 0.
1089	gl.activeTexture(GL_TEXTURE0);
1090	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
1091
1092	// Setup nearest neighbor filtering and clamp-to-edge.
1093	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
1094	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
1095	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
1096	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
1097
1098	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
1099
1100	// Draw.
1101	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
1102	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
1103	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
1104
1105	// Compute reference.
1106	ReferenceParams refParams(TEXTURETYPE_2D);
1107	refParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
1108	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], refParams);
1109
1110	// Compare and log.
1111	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
1112
1113	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
1114							isOk ? "Pass"				: "Image comparison failed");
1115
1116	return STOP;
1117}
1118
1119// TextureCubeFileCase
1120
1121class TextureCubeFileCase : public tcu::TestCase
1122{
1123public:
1124								TextureCubeFileCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
1125								~TextureCubeFileCase	(void);
1126
1127	void						init					(void);
1128	void						deinit					(void);
1129	IterateResult				iterate					(void);
1130
1131private:
1132								TextureCubeFileCase		(const TextureCubeFileCase& other);
1133	TextureCubeFileCase&		operator=				(const TextureCubeFileCase& other);
1134
1135	bool						testFace				(tcu::CubeFace face);
1136
1137	glu::RenderContext&			m_renderCtx;
1138	const glu::ContextInfo&		m_renderCtxInfo;
1139
1140	std::vector<std::string>	m_filenames;
1141
1142	glu::TextureCube*			m_texture;
1143	TextureRenderer				m_renderer;
1144
1145	int							m_curFace;
1146	bool						m_isOk;
1147};
1148
1149TextureCubeFileCase::TextureCubeFileCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
1150	: TestCase			(testCtx, name, description)
1151	, m_renderCtx		(renderCtx)
1152	, m_renderCtxInfo	(renderCtxInfo)
1153	, m_filenames		(filenames)
1154	, m_texture			(DE_NULL)
1155	, m_renderer		(renderCtx, testCtx, glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
1156	, m_curFace			(0)
1157	, m_isOk			(false)
1158{
1159}
1160
1161TextureCubeFileCase::~TextureCubeFileCase (void)
1162{
1163	deinit();
1164}
1165
1166void TextureCubeFileCase::init (void)
1167{
1168	// Create texture.
1169	DE_ASSERT(m_filenames.size() % 6 == 0);
1170	m_texture = glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size()/6, m_filenames);
1171
1172	m_curFace	= 0;
1173	m_isOk		= true;
1174}
1175
1176void TextureCubeFileCase::deinit (void)
1177{
1178	delete m_texture;
1179	m_texture = DE_NULL;
1180
1181	m_renderer.clear();
1182}
1183
1184bool TextureCubeFileCase::testFace (tcu::CubeFace face)
1185{
1186	const glw::Functions&	gl					= m_renderCtx.getFunctions();
1187	TestLog&				log					= m_testCtx.getLog();
1188	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(), m_texture->getRefTexture().getSize(), deStringHash(getName())+(deUint32)face);
1189	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
1190	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
1191	Sampler					sampler				(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
1192	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
1193	vector<float>			texCoord;
1194
1195	computeQuadTexCoordCube(texCoord, face);
1196
1197	// \todo [2011-10-28 pyry] Image set name / section?
1198	log << TestLog::Message << face << TestLog::EndMessage;
1199
1200	// Setup base viewport.
1201	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
1202
1203	// Bind to unit 0.
1204	gl.activeTexture(GL_TEXTURE0);
1205	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
1206
1207	// Setup nearest neighbor filtering and clamp-to-edge.
1208	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1209	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1210	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1211	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1212
1213	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
1214
1215	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
1216	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
1217	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
1218
1219	// Compute reference.
1220	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_CUBE, sampler));
1221
1222	// Compare and log.
1223	return compareImages(log, referenceFrame, renderedFrame, threshold);
1224}
1225
1226TextureCubeFileCase::IterateResult TextureCubeFileCase::iterate (void)
1227{
1228	// Execute test for all faces.
1229	if (!testFace((tcu::CubeFace)m_curFace))
1230		m_isOk = false;
1231
1232	m_curFace += 1;
1233
1234	if (m_curFace == tcu::CUBEFACE_LAST)
1235	{
1236		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
1237								m_isOk ? "Pass"					: "Image comparison failed");
1238		return STOP;
1239	}
1240	else
1241		return CONTINUE;
1242}
1243
1244// TextureFormatTests
1245
1246TextureFormatTests::TextureFormatTests (Context& context)
1247	: TestCaseGroup(context, "format", "Texture Format Tests")
1248{
1249}
1250
1251TextureFormatTests::~TextureFormatTests (void)
1252{
1253}
1254
1255vector<string> toStringVector (const char* const* str, int numStr)
1256{
1257	vector<string> v;
1258	v.resize(numStr);
1259	for (int i = 0; i < numStr; i++)
1260		v[i] = str[i];
1261	return v;
1262}
1263
1264void TextureFormatTests::init (void)
1265{
1266	tcu::TestCaseGroup* unsizedGroup	= DE_NULL;
1267	tcu::TestCaseGroup*	sizedGroup		= DE_NULL;
1268	tcu::TestCaseGroup* compressedGroup	= DE_NULL;
1269	addChild((unsizedGroup		= new tcu::TestCaseGroup(m_testCtx, "unsized",		"Unsized formats")));
1270	addChild((sizedGroup		= new tcu::TestCaseGroup(m_testCtx, "sized",		"Sized formats")));
1271	addChild((compressedGroup	= new tcu::TestCaseGroup(m_testCtx, "compressed",	"Compressed formats")));
1272
1273	tcu::TestCaseGroup*	sized2DGroup		= DE_NULL;
1274	tcu::TestCaseGroup*	sizedCubeGroup		= DE_NULL;
1275	tcu::TestCaseGroup*	sized2DArrayGroup	= DE_NULL;
1276	tcu::TestCaseGroup*	sized3DGroup		= DE_NULL;
1277	sizedGroup->addChild((sized2DGroup			= new tcu::TestCaseGroup(m_testCtx, "2d",			"Sized formats (2D)")));
1278	sizedGroup->addChild((sizedCubeGroup		= new tcu::TestCaseGroup(m_testCtx, "cube",			"Sized formats (Cubemap)")));
1279	sizedGroup->addChild((sized2DArrayGroup		= new tcu::TestCaseGroup(m_testCtx, "2d_array",		"Sized formats (2D Array)")));
1280	sizedGroup->addChild((sized3DGroup			= new tcu::TestCaseGroup(m_testCtx, "3d",			"Sized formats (3D)")));
1281
1282	struct
1283	{
1284		const char*	name;
1285		deUint32		format;
1286		deUint32		dataType;
1287	} texFormats[] =
1288	{
1289		{ "alpha",							GL_ALPHA,			GL_UNSIGNED_BYTE },
1290		{ "luminance",						GL_LUMINANCE,		GL_UNSIGNED_BYTE },
1291		{ "luminance_alpha",				GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
1292		{ "rgb_unsigned_short_5_6_5",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
1293		{ "rgb_unsigned_byte",				GL_RGB,				GL_UNSIGNED_BYTE },
1294		{ "rgba_unsigned_short_4_4_4_4",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
1295		{ "rgba_unsigned_short_5_5_5_1",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
1296		{ "rgba_unsigned_byte",				GL_RGBA,			GL_UNSIGNED_BYTE }
1297	};
1298
1299	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1300	{
1301		deUint32	format			= texFormats[formatNdx].format;
1302		deUint32	dataType		= texFormats[formatNdx].dataType;
1303		string	nameBase		= texFormats[formatNdx].name;
1304		string	descriptionBase	= string(glu::getPixelFormatName(format)) + ", " + glu::getTypeName(dataType);
1305
1306		unsizedGroup->addChild(new Texture2DFormatCase			(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_pot").c_str(),			(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType, 128, 128));
1307		unsizedGroup->addChild(new Texture2DFormatCase			(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType,  63, 112));
1308		unsizedGroup->addChild(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  64,  64));
1309		unsizedGroup->addChild(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  57,  57));
1310		unsizedGroup->addChild(new Texture2DArrayFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_array_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	format, dataType,  64,  64,  8));
1311		unsizedGroup->addChild(new Texture2DArrayFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_array_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	format, dataType,  63,  57,  7));
1312		unsizedGroup->addChild(new Texture3DFormatCase			(m_testCtx, m_context.getRenderContext(),	(nameBase + "_3d_pot").c_str(),			(descriptionBase + ", GL_TEXTURE_3D").c_str(),			format, dataType,   8,  32, 16));
1313		unsizedGroup->addChild(new Texture3DFormatCase			(m_testCtx, m_context.getRenderContext(),	(nameBase + "_3d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_3D").c_str(),			format, dataType,  11,  31,  7));
1314	}
1315
1316	struct
1317	{
1318		const char*	name;
1319		deUint32		internalFormat;
1320	} sizedColorFormats[] =
1321	{
1322		{ "rgba32f",			GL_RGBA32F,			},
1323		{ "rgba32i",			GL_RGBA32I,			},
1324		{ "rgba32ui",			GL_RGBA32UI,		},
1325		{ "rgba16f",			GL_RGBA16F,			},
1326		{ "rgba16i",			GL_RGBA16I,			},
1327		{ "rgba16ui",			GL_RGBA16UI,		},
1328		{ "rgba8",				GL_RGBA8,			},
1329		{ "rgba8i",				GL_RGBA8I,			},
1330		{ "rgba8ui",			GL_RGBA8UI,			},
1331		{ "srgb8_alpha8",		GL_SRGB8_ALPHA8,	},
1332		{ "rgb10_a2",			GL_RGB10_A2,		},
1333		{ "rgb10_a2ui",			GL_RGB10_A2UI,		},
1334		{ "rgba4",				GL_RGBA4,			},
1335		{ "rgb5_a1",			GL_RGB5_A1,			},
1336		{ "rgba8_snorm",		GL_RGBA8_SNORM,		},
1337		{ "rgb8",				GL_RGB8,			},
1338		{ "rgb565",				GL_RGB565,			},
1339		{ "r11f_g11f_b10f",		GL_R11F_G11F_B10F,	},
1340		{ "rgb32f",				GL_RGB32F,			},
1341		{ "rgb32i",				GL_RGB32I,			},
1342		{ "rgb32ui",			GL_RGB32UI,			},
1343		{ "rgb16f",				GL_RGB16F,			},
1344		{ "rgb16i",				GL_RGB16I,			},
1345		{ "rgb16ui",			GL_RGB16UI,			},
1346		{ "rgb8_snorm",			GL_RGB8_SNORM,		},
1347		{ "rgb8i",				GL_RGB8I,			},
1348		{ "rgb8ui",				GL_RGB8UI,			},
1349		{ "srgb8",				GL_SRGB8,			},
1350		{ "rgb9_e5",			GL_RGB9_E5,			},
1351		{ "rg32f",				GL_RG32F,			},
1352		{ "rg32i",				GL_RG32I,			},
1353		{ "rg32ui",				GL_RG32UI,			},
1354		{ "rg16f",				GL_RG16F,			},
1355		{ "rg16i",				GL_RG16I,			},
1356		{ "rg16ui",				GL_RG16UI,			},
1357		{ "rg8",				GL_RG8,				},
1358		{ "rg8i",				GL_RG8I,			},
1359		{ "rg8ui",				GL_RG8UI,			},
1360		{ "rg8_snorm",			GL_RG8_SNORM,		},
1361		{ "r32f",				GL_R32F,			},
1362		{ "r32i",				GL_R32I,			},
1363		{ "r32ui",				GL_R32UI,			},
1364		{ "r16f",				GL_R16F,			},
1365		{ "r16i",				GL_R16I,			},
1366		{ "r16ui",				GL_R16UI,			},
1367		{ "r8",					GL_R8,				},
1368		{ "r8i",				GL_R8I,				},
1369		{ "r8ui",				GL_R8UI,			},
1370		{ "r8_snorm",			GL_R8_SNORM,		}
1371	};
1372
1373	struct
1374	{
1375		const char*	name;
1376		deUint32		internalFormat;
1377	} sizedDepthStencilFormats[] =
1378	{
1379		// Depth and stencil formats
1380		{ "depth_component32f",	GL_DEPTH_COMPONENT32F	},
1381		{ "depth_component24",	GL_DEPTH_COMPONENT24	},
1382		{ "depth_component16",	GL_DEPTH_COMPONENT16	},
1383		{ "depth32f_stencil8",	GL_DEPTH32F_STENCIL8	},
1384		{ "depth24_stencil8",	GL_DEPTH24_STENCIL8		}
1385	};
1386
1387	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(sizedColorFormats); formatNdx++)
1388	{
1389		deUint32	internalFormat	= sizedColorFormats[formatNdx].internalFormat;
1390		string	nameBase		= sizedColorFormats[formatNdx].name;
1391		string	descriptionBase	= glu::getPixelFormatName(internalFormat);
1392
1393		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat, 128, 128));
1394		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat,  63, 112));
1395		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  64,  64));
1396		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  57,  57));
1397		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  64,  64,  8));
1398		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  63,  57,  7));
1399		sized3DGroup->addChild		(new Texture3DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_3D").c_str(),			internalFormat,   8,  32, 16));
1400		sized3DGroup->addChild		(new Texture3DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_3D").c_str(),			internalFormat,  11,  31,  7));
1401	}
1402
1403	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(sizedDepthStencilFormats); formatNdx++)
1404	{
1405		deUint32	internalFormat	= sizedDepthStencilFormats[formatNdx].internalFormat;
1406		string	nameBase		= sizedDepthStencilFormats[formatNdx].name;
1407		string	descriptionBase	= glu::getPixelFormatName(internalFormat);
1408
1409		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat, 128, 128));
1410		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat,  63, 112));
1411		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  64,  64));
1412		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  57,  57));
1413		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  64,  64,  8));
1414		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  63,  57,  7));
1415	}
1416
1417	// ETC-1 compressed formats.
1418	{
1419		static const char* filenames[] =
1420		{
1421			"data/etc1/photo_helsinki_mip_0.pkm",
1422			"data/etc1/photo_helsinki_mip_1.pkm",
1423			"data/etc1/photo_helsinki_mip_2.pkm",
1424			"data/etc1/photo_helsinki_mip_3.pkm",
1425			"data/etc1/photo_helsinki_mip_4.pkm",
1426			"data/etc1/photo_helsinki_mip_5.pkm",
1427			"data/etc1/photo_helsinki_mip_6.pkm",
1428			"data/etc1/photo_helsinki_mip_7.pkm"
1429		};
1430		compressedGroup->addChild(new Texture2DFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", toStringVector(filenames, DE_LENGTH_OF_ARRAY(filenames))));
1431	}
1432
1433	{
1434		vector<string> filenames;
1435		filenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
1436		compressedGroup->addChild(new Texture2DFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_npot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", filenames));
1437	}
1438
1439	{
1440		static const char* faceExt[] = { "neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z" };
1441
1442		const int		potNumLevels	= 7;
1443		vector<string>	potFilenames;
1444		for (int level = 0; level < potNumLevels; level++)
1445			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1446				potFilenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) + ".pkm");
1447
1448		compressedGroup->addChild(new TextureCubeFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_CUBE_MAP", potFilenames));
1449
1450		vector<string> npotFilenames;
1451		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1452			npotFilenames.push_back(string("data/etc1/skybox_61x61_") + faceExt[face] + ".pkm");
1453
1454		compressedGroup->addChild(new TextureCubeFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_npot", "GL_ETC_RGB8_OES, GL_TEXTURE_CUBE_MAP", npotFilenames));
1455	}
1456
1457	// ETC-2 and EAC compressed formats.
1458	struct {
1459		const char*						descriptionBase;
1460		const char*						nameBase;
1461		tcu::CompressedTexture::Format	format;
1462	} etc2Formats[] =
1463	{
1464		{ "GL_COMPRESSED_R11_EAC",							"eac_r11",							tcu::CompressedTexture::EAC_R11,						},
1465		{ "GL_COMPRESSED_SIGNED_R11_EAC",					"eac_signed_r11",					tcu::CompressedTexture::EAC_SIGNED_R11,					},
1466		{ "GL_COMPRESSED_RG11_EAC",							"eac_rg11",							tcu::CompressedTexture::EAC_RG11,						},
1467		{ "GL_COMPRESSED_SIGNED_RG11_EAC",					"eac_signed_rg11",					tcu::CompressedTexture::EAC_SIGNED_RG11,				},
1468		{ "GL_COMPRESSED_RGB8_ETC2",						"etc2_rgb8",						tcu::CompressedTexture::ETC2_RGB8,						},
1469		{ "GL_COMPRESSED_SRGB8_ETC2",						"etc2_srgb8",						tcu::CompressedTexture::ETC2_SRGB8,						},
1470		{ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",	"etc2_rgb8_punchthrough_alpha1",	tcu::CompressedTexture::ETC2_RGB8_PUNCHTHROUGH_ALPHA1,	},
1471		{ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",	"etc2_srgb8_punchthrough_alpha1",	tcu::CompressedTexture::ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,	},
1472		{ "GL_COMPRESSED_RGBA8_ETC2_EAC",					"etc2_eac_rgba8",					tcu::CompressedTexture::ETC2_EAC_RGBA8,					},
1473		{ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",			"etc2_eac_srgb8_alpha8",			tcu::CompressedTexture::ETC2_EAC_SRGB8_ALPHA8,			}
1474	};
1475
1476	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(etc2Formats); formatNdx++)
1477	{
1478		string descriptionBase	= etc2Formats[formatNdx].descriptionBase;
1479		string nameBase			= etc2Formats[formatNdx].nameBase;
1480
1481		compressedGroup->addChild(new Compressed2DFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_2d_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			etc2Formats[formatNdx].format,	1,	128,	64));
1482		compressedGroup->addChild(new CompressedCubeFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_cube_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	etc2Formats[formatNdx].format,	1,	64,		64));
1483		compressedGroup->addChild(new Compressed2DFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_2d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			etc2Formats[formatNdx].format,	1,	51,		65));
1484		compressedGroup->addChild(new CompressedCubeFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_cube_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	etc2Formats[formatNdx].format,	1,	51,		51));
1485	}
1486
1487
1488}
1489
1490} // Functional
1491} // gles3
1492} // deqp
1493